Повреждение памяти при использовании clEnqueueWriteBuffer — OpenCL

Я работаю в некотором коде, который отправляет большие объемы данных с хоста на устройство, и он ведет себя хаотично.

В следующем фрагменте кода я пытаюсь отправить с хоста на устройство массив.
Размер массива увеличивается на каждой итерации, постепенно увеличивая объем памяти, отправляемой устройству.
Первый элемент в массиве заполняется ненулевым значением, он читается изнутри ядра и выводится на консоль.
Значение должно быть одинаковым, когда оно читается с хоста и с устройства, но на некоторых итерациях это не так.

Вот код:


int SizeArray = 0;

for(int j=1; j<100 ;j++){

//Array memory allocation, starting with 4MB in first iteration to 400MB in last one
SizeArray = j * 1000000 * sizeof(float);
Array = (float*)malloc(SizeArray);
memset(Array, 0, SizeArray);

//Give the array's first element some nonzero value
//This is the value that is expected to be printed by the kernel execution
Array[0] = j;

memArray = clCreateBuffer(context, CL_MEM_READ_WRITE, SizeArray, NULL, &ret);

//Write the array contents into the buffer inside the device
ret = clEnqueueWriteBuffer(command_queue, memArray, CL_TRUE, 0, SizeArray, Array, 0, NULL, NULL);
ret = clSetKernelArg(kernel, 0, sizeof(cl_mem), (void *)&memArray);

getchar();

//Execute the kernel where the content of the first element of the array will be printed
ret = clEnqueueNDRangeKernel(command_queue, kernel, 3, NULL, mGlobalWorkSizePtr, mLocalWorkSizePtr, 0, NULL,NULL);
ret = clFinish(command_queue);

/****** FAIL! Kernel prints correct value of Array's first element ONLY IN
SOME ITERATIONS (when it fails zero values are printed)! Depending on SizeArray :?? ******/

free(Array);
ret = clReleaseMemObject(memArray);
}

Устройство, на котором был протестирован этот код, имеет следующие особенности:

    - Название: Intel (R) HD Graphics 4000 - DeviceVersion: OpenCL 1.1 - DriverVersion: 8.15.10.2696 - MaxMemoryAllocationSize: 425721856 - GlobalMemoryCacheSize: 2097152 - GlobalMemorySize: 1702887424 - MaxConstantBufferSize: 65536 - LocalMemorySize: 65536

Ядро печатает неверные значения или нет, в зависимости от размера буфера, отправляемого на устройство.

Вот вывод:


Array GPU: 1.000000
Array GPU: 2.000000
Array GPU: 3.000000
Array GPU: 4.000000
Array GPU: 5.000000
Array GPU: 6.000000
Array GPU: 7.000000
Array GPU: 8.000000
Array GPU: 9.000000
Array GPU: 10.000000
Array GPU: 11.000000
Array GPU: 12.000000
Array GPU: 13.000000
Array GPU: 14.000000
Array GPU: 15.000000
Array GPU: 16.000000
Array GPU: 17.000000
Array GPU: 18.000000
Array GPU: 19.000000
Array GPU: 20.000000
Array GPU: 21.000000
Array GPU: 22.000000
Array GPU: 23.000000
Array GPU: 24.000000
Array GPU: 25.000000
Array GPU: 0.000000     <-------- INCORRECT VALUE, kernel is receiving corrupted memory
Array GPU: 0.000000     <-------- INCORRECT VALUE, kernel is receiving corrupted memory
Array GPU: 0.000000     <-------- INCORRECT VALUE, kernel is receiving corrupted memory
Array GPU: 0.000000     <-------- INCORRECT VALUE, kernel is receiving corrupted memory
Array GPU: 0.000000     <-------- INCORRECT VALUE, kernel is receiving corrupted memory
Array GPU: 0.000000     <-------- INCORRECT VALUE, kernel is receiving corrupted memory
Array GPU: 0.000000     <-------- INCORRECT VALUE, kernel is receiving corrupted memory
Array GPU: 0.000000     <-------- INCORRECT VALUE, kernel is receiving corrupted memory
Array GPU: 34.000000
Array GPU: 35.000000
Array GPU: 36.000000
Array GPU: 37.000000
Array GPU: 38.000000
Array GPU: 39.000000
Array GPU: 40.000000
Array GPU: 41.000000
Array GPU: 42.000000
Array GPU: 43.000000
Array GPU: 44.000000
Array GPU: 45.000000
Array GPU: 46.000000
Array GPU: 47.000000
Array GPU: 48.000000
Array GPU: 49.000000
Array GPU: 50.000000
Array GPU: 51.000000
Array GPU: 52.000000
Array GPU: 53.000000
Array GPU: 54.000000
Array GPU: 55.000000
Array GPU: 56.000000
Array GPU: 57.000000
Array GPU: 58.000000
Array GPU: 0.000000     <-------- INCORRECT VALUE, kernel is receiving corrupted memory
Array GPU: 0.000000     <-------- INCORRECT VALUE, kernel is receiving corrupted memory
Array GPU: 0.000000     <-------- INCORRECT VALUE, kernel is receiving corrupted memory
Array GPU: 0.000000     <-------- INCORRECT VALUE, kernel is receiving corrupted memory
Array GPU: 0.000000     <-------- INCORRECT VALUE, kernel is receiving corrupted memory
Array GPU: 0.000000     <-------- INCORRECT VALUE, kernel is receiving corrupted memory
Array GPU: 0.000000     <-------- INCORRECT VALUE, kernel is receiving corrupted memory
Array GPU: 0.000000     <-------- INCORRECT VALUE, kernel is receiving corrupted memory
Array GPU: 0.000000     <-------- INCORRECT VALUE, kernel is receiving corrupted memory
Array GPU: 68.000000
Array GPU: 69.000000
...

Как видите, устройство получает неправильные значения без видимого шаблона, и код ошибки не возвращается clEnqueueWriteBuffer функция.

Подводя итог: Блок памяти отправляется ядру, но ядро ​​получает нулевую память в зависимости от общего размера отправленного блока.

Один и тот же код, протестированный на разных компьютерах, ведет себя по-разному (неправильные значения в разных итерациях).

Как избежать повреждения памяти? Я что-то пропустил?

Заранее спасибо.


ВотВот полный рабочий код:


Редактировать: После некоторых испытаний необходимо уточнить, что проблема не в Printf. Проблема, похоже, заключается в передаче данных на устройство, предшествующее выполнению ядра.

Вотэто код без выполнения ядра. Результаты все еще неверны.

5

Решение

Ты пытался

   CL_MEM_READ_WRITE | CL_MEM_ALLOC_HOST_PTR

так как ваш GPU разделяет ту же память с процессором?

Устройство также находится в том же месте хоста для вашего iGPU.

Создайте несколько буферов, проведите стресс-тестирование на них, если все они получат недопустимые значения, затем установите другую версию драйвера, возможно, более новую, если это не решит, RMA вашей карты.

Если только один буфер ошибочен, то это просто ошибка vram, пометьте этот буфер как непригодный для использования и создайте новые буферы как необходимые и избегайте этого буфера, но я не уверен, что драйвер меняет местами буферы в фоновом режиме. Если каждое ядро ​​работает со сбоями, то ядра тоже могут быть повреждены.

0

Другие решения


По вопросам рекламы [email protected]