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

huangapple go评论65阅读模式
英文:

LWJGL finding different OpenCL installation when runing outside of IDE

问题

我在 IntelliJ 中使用 Java 进行业余爱好编程已经有一段时间了,最近决定开始使用 OpenCL 进行并行计算。我相当确定已经没有错误地将 LWJGL 库下载并添加到我的项目中,因为它总是能够编译通过。问题是,当我运行程序时,它会产生以下输出:

找到的平台数:1
正在处理平台 140038554960288
平台名称:Clover
平台供应商:Mesa
平台版本:OpenCL 1.1 Mesa 20.1.5
错误:-1
在线程“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
找到的平台数:1
正在处理平台 140169617041680
平台名称:NVIDIA CUDA
平台供应商:NVIDIA Corporation
平台版本:OpenCL 1.2 CUDA 10.2.178
错误:0
1
找到的设备数:1
名称:GeForce GTX 1080

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

user@user-desktop:~$ clinfo
平台数 1
平台名称 NVIDIA CUDA
平台供应商 NVIDIA Corporation
平台版本 OpenCL 1.2 CUDA 11.0.228
平台配置 FULL_PROFILE
平台扩展 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
平台扩展函数后缀 NV

平台名称 NVIDIA CUDA
设备数 1
设备名称 GeForce GTX 1080
...

有趣的是,当我更改驱动程序(从开源驱动切换到专有驱动,反之亦然)时,`clinfo` 会暂时找不到平台(直到我重新启动计算机,当然了),但在 IntelliJ 中,代码仍会产生相同的输出(并在没有安装平台的情况下找到一个平台!),然而在运行 JAR 文件时却找不到平台。

我尝试过多个不同的 JRE 版本,但在 IntelliJ 中都无法工作。我还尝试过更改类路径,但似乎没有什么作用。

这一切都发生在 Linux Mint 19 下。而在我的笔记本电脑上使用 Windows 进行相同的操作则没有任何问题,一切正常运行。

用于测试的代码如下:

// 你的 Java 代码部分

英文:

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

答案1

得分: 0

虽然我没有找到确切的问题,但通过从他们的网站重新安装IntelliJ来解决了这个问题。似乎我之前通过Linux Mint软件管理器进行的安装存在问题。现在一切都正常显示了。谢谢阅读和帮助。

英文:

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

huangapple
  • 本文由 发表于 2020年10月20日 03:36:05
  • 转载请务必保留本文链接:https://go.coder-hub.com/64434070.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定