2

簡単な文字割り当てを行う以下のコードを見てください

__global__ void seehowpointerwork(char* gpuHello, char* finalPoint){

    char* temp;
    bool found = false;
    for(int i = 0 ; i < 11; i++){
        if(gpuHello[i] == ' '){
            temp = &gpuHello[i+1];
            found = true;

            break;
        }
    }
    bool sth = found;
    finalPoint = temp;

}
int main()
{
    // Testing one concept;
    string hello = "Hello World";
    char* gpuHello;
    cudaMalloc((void**)&gpuHello, 11 * sizeof(char));
    cudaMemcpy(gpuHello, hello.c_str(), 11 * sizeof(char), cudaMemcpyHostToDevice);
    char* didItFind;
    char* whatIsIt = (char*)malloc(5 * sizeof(char));
    seehowpointerwork<<<1,1>>>(gpuHello, didItFind);
    cudaMemcpy(whatIsIt,didItFind, 5 * sizeof(char), cudaMemcpyDeviceToHost);
    cout<<"The pointer points to : " << whatIsIt;
    return 0;
}

私が印刷するときwhatIsIt、なぜそれが答えとして「世界」を印刷せず、ランダムな文字列を印刷するだけなのか、私は本当に理解していません。

指摘されたヌル文字を考慮した後、バージョンを更新します

__global__ void seehowpointerwork(char* gpuHello, char* finalPoint){

    char* temp;
    bool found = false;
    for(int i = 0 ; i < 11; i++){
        if(gpuHello[i] == ' '){
            temp = gpuHello;
            found = true;

            break;
        }
    }
    bool sth = found;
    finalPoint = temp;

}
int main()
{
    // Testing one concept;
    string hello = "Hello World";
    char* gpuHello;
    cudaMalloc((void**)&gpuHello, 12 * sizeof(char));
    cudaMemcpy(gpuHello, hello.c_str(), 12 * sizeof(char), cudaMemcpyHostToDevice);
    char* didItFind;
    char* whatIsIt = (char*)malloc(6 * sizeof(char));
    seehowpointerwork<<<1,1>>>(gpuHello, didItFind);
    cudaMemcpy(whatIsIt,didItFind, 6 * sizeof(char), cudaMemcpyDeviceToHost);
    cout<<"The pointer points to : " << whatIsIt;
    return 0;
}
4

1 に答える 1

3

finalPointカーネルを定義した方法で動作させる場合は、値ではなく参照で渡す必要があります。おそらくこのようなもの:

#include <cstdio>
#include <iostream>
#include <string>

using namespace std;

__global__ void seehowpointerwork(char * gpuHello, char ** finalPoint){

    char* temp;
    for(int i = 0 ; i < 11; i++){
        if(gpuHello[i] == ' '){
            temp = &gpuHello[i+1];
            break;
        }
    }
    *finalPoint = temp;
}

inline void gpuAssert(cudaError_t code, char *file, int line, 
                 bool abort=true)
{  
   if (code != cudaSuccess) {
      printf("GPUassert: %s %s %d\n", cudaGetErrorString(code), file, line);
      if (abort) exit(code);
   }
}
#define gpuErrchk(ans) { gpuAssert((ans), __FILE__, __LINE__); }

int main()
{
    string hello = "Hello World";
    char* gpuHello;
    gpuErrchk( cudaMalloc((void**)&gpuHello, 11 * sizeof(char)) );
    gpuErrchk( cudaMemcpy(gpuHello, hello.data(), 11 * sizeof(char), cudaMemcpyHostToDevice) );
    char ** didItFinda, * didItFindb;
    gpuErrchk( cudaMalloc((void **)&didItFinda, sizeof(char *)) );
    char* whatIsIt = (char*)malloc(5 * sizeof(char));
    seehowpointerwork<<<1,1>>>(gpuHello, didItFinda);
    gpuErrchk( cudaPeekAtLastError() );
    gpuErrchk( cudaMemcpy(&didItFindb, didItFinda, sizeof(char *), cudaMemcpyDeviceToHost) );
    gpuErrchk( cudaMemcpy(whatIsIt, didItFindb, 5 * sizeof(char), cudaMemcpyDeviceToHost) );
    cout<<"The pointer points to : " << whatIsIt << endl;
    return 0;
}

このバージョンをコンパイルして実行すると、次のようになります。

$ nvcc -arch=sm_12 -Xptxas="-v" programmer.cu 
ptxas info    : Compiling entry function '_Z17seehowpointerworkPcPS_' for 'sm_12'
ptxas info    : Used 4 registers, 8+16 bytes smem, 8 bytes cmem[1]

$ ./a.out 
The pointer points to : World

現状では、デバイスからホストへのコピーは失敗します。これdidItFindは、が有効なデバイスポインターではないためです。カーネルに値で渡したため、ホスト上の値をカーネルで変更することはできません。上記のコードには、この種の問題を見つけるのに十分なエラーチェックが含まれています。すべてのAPI呼び出しのリターンステータスを常にチェックする必要があります。

于 2012-07-14T21:14:55.143 に答える