Передача структур в ядра CUDA - PullRequest
13 голосов
/ 14 ноября 2010

Я новичок в CUDA C и пытаюсь передать структуру typedef в ядро.Мой метод работал нормально, когда я пробовал его со структурой, содержащей только целые числа, но когда я переключаюсь на числа с плавающей точкой, я получаю бессмысленные числа как результатыЯ предполагаю, что это связано с выравниванием, и я попытался включить __align__ вместе с моим объявлением типа, но безрезультатно.Может кто-нибудь привести пример того, как это делается, или предложить альтернативный подход?Я пытаюсь настроить его так, чтобы я мог легко добавлять или удалять поля, не изменяя ничего, кроме структуры и ядра.Мой код:

typedef struct __align__(8)
{
    float a, b;
} point;

__global__ void testKernel(point *p)
{
    int i = blockIdx.x * blockDim.x + threadIdx.x;
    p[i].a = 1.1;
    p[i].b = 2.2;
}

int main(void)
{
        // set number of points 
    int numPoints    = 16,
        gpuBlockSize = 4,
        pointSize    = sizeof(point),
        numBytes     = numPoints * pointSize,
        gpuGridSize  = numPoints / gpuBlockSize;

        // allocate memory
    point *cpuPointArray = new point[numPoints],
          *gpuPointArray = new point[numPoints];
    cpuPointArray = (point*)malloc(numBytes);
    cudaMalloc((void**)&gpuPointArray, numBytes);

        // launch kernel
    testKernel<<<gpuGridSize,gpuBlockSize>>>(gpuPointArray);

        // retrieve the results
    cudaMemcpy(cpuPointArray, gpuPointArray, numBytes, cudaMemcpyDeviceToHost);
    printf("testKernel results:\n");
    for(int i = 0; i < numPoints; ++i)
    {
        printf("point.a: %d, point.b: %d\n",cpuPointArray[i].a,cpuPointArray[i].b);
    }

        // deallocate memory
    free(cpuPointArray);
    cudaFree(gpuPointArray);

    return 0;
}

Ответы [ 2 ]

19 голосов
/ 14 ноября 2010

Поскольку, похоже, нет достойной документации о том, как это сделать, я решил опубликовать окончательный, пересмотренный код здесь. Оказывается, что часть __align__ также была ненужной, настоящей проблемой было использование% d в printf при попытке печати чисел с плавающей запятой.

#include <stdlib.h>
#include <stdio.h>

typedef struct
{
    float a, b;
} point;

__global__ void testKernel(point *p)
{
    int i = blockIdx.x * blockDim.x + threadIdx.x;
    p[i].a = 1.1;
    p[i].b = 2.2;
}

int main(void)
{
        // set number of points 
    int numPoints    = 16,
        gpuBlockSize = 4,
        pointSize    = sizeof(point),
        numBytes     = numPoints * pointSize,
        gpuGridSize  = numPoints / gpuBlockSize;

        // allocate memory
    point *cpuPointArray,
          *gpuPointArray;
    cpuPointArray = (point*)malloc(numBytes);
    cudaMalloc((void**)&gpuPointArray, numBytes);

        // launch kernel
    testKernel<<<gpuGridSize,gpuBlockSize>>>(gpuPointArray);

        // retrieve the results
    cudaMemcpy(cpuPointArray, gpuPointArray, numBytes, cudaMemcpyDeviceToHost);
    printf("testKernel results:\n");
    for(int i = 0; i < numPoints; ++i)
    {
        printf("point.a: %f, point.b: %f\n",cpuPointArray[i].a,cpuPointArray[i].b);
    }

        // deallocate memory
    free(cpuPointArray);
    cudaFree(gpuPointArray);

    return 0;
}
4 голосов
/ 14 ноября 2010

Посмотрите, как это делается в заголовке vector_types.h, который находится в вашем каталоге включения CUDA. Это уже должно дать вам несколько советов.

Однако главная проблема здесь - это %d в ваших printf вызовах. Вы пытаетесь теперь печатать числа, а не целые числа. Поэтому те, кто действительно должен использовать вместо этого %f.

...