Почему моя довольно тривиальная программа CUDA ошибается с определенными аргументами?
Я сделал простую программу CUDA для практики. Он просто копирует данные из одного массива в другой:
import pycuda.driver as cuda
import pycuda.autoinit
import numpy as np
from pycuda.compiler import SourceModule
# Global constants
N = 2**20 # size of array a
a = np.linspace(0, 1, N)
e = np.empty_like(a)
block_size_x = 512
# Instantiate block and grid sizes.
block_size = (block_size_x, 1, 1)
grid_size = (N / block_size_x, 1)
# Create the CUDA kernel, and run it.
mod = SourceModule("""
__global__ void D2x_kernel(double* a, double* e, int N) {
int tid = blockDim.x * blockIdx.x + threadIdx.x;
if (tid > 0 && tid < N - 1) {
e[tid] = a[tid];
}
}
""")
func = mod.get_function('D2x_kernel')
func(a, cuda.InOut(e), np.int32(N), block=block_size, grid=grid_size)
print str(e)
Тем не менее, я получаю эту ошибку: pycuda._driver.LogicError: cuLaunchKernel failed: invalid value
Когда я избавлюсь от второго аргумента double* e
в моей функции ядра и вызвать ядро без аргумента e
ошибка уходит. Это почему? Что означает эта ошибка?
1 ответ
Ваш a
массив не существует в памяти устройства, поэтому я подозреваю, что PyCUDA игнорирует (или иным образом обрабатывает) первый аргумент для вызова вашего ядра и только передает e
а также N
... так что вы получите ошибку, потому что ядро ожидало три аргумента, а оно получило только два. Удаление double* e
из вашего определения ядра может быть исключено сообщение об ошибке, которое вы получаете, но ваше ядро все равно не будет работать должным образом.
Быстро исправить это следует обернуть a
в cuda.In()
вызов, который инструктирует PyCUDA для копирования a
на устройство перед запуском ядра. То есть строка запуска вашего ядра должна быть:
func(cuda.In(a), cuda.InOut(e), np.int32(N), block=block_size, grid=grid_size)
Изменить: Кроме того, вы понимаете, что ваше ядро не копирует первый и последний элементы a
в e
? Ваш if (tid > 0 && tid < N - 1)
заявление мешает этому. Для всего массива это должно быть if (tid < N)
,