【问题标题】:cublasSgemm invalid __global__ readcublasSgemm 无效 __global__ 读取
【发布时间】:2016-01-20 18:18:39
【问题描述】:

当尝试使用cublasSgemm 例程执行张量矩阵乘积时,会发生地址越界错误,下面提供了一个示例:-

========= Invalid __global__ read of size 4
=========     at 0x000019f8 in sgemm_sm35_ldg_nn_64x16x64x16x16
=========     by thread (6,3,0) in block (6,3,0)
=========     Address 0x7ffc059064a8 is out of bounds
=========     Saved host backtrace up to driver entry point at kernel launch time
=========     Host Frame:/lib64/libcuda.so.1 (cuLaunchKernel + 0x2cd) [0x15859d]
=========     Host Frame:/usr/local/cuda-7.5/lib64/libcublas.so.7.5 [0x21fb31]
=========     Host Frame:/usr/local/cuda-7.5/lib64/libcublas.so.7.5 [0x23a343]
=========     Host Frame:/usr/local/cuda-7.5/lib64/libcublas.so.7.5 [0x1d4e92]
=========     Host Frame:/usr/local/cuda-7.5/lib64/libcublas.so.7.5 [0x1d17b4]
=========     Host Frame:/usr/local/cuda-7.5/lib64/libcublas.so.7.5 [0x1d2c5e]
=========     Host Frame:/usr/local/cuda-7.5/lib64/libcublas.so.7.5 [0x1d37b2]
=========     Host Frame:/usr/local/cuda-7.5/lib64/libcublas.so.7.5 [0xecd31]
=========     Host Frame:./test [0x2c0e]
=========     Host Frame:./test [0x2a99]
=========     Host Frame:/lib64/libc.so.6 (__libc_start_main + 0xf5) [0x21af5]
=========     Host Frame:./test [0x2749]

在我的应用程序中多次检查尺寸并确定这不是问题后,我编写了一个最小的工作示例。下面是一个将两个方阵相乘的简单示例:-

#include "stdlib.h"
#include "time.h"
#include "stdio.h"
#include "cuda.h"
#include <cuda_runtime.h>
#include "cublas_v2.h"
#include <math.h>
#include "cuda_error.h"

void matrixMult(cublasOperation_t transA, cublasOperation_t transB, int M, int N,
            int K, float alpha, float *A, float *B, float beta, float *C,
                cublasHandle_t *cb_handle);

int main(){
    int i, j, idx;
    int D = 500;

    int len = D*D;
    float *A_h, *B_h, *C_h;
    float *A_d, *B_d, *C_d;

    A_h = (float*)malloc(len*sizeof(float));
    B_h = (float*)malloc(len*sizeof(float));
    C_h = (float*)malloc(len*sizeof(float));

    srand48(time(NULL));
    for(i=0; i<D; i++){
        for(j=0; j<D; j++){
            A_h[i*D + j] = drand48();
            B_h[i*D + j] = drand48();
        }
    }

    cudaCheck(cudaMalloc((void**)&A_d, len*sizeof(float)));
    cudaCheck(cudaMalloc((void**)&B_d, len*sizeof(float)));
    cudaCheck(cudaMalloc((void**)&C_d, len*sizeof(float)));
    cudaCheck(cudaMemcpy(A_d, A_h, len*sizeof(float),  cudaMemcpyHostToDevice));
    cudaCheck(cudaMemcpy(B_d, B_h, len*sizeof(float), cudaMemcpyHostToDevice));

    cublasHandle_t cb_handle;
    cublasCheck(cublasCreate(&cb_handle));
    cublasSetPointerMode(cb_handle, CUBLAS_POINTER_MODE_DEVICE);
    matrixMult(CUBLAS_OP_N, CUBLAS_OP_N, D, D, D, 1.0, B_d, A_d, 0.0, C_d, &cb_handle);
    cublasDestroy(cb_handle);

    cudaCheck(cudaMemcpy(C_h, C_d, len*sizeof(float), cudaMemcpyDeviceToHost));
    cudaCheck(cudaFree(A_d));
    cudaCheck(cudaFree(B_d));
    cudaCheck(cudaFree(C_d));

    free(A_h);
    free(B_h);
    free(C_h);
}

void matrixMult(cublasOperation_t transA, cublasOperation_t transB, int M, int N,
            int K, float alpha, float *A, float *B, float beta, float *C,
            cublasHandle_t *cb_handle){
    int lda = (transA == CUBLAS_OP_N) ? K : M;
    int ldb = (transB == CUBLAS_OP_N) ? N : K;
    int ldc = N;
    cublasCheck(cublasSgemm(*cb_handle, transB, transA, N, M, K, &alpha, B, ldb, A, lda, &beta, C, ldc));
}

使用以下微不足道的错误捕获标头:-

#ifndef CUDA_ERROR_CHECK
#define CUDA_ERROR_CHECK

#include <cuda_runtime.h>
#include "cublas_v2.h"

#define cudaCheck(ans){cuda_assert((ans), __FILE__, __LINE__);}
#define cublasCheck(ans){cublas_assert((ans), __FILE__, __LINE__);}

inline void cuda_assert(cudaError_t code, const char *file, int line){
   if(code != cudaSuccess){
      fprintf(stderr,"CUDA Error: %s %s %d\n", cudaGetErrorString(code), file, line);
      exit(code);
   }
}

inline void cublas_assert(cublasStatus_t code, const char *file, int line){
    if(code != CUBLAS_STATUS_SUCCESS){
        fprintf(stderr, "CUBLAS Error! %s line: %d error code: %d\n", file, line, code);
        exit(code);
    }
}

#endif

请注意,上述错误输出是由上述方阵示例产生的。我的张量积应用程序产生了类似的输出。

我正在使用带有 Titan Black 卡的 CUDA 7.5。我是在做一些根本性的错误,还是可能是我的 cuBLAS 安装存在问题?

【问题讨论】:

    标签: cuda cublas


    【解决方案1】:

    如果你消除这个:

    cublasSetPointerMode(cb_handle, CUBLAS_POINTER_MODE_DEVICE);
    

    您的代码将毫无错误地运行。目前尚不清楚您为什么将指针模式设置为CUBLAS_POINTER_MODE_DEVICEdocumentation 表示:

    使用标量参数的函数有两类:

    • 通过引用主机或设备上的 alpha 和/或 beta 参数作为缩放因子的函数,例如 gemm

    • 在主机或设备上返回标量结果的函数,例如 amax()、amin、asum()、rotg()、rotmg()、dot() 和 nrm2()。

    对于第一类的函数,当指针模式设置为CUBLAS_POINTER_MODE_HOST时,标量参数alpha和/或beta可以在栈上,也可以在堆上分配。

    CUBLAS_POINTER_MODE_HOST默认 设置,在您的情况下它是正确的设置,其中 &amp;alpha&amp;beta 是指向主机内存的指针:

    cublasCheck(cublasSgemm(*cb_handle, transB, transA, N, M, K, &alpha, B, ldb, A, lda, &beta, C, ldc));
    

    【讨论】:

    • 天哪!我想我对该函数的作用感到困惑,认为它适合我的用例,所以没有考虑仔细检查它。谢谢。
    • 忽略了这是一个可能的原因。
    猜你喜欢
    • 1970-01-01
    • 2014-10-11
    • 1970-01-01
    • 2018-07-07
    • 1970-01-01
    • 2017-04-09
    • 2014-06-30
    • 2015-07-07
    • 1970-01-01
    相关资源
    最近更新 更多