Тип Qualifiers для класса устройства в CUDA - PullRequest
4 голосов
/ 22 февраля 2011

В настоящее время я пытаюсь создать фрагмент кода CUDA с классом, который будет использоваться исключительно на стороне устройства (т. Е. Хосту не нужно знать о его существовании).Однако я не могу определить правильные квалификаторы для класса (deviceclass ниже):

__device__ float devicefunction (float *x) {return x[0]+x[1];}

class deviceclass {
    private:
        float _a;

    public:
        deviceclass(float *x) {_a = devicefunction(x);}

        float getvalue () {return _a;}
};    

// Device code
__global__ void VecInit(float* A, int N)
{
    int i = blockDim.x * blockIdx.x + threadIdx.x;
    if (i < N) {
        deviceclass *test;

        test = new deviceclass(1.0, 2.0);

        A[i] = test->getvalue();
    }
}

// Standard CUDA guff below: Variables
float *h_A, *d_A;

// Host code
int main(int argc, char** argv)
{
    printf("Vector initialization...\n");
    int N = 10000;
    size_t size = N * sizeof(float);

    // Allocate
    h_A = (float*)malloc(size);
    cudaMalloc(&d_A, size);

    printf("Computing...\n");
    // Invoke kernel
    int threadsPerBlock = 256;
    int blocksPerGrid = (N + threadsPerBlock - 1) / threadsPerBlock;
    VecInit<<<blocksPerGrid, threadsPerBlock>>>(d_A, N);

    // Copy result from device memory to host memory
    cudaMemcpy(h_A, d_A, size, cudaMemcpyDeviceToHost);

    //...etc
}

Установка Deviceclass в качестве единственного __device__ выдает ошибку при вызове из глобальной функции, однако установкаэто как __device__ __host__ или __global__ кажется ненужным.Может ли кто-нибудь указать мне правильное направление?

Ответы [ 2 ]

11 голосов
/ 23 февраля 2011

Оказывается, квалификаторы должны идти на функции-члены класса, ниже приведена полностью рабочая версия:

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

using namespace std;

void Cleanup(void);


// Functions to be pointed to
__device__ float Plus (float a, float b) {return a+b;}

class deviceclass {

    private:
        float test;

    public:
        __device__ deviceclass(float a, float b) {
            test = Plus(a,b);
        }

        __device__ float getvalue() {return test;}
};

// Device code
__global__ void VecInit(float* A, int N)
{
    int i = blockDim.x * blockIdx.x + threadIdx.x;
    if (i < N) {
        deviceclass test(1.0, 2.0);

        A[i] = test.getvalue();
    }
}

// Standard CUDA guff below: Variables
float *h_A, *d_A;

// Host code
int main(int argc, char** argv)
{
    printf("Vector initialization...\n");
    int N = 10000;
    size_t size = N * sizeof(float);

    // Allocate
    h_A = (float*)malloc(size);
    cudaMalloc(&d_A, size);

    printf("Computing...\n");
    // Invoke kernel
    int threadsPerBlock = 256;
    int blocksPerGrid = (N + threadsPerBlock - 1) / threadsPerBlock;
    VecInit<<<blocksPerGrid, threadsPerBlock>>>(d_A, N);

    // Copy result from device memory to host memory
    cudaMemcpy(h_A, d_A, size, cudaMemcpyDeviceToHost);



    // Verify result
    int i;
    for (i = 0; i < N; ++i) {
        cout << endl << h_A[i];
    }

    cout << endl;

    Cleanup();
}

void Cleanup(void)
{
    // Free device memory
    if (d_A)
        cudaFree(d_A);

    // Free host memory
    if (h_A)
        free(h_A);

    cudaThreadExit();

    exit(0);
}
0 голосов
/ 22 февраля 2011

Я так понимаю, Node() это опечатка.

Из Руководства по программированию CUDA C, раздел 3.1.5:

Однако для кода устройства полностью поддерживается только подмножество C ++

и Приложение D.6:

Код, скомпилированный для устройств с вычислительными возможностями 2.x и выше, может использовать классы C ++ ...

Я думаю, что ваш код использует несовместимый C ++.

...