Cuda cublas函数的零值

Cuda cublas函数的零值,cuda,linear-algebra,cublas,Cuda,Linear Algebra,Cublas,我试图用共轭梯度法解Ax=b系统 我使用的是这个示例,但不是使用cusparseScsrmv函数,而是使用cublasSgemv来执行Ax 我的问题是cublasSdot函数中的“dot”变量为零,这导致a=r1/dot为nan #include <stdio.h> #include <stdlib.h> #include <math.h> #include <iostream> #include <assert.h> #include

我试图用共轭梯度法解Ax=b系统

我使用的是这个示例,但不是使用cusparseScsrmv函数,而是使用cublasSgemv来执行Ax

我的问题是cublasSdot函数中的“dot”变量为零,这导致
a=r1/dot
为nan

#include <stdio.h>
#include <stdlib.h>
#include <math.h>
#include <iostream>
#include <assert.h>
#include <cublas_v2.h>

using namespace std;


int main() {

    int Rows = 80 ,Cols = 64;
    int NbElements = Rows * Cols;

    //allocate host memory
    float * A, * x, * rhs;

    A = (float *) malloc( NbElements  * (Rows + Cols)* sizeof(float) );
    x = (float *) malloc( (Rows + Cols) * sizeof(float) );
    rhs = (float *)malloc(sizeof(float)*  NbElements );

    //allocate device memory
    float * devA, * devx;

    cudaMalloc( &devA, NbElements * (Rows + Cols) * sizeof(float) );
    cudaMalloc( &devx, (Rows + Cols)  * sizeof(float) );

    //read Input
    FILE * theFile;
    theFile = fopen( "A", "rb" );
    assert( NULL != theFile );
    assert( NbElements * (Rows + Cols) == fread( A, sizeof(float), NbElements * (Rows + Cols) , theFile ) );
    cudaMemcpy(devA, A, NbElements *  (Rows + Cols) * sizeof(float),cudaMemcpyHostToDevice);

    fclose( theFile );


    const float tol = 1e-5f;
    const int max_iter = 1000;
    float a, b, na, r0, r1,dot;
    float *devAx, *devr , *devp;
    float alpha, beta, alpham1;

    for (int i = 0; i < (Rows + Cols); i++)
        x[i] = 0.0;

    for (int i = 0; i < NbElements; i++)
        rhs[i] = 1.0;

    /* Get handle to the CUBLAS context */
    cublasHandle_t cublasHandle = 0;
    cublasStatus_t cublasStatus;
    cublasStatus = cublasCreate(&cublasHandle);

    cudaMalloc((void **)&devAx, NbElements * sizeof(float));
    cudaMalloc((void **)&devr, NbElements * sizeof(float));
    gcudaMalloc((void **)&devp, NbElements * sizeof(float));

    cudaMemcpy(devx, x, (Rows + Cols) * sizeof(float), cudaMemcpyHostToDevice);
    cudaMemcpy(devr, rhs, NbElements * sizeof(float), cudaMemcpyHostToDevice);

    alpha = 1.0;
    alpham1 = -1.0;
    beta = 0.0;
    r0 = 0.0;

    cublasSgemv(cublasHandle , CUBLAS_OP_N , NbElements  , (Rows + Cols) , &alpha , devA ,  NbElements  ,  devx , 1 , &beta , devAx , 1 );
    cublasSaxpy(cublasHandle,  NbElements  , &alpham1, devAx, 1, devr, 1);
    cublasStatus = cublasSdot(cublasHandle, NbElements , devr, 1, devr, 1, &r1);

    int k = 1;
    while (r1 > tol*tol && k <= max_iter)
    {
        if (k > 1)
        {
            b = r1 / r0;
            cublasStatus = cublasSscal(cublasHandle, NbElements, &b, devp, 1);
            cublasStatus = cublasSaxpy(cublasHandle,  NbElements , &alpha, devr, 1, devp, 1);

        }
        else
        {
            cublasStatus = cublasScopy(cublasHandle,  NbElements , devr, 1, devp, 1);
        }

        cublasSgemv(cublasHandle , CUBLAS_OP_N , NbElements  , (Rows + Cols) ,  &alpha , devA ,  NbElements  ,  devx , 1 , &beta , devAx , 1 );

        cublasStatus = cublasSdot(cublasHandle,  NbElements , devp, 1, devAx, 1, &dot);
        a = r1 / dot;

        cout <<"dot = "<<dot<<endl;

        cublasStatus = cublasSaxpy(cublasHandle,  NbElements , &a, devp, 1, devx, 1);
        na = -a;

        cublasStatus = cublasSaxpy(cublasHandle,  NbElements , &na, devAx, 1, devr, 1);

        r0 = r1;
        cublasStatus = cublasSdot(cublasHandle,  NbElements , devr, 1, devr, 1, &r1);

        cudaThreadSynchronize();
        cout << "\niteration = "<<k<<" , residual = "<<sqrt(r1)<<endl;
        k++;
    }

    cudaMemcpy(x, devx, (Rows + Cols) *sizeof(float), cudaMemcpyDeviceToHost);
    cublasDestroy(cublasHandle);


    {   FILE * theFile;
        theFile = fopen( "X", "wb" );
        assert( NULL != theFile );
        fwrite( x, sizeof(float), (Rows + Cols) , theFile );
        fclose( theFile );
    }

    free(rhs);
    free( A );
    free( x );

    // clean up device memory
    cudaFree( devA );
    cudaFree( devx );
    cudaFree( devr );
    cudaFree( devp );
    cudaFree( devAx );

    return 0;
} 
#包括
#包括
#包括
#包括

