为什么混合C/magma代码seg故障而独立C代码工作?

为什么混合C/magma代码seg故障而独立C代码工作?,c,matlab,gpu,mex,magma,C,Matlab,Gpu,Mex,Magma,下面的MEXed C代码只是调用magma来反转矩阵。独立的C代码(也已发布)可以工作,但mex代码崩溃 我已经三次检查了文档,验证了其他magma功能是否按预期工作,并且(这篇文章是magma论坛的交叉文章)。这意味着问题在于mex。我想知道是什么导致mex代码出现seg故障,以及如何使其按预期运行 混合编码: #include <mex.h> #include <stdlib.h> #include <stdio.h> #include <strin

下面的MEXed C代码只是调用magma来反转矩阵。独立的C代码(也已发布)可以工作,但mex代码崩溃

我已经三次检查了文档,验证了其他magma功能是否按预期工作,并且(这篇文章是magma论坛的交叉文章)。这意味着问题在于mex。我想知道是什么导致mex代码出现seg故障,以及如何使其按预期运行

混合编码:

#include <mex.h>
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <math.h>
#include <stddef.h>
#include <magma_v2.h>
#include <cuda_runtime.h>

void mat2magma(magmaDoubleComplex* p, double* pr, double* pi,int numElements)
{
    int j=0;
    for(j=0;j<numElements;j++){
        p[j].x=pr[j];
        p[j].y=pi[j];
    }
}

void magma2mat(magmaDoubleComplex* p, double* pr, double* pi,int numElements)
{
    int j=0;
    for(j=0;j<numElements;j++){
        pr[j]= p[j].x;
        pi[j]= p[j].y;
    }
}

/*gateway function*/
void mexFunction( int nlhs, mxArray *plhs[],
        int nrhs, const mxArray *prhs[]) {

    /*initialize magma*/
    magma_init();
    magma_queue_t queue = NULL;
    magma_device_t dev;
    magma_getdevice(&dev);
    magma_queue_create(dev,&queue );

    magma_int_t m,ldwork,info;
    magma_int_t *piv;
    magmaDoubleComplex *a,*da,*dwork;

    /* Matlab -> Host */
    m=mxGetM(prhs[0]);
    piv=(magma_int_t*) malloc(m*sizeof(magma_int_t));
    magma_zmalloc_cpu(&a,m*m);
    mat2magma(a,mxGetPr(prhs[0]),mxGetPi(prhs[0]),m*m);
    ldwork = m*magma_get_zgetri_nb(m);

    /* Host -> GPU */
    magma_zmalloc(&dwork,ldwork);
    magma_zmalloc(&da,m*m);
    magma_zsetmatrix(m,m,a,m,da,m,queue);

    /*LU and Inverse */
    magma_zgetrf_gpu(m,m,da,m,piv,&info);
    magma_zgetri_gpu(m,da,m,piv,dwork,ldwork,&info);

    /*GPU -> Host */
    magma_zgetmatrix(m,m,da,m,a,m,queue);

    /*Host -> Matlab*/
    plhs[0] = mxCreateDoubleMatrix(m,m,mxCOMPLEX);
    magma2mat(a,mxGetPr(plhs[0]),mxGetPi(plhs[0]),m*m);
    free(a);
    free(piv);
    magma_free(dwork);
    magma_free(da);
    magma_queue_destroy(queue);
    magma_finalize();
}
独立C代码:

#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <math.h>
#include <stddef.h>
#include <magma_v2.h>
#include <cuda_runtime.h>
#include <sys/time.h>
#include <time.h>

