Подтвердить что ты не робот

Передача структур в ядра CUDA

Я новичок в CUDA C и пытаюсь передать структуру typedef'd в ядро. Мой метод работал нормально, когда я попробовал его со структурой, содержащей только ints, но когда я переключаюсь на float, я получаю бессмысленные числа в качестве результатов. Я предполагаю, что это связано с выравниванием, и я попытался включить __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;
}
4b9b3361

Ответ 1

Поскольку, похоже, нет достойной документации о том, как это сделать, я думал, что разместил здесь окончательный, пересмотренный код. Оказывается, что часть __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;
}

Ответ 2

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

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