2

私はCUDAを初めて使用します。あなたの助けに感謝し、あなたが私を助けてくれることを願っています。

2D配列の複数の要素をベクトルに格納してからベクトルを操作する必要がありますが、コードがうまく機能しません。デバッグすると、デバイスに2D配列を割り当てて、そこにcudaMallocPitchコピーするときに間違いが見つかります。の配列cudaMemcpy2D。これは私のコードです:

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

#define maxThreads 96

__global__ void extract(int mSize, float* dev_vector, float* dev_matrix, int N)
{
    int idx = threadIdx.x + blockIdx.x * blockDim.x;

    while(idx<N)
    {
        dev_vector[idx] = *(dev_matrix+(mSize*idx+N));
        idx += blockDim.x * gridDim.x;
    }
}

int main()
{
    //CPU variables
    int mSize = 5;
    float* matrix;
    int N = 4; // Vector size
    int i,j;
    float* vector;
    int blocks, threads;

    float* dev_matrix;
    float* dev_vector;

    blocks = 1+((N-1)/maxThreads);
    threads = 1+((N-1)/blocks);

    unsigned long int pitch;
    unsigned long int memsize_vector = N*sizeof(float);
    unsigned long int memsize_matrix = mSize*sizeof(float);


    matrix = new float[memsize_matrix*memsize_matrix];
    vector = new float[memsize_vector];

    //Create 2D array
    for(i=0; i<mSize; i++)
        for(j=0; j<mSize; j++)
        {
            matrix[i+mSize*j] = ((i+1)+(j+1));
        }

    printf("\n");
    for (i=0; i<mSize; i++){
        for(j=0; j<mSize; j++){
            printf("% 1.5f ", matrix[i+mSize*j]);
        }
        printf("\n");
    }
    printf("\n");


    cudaMallocPitch((void **)&dev_matrix, &pitch, memsize_matrix, mSize);
    cudaMalloc((void **)&dev_vector, memsize_vector);

    cudaMemcpy2D(dev_matrix, pitch, matrix, memsize_matrix, memsize_matrix, mSize,
                     cudaMemcpyHostToDevice);

    extract<<<blocks,threads>>>(mSize, dev_vector, dev_matrix, N);
    cudaDeviceSynchronize();

    cudaMemcpy(vector, dev_vector, memsize_vector, cudaMemcpyDeviceToHost);

    printf("Vector values are:\n");
    for(i=0; i<N; i++)
        printf(" % 1.5f ", vector[i]);
    printf("\n");

    cudaFree(dev_matrix);
    cudaFree(dev_vector);

}
4

3 に答える 3

1

このコードには多くの問題があります。これには、バイト単位の配列サイズとコード内のいくつかの場所で互換性のあるワードサイズの使用、誤った型の使用(size_t非常に正当な理由で存在することに注意)、潜在的な切り捨ておよび型キャストの問題が含まれます。もっと。

しかし、コアの問題は、カーネル内のピッチメモリのアドレス指定であり、ピッチ値を渡すことさえありません。のドキュメントを読むcudaMallocPitchと、カーネル内のピッチメモリをアドレス指定するための正しい方法がわかります。カーネル次のようになります。

__global__ void extract(size_t mpitch, float* dev_vector, float* dev_matrix, int N)
{
    int idx = threadIdx.x + blockIdx.x * blockDim.x;
    int stride = blockDim.x * gridDim.x;

    while(idx<N)
    {          
        dev_vector[idx] = *(float *)( ((char*)dev_matrix + idx * mpitch) + N );
        idx += stride;
    }
}

[免責事項:コンパイルまたはテストしたことはありません。自己責任で使用してください]。

次に、カーネルの変更を反映するために、ホストコードのすべての問題を修正する必要があります。

于 2013-02-21T06:40:09.720 に答える
1

すべてのおかげで、アレックス私はそれを見ていませんでした、そしてそれを修正します、ありがとう。

talonmies、ありがとう、私のコードはあなたの提案で動作します。どうもありがとう、最後にこれは私のカーネルです:

__global__ void sumreduct(size_t pitch, float* dev_vector, float* dev_matrix, int  columns, int N)
{
int idx = threadIdx.x + blockIdx.x * blockDim.x;
int stride = blockDim.x * gridDim.x;

while(idx<N)
{
    dev_vector[idx] = *(float *)( ((char*)dev_matrix + idx * pitch) + columns);
    idx += stride;
} 
}

「size_t」については、Nsightが次の警告を表示するため、「Unsignedint」を使用していました。

タイプ「size_t」を解決できませんでした

ありがとう

于 2013-02-21T21:00:46.197 に答える
0

本当に長さ[memsizeMatrix*memsizeMatrix]のソースマトリックスを宣言するつもりでしたか?

これにより、400フロート、つまり1600バイトが割り当てられます。これは、ソースピッチがオフであり、Memcpy2D呼び出しが失敗していることを意味します。

私はあなたが言うつもりだったと思います

matrix = new float[mSize*mSize];
于 2013-02-20T23:38:56.267 に答える