3

動的並列処理を使用して CUBLAS を実行するカーネルを cubin ファイルにコンパイルしようとしています。コマンドを使用してコードをコンパイルしようとすると

nvcc -cubin -m64 -lcudadevrt -lcublas_device -gencode arch=compute_35,code=sm_35 -o test.cubin -c test.cu

私は得るptxas fatal : Unresolved extern function 'cublasCreate_v2

コンパイル オプションを追加する-rdc=trueと問題なくコンパイルされますが、cuModuleLoad を使用してモジュールをロードしようとすると、エラー 500: CUDA_ERROR_NOT_FOUND が発生します。cuda.h から:

/**
 * This indicates that a named symbol was not found. Examples of symbols
 * are global/constant variable names, texture names, and surface names.
 */
CUDA_ERROR_NOT_FOUND                      = 500,

カーネルコード:

#include <stdio.h>
#include <cublas_v2.h>
extern "C" {
__global__ void a() {
    cublasHandle_t cb_handle = NULL;
    cudaStream_t stream;
    if( threadIdx.x == 0 ) {
        cublasStatus_t status = cublasCreate_v2(&cb_handle);
        cublasSetPointerMode_v2(cb_handle, CUBLAS_POINTER_MODE_HOST);
        if (status != CUBLAS_STATUS_SUCCESS) {
            return;
        }
        cudaStreamCreateWithFlags(&stream, cudaStreamNonBlocking);
        cublasSetStream_v2(cb_handle, stream);
    }
    __syncthreads();
    int jp;
    double A[3];
    A[0] = 4.0f;
    A[1] = 5.0f;
    A[2] = 6.0f;
    cublasIdamax_v2(cb_handle, 3, A, 1, &jp );
}
}

注: のスコープAはローカルであるため、 に指定されたポインターのデータcublasIdamax_v2は定義jpされていないため、このコードでは多かれ少なかれランダムな値になります。それを行う正しい方法はA、グローバルメモリに置くことです。

ホスト コード:

#include <stdio.h>
#include <cuda.h>
#include <cuda_runtime_api.h>

int main() {
    CUresult error;
    CUdevice cuDevice;
    CUcontext cuContext;
    CUmodule cuModule;
    CUfunction testkernel;
    // Initialize
    error = cuInit(0);
    if (error != CUDA_SUCCESS) printf("ERROR: cuInit, %i\n", error);
    error = cuDeviceGet(&cuDevice, 0);
    if (error != CUDA_SUCCESS) printf("ERROR: cuInit, %i\n", error);
    error = cuCtxCreate(&cuContext, 0, cuDevice);
    if (error != CUDA_SUCCESS) printf("ERROR: cuCtxCreate, %i\n", error);
    error = cuModuleLoad(&cuModule, "test.cubin");
    if (error != CUDA_SUCCESS) printf("ERROR: cuModuleLoad, %i\n", error);
    error = cuModuleGetFunction(&testkernel, cuModule, "a");
    if (error != CUDA_SUCCESS) printf("ERROR: cuModuleGetFunction, %i\n", error);
    return 0;
}

ホスト コードは、nvcc -lcuda test.cpp. カーネルを単純なカーネル (以下) に置き換えて、.xml なし-rdc=trueでコンパイルすると、正常に動作します。

シンプルな作業カーネル

#include <stdio.h>
extern "C" {
__global__ void a() {
    printf("hello\n");
}
}

前もって感謝します

  • ソーレン
4

1 に答える 1

4

あなたは-dlink最初のアプローチに欠けています:

nvcc -cubin -m64 -lcudadevrt -lcublas_device -gencode arch=compute_35,code=sm_35 -o test.cubin -c test.cu -dlink

次の 2 つの手順で行うこともできます。

nvcc -m64 test.cu -gencode arch=compute_35,code=sm_35 -o test.o -dc
nvcc -dlink test.o -arch sm_35 -lcublas_device -lcudadevrt -cubin -o test.cubin
于 2013-03-15T01:32:22.640 に答える