Cuda 为什么cublasGetVector会得到这个结果?

Cuda 为什么cublasGetVector会得到这个结果?,cuda,cublas,Cuda,Cublas,很难理解数组(维度)是如何在cublas中组织的。执行了以下测试,但无法解释输出。谢谢你的帮助 include <stdio.h> include <stdlib.h> include <cublas.h> define DIMX 5 define DIMY 5 define ROW 2 define COL 3 typedef int TYPE; void print_matrix(TYPE * v) { int i,j; for (i

很难理解数组(维度)是如何在cublas中组织的。执行了以下测试,但无法解释输出。谢谢你的帮助

include <stdio.h>
include <stdlib.h>
include <cublas.h>

define DIMX 5
define DIMY 5
define ROW 2
define COL 3

typedef int TYPE;

void print_matrix(TYPE * v)
{
    int i,j;
    for (i=0; i<DIMX; i++)
    {
        for (j=0; j<DIMY; j++) printf("%5d ",v[i*DIMY+j]);
        printf("\n");
    }
}

    int main()
    {
        printf("Hello world!\n");

        int i;
        //Initialize the array
        TYPE v[DIMX*DIMY];
        for (i=0; i<DIMX*DIMY; i++) v[i]=i+1;
        printf("Before:\n");
        print_matrix(v);

        //Cublas part
        cublasInit();
        int *cv;
        cublasAlloc(DIMX*DIMY,sizeof(TYPE),(void**)&cv);
        cublasSetMatrix(ROW,COL,sizeof(TYPE),v,DIMX,cv,DIMY);
        //cublasGetVector(DIMX*DIMY,sizeof(TYPE),cv,1,v,1);
        cublasGetVector(DIMX*DIMY,sizeof(TYPE),cv,DIMX,v,DIMX);
        cublasFree(cv);
        cublasShutdown();

        printf("After:\n");
        print_matrix(v);
        return 0;
    }
包括
包括
包括
定义DIMX 5
定义模糊5
定义第2行
定义第3列
typedef int类型;
无效打印矩阵(类型*v)
{
int i,j;

对于(i=0;i您遇到的第一个问题是没有进行错误检查。如果进行错误检查,您会发现调用cublasGetVector时出现映射错误。其次,您需要查看的API定义。在调用cublasSetMatrix时,对于第一个矩阵的前导维,您有DIMX和前导维具有DIMY的第二个矩阵的维数。两者都应为DIMX。这并不重要,因为您处理的是方矩阵。cublasGetVector调用的问题是,您正在为inc参数传递DIMX和DIMY,这会导致此复制操作超出GPU内存中矩阵cv的末尾。您应该如果希望根据行和列参数捕获左上角元素,则将增量值传递为1。下面是一些代码,我认为这是您想要的,并显示了一个错误检查示例:

#include <stdio.h>
#include <stdlib.h>
#include <cublas.h>
#include <helper_cuda.h>

#define DIMX 5
#define DIMY 5
#define ROW 2
#define COL 3

typedef int TYPE;

#define cublasCheckErrors(fn) \
    do { \
        cublasStatus_t __err = fn; \
        if (__err != CUBLAS_STATUS_SUCCESS) { \
            fprintf(stderr, "Fatal error: %s (at %s:%d)\n", \
                _cudaGetErrorEnum(__err), \
                __FILE__, __LINE__); \
            fprintf(stderr, "*** FAILED - ABORTING\n"); \
            exit(1); \
        } \
    } while (0)

void print_matrix(TYPE * v)
{
    int i,j;
    for (i=0; i<DIMX; i++)
    {
        for (j=0; j<DIMY; j++) printf("%5d ",v[i*DIMY+j]);
        printf("\n");
    }
}

    int main()
    {
        printf("Hello world!\n");

        int i;
        //Initialize the array
        TYPE v[DIMX*DIMY];
        for (i=0; i<DIMX*DIMY; i++) v[i]=i+1;
        printf("Before:\n");
        print_matrix(v);

        //Cublas part
        cublasCheckErrors(cublasInit());
        int *cv;
        cublasCheckErrors(cublasAlloc(DIMX*DIMY,sizeof(TYPE),(void**)&cv));
        cublasCheckErrors(cublasSetMatrix(ROW,COL,sizeof(TYPE),v,DIMX,cv,DIMX));
        //cublasGetVector(DIMX*DIMY,sizeof(TYPE),cv,1,v,1);
        cublasCheckErrors(cublasGetVector(DIMX*DIMY,sizeof(TYPE),cv,1,v,1));
        cublasCheckErrors(cublasFree(cv));
        cublasCheckErrors(cublasShutdown());

        printf("After:\n");
        print_matrix(v);
        return 0;
    }
这假设您有一个标准的CUDA 5安装,并且您在标准位置安装了CUDA 5示例。这允许我为cublas选择一个方便的错误解析器:_cudaGetErrorEnum()

通过这些更改,我得到如下结果:

g++ -I/usr/local/cuda/include -I /usr/local/cuda/samples/common/inc -L/usr/local/cuda/lib64 -lcublas -o t24 t24.cpp
Hello world!
Before:
    1     2     3     4     5
    6     7     8     9    10
   11    12    13    14    15
   16    17    18    19    20
   21    22    23    24    25
After:
    1     2     0     0     0
    6     7     0     0     0
   11    12     0     0     0
    0     0     0     0     0
    0     0     0     0     0
还要注意,您只是部分填充了cv,但将cv的所有内容复制回了v。这意味着在After:result中我上面有零的地方,您可以有任何数字。因此,您应该将cv的所有元素初始化为某个值。而我的After:result显示了非零的2列和3行,因为一个参数行,您将它传递到CuBaseMatLME调用的错误位置。CuBLAS API通常期望列为主要形式的事物,这是从行主要形式(典型C或C++形式)索引的反转。