diff --git a/src/com/sheepit/client/hardware/gpu/GPU.java b/src/com/sheepit/client/hardware/gpu/GPU.java index 9866d42..4d23fc8 100644 --- a/src/com/sheepit/client/hardware/gpu/GPU.java +++ b/src/com/sheepit/client/hardware/gpu/GPU.java @@ -74,8 +74,8 @@ public class GPU { return devices; } - public static GPUDevice getGPUDevice(String device_model) { - if (device_model == null) { + public static GPUDevice getGPUDevice(String deviceId) { + if (deviceId == null) { return null; } @@ -88,7 +88,7 @@ public class GPU { } for (GPUDevice dev : devices) { - if (device_model.equals(dev.getId()) || device_model.equals(dev.getModel())) { + if (deviceId.equals(dev.getId()) || deviceId.equals(dev.getOldId())) { return dev; } } diff --git a/src/com/sheepit/client/hardware/gpu/GPUDevice.java b/src/com/sheepit/client/hardware/gpu/GPUDevice.java index b138a51..94371dd 100644 --- a/src/com/sheepit/client/hardware/gpu/GPUDevice.java +++ b/src/com/sheepit/client/hardware/gpu/GPUDevice.java @@ -26,6 +26,8 @@ public class GPUDevice { private String id; + private String oldId; // for backward compatibility + public GPUDevice(String type, String model, long ram, String id) { this.type = type; this.model = model; @@ -65,6 +67,14 @@ public class GPUDevice { this.id = id; } + public String getOldId() { + return oldId; + } + + public void setOldId(String id) { + this.oldId = id; + } + @Override public String toString() { return "GPUDevice [type=" + type + ", model='" + model + "', memory=" + memory + ", id=" + id + "]"; diff --git a/src/com/sheepit/client/hardware/gpu/nvidia/Nvidia.java b/src/com/sheepit/client/hardware/gpu/nvidia/Nvidia.java index 0d98b96..e1286ed 100644 --- a/src/com/sheepit/client/hardware/gpu/nvidia/Nvidia.java +++ b/src/com/sheepit/client/hardware/gpu/nvidia/Nvidia.java @@ -66,7 +66,7 @@ public class Nvidia implements GPULister { List devices = new LinkedList(); - HashMap devicesWithPciId = new HashMap(count.getValue()); + HashMap devicesWithPciId = new HashMap(count.getValue()); for (int num = 0; num < count.getValue(); num++) { IntByReference aDevice = new IntByReference(); @@ -76,12 +76,24 @@ public class Nvidia implements GPULister { continue; } + IntByReference pciDomainId = new IntByReference(); IntByReference pciBusId = new IntByReference(); + IntByReference pciDeviceId = new IntByReference(); + result = cudalib.cuDeviceGetAttribute(pciDomainId, CUDeviceAttribute.CU_DEVICE_ATTRIBUTE_PCI_DOMAIN_ID, aDevice.getValue()); + if (result != CUresult.CUDA_SUCCESS) { + System.out.println("Nvidia::getGpus cuDeviceGetAttribute for CU_DEVICE_ATTRIBUTE_PCI_DOMAIN_ID failed (ret: " + CUresult.stringFor(result) + ")"); + continue; + } result = cudalib.cuDeviceGetAttribute(pciBusId, CUDeviceAttribute.CU_DEVICE_ATTRIBUTE_PCI_BUS_ID, aDevice.getValue()); if (result != CUresult.CUDA_SUCCESS) { System.out.println("Nvidia::getGpus cuDeviceGetAttribute for CU_DEVICE_ATTRIBUTE_PCI_BUS_ID failed (ret: " + CUresult.stringFor(result) + ")"); continue; } + result = cudalib.cuDeviceGetAttribute(pciDeviceId, CUDeviceAttribute.CU_DEVICE_ATTRIBUTE_PCI_DEVICE_ID, aDevice.getValue()); + if (result != CUresult.CUDA_SUCCESS) { + System.out.println("Nvidia::getGpus cuDeviceGetAttribute for CU_DEVICE_ATTRIBUTE_PCI_DEVICE_ID failed (ret: " + CUresult.stringFor(result) + ")"); + continue; + } byte name[] = new byte[256]; @@ -105,18 +117,24 @@ public class Nvidia implements GPULister { return null; } - devicesWithPciId.put(pciBusId.getValue(), new GPUDevice(TYPE, new String(name).trim(), ram.getValue(), "FAKE")); + String blenderId = String.format("CUDA_%s_%04x:%02x:%02x", + new String(name).trim(), + pciDomainId.getValue(), + pciBusId.getValue(), + pciDeviceId.getValue()); + devicesWithPciId.put(Integer.toString(pciBusId.getValue()), new GPUDevice(TYPE, new String(name).trim(), ram.getValue(), blenderId)); } - // generate proper cuda id + // for backward compatibility generate a CUDA_N id // in theory a set to environment "CUDA_DEVICE_ORDER=PCI_BUS_ID" should be enough but it didn't work int i = 0; - for (Map.Entry entry : devicesWithPciId.entrySet()){ + for (Map.Entry entry : devicesWithPciId.entrySet()){ GPUDevice aDevice = entry.getValue(); - aDevice.setId(TYPE + "_" + Integer.toString(i)); + aDevice.setOldId(TYPE + "_" + Integer.toString(i)); devices.add(aDevice); i++; } + return devices; } diff --git a/src/com/sheepit/client/hardware/gpu/opencl/OpenCL.java b/src/com/sheepit/client/hardware/gpu/opencl/OpenCL.java index 294a05a..835b50c 100644 --- a/src/com/sheepit/client/hardware/gpu/opencl/OpenCL.java +++ b/src/com/sheepit/client/hardware/gpu/opencl/OpenCL.java @@ -105,13 +105,12 @@ public class OpenCL implements GPULister { } for (int j = 0; j < device_count.getValue(); j++) { - String platform_vendor = getInfoPlatform(lib, plateforms[i], OpenCLLib.CL_PLATFORM_VENDOR); - if (platform_vendor != null && platform_vendor.toLowerCase().equals("advanced micro devices, inc.")) { // opencl is only used for amd gpus - String name = getInfodeviceString(lib, devices[j], OpenCLLib.CL_DEVICE_BOARD_NAME_AMD); - long vram = getInfodeviceLong(lib, devices[j], OpenCLLib.CL_DEVICE_GLOBAL_MEM_SIZE); - if (name != null && vram > 0) { - available_devices.add(new GPUDevice(TYPE, name, vram, TYPE + "_" + id)); - } + String name = getInfodeviceString(lib, devices[j], OpenCLLib.CL_DEVICE_BOARD_NAME_AMD); + long vram = getInfodeviceLong(lib, devices[j], OpenCLLib.CL_DEVICE_GLOBAL_MEM_SIZE); + if (name != null && vram > 0) { + GPUDevice gpu = new GPUDevice(TYPE, new String(name).trim(), vram, getBlenderId(lib, devices[j])); + gpu.setOldId(TYPE + "_" + id); + available_devices.add(gpu); } id++; } @@ -158,4 +157,16 @@ public class OpenCL implements GPULister { return new String(name).trim(); } + + private static String getBlenderId(OpenCLLib lib, CLDeviceId.ByReference device) { + byte topology[] = new byte[24]; + + int status = lib.clGetDeviceInfo(device, 0x4037, 24, topology, null); + if (status != OpenCLLib.CL_SUCCESS) { + System.out.println("OpenCL::getBlenderId failed(I) status: " + status); + return ""; + } + + return String.format("%02x:%02x.%01x", topology[21], topology[22], topology[23]); + } } diff --git a/src/com/sheepit/client/standalone/Worker.java b/src/com/sheepit/client/standalone/Worker.java index d6c74b4..567afe1 100644 --- a/src/com/sheepit/client/standalone/Worker.java +++ b/src/com/sheepit/client/standalone/Worker.java @@ -154,26 +154,17 @@ public class Worker { if (gpu_device != null) { if (gpu_device.startsWith(Nvidia.TYPE) == false && gpu_device.startsWith(OpenCL.TYPE) == false) { - System.err.println("CUDA_DEVICE should look like '" + Nvidia.TYPE + "_X' or '" + OpenCL.TYPE + "_X' where X is a number"); - return; + System.err.println("GPU_ID should look like '" + Nvidia.TYPE + "_X' or '" + OpenCL.TYPE + "_X' more info on gpus available with --show-gpu"); + System.exit(2); } String family = ""; - try { - if (gpu_device.startsWith(Nvidia.TYPE)) { - family = Nvidia.TYPE; - } - else if (gpu_device.startsWith(OpenCL.TYPE)) { - family = OpenCL.TYPE; - } - Integer.parseInt(gpu_device.substring(family.length() + 1)); // for the _ - } - catch (NumberFormatException en) { - System.err.println("Gpu device code should look like '" + family + "_X' where X is a number"); + if (gpu_device.startsWith(Nvidia.TYPE) == false && gpu_device.startsWith(OpenCL.TYPE) == false) { + System.err.println("GPU_ID should look like '" + Nvidia.TYPE + "_X' or '" + OpenCL.TYPE + "_X' more info on gpus available with --show-gpu"); return; } GPUDevice gpu = GPU.getGPUDevice(gpu_device); if (gpu == null) { - System.err.println("GPU unknown"); + System.err.println("GPU unknown, list of available gpus can be display with --show-gpu"); System.exit(2); } config.setUseGPU(gpu);