Fix: do not use gpu order to set its id, instead use the same method as blender

This commit is contained in:
Laurent Clouet
2019-07-09 17:55:00 +02:00
parent 242104735b
commit a09f1ab016
5 changed files with 59 additions and 29 deletions

View File

@@ -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;
}
}

View File

@@ -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 + "]";

View File

@@ -66,7 +66,7 @@ public class Nvidia implements GPULister {
List<GPUDevice> devices = new LinkedList<GPUDevice>();
HashMap<Integer, GPUDevice> devicesWithPciId = new HashMap<Integer, GPUDevice>(count.getValue());
HashMap<String, GPUDevice> devicesWithPciId = new HashMap<String, GPUDevice>(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<Integer, GPUDevice> entry : devicesWithPciId.entrySet()){
for (Map.Entry<String, GPUDevice> 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;
}

View File

@@ -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));
}
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]);
}
}

View File

@@ -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);