Я знаю, что начать работу с массивами в C, и особенно в PyCUDA, может быть довольно сложно, мне потребовались месяцы, чтобы заставить работать алгоритм 2D скользящего максимума.
В этом примере вы не можете получить доступ к элементам массива, как в Python, где вы можете просто предоставить индекс, поскольку вы передаете указатель на адрес памяти на первый элемент в каждом массиве. Полезный пример того, как это работает в C, можно найти здесь . Вам также нужно будет указать длину для массивов (при условии, что они все равны, чтобы мы не выходили за пределы), и, если они имеют разную длину, все они соответственно.
Надеюсь, вы сможете понять, как получить доступ к элементам массива через указатели на C по этой ссылке. Затем @talonmies предоставляет хороший пример здесь для передачи в двумерном массиве (это то же самое, что и одномерный массив, поскольку двумерный массив сглаживается в одномерный в памяти на графическом процессоре). Однако, когда я работал с этим, я никогда не проходил мимо шагов, которые делает @talonmies, работая так, как в учебном пособии TutorialsPoint сказано, что *(pointer_to_array + index)
- это правильно. Предоставление здесь памяти заставит вас выйти за пределы.
Поэтому мой код для этого будет выглядеть так:
C_Code = """
__global__ void array_desaturation(float *array_A, float *array_B, float *array_C, float *outputArray, int arrayLengths){
int index = blockIdx.x * blockDim.x + threadIdx.x;
if(index >= arrayLengths){ // In case our threads created would be outwise out of the bounds for our memory, if we did we would have some serious unpredictable problems
return;
}
// These variables will get the correct values from the arrays at the appropriate index relative to their unique memory addresses (You could leave this part out but I like the legibility)
float aValue = *(array_A + index);
float bValue = *(array_B + index);
float cValue = *(array_C + index);
*(outputArray + index) = ((aValue + bValue + cValue)/3); //Set the (output arrays's pointer + offset)'s value to our average value
}"""
desaturate_mod = SourceModule(C_Code)
desaturate_kernel = desaturate_mod.get_function("array_desaturation")
desaturate_kernel(cuda.In(array_A), # Input
cuda.In(array_B), # Input
cuda.In(array_C), # Input
cuda.Out(outputArray), # Output
numpy.int32(len(array_A)), # Array Size if they are all the same length
block=(blockSize[0],blockSize[1],1), # However you want for the next to parameters but change your index accordingly
grid=(gridSize[0],gridSize[1],1)
)
print(outputArray) # Done! Make sure you have defined all these arrays before ofc