Адресация памяти PyCUDA: смещение памяти?

#python #cuda #addressing #relative-addressing #pycuda

#python #cuda #адресация #относительная адресация #pycuda

Вопрос:

У меня есть большой фрагмент сгенерированных данных (A [i, j, k]) на устройстве, но мне нужен только один «фрагмент» A [i,:,:], и в обычном CUDA это может быть легко выполнено с помощью некоторой арифметики указателей.

Можно ли то же самое сделать в pycuda? т.е

 cuda.memcpy_dtoh(h_iA,d_A (i*stride))
  

Очевидно, что это совершенно неправильно, поскольку нет информации о размере (если не выводится из формы dest), но, надеюсь, вы поняли идею?

Ответ №1:

Класс PyCUDA gpuArray поддерживает нарезку одномерных массивов, но не более высоких измерений, которые требуют шага (хотя он приближается). Однако вы можете получить доступ к базовому указателю в многомерном графическом массиве из элемента gpuarray, который является pycuda.driver.Тип DeviceAllocation и информация о размере из элемента gpuArray.dtype.itemsize. Затем вы можете выполнить ту же арифметику указателей, которую вы имели в виду, чтобы получить что-то, что будут принимать функции memcpy драйвера.

Это не очень похоже на python, но это действительно работает (или, по крайней мере, это работало, когда я много занимался взломом PyCUDA MPI в прошлом году).

Ответ №2:

Маловероятно, что это реализовано в PyCUDA.

Я могу предложить следующие решения:

  1. Скопируйте весь массив A в память и создайте массив numpy из интересующего фрагмента.
  2. Создайте ядро, которое считывает матрицу и создает желаемый фрагмент.
  3. Измените порядок созданных данных таким образом, чтобы вы могли считывать фрагмент за раз из арифметики указателей.

Комментарии:

1. Я все равно выбрал вариант 1, но оставил вопрос открытым на несколько часов, чтобы посмотреть, есть ли у кого-нибудь еще волшебное решение, о котором мы не подумали.

2. Да, я тоже это делаю, даже больше недели. Не каждый может читать SO каждый день 🙂