Имеет ли значение порядок выделения памяти в кюранде PyCUDA? - PullRequest
0 голосов
/ 10 апреля 2020

Я использую интерфейс PyCUDA [ 1 ] поверх унифицированной памяти CUDA [ 2 ]. В какой-то момент я добавил генераторы случайных чисел [ 3 ] и уставился на мертвые ядра в Jupyter Notebook: The kernel appears to have died

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

import pycuda.curandom
from pycuda import autoinit, driver
import numpy as np

gpu_data_1 = driver.managed_zeros(shape=5, dtype=np.int32, mem_flags=driver.mem_attach_flags.GLOBAL)
gpu_generator = pycuda.curandom.XORWOWRandomNumberGenerator(pycuda.curandom.seed_getter_uniform)
gpu_data_2 = driver.managed_zeros(shape=5, dtype=np.int32, mem_flags=driver.mem_attach_flags.GLOBAL)

Код выше не работает без какого-либо сообщения об ошибке, но если я поставлю gpu_generator = ... строку на одну строку выше или ниже, похоже, что он работает нормально .

Я полагаю, что PyCUDA может каким-то образом не выполнить prepare вызов , который идет к этому ядру:

extern "C" {
    __global__ void prepare(curandStateXORWOW *s, const int n,
        unsigned int *v, const unsigned int o)
    {
      const int id = blockIdx.x*blockDim.x+threadIdx.x;
      if (id < n)
        curand_init(v[id], id, o, &s[id]);
    }
}

Есть идеи, в чем может быть проблема?

1 Ответ

2 голосов
/ 10 апреля 2020

Это недопустимо в режиме до Pascal UM (Unified Memory) для кода хоста, который касается управляемого размещения после запуска ядра, но до выпуска cudaDeviceSynchronize().

Я предполагаю, что этот код нарушает это правило. Если я запускаю ваш репозиторий в системе Maxwell, я получаю следующее:

$ cuda-memcheck python ./idontthinkso.py
========= CUDA-MEMCHECK
========= Error: process didn't terminate successfully
========= Fatal UVM CPU fault due to invalid operation
=========     during write access to address 0x703bc1000
=========
========= ERROR SUMMARY: 1 error

Это взрыв системы управляемой памяти. Размещение вызова синхронизации между настройкой генератора случайных чисел (которая запускает ядро) и вызовом нулей (которое касается управляемой памяти) избавляет меня от этого в моей системе:

$ cat idontthinkso.py 
import pycuda.curandom
from pycuda import autoinit, driver
import numpy as np

gpu_data_1 = driver.managed_zeros(shape=5, dtype=np.int32, mem_flags=driver.mem_attach_flags.GLOBAL)
gpu_generator = pycuda.curandom.XORWOWRandomNumberGenerator(pycuda.curandom.seed_getter_uniform)
autoinit.context.synchronize()
gpu_data_2 = driver.managed_zeros(shape=5, dtype=np.int32, mem_flags=driver.mem_attach_flags.GLOBAL)

$ cuda-memcheck python ./idontthinkso.py
========= CUDA-MEMCHECK
========= ERROR SUMMARY: 0 errors

Режим единой системы обмена сообщениями, в котором вы находитесь, будет различаться в зависимости от того, какой GPU, драйвер и ОС вы используете.

...