#包括)

出现在
cuBlasSdot
指令中的
devAx
数组

cublasStatus = cublasSdot(cublasHandle,  NbElements , devp, 1, devAx, 1, &dot);
是一个消失向量。这是因为
devAx
数组是在该行计算的

cublasSgemv(cublasHandle , CUBLAS_OP_N , NbElements  , (Rows + Cols) , &alpha , devA ,  NbElements  ,  devx , 1 , &beta , devAx , 1 );
作为
devA
devx
之间的矩阵向量积。反过来,
devx
x
cudaMemcpy
,它被初始化为消失向量

for (int i = 0; i < (Rows + Cols); i++)
    x[i] = 0.0;
for(int i=0;i<(行+列);i++)
x[i]=0.0;

我怀疑代码的其余部分没有多大意义,因为共轭梯度应该也适用于消失的初始猜测。

171行代码就是很多代码。尤其是当这些行中至少有30行有过多的空白时。我们怎么知道出了什么问题?代码需要一个我们没有的输入文件。请将您的“我的代码不起作用的问题”简短、完整。您已经在这里问了190个问题,您肯定了解这里的工作原理吗?我想说,通过自己跟踪错误来调试这样的代码应该很容易<如果
devp
为零或
devAx
为零,或者它们同时为零,或者它们是正交的,则code>dot
可以为零。您确定了
dot
为零的原因了吗?了解这一点可以帮助您定位错误或帮助他人帮助您。正如@Talonmes所提到的,您仍然只是打开和关闭包含矩阵
A
的文件,而不是加载它。投票关闭。在
fopen
fclose
之间,我看不到任何
fread
。我已经刷新了页面。你纠正了什么?这正是@Talonmes所说的浪费时间!我只是得出了同样的结论。[a]{x}={0}当{x}={0}时,[a]{x}={0}不应该太令人惊讶。。。。我期待着一些更微妙的东西,比如输入矩阵不是SPD或其他什么,但考虑到这是谁的问题,我想即使是这样,也期待着一个不切实际的程度sophistication@talonmies我觉得这个方法也有一种误解,,由于共轭梯度要求矩阵
A
是正定的,因此通过将线性系统乘以
A
的伴随项即可得到该结果。此外,我不认为该例程在算法上是正确的,我建议OP通过。@JackOLantern:你说得对。我只是遵循了cuda示例,该示例也使用了从x复制的devx。无论如何,我这几天会检查它,谢谢。