Почему моя довольно тривиальная программа 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),

Другие вопросы по тегам