I've been using java in IntelliJ as a hobby for quite some time and have decided to start using OpenCL for parallel computing. I'm pretty sure that I've made no mistake downloading and adding the LWJGL library to my project, since it does always compile. The problem is that when I run the program, it produces this output:
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)
The program checks each return of the OpenCL functions using assert
and crashes when one does not return CL_SUCCESS. The error here is CL_DEVICE_NOT_FOUND.
When I export the project as a jar and run it inside my IDE, it produces the same output. However, if I copy the command issued (/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
) to the console and run the jar there, it gives me the following (expected) output:
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
I used the clinfo
to see which OpenCL platforms my computer finds:
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
...
Interestingly, when I change drivers (from the opensource to the proprietary and vice-versa), the clinfo
temporarily finds no platforms (until I reboot of course), but in IntelliJ, the code produces the same output (and finds a platform when none is installed!), while when run in a jar no platform is found.
I have tried several different JRE, but none work in IntelliJ. I have also tried changing the classpath, but nothing seems to work.
This is all under Linux Mint 19. When I do the same on my Laptop with Windows, there are no issues and everything works fine. The code used to test:
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("\t\tName: " + 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);
}
}
}
While I did not find the exact problem, I solved it by reinstalling IntelliJ from their website. It seems that my previous installation done by the Linux Mint Software Manager was faulty. Everything is showing up fine now Thanks for reading and helping though