/*gateway function*/
int main() {

    /*initialize magma*/
    magma_init();
    magma_queue_t queue = NULL;
    magma_device_t dev;
    magma_getdevice(&dev);
    magma_queue_create(dev,&queue );

    int m,ldwork,info;
    int *piv;
    magmaDoubleComplex *a,*da,*dwork;

    /* allocate and initialize a = magic(3)+magic(3)*1i; */
    m=3;
    piv=(int*) malloc(m*sizeof(int));
    ldwork = m*magma_get_zgetri_nb(m);
    magma_zmalloc_cpu(&a,m*m);
    a[0].x=8;a[0].y=8;
    a[1].x=3;a[1].y=3;
    a[2].x=4;a[2].y=4;
    a[3].x=1;a[3].y=1;
    a[4].x=5;a[4].y=5;
    a[5].x=9;a[5].y=9;
    a[6].x=6;a[6].y=6;
    a[7].x=7;a[7].y=7;
    a[8].x=2;a[8].y=2;

    /* Host -> GPU */
    magma_zmalloc(&dwork,ldwork);
    magma_zmalloc(&da,m*m);
    magma_zsetmatrix(m,m,a,m,da,m,queue);

    /*LU and Inverse */
    magma_zgetrf_gpu(m,m,da,m,piv,&info);
    magma_zgetri_gpu(m,da,m,piv,dwork,ldwork,&info);

    /*GPU -> Host */
    magma_zgetmatrix(m,m,da,m,a,m,queue);

    /* display inv(a) */
    for (int i=0;i<(m*m);i++){
        printf("%f +%fi\n",a[i].x,a[i].y);
    }

    /* free memory */
    free(a);
    free(piv);
    magma_free(dwork);
    magma_free(da);
    magma_queue_destroy(queue);
    magma_finalize();

    return 0;
}
#包括
#包括
#包括
#包括
#包括
#包括
#包括
#包括
#包括
/*网关功能*/
int main(){
/*初始化岩浆*/
magma_init();
magma_queue_t queue=NULL;
magma_设备开发;
magma_getdevice&dev;
magma_队列_创建(开发和队列);
INTM、ldwork、info;
int*piv;
岩浆复合物*a,*da,*dwork;
/*分配并初始化a=magic(3)+magic(3)*1i*/
m=3;
piv=(int*)malloc(m*sizeof(int));
ldwork=m*magma_get_zgetri_nb(m);
magma_zmaloc_cpu(&a,m*m);
a[0].x=8;a[0].y=8;
a[1].x=3;a[1].y=3;
a[2].x=4;a[2].y=4;
a[3].x=1;a[3].y=1;
a[4].x=5;a[4].y=5;
a[5].x=9;a[5].y=9;
a[6].x=6;a[6].y=6;
a[7].x=7;a[7].y=7;
a[8].x=2;a[8].y=2;
/*主机->GPU*/
magma_zmalloc(&dwork,ldwork);
岩浆(&da,m*m);
岩浆基质(m,m,a,m,da,m,队列);
/*吕与逆*/
magma_zgetrf_gpu(m、m、da、m、piv和信息);
magma_zgetri_gpu(m、da、m、piv、dwork、ldwork和info);
/*GPU->主机*/
岩浆基质(m,m,da,m,a,m,队列);
/*显示库存(a)*/

对于(int i=0;i我的系统管理员已经弄明白了为什么独立C代码可以工作而混合C代码不能工作。我将在这里公布原因,以防它对在Matlab中使用Magma时遇到相同问题的任何人都有帮助

  • 我使用的Matlab版本是2014a。这个版本的最新版本是4.7.x。我使用的是更高版本的gcc来编译代码。我从未遇到过在Matlab中使用不同版本的gcc的问题,尽管它给出了警告,但对于上面的代码来说,它确实很重要

  • 确保magma_int_t为int64


  • 有了这两个建议,Magma可以毫无问题地混合到matlab中。

    它在哪里发生SEGFULT?seg错误发生在调用Magma_zgetrf_gpu时。如果Magma_zgetrf_gpu和Magma_zgetri_gpu调用都被注释,混合代码运行良好,只需将未更改的输入矩阵返回到LHS。尝试使用
    打印一些值>mexPrintf
    在这些调用之前。最可能的情况是向其中一个输入变量传递了错误的类型。打印其中的1个元素,然后查看哪个打印给出了SEGFULT(或打印垃圾)我在每个阶段都尝试过。每个参数都是正确的。事实上,如果我不调用这两个函数,矩阵从prhs->主机内存从matlab转换到Interleave->gpu内存->主机内存从Interleave转换到matlab->plhs。成功了。我真的被难倒了!我需要这段代码!一定有区别,否则,该函数在C和mex版本中也会执行相同的操作。一旦bruteforce调试方法创建一个函数,该函数将在调用
    magma_zgetrf_gpu
    之前将所有变量保存到文本文件中。对两个版本使用完全相同的函数,并保存所有输入变量。然后尝试查看有何错误。但是如果ll是一样的,同样的行为是预期的,最终,计算机是确定性的。,
    #include <stdlib.h>
    #include <stdio.h>
    #include <string.h>
    #include <math.h>
    #include <stddef.h>
    #include <magma_v2.h>
    #include <cuda_runtime.h>
    #include <sys/time.h>
    #include <time.h>
    
    /*gateway function*/
    int main() {
    
        /*initialize magma*/
        magma_init();
        magma_queue_t queue = NULL;
        magma_device_t dev;
        magma_getdevice(&dev);
        magma_queue_create(dev,&queue );
    
        int m,ldwork,info;
        int *piv;
        magmaDoubleComplex *a,*da,*dwork;
    
        /* allocate and initialize a = magic(3)+magic(3)*1i; */
        m=3;
        piv=(int*) malloc(m*sizeof(int));
        ldwork = m*magma_get_zgetri_nb(m);
        magma_zmalloc_cpu(&a,m*m);
        a[0].x=8;a[0].y=8;
        a[1].x=3;a[1].y=3;
        a[2].x=4;a[2].y=4;
        a[3].x=1;a[3].y=1;
        a[4].x=5;a[4].y=5;
        a[5].x=9;a[5].y=9;
        a[6].x=6;a[6].y=6;
        a[7].x=7;a[7].y=7;
        a[8].x=2;a[8].y=2;
    
        /* Host -> GPU */
        magma_zmalloc(&dwork,ldwork);
        magma_zmalloc(&da,m*m);
        magma_zsetmatrix(m,m,a,m,da,m,queue);
    
        /*LU and Inverse */
        magma_zgetrf_gpu(m,m,da,m,piv,&info);
        magma_zgetri_gpu(m,da,m,piv,dwork,ldwork,&info);
    
        /*GPU -> Host */
        magma_zgetmatrix(m,m,da,m,a,m,queue);
    
        /* display inv(a) */
        for (int i=0;i<(m*m);i++){
            printf("%f +%fi\n",a[i].x,a[i].y);
        }
    
        /* free memory */
        free(a);
        free(piv);
        magma_free(dwork);
        magma_free(da);
        magma_queue_destroy(queue);
        magma_finalize();
    
        return 0;
    }