}; // Keep everything until the miner quits. public static bool InitializeADL(OpenCLDevice[] mDevices) { var ADLRet = -1; var NumberOfAdapters = 0; if (null != ADL.ADL_Main_Control_Create) { ADLRet = ADL.ADL_Main_Control_Create(ADL.ADL_Main_Memory_Alloc, 1); } if (ADL.ADL_SUCCESS == ADLRet) { MainForm.Logger("Successfully initialized AMD Display Library."); if (null != ADL.ADL_Adapter_NumberOfAdapters_Get) { ADL.ADL_Adapter_NumberOfAdapters_Get(ref NumberOfAdapters); } MainForm.Logger("Number of ADL Adapters: " + NumberOfAdapters.ToString()); if (0 < NumberOfAdapters) { ADLAdapterInfoArray OSAdapterInfoData; OSAdapterInfoData = new ADLAdapterInfoArray(); if (null == ADL.ADL_Adapter_AdapterInfo_Get) { MainForm.Logger("ADL.ADL_Adapter_AdapterInfo_Get() is not available."); } else { var AdapterBuffer = IntPtr.Zero; var size = Marshal.SizeOf(OSAdapterInfoData); AdapterBuffer = Marshal.AllocCoTaskMem((int)size); Marshal.StructureToPtr(OSAdapterInfoData, AdapterBuffer, false); ADLRet = ADL.ADL_Adapter_AdapterInfo_Get(AdapterBuffer, size); if (ADL.ADL_SUCCESS == ADLRet) { OSAdapterInfoData = (ADLAdapterInfoArray)Marshal.PtrToStructure(AdapterBuffer, OSAdapterInfoData.GetType()); bool adrenalineWorkaroundRequired = false; foreach (var device in mDevices) { var openclDevice = device.GetComputeDevice(); if (device.GetVendor() == "AMD" && openclDevice.PciBusIdAMD <= 0) { adrenalineWorkaroundRequired = true; } } if (adrenalineWorkaroundRequired) { // workaround for Adrenalin drivers as PciBusIdAMD does not work properly. MainForm.Logger("Manually matching OpenCL devices with ADL devices..."); List <int> taken = new List <int> { }; foreach (var device in mDevices) { var openclDevice = device.GetComputeDevice(); if (device.GetVendor() == "AMD") { string boardName = (new System.Text.RegularExpressions.Regex("[^a-zA-Z0-9]+$")).Replace(System.Text.Encoding.ASCII.GetString(openclDevice.BoardNameAMD), ""); // Drop '\0' int boardCounter = 0; for (var i = 0; i < NumberOfAdapters; ++i) { if (OSAdapterInfoData.ADLAdapterInfo[i].AdapterName == boardName && !taken.Contains(OSAdapterInfoData.ADLAdapterInfo[i].BusNumber)) { boardCounter++; } while (i + 1 < NumberOfAdapters && OSAdapterInfoData.ADLAdapterInfo[i].BusNumber == OSAdapterInfoData.ADLAdapterInfo[i + 1].BusNumber) { ++i; } } if (boardCounter <= 1) { for (var i = 0; i < NumberOfAdapters; ++i) { if (OSAdapterInfoData.ADLAdapterInfo[i].AdapterName == boardName && !taken.Contains(OSAdapterInfoData.ADLAdapterInfo[i].BusNumber)) { device.ADLAdapterIndex = i; taken.Add(OSAdapterInfoData.ADLAdapterInfo[i].BusNumber); break; } while (i + 1 < NumberOfAdapters && OSAdapterInfoData.ADLAdapterInfo[i].BusNumber == OSAdapterInfoData.ADLAdapterInfo[i + 1].BusNumber) { ++i; } } } else { OpenCLDummyLbryMiner dummyMiner = new OpenCLDummyLbryMiner(device); dummyMinerList.Add(dummyMiner); dummyMiner.Start(); int[] activityTotalArray = new int[NumberOfAdapters]; for (var i = 0; i < NumberOfAdapters; ++i) { activityTotalArray[i] = 0; } for (var j = 0; j < 10; ++j) { for (var i = 0; i < NumberOfAdapters; ++i) { if (OSAdapterInfoData.ADLAdapterInfo[i].AdapterName == boardName && !taken.Contains(OSAdapterInfoData.ADLAdapterInfo[i].BusNumber)) { ADLPMActivity OSADLPMActivityData; OSADLPMActivityData = new ADLPMActivity(); var activityBuffer = IntPtr.Zero; size = Marshal.SizeOf(OSADLPMActivityData); activityBuffer = Marshal.AllocCoTaskMem((int)size); Marshal.StructureToPtr(OSADLPMActivityData, activityBuffer, false); if (null != ADL.ADL_Overdrive5_CurrentActivity_Get) { ADLRet = ADL.ADL_Overdrive5_CurrentActivity_Get(i, activityBuffer); if (ADL.ADL_SUCCESS == ADLRet) { OSADLPMActivityData = (ADLPMActivity)Marshal.PtrToStructure(activityBuffer, OSADLPMActivityData.GetType()); activityTotalArray[i] += OSADLPMActivityData.iActivityPercent; } } } while (i + 1 < NumberOfAdapters && OSAdapterInfoData.ADLAdapterInfo[i].BusNumber == OSAdapterInfoData.ADLAdapterInfo[i + 1].BusNumber) { ++i; } } System.Threading.Thread.Sleep(100); } int candidate = -1; int candidateActivity = 0; for (var i = 0; i < NumberOfAdapters; ++i) { if (OSAdapterInfoData.ADLAdapterInfo[i].AdapterName == boardName && !taken.Contains(OSAdapterInfoData.ADLAdapterInfo[i].BusNumber)) { if (candidate < 0 || activityTotalArray[i] > candidateActivity) { candidateActivity = activityTotalArray[i]; candidate = i; } } while (i + 1 < NumberOfAdapters && OSAdapterInfoData.ADLAdapterInfo[i].BusNumber == OSAdapterInfoData.ADLAdapterInfo[i + 1].BusNumber) { ++i; } } device.ADLAdapterIndex = candidate; taken.Add(OSAdapterInfoData.ADLAdapterInfo[candidate].BusNumber); dummyMiner.Stop(); for (int i = 0; i < 50; ++i) { if (dummyMiner.Stopped) { break; } System.Threading.Thread.Sleep(100); } if (!dummyMiner.Stopped) { MainForm.Logger("Failed at matching OpenCL devices with ADL devices. Restarting..."); System.Windows.Forms.Application.Exit(); } } } } } else { // Use openclDevice.PciBusIdAMD for matching. foreach (var device in mDevices) { var openclDevice = device.GetComputeDevice(); if (device.GetVendor() == "AMD") { for (var i = 0; i < NumberOfAdapters; i++) { var IsActive = 0; if (null != ADL.ADL_Adapter_Active_Get) { ADLRet = ADL.ADL_Adapter_Active_Get(OSAdapterInfoData.ADLAdapterInfo[i].AdapterIndex, ref IsActive); } if (OSAdapterInfoData.ADLAdapterInfo[i].BusNumber == openclDevice.PciBusIdAMD && (device.ADLAdapterIndex < 0 || IsActive != 0)) { device.ADLAdapterIndex = OSAdapterInfoData.ADLAdapterInfo[i].AdapterIndex; } } } } } } else { MainForm.Logger("ADL_Adapter_AdapterInfo_Get() returned error code " + ADLRet.ToString()); } // Release the memory for the AdapterInfo structure if (IntPtr.Zero != AdapterBuffer) { Marshal.FreeCoTaskMem(AdapterBuffer); } } } return(true); } else { MainForm.Logger("Failed to initialize AMD Display Library."); return(false); } }