arrays #cuda #pycuda
#cuda #pycuda
Вопрос:
При попытке выполнить приведенный ниже код с int d[1];
помощью, он работает нормально, но с int d[in_integer];
или int c[in_matrix[0]];
это приводит к сбою компиляции nvcc. Могу ли я узнать, может ли кто-нибудь подсказать, почему? Возможно ли объявить массив в pycuda с размером, определяемым значением параметра функции?
import pycuda.driver as cuda
import pycuda.autoinit
from pycuda.compiler import SourceModule
import os
import numpy as np
_path = r"D:Program Files (x86)Microsoft Visual Studio2019CommunityVCToolsMSVC14.28.29910binHostx64x64"
if os.system("cl.exe"):
os.environ['PATH'] = ';' _path
if os.system("cl.exe"):
raise RuntimeError("cl.exe still not found, path probably incorrect")
a = np.asarray([1, 2])
a = a.astype(np.int32)
a_gpu = cuda.mem_alloc(a.nbytes)
cuda.memcpy_htod(a_gpu, a)
b = np.zeros(1).astype(np.int32)
b_gpu = cuda.mem_alloc(b.nbytes)
cuda.memcpy_htod(b_gpu, b)
mod = SourceModule("""
__global__ void array_declaration(int *in_matrix, int *out_matrix, int in_integer)
{
int d[1];
//int d[in_integer];
//int d[in_matrix[0]];
out_matrix[0] = in_matrix[0];
}
""")
func = mod.get_function("array_declaration")
func(a_gpu, b_gpu, np.int32(1), block=(1,1,1))
b_out = np.empty_like(b)
cuda.memcpy_dtoh(b_out, b_gpu)
print(b_out)
ошибка выглядит следующим образом
Traceback (most recent call last):
File "D:PythonProjectsTradeAnalysisTestTestCUDAArrayDeclaration.py", line 37, in <module>
""")
File "D:ProgramDataAnaconda3libsite-packagespycudacompiler.py", line 291, in __init__
arch, code, cache_dir, include_dirs)
File "D:ProgramDataAnaconda3libsite-packagespycudacompiler.py", line 254, in compile
return compile_plain(source, options, keep, nvcc, cache_dir, target)
File "D:ProgramDataAnaconda3libsite-packagespycudacompiler.py", line 137, in compile_plain
stderr=stderr.decode("utf-8", "replace"))
CompileError: nvcc compilation of C:UsersHENRYC~1AppDataLocalTemptmpy0kcq_5ikernel.cu failed
Комментарии:
1. Можете ли вы поделиться возникшей у вас ошибкой компиляции?
2. C и, соответственно, CUDA не поддерживают массивы с динамическим размером. Они должны быть статического размера. Вот почему код не компилируется
Ответ №1:
Возможно ли объявить массив в pycuda с размером, определяемым значением параметра функции?
Вместо этого:
int d[in_integer];
сделайте это:
int *d = new int[in_integer];
или, что эквивалентно:
int *d = (int *)malloc(in_integer*sizeof(d[0]));
Технически это указатель с выделением, а не массив, но он будет функционировать аналогично для большинства вариантов использования в C или CUDA C .
Такого рода распределение памяти внутри ядра устройства имеет множество предостережений:
- по умолчанию общее выделенное пространство (количество потоков, для которых в данный момент открыто выделение, умноженное на размер выделения), используемое вашим ядром, не может превышать 8 МБ. Это регулируется.
- обычно у вас должна быть соответствующая
delete[]
операция C после завершения использования указателя (илиfree()
, если вы использовалиmalloc()
) в вашем коде ядра (что также может помочь с пунктом выше) - среда выполнения устройства CUDA указывает здесь на ошибку выделения, возвращая нулевой указатель. При возникновении проблем рекомендуется проверять наличие NULL в коде ядра, прежде чем использовать указатель.
- сам этап выделения устройства может заметно повлиять на производительность ядра (продолжительность выполнения). Если ваше ядро выполняет много работы / много других вещей, это может быть вообще не заметно. Для ядер, выполняющих мало работы, это может быть очень заметно. После завершения выделения использование выделенного указателя не должно иметь каких-либо существенных отличий в производительности от использования определения массива, где размер известен как константа времени компиляции.