2015-02-06 8 views
1

Это моя OpenCL функция ядраJOCL синтаксис локального доступа к памяти

private static String programSource = 


     "__kernel void "+ 
     "sampleKernel(__local float *a,"+ 
     "    __local float *b,"+ 
     "    __global float *c,"+ 
     "    __global float *d)"+ 

     "{"+ 
     " int gid=get_local_id(0);"+ 
     " c[gid]=a[gid]+b[gid];"+ 
     " d[gid]=a[gid]-1;"+ 
     "}"; 

    clSetKernelArg(kernel, 0, Sizeof.cl_mem, Pointer.to(memObjects[0])); 
    clSetKernelArg(kernel, 1, Sizeof.cl_mem, Pointer.to(memObjects[1])); 
    clSetKernelArg(kernel, 2, Sizeof.cl_mem, Pointer.to(memObjects[2])); 
    clSetKernelArg(kernel, 3, Sizeof.cl_mem, Pointer.to(memObjects[3])); 

Я использовал глобальную память для хранения данных. Теперь я попытался преобразовать место хранения в локальную память. Так что мой код выглядит следующим образом:

private static String programSource = 
      "__kernel void "+ 
      "sampleKernel(__local float *a,"+ 
      "    __local float *b,"+ 
      "    __global float *c,"+ 
      "    __global float *d)"+ 
      "{"+ 
      " int gid=get_local_id(0);"+ 
      " c[gid]=a[gid]+b[gid];"+ 
      " d[gid]=a[gid]-1;"+ 
      "}"; 
     clSetKernelArg(kernel, 0, Sizeof.cl_mem, NULL); 
     clSetKernelArg(kernel, 1, Sizeof.cl_mem, NULL); 
     clSetKernelArg(kernel, 2, Sizeof.cl_mem, Pointer.to(memObjects[2])); 
     clSetKernelArg(kernel, 3, Sizeof.cl_mem, Pointer.to(memObjects[3])); 

Когда я выполняю приведенный выше код я получаю следующую ошибку синтаксиса:

NULL cannot be resolved to a variable. 

Можно ли определить свою ошибку?

Заранее благодарен!

ответ

0

Глядя на other JOCL examples that use local memory, вы делаете правильные вещи, но последний аргумент должен быть null вместо NULL (бывший в том, что Java ключевое слово, последний, как правило, используется в C/C++).

Таким образом, способ, которым вы фактически используете локальную память внутри вашего ядра, не совсем корректен (хотя я понимаю, что это может быть просто ядро ​​примера для работы хоста). Перенос данных в/из локальной памяти должен быть явным образом управляться внутри ядра - хост не может инициализировать локальную память (в вашем примере буферы локальной памяти будут содержать значения мусора). Ваши входные значения должны передаваться ядру в глобальных буферах памяти.

В настоящее время ваши вызовы clSetKernelArg выделяют только 4 или 8 байтов (Sizeof.cl_mem) для каждого локального буфера памяти, который, вероятно, не тот, который вам нужен. Это хорошо для аргументов глобальной памяти, поскольку вы только сохраняете указатель - фактическое выделение буфера выполняется, когда вы вызываете clCreateBuffer. Для аргументов локальной памяти этот размер представляет собой объем памяти, который вы хотите выделить для буфера, и поэтому необходимо отразить объем данных, который вы хотите сохранить в локальной памяти (для каждой рабочей группы).

+0

Да, сработал null. Я использовал строчные буквы. Основываясь на вашем комментарии, я понял, что хост передает a, b в глобальную память. Затем, используя ядро, я должен перенести данные из глобальной в локальную память. Это правильно? Если да, то каков был бы правильный способ хранения массивов a & b в локальной памяти? Какие изменения следует внести в функции clSetKernelArg и ядра? Что касается распределения памяти в clSetKernelArg, он хорошо работает для глобальных массивов c и d. Я выделяю только 4 байта. Почему этого недостаточно для массивов a, b тоже? –

+0

@SadhanaRayan Я добавил несколько заметок о том, почему параметр размера в 'clSetKernelArg' отличается для локальной памяти, чем для глобального. Для вашего ядра примера ваши массивы 'a' и' b' должны находиться в глобальной памяти, иначе они не могут быть инициализированы хостом. Вы можете скопировать их в локальную память вручную (например, 'local_a [i] = global_a [i]'), если хотите. Это просто сделает ядро ​​медленнее, но ваше ядерное ядро ​​действительно не имеет смысла для локальной памяти. – jprice

+0

У меня есть большой код для работы в GPU. На данный момент я просто занимаюсь доступом к различным воспоминаниям. Я прочитал статью по этой ссылке: http://www.openclblog.com/2011/03/is-your-local-memory-really-local.html По его словам, у меня есть CL_GLOBAL. Значит ли это, что улучшения не произойдет, даже если я храню массивы в локальной памяти? –

0

Дайте ему попробовать с

clSetKernelArg(kernel, 0, Sizeof.cl_mem, new Pointer()); 
clSetKernelArg(kernel, 1, Sizeof.cl_mem, new Pointer()); 

Это должно создать действительный NULL-указатель.

+0

Я пробовал использовать «новый указатель()», а также «null». Оба работали. Теперь синтаксическая ошибка исчезла. Но все же я не получаю ожидаемых результатов. c [] содержит 0.0 и d [] имеет -1.0. Как сказал jprice, я предполагаю, что локальная память должна быть инициализирована изнутри ядра. Каковы изменения, которые должны быть сделаны в коде для хранения исходных массивов a & b в локальной памяти? –

+0

Каковы ваши ожидаемые результаты? 'a' и' b' - неинициализированные значения float, поэтому «случайным образом» они установлены на «0.0». – Christian

+0

Я нашел ошибку. Я потерял входные и выходные массивы. a, b должен быть глобальным, а c, d - локальным. –

 Смежные вопросы

  • Нет связанных вопросов^_^