【问题标题】:LWJGL finding different OpenCL installation when runing outside of IDELWJGL 在 IDE 之外运行时发现不同的 OpenCL 安装
【发布时间】:2020-10-19 19:36:05
【问题描述】:

我在 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("\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);
        }
    }
}

【问题讨论】:

  • 在 IDE 下似乎只检测到 Mesa icd,而不是 Nvidia。您是否以其他(前提升的)用户身份运行 intellij?
  • 已解决,见下文,但无论如何感谢您说出没有您我不会尝试的事情
  • 不要编辑问题以表明它已解决。请改为阅读此内容:stackoverflow.com/help/someone-answers您可以接受自己的答案。

标签: java intellij-idea opencl lwjgl


【解决方案1】:

虽然我没有找到确切的问题,但我通过从他们的网站重新安装 IntelliJ 解决了这个问题。看来我之前由 Linux Mint 软件管理器完成的安装有问题。现在一切都很好 感谢您的阅读和帮助

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2015-10-03
    • 1970-01-01
    • 1970-01-01
    • 2013-07-30
    • 1970-01-01
    • 1970-01-01
    • 2017-06-30
    • 1970-01-01
    相关资源
    最近更新 更多