【问题标题】:OpenCL compile failed aparapiOpenCL 编译失败
【发布时间】:2018-05-28 22:49:24
【问题描述】:

有谁知道这意味着什么以及这是怎么发生的?在我看来是对的。我正在尝试将 GPU 用于神经网络。

这是错误:

!!!!!!! clCreateCommandQueue() failed out of host memory
May 28, 2018 6:36:39 PM com.aparapi.internal.kernel.KernelRunner fallBackToNextDevice
WARNING: Device failed for Util$1, devices={AMD<GPU>|AMD<CPU>|Java Alternative Algorithm|Java Thread Pool}: OpenCL compile failed
com.aparapi.internal.exception.AparapiException: OpenCL compile failed
    at com.aparapi.internal.kernel.KernelRunner.fallBackToNextDevice(KernelRunner.java:1286)
    at com.aparapi.internal.kernel.KernelRunner.executeInternalInner(KernelRunner.java:1550)
    at com.aparapi.internal.kernel.KernelRunner.executeInternalOuter(KernelRunner.java:1351)
    at com.aparapi.internal.kernel.KernelRunner.execute(KernelRunner.java:1342)
    at com.aparapi.Kernel.execute(Kernel.java:2856)
    at com.aparapi.Kernel.execute(Kernel.java:2813)
    at com.aparapi.Kernel.execute(Kernel.java:2753)
    at Util.Util.dotProduct(Util.java:46)
    at Network.FullyConnectedNetwork.predictOutput(FullyConnectedNetwork.java:181)
    at Network.FullyConnectedNetwork.test(FullyConnectedNetwork.java:321)
    at Run.RunFullyConnected.main(RunFullyConnected.java:32)

这是导致错误的代码:

public static double dotProduct(ArrayList<Double> in1, ArrayList<Double> in2) {

        final double[] in1Copy = new double[in1.size()];
        final double[] in2Copy = new double[in1.size()];
        for(int i = 0; i < in1.size(); i++) {
            in1Copy[i] = in1.get(i);
            in2Copy[i] = in2.get(i);
        }

        final double[] result = new double[1];

        Kernel kernel = new Kernel() {
            @Override
            public void run() {
                int i = getGlobalId();
                result[0] += in1Copy[i] + in2Copy[i];
            }
        };

        Range range = Range.create(in1Copy.length);
        kernel.execute(range);
        return result[0];

    }

【问题讨论】:

  • 我在下面留下了一个答案,但是如果您可以在 cmets 中告诉我您的系统、它的内存和您使用的 GPU,我可以让您更好地了解它可能失败的原因。很可能你只是没有足够的内存。

标签: java opencl gpgpu aparapi


【解决方案1】:

你的问题都在这一行:

result[0] += in1Copy[i] + in2Copy[i];

这里最大的问题是您试图同时从多个线程对同一内存位置(读取变量)执行读/写操作。即使允许这样做,也会导致意想不到的结果。您正在一个 GPGPU 环境中工作,您希望最大限度地减少对锁定的需求。这意味着您需要使用 map-reduce 类型的方法来解决这些问题。为此,您应该创建一个与 in1 和 in2 大小相同的实际结果数组。对每个线程执行添加到该数组(映射步骤),然后作为第二步将数组的所有元素添加在一起(减少步骤)。

作为旁注,您获得的异常与我刚才提到的无关。问题很可能是您在一个根本没有足够内存的系统上运行。例如,以下在我的机器上运行得很好,除了我在上一段中提到的问题(刚刚测试过)。

import com.aparapi.*;
import org.junit.Test;

public class DotProductTest {
  @Test
  public void dotProduct() {

        final double[] in1Copy = new double[4096];
        final double[] in2Copy = new double[4096];
        for(int i = 0; i < 4096; i++) {
            in1Copy[i] = i;
            in2Copy[i] = i*10.0;
        }

        final double[] result = new double[1];

        Kernel kernel = new Kernel() {
            @Override
            public void run() {
                int i = getGlobalId();
                result[0] += in1Copy[i] + in2Copy[i];
            }
        };

        Range range = Range.create(in1Copy.length);
        kernel.execute(range);
        System.out.println(result[0]);

    }
}

【讨论】:

  • 我在不使用 Aparapi 的情况下运行它时有足够的内存。点积介于 2300 左右大小的向量之间。我使用的是具有 8 GB RAM 和 Radeon RX 560 显卡的 Windows 10。内存问题是GPU内存问题还是RAM内存问题?顺便感谢您的回答。
  • @dandan 你用的是什么版本的aparapi?
  • 我使用的是 1.8.0 版本。
  • @dandan 可能值得一试 1.10.0 我们刚刚修复了一些可能与此处相关的内容。
  • 1.10.0 对我不起作用,所以我使用了 1.9.0。它似乎还没有在 maven 上发布?
猜你喜欢
  • 1970-01-01
  • 2021-10-07
  • 2021-06-14
  • 2021-01-29
  • 2018-11-06
  • 1970-01-01
  • 2013-02-01
  • 2016-08-16
  • 2015-09-07
相关资源
最近更新 更多