2

だから私はCUDAプログラミングの基本を自分自身に教えるために非常に基本的なCUDAコード(ベクトル加算)を書いています。1つの.cuファイルを作成すると機能しますが、現在は、.cファイルと.cuファイルをリンクして機能させようとしています。私のmain.cファイルは次のとおりです。

#include "Test.h"
#include <stdlib.h>

int main(int argc, char *argv[]) {
        int n = 1000;
        size_t size = n * sizeof(float);
        int i;

        float *h_a = malloc(size), *h_b = malloc(size), *h_c = malloc(size);

        for(i = 0; i < n; i++) {
                h_a[i] = h_b[i] = i;
        }

        addVec(h_a, h_b, h_c, n);

        exit(0);
}

ここで、Test.hは単に次のように述べています。

void addVec(float *, float *, float *, int);

私のvecAdd.cuファイルには次のように書かれています。

#include "Test.h"

__global__ void vecAdd(float *a, float *b, float *c, int n) {
        int i = blockDim.x * blockIdx.x + threadIdx.x;

        if(i < n)
                c[i] = a[i] + b[i];
}

void addVec(float *a, float *b, float *c, int n) {
        float *d_a, *d_b, *d_c;
        size_t size = n * sizeof(float);

        cudaMalloc(&d_a, size);
        cudaMalloc(&d_b, size);
        cudaMalloc(&d_c, size);

        ...
}

次に、コマンドを実行します。

gcc -c -Wall -O3 main.c -o ../obj/main.o
nvcc -c -O3 vecAdd.cu -o ../obj/vecAdd.o
gcc -L/usr/local/cuda/lib64 -lcudart ../obj/main.o ../obj/vecAdd.o -o ../bin/nvTest

最初の2つは正常に機能します。最後の1つは、2つのオブジェクトファイルをリンクしようとすると、vecAdd.cuで定義されていますが、addVecへの未定義の参照があることを示しています...何が間違っていますか?

4

1 に答える 1

6

ここで説明されているものと基本的に同じ C/C++ リンケージの問題があります。これは、nvcc がホスト コードに C++ コンパイラを使用しており (C++ スタイルのリンケージ参照、つまり「マングリング」を作成)、gcc が main.c を ac (c++ ではない) ファイルとして解釈し、c スタイルのリンケージ参照を作成しているためです。

それを修正するには、少なくとも 2 つの方法があります。

  1. main.c を main.cpp に変換し、現在 gcc を使用している場所で g++ を使用します (最初と 3 番目のコンパイルとリンクの手順で)。その後、すべてが一貫して C++ スタイルの参照になります。
  2. C++ モジュール (vecAdd.cu) 内で、外部参照がここで説明されているように C スタイルであることを宣言します。
于 2012-12-06T04:30:02.900 に答える