LWJGL在IDE外部运行时发现不同的OpenCL安装



我在IntelliJ中使用java作为一种爱好已经有一段时间了,并决定开始使用OpenCL进行并行计算。我确信我下载LWJGL库并将其添加到我的项目中没有错,因为它总是编译的。问题是,当我运行程序时,它会产生以下输出:

Platforms found: 1
Treating platform 140038554960288
Platform name: Clover 
Platform vendor: Mesa 
Platform version: OpenCL 1.1 Mesa 20.1.5 
Error: -1
Exception in thread "main" java.lang.AssertionError: -1
at ch.test.Test1.devices_gpu(Test1.java:71)
at ch.test.Test1.treatPlatform(Test1.java:22)
at ch.test.Test1.main(Test1.java:94)

该程序使用assert检查OpenCL函数的每次返回,当没有返回CL_SUCCESS时崩溃。此处的错误为CL_DEVICE_NOT_FOUND。

当我将项目导出为jar并在IDE中运行时,它会产生相同的输出。但是,如果我将发出的命令(/home/user/Downloads/jdk-14.0.2/bin/java -ea -Dfile.encoding=UTF-8 -jar /home/user/IdeaProjects/LWJGLTest/out/artifacts/LWJGLTest_jar/LWJGLTest.jar(复制到控制台并在那里运行jar,它会给我以下(预期的(输出:

user@user-desktop:~$ /home/user/Downloads/jdk-14.0.2/bin/java -ea -Dfile.encoding=UTF-8 -jar /home/user/IdeaProjects/LWJGLTest/out/artifacts/LWJGLTest_jar/LWJGLTest.jar
Platforms found: 1
Treating platform 140169617041680
Platform name: NVIDIA CUDA
Platform vendor: NVIDIA Corporation
Platform version: OpenCL 1.2 CUDA 10.2.178
Error: 0
1
Devices found: 1
Name: GeForce GTX 1080

我使用clinfo来查看我的计算机找到了哪些OpenCL平台:

user@user-desktop:~$ clinfo
Number of platforms                               1
Platform Name                                   NVIDIA CUDA
Platform Vendor                                 NVIDIA Corporation
Platform Version                                OpenCL 1.2 CUDA 11.0.228
Platform Profile                                FULL_PROFILE
Platform Extensions                             cl_khr_global_int32_base_atomics cl_khr_global_int32_extended_atomics cl_khr_local_int32_base_atomics cl_khr_local_int32_extended_atomics cl_khr_fp64 cl_khr_byte_addressable_store cl_khr_icd cl_khr_gl_sharing cl_nv_compiler_options cl_nv_device_attribute_query cl_nv_pragma_unroll cl_nv_copy_opts cl_nv_create_buffer cl_khr_int64_base_atomics cl_khr_int64_extended_atomics
Platform Extensions function suffix             NV
Platform Name                                   NVIDIA CUDA
Number of devices                                 1
Device Name                                     GeForce GTX 1080
...

有趣的是,当我更改驱动程序(从开源到专有,反之亦然(时,clinfo暂时找不到任何平台(当然,直到我重新启动(,但在IntelliJ中,代码会产生相同的输出(当没有安装时会找到一个平台!(,而当在jar中运行时,则找不到平台。

我尝试过几种不同的JRE,但在IntelliJ中都不起作用。我也尝试过更改类路径,但似乎什么都不起作用。

这一切都在Linux Mint 19下。当我在带Windows的笔记本电脑上做同样的事情时,没有问题,一切都很好。用于测试的代码:

package ch.test;
import org.lwjgl.PointerBuffer;
import org.lwjgl.opencl.CL22;
import java.nio.ByteBuffer;
public class Test1 {
static int getNumOfPlatforms() {
int[] buffer = new int[1];
int error = CL22.clGetPlatformIDs(null, buffer);
assert error == CL22.CL_SUCCESS;
return buffer[0];
}
static void treatPlatform(long plat) {
System.out.println("tPlatform name: " + getPlatformParam(plat, CL22.CL_PLATFORM_NAME));
System.out.println("tPlatform vendor: " + getPlatformParam(plat, CL22.CL_PLATFORM_VENDOR));
System.out.println("tPlatform version: " + getPlatformParam(plat, CL22.CL_PLATFORM_VERSION));
PointerBuffer devices = devices_gpu(plat);
System.out.println("tDevices found: " + devices.capacity());
while(devices.hasRemaining()) {
treatDevice(devices.get());
}
}

static void treatDevice(long device) {
System.out.println("ttName: " + deviceProperty(device, CL22.CL_DEVICE_NAME));
}
static String deviceProperty(long device, int prop) {
PointerBuffer length = PointerBuffer.allocateDirect(1);
CL22.clGetDeviceInfo(device, prop, (long[])null, length);
ByteBuffer value = ByteBuffer.allocateDirect((int)length.get());
CL22.clGetDeviceInfo(device, prop, value, null);
StringBuilder builder = new StringBuilder(value.capacity());
for(int i = 0; i < builder.capacity(); i++){
builder.append((char)value.get());
}
return builder.toString();
}
static String getPlatformParam(long plat, int attr) {
PointerBuffer length = PointerBuffer.allocateDirect(1);
CL22.clGetPlatformInfo(plat, attr, (long[])null, length);
ByteBuffer value = ByteBuffer.allocateDirect((int)length.get());
CL22.clGetPlatformInfo(plat, attr, value, null);
StringBuilder builder = new StringBuilder(value.capacity());
for(int i = 0; i < builder.capacity(); i++){
builder.append((char)value.get());
}
return builder.toString();
}
static PointerBuffer devices_gpu(long plat) {
int error;
int[] amount = new int[]{-1};
error = CL22.clGetDeviceIDs(plat, CL22.CL_DEVICE_TYPE_ALL, null, amount);
System.out.println("Error: " + error);
assert error == CL22.CL_SUCCESS: error;

System.out.println(amount[0]);
PointerBuffer devices = PointerBuffer.allocateDirect(amount[0]);
error = CL22.clGetDeviceIDs(plat, CL22.CL_DEVICE_TYPE_ALL, devices, (int[])null);
assert error == CL22.CL_SUCCESS: error;
return devices;
}
public static void main(String[] args) {
int error;
int amountOfPlatforms = getNumOfPlatforms();
System.out.println("Platforms found: " + amountOfPlatforms);
PointerBuffer platforms = PointerBuffer.allocateDirect(amountOfPlatforms);
error = CL22.clGetPlatformIDs(platforms, (int[])null);
assert error == CL22.CL_SUCCESS;
while(platforms.hasRemaining()) {
long plat = platforms.get();
System.out.println("Treating platform " + plat);
treatPlatform(plat);
}
}
}

虽然我没有找到确切的问题,但我通过从他们的网站重新安装IntelliJ来解决它。我以前用Linux Mint软件管理器进行的安装似乎有问题。现在一切都很好感谢阅读并提供帮助

最新更新