Вывод программы CUDA не то, что ожидалось - PullRequest
0 голосов
/ 03 июля 2011
#include<cuda_runtime.h>
#include<stdio.h>
#include<cuda.h>
#include<stdlib.h>


__global__ void setVal(char **c){

c[(blockIdx.y * gridDim.x) + blockIdx.x] = "hello\0";

}


int main(){

char **gpu = NULL;
cudaMalloc((void**)&gpu, 6 * sizeof(char *));
int i;
/*
I cannot access second level directly
for( i =0 ; i < 6 ;i++){
    cudaMalloc((void**)&gpu[i], 10 * sizeof(char));
}*/


dim3 grid(3,2);
setVal<<<grid, 1>>>(gpu);
char *p = (char*)malloc(10 * sizeof(char));
char *x[6];

cudaMemcpy(x, gpu, 6*sizeof(char*), cudaMemcpyDeviceToHost);
for( i =0 ; i< 6; i++){
    cudaMemcpy(p, x[i], 10*sizeof(char), cudaMemcpyDeviceToHost);
    //put synchronize here if problem
    printf("%s\n",p);

}


getchar();
return 0;
}

Основываясь на всех предложениях, я пересмотрел свой код, чтобы сделать мою концепцию правильной.Но код все еще не работает :(. Любая помощь будет оценена

Ответы [ 3 ]

3 голосов
/ 03 июля 2011

Попробуйте - я тестировал его на GTX 285 под CUDA 3.2 - так что это немного более ограничительно, чем текущая версия, но работает.

#include<stdio.h>
#include<string.h>

__global__ void setValues(char** word)
{
    volatile char* myWord = word[blockIdx.x];

    myWord[0] = 'H';
    myWord[1] = 'o';
    myWord[2] = 'l';
    myWord[3] = 'a';
    myWord[4] = '\0';
}

int main()
{
    const size_t bufferSize = 32;
    const int nObjects = 10;

    char*  h_x[nObjects];
    char** d_x = 0;

    cudaMalloc( (void**)(&d_x), nObjects * sizeof(char*) );

    for ( int i=0; i < nObjects; i++ )
    {
        h_x[i] = NULL;
        cudaMalloc( (void**)(&h_x[i]), bufferSize * sizeof(char) );
        printf("h_x[%d] = %lx\n",i,(unsigned long)h_x[i]);
    }

    cudaMemcpy( d_x, h_x, nObjects*sizeof(char*), cudaMemcpyHostToDevice);
    printf("Copied h_x[] to d_x[]\n");

    char msg[] = "Hello World!";
    cudaMemcpy( h_x[0], msg, 13*sizeof(char), cudaMemcpyHostToDevice );

    /*  Force Thread Synchronization  */
    cudaError err = cudaThreadSynchronize();

    /*  Check for and display Error  */
    if ( cudaSuccess != err )
    {
        fprintf( stderr, "Cuda error in file '%s' in line %i : %s.\n",
                __FILE__, __LINE__, cudaGetErrorString( err) );
    }

    setValues<<<nObjects,1>>>(d_x);

    /*  Force Thread Synchronization  */
    err = cudaThreadSynchronize();

    /*  Check for and display Error  */
    if ( cudaSuccess != err )
    {
        fprintf( stderr, "Cuda error in file '%s' in line %i : %s.\n",
                __FILE__, __LINE__, cudaGetErrorString( err) );
    }

    printf("Kernel Completed Successfully.  Woot.\n\n");

    char p[bufferSize];

    printf("d_x = %lx\n", (unsigned long)d_x );
    printf("h_x = %lx\n", (unsigned long)h_x );

    cudaMemcpy( h_x, d_x, nObjects*sizeof(char*), cudaMemcpyDeviceToHost);

    printf("d_x = %lx\n", (unsigned long)d_x );
    printf("h_x = %lx\n", (unsigned long)h_x );

    for ( int i=0; i < nObjects; i++ )
    {
        cudaMemcpy( &p, h_x[i], bufferSize*sizeof(char), cudaMemcpyDeviceToHost);
        printf("%d p[] = %s\n",i,p);
    }

    /*  Force Thread Synchronization  */
    err = cudaThreadSynchronize();

    /*  Check for and display Error  */
    if ( cudaSuccess != err )
    {
        fprintf( stderr, "Cuda error in file '%s' in line %i : %s.\n",
                __FILE__, __LINE__, cudaGetErrorString( err) );
    }

    getchar();

    return 0;
}

Как отмечает @Jon, вы не можете передать x (как вы заявили) в GPU, потому что это адрес, который находится на CPU . В приведенном выше коде я создаю массив символов char * и передаю их символу **, который я также разместил в графическом процессоре. Надеюсь, это поможет!

2 голосов
/ 03 июля 2011

Основная проблема с вашим кодом заключается в том, что вы не выделяете память устройства для вызова setValues. Вы не можете передать ему указатель на память хоста (char * x [6]) и ожидать, что это сработает; ядра CUDA должны работать с памятью CUDA. Вы создаете эту память, затем оперируете ею и копируете ее обратно:

#include <stdio.h>
#include <string.h>
#include <cuda.h>
#include <cuda_runtime.h>

__global__ void setValues(char *arr){
    arr[blockIdx.y * gridDim.x + blockIdx.x] = '4';
}

int main() {
    const int NCHARS=6;
    char *xd;

    cudaMalloc(&xd, NCHARS);
    dim3 grid(3,2);
    setValues<<<grid,1>>>(xd);

    char *p;
    p = (char*) malloc(20*sizeof(char));
    strcpy(p,"");

    cudaMemcpy(p, xd, NCHARS, cudaMemcpyDeviceToHost);
    p[NCHARS]='\0';

    printf("<%s>\n", p);
    getchar();

    cudaFree(xd);

    return 0;
}
1 голос
/ 03 июля 2011

Здесь я вижу несколько проблем. Вот некоторые из наиболее очевидных:

Во-первых, я предполагаю, что константа символьной строки «4» хранится в памяти хоста (ЦП), поэтому вам придется явно копировать ее в память устройства (глобальную). Как только строка «4» находится в памяти устройства, , затем вы можете сохранить указатель на «4» в значении памяти устройства, например, элемент массива arr.

.

Во-вторых, массив x, передаваемый ядру setValues, также находится в памяти хоста. Помните, что вам нужно использовать cudaMalloc для выделения (глобальной) области памяти устройства, на которую ядро ​​может указывать.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...