Read Nvidia Driver version via NVML

This commit is contained in:
harlekin
2023-01-06 14:19:34 +00:00
parent aaa1b466dd
commit 1bf519c9c3
9 changed files with 115 additions and 27 deletions

View File

@@ -28,6 +28,8 @@ public class GPUDevice {
private String oldId; // for backward compatibility
private String driverVersion;
public GPUDevice(String type, String model, long ram, String id) {
this.type = type;
this.model = model;
@@ -80,7 +82,34 @@ public class GPUDevice {
this.oldId = id;
}
public String getDriverVersion() {
return this.driverVersion;
}
public void setDriverVersion(String driverVersion) {
this.driverVersion = driverVersion;
}
@Override public String toString() {
return "GPUDevice [type=" + type + ", model='" + model + "', memory=" + memory + ", id=" + id + "]";
return "GPUDevice [type=" + type + ", model='" + model + "', memory=" + memory + ", id=" + id + ", driverVersion=" + driverVersion + "]";
}
public static int compareVersions(String version1, String version2) {
int comparisonResult = 0;
String[] version1Splits = version1.split("\\.");
String[] version2Splits = version2.split("\\.");
int maxLengthOfVersionSplits = Math.max(version1Splits.length, version2Splits.length);
for (int i = 0; i < maxLengthOfVersionSplits; i++){
Integer v1 = i < version1Splits.length ? Integer.parseInt(version1Splits[i]) : 0;
Integer v2 = i < version2Splits.length ? Integer.parseInt(version2Splits[i]) : 0;
int compare = v1.compareTo(v2);
if (compare != 0) {
comparisonResult = compare;
break;
}
}
return comparisonResult;
}
}

View File

@@ -187,7 +187,7 @@ public class HIP implements GPULister {
return null;
}
boolean driverTooOld = compareVersions(driverVersion, MINIMAL_WINDOWS_DRIVER_VERSION) < 0;
boolean driverTooOld = GPUDevice.compareVersions(driverVersion, MINIMAL_WINDOWS_DRIVER_VERSION) < 0;
if (driverTooOld) {
System.out.println("HIP::getGpus AMD driver too old");
@@ -207,29 +207,11 @@ public class HIP implements GPULister {
String deviceIdentifier = getIdentifier(i);
String oldID = TYPE + "_" + numberedID;
GPUDevice device = new GPUDevice(TYPE, deviceName, vram, deviceIdentifier, oldID);
device.setDriverVersion(driverVersion);
gpuDevices.add(device);
numberedID++;
}
return gpuDevices;
}
private int compareVersions(String version1, String version2) {
int comparisonResult = 0;
String[] version1Splits = version1.split("\\.");
String[] version2Splits = version2.split("\\.");
int maxLengthOfVersionSplits = Math.max(version1Splits.length, version2Splits.length);
for (int i = 0; i < maxLengthOfVersionSplits; i++){
Integer v1 = i < version1Splits.length ? Integer.parseInt(version1Splits[i]) : 0;
Integer v2 = i < version2Splits.length ? Integer.parseInt(version2Splits[i]) : 0;
int compare = v1.compareTo(v2);
if (compare != 0) {
comparisonResult = compare;
break;
}
}
return comparisonResult;
}
}

View File

@@ -25,20 +25,23 @@ import com.sun.jna.ptr.LongByReference;
public interface CUDA extends Library {
public int cuInit(int flags);
/*
* @return: CUDA_SUCCESS, CUDA_ERROR_DEINITIALIZED, CUDA_ERROR_NOT_INITIALIZED, CUDA_ERROR_INVALID_CONTEXT, CUDA_ERROR_INVALID_VALUE
*/
public int cuDeviceGetCount(IntByReference count);
public int cuDeviceGetName(byte[] name, int len, int dev);
public int cuDeviceGet(IntByReference device, int ordinal);
public int cuDeviceGetAttribute(IntByReference pi, int attrib, int dev);
public int cuDeviceTotalMem_v2(LongByReference bytes, int dev);
public int cuDeviceTotalMem(LongByReference bytes, int dev);
public int cudaRuntimeGetVersion(IntByReference version);
public int cudaDriverGetVersion(IntByReference version);
}

View File

