java - OpenCL 编译失败
问题描述
有谁知道这意味着什么以及这怎么可能发生?在我看来是对的。我正在尝试将 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];
}
解决方案
您的问题都在这一行:
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]);
}
}
推荐阅读
- python - 在熊猫数据框的标题行之前添加具有 excel countif 条件的行
- javascript - 为什么数组的相应部分在我的代码中不匹配?
- rust - 如何将“无”值传递给 rust 中的异步函数
- python - python参数文档字符串中的小于号未显示在PyCharm中
- syslog - Rsyslog 解析问题 - 发送到 Rsyslog 的 syslog 消息中没有标头
- javascript - React Typescript - 显示当前未显示的隐藏 Div
- google-drive-api - 如何在我的谷歌驱动器中获取 PDF 文档的 URL 以用作 twilio 传真的 MediaUrl
- ios - 我需要使用最新的插件来修复 UIWebview 问题吗?
- html - 需要内联按钮的帮助
- python - setuptools_scm 引发 AssertionError:不支持自己的开发号