Возврат к коду хоста в pyCUDA после асинхронного запуска ядра

Я пытаюсь запустить ядро ​​​​в pyCUDA, а затем завершить работу ядра, записав в глобальную память графического процессора. Вот простой пример ядра, которое я хотел бы иметь возможность завершить в какой-то момент после входа в бесконечный цикл while:

__global__ void countUp(u16 *inShot, u64 *counter) {
  while(inShot[0]) {
    counter[0]++;
  }
}

Из того, что я читал о потоках в CUDA, я должен иметь возможность запускать это ядро ​​​​после создания потока, и он будет неблокирующим на хосте, т.е. Я должен иметь возможность делать что-то на хосте после того, как это ядро ​​будет запущено и запущено. Я компилирую указанное выше ядро ​​в файл cubin и запускаю его в pyCUDA следующим образом:

import numpy as np
from pycuda import driver, compiler, gpuarray, tools
# -- initialize the device
import pycuda.autoinit

strm1 = driver.Stream()

h_inShot = np.zeros((1,1))
d_inShot = gpuarray.to_gpu_async(h_inShot.astype(np.uint16), stream = strm1)
h_inShot = np.ones((1,1))
h_counter = np.zeros((1,1))
d_counter = gpuarray.to_gpu_async(h_counter.astype(np.uint64), stream = strm1)

testCubin = "testKernel.cubin"
mod = driver.module_from_file(testCubin)
countUp = mod.get_function("countUp")

countUp(d_inShot, d_counter,
        grid = (1, 1, 1),
        block = (1, 1, 1),
        stream = strm1
        )

Запуск этого сценария приводит к тому, что ядро ​​входит в бесконечный цикл while по очевидным причинам. Запуск этого скрипта из среды ipython, похоже, не возвращает управление хосту после запуска ядра (я не могу вводить новые команды, так как думаю, что он ждет завершения работы ядра). Я хотел бы, чтобы управление вернулось к хосту, чтобы я мог изменить значение в указателе глобальной памяти графического процессора d_inShot и заставить ядро ​​​​выйти из цикла while. Возможно ли это, и если да, то как мне это сделать в pyCUDA? Спасибо.


person Mitch    schedule 07.05.2015    source источник


Ответы (1)


Я понял это, поэтому публикую свое решение. Несмотря на то, что асинхронные memcpy не блокируются, я обнаружил, что выполнение memcpy с использованием того же потока, что и работающее ядро, не работает. Мое решение состояло в том, чтобы создать еще один поток:

strm2 = driver.Stream()

а затем измените d_inShot следующим образом:

d_inShot.set_async(h_inShot.astype(np.uint16), stream = strm2)

И это сработало для меня.

person Mitch    schedule 08.05.2015