"неизвестная ошибка" при использовании функции динамического выделения внутри устройства в CUDA



Я пытаюсь реализовать связанный список в приложении CUDA для моделирования растущей сети. В oder для этого я использую malloc внутри функции __device__, стремясь выделить память в глобальной памяти.
Код такой:



void __device__ insereviz(Vizinhos **lista, Nodo *novizinho, int *Gteste)
{
Vizinhos *vizinho;

vizinho=(Vizinhos *)malloc(sizeof(Vizinhos));

vizinho->viz=novizinho;

vizinho->proxviz=*lista;

*lista=vizinho;

novizinho->k=novizinho->k+1;
}


После определенного количества выделенных элементов (около 90000) моя программа возвращает "неизвестную ошибку". Сначала я думал, что это ограничение памяти, но я проверил nvidia-smi и у меня есть



+------------------------------------------------------+                       
| NVIDIA-SMI 331.38 Driver Version: 331.38 |
|-------------------------------+----------------------+----------------------+
| GPU Name Persistence-M| Bus-Id Disp.A | Volatile Uncorr. ECC |
| Fan Temp Perf Pwr:Usage/Cap| Memory-Usage | GPU-Util Compute M. |
|===============================+======================+======================|
| 0 GeForce GTX 770 Off | 0000:01:00.0 N/A | N/A |
| 41% 38C N/A N/A / N/A | 159MiB / 2047MiB | N/A Default |
+-------------------------------+----------------------+----------------------+


Так что это не кажется проблемой памяти, если только malloc не выделяет внутри общей памяти. Чтобы проверить это, я попытался запустить две сети в отдельных блоках, и все еще есть ограничение в количестве структур, которые я могу выделить. Но когда я пытаюсь запустить два экземпляра одной и той же программы с меньшим количеством структур, они оба заканчиваются без ошибок.



Я также попробовал cuda-memcheck и получил



========= CUDA-MEMCHECK
========= Invalid __global__ write of size 8
========= at 0x000001b0 in /work/home/melo/proj_cuda/testalloc/cuda_testamalloc.cu:164:insereviz(neighbor**, node*, int*)
========= by thread (0,0,0) in block (0,0,0)
========= Address 0x00000000 is out of bounds
========= Device Frame:/work/home/melo/proj_cuda/testalloc/cuda_testamalloc.cu:142:insereno(int, int, node**, node**, int*) (insereno(int, int, node**, node**, int*) : 0x648)
========= Device Frame:/work/home/melo/proj_cuda/testalloc/cuda_testamalloc.cu:111:fazrede(node**, int, int, int, int*) (fazrede(node**, int, int, int, int*) : 0x4b8)
========= Saved host backtrace up to driver entry point at kernel launch time
========= Host Frame:/usr/lib/libcuda.so.1 (cuLaunchKernel + 0x331) [0x138281]
========= Host Frame:gpu_testamalloc5 [0x1bd48]
========= Host Frame:gpu_testamalloc5 [0x3b213]
========= Host Frame:gpu_testamalloc5 [0x2fe3]
========= Host Frame:gpu_testamalloc5 [0x2e39]
========= Host Frame:gpu_testamalloc5 [0x2e7f]
========= Host Frame:gpu_testamalloc5 [0x2c2f]
========= Host Frame:/lib/x86_64-linux-gnu/libc.so.6 (__libc_start_main + 0xfd) [0x1eead]
========= Host Frame:gpu_testamalloc5 [0x2829]


Есть ли какие-либо ограничения в запуске ядра или что-то, что я упускаю? Как я могу это проверить?



Спасибо,



Рикардо

632   1  

1 ответ:

Наиболее вероятная причина заключается в том, что вам не хватает места в "куче устройств". Это изначально по умолчанию 8 МБ, но вы можете изменить его.

Ссылаясь на документацию , мы видим, что устройство malloc выделяет из кучи устройств.

Если возникает ошибка, нулевой указатель будет возвращен malloc. Это хорошая практика, чтобы проверить для этого нулевого указателя в коде устройства (и в коде хоста - это ничем не отличается от хоста malloc в этом отношении). Если вы получите Нулевой указатель, вы исчерпали пространство кучи устройства.

Как указано в документации, размер кучи устройств можно настроить перед вызовом ядра с помощью:

cudaDeviceSetLimit(cudaLimitMallocHeapSize, size_t size)

Функция API среды выполнения.

Если вы проигнорируете все это и попытаетесь использовать нулевой указатель, возвращенный в любом случае, вы получите недопустимые обращения в коде устройства, например:

=========     Address 0x00000000 is out of bounds

Comments

    Ничего не найдено.