Сбой компиляции OpenCL aparapi - PullRequest
0 голосов
/ 29 мая 2018

Кто-нибудь знает, что это значит и как это могло произойти?Это выглядит правильно для меня.Я пытаюсь использовать графический процессор для нейронной сети.

Это ошибка:

!!!!!!! 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];

    }

1 Ответ

0 голосов
/ 29 мая 2018

Все ваши проблемы лежат в этой строке:

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

Самая большая проблема здесь заключается в том, что вы пытаетесь выполнить операцию чтения / записи в одну и ту же область памяти (переменную чтения) из нескольких потоков одновременно,Даже если бы это было разрешено, это привело бы к неожиданным результатам.Вы работаете в среде GPGPU, где хотите минимизировать необходимость блокировки.Это означает, что вам нужно использовать подход типа карты-уменьшения для решения подобных проблем.Для этого вы должны создать реальный массив результатов того же размера, что и 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]);

    }
}
...