@@ -0,0 +1,14 @@
package com.sheepit.client.hardware.gpu.nvidia;
import com.sun.jna.Library;
import com.sun.jna.ptr.IntByReference;
//https://docs.nvidia.com/deploy/nvml-api/group__nvmlSystemQueries.html#group__nvmlSystemQueries
public interface NVML extends Library {
public int nvmlInit_v2();
public int nvmlShutdown ();
public int nvmlSystemGetDriverVersion(byte[] version, int length);
}

View File

@@ -0,0 +1,9 @@
package com.sheepit.client.hardware.gpu.nvidia;
//https://docs.nvidia.com/deploy/nvml-api/group__nvmlDeviceEnumvs.html
public class NVMLResult {
public static final int NVML_SUCCESS = 0;
public static final int NVML_ERROR_UNITIALIZED = 1; //NVML was not initialized with nvmlInit()
public static final int NVML_ERROR_INVALID_ARGUMENT = 2;
public static final int NVML_ERROR_INSUFFICIENT_SIZE = 7;
}

View File

@@ -6,6 +6,7 @@ import java.util.List;
import com.sheepit.client.hardware.gpu.GPUDevice;
import com.sheepit.client.hardware.gpu.GPULister;
import com.sheepit.client.os.OS;
import com.sun.jna.Memory;
import com.sun.jna.Native;
import com.sun.jna.ptr.IntByReference;
import com.sun.jna.ptr.LongByReference;
@@ -13,6 +14,9 @@ import com.sun.jna.ptr.LongByReference;
public class Nvidia implements GPULister {
public static String TYPE = "OPTIX";
//https://docs.blender.org/manual/en/3.3/render/cycles/gpu_rendering.html#optix-nvidia
private static final String MINIMUM_DRIVER_VERSION = "470";
@Override public List<GPUDevice> getGpus() {
OS os = OS.getOS();
String path = os.getCUDALib();
@@ -127,9 +131,44 @@ public class Nvidia implements GPULister {
return null;
}
NVML nvml = null;
try {
nvml = Native.load(os.getNVMLLib(), NVML.class);
}
catch (UnsatisfiedLinkError e) {
System.out.println("Nvidia::getGpus failed to load NVML library");
return null;
}
result = nvml.nvmlInit_v2();
if (result != NVMLResult.NVML_SUCCESS) {
System.out.println("Nvidia::getGpus failed to nvmlInit failed. Returned " + result);
return null;
}
short stringLength = 80;
byte[] driverStringBuffer = new byte[stringLength];
result = nvml.nvmlSystemGetDriverVersion(driverStringBuffer, stringLength); //The returned char* will never exceed 80 characters according to the docs
if (result != NVMLResult.NVML_SUCCESS) {
System.out.println("Nvidia::getGpus failed to retrieve driver version");
nvml.nvmlShutdown();
return null;
}
nvml.nvmlShutdown();
String driverVersion = new String(driverStringBuffer);
boolean driverTooOld = GPUDevice.compareVersions(driverVersion, MINIMUM_DRIVER_VERSION) < 0;
if (driverTooOld) {
System.out.println("Nvidia::getGpus driver version too old: " + driverVersion);
return null;
}
String blenderId = String
.format("CUDA_%s_%04x:%02x:%02x_OptiX", new String(name).trim(), pciDomainId.getValue(), pciBusId.getValue(), pciDeviceId.getValue());
GPUDevice gpu = new GPUDevice(TYPE, new String(name).trim(), ram.getValue(), blenderId);
gpu.setDriverVersion(driverVersion);
// for backward compatibility generate a CUDA_N id
gpu.setOldId(TYPE + "_" + num);
devices.add(gpu);

View File

@@ -49,6 +49,10 @@ public class Linux extends OS {
return "cuda";
}
@Override public String getNVMLLib() {
return "nvidia-ml";
}
@Override public Process exec(List<String> command, Map<String, String> env_overight) throws IOException {
Map<String, String> new_env = new HashMap<String, String>();
new_env.putAll(java.lang.System.getenv()); // clone the env

View File

@@ -63,6 +63,11 @@ public abstract class OS {
return null;
}
//path to NVIDIA NVML lib
public String getNVMLLib() {
return null;
}
public abstract boolean getSupportHighPriority();
public abstract boolean checkNiceAvailability();

View File

@@ -42,6 +42,9 @@ public class Windows extends OS {
@Override public String getCUDALib() {
return "nvcuda";
}
@Override public String getNVMLLib() {
return "nvml";
}
@Override public Process exec(List<String> command, Map<String, String> env) throws IOException {
// disable a popup because the renderer might crash (seg fault)