代码之家  ›  专栏  ›  技术社区  ›  Gavin Portwood

LAPACK C(mkl)dptsv行主要/列主要:它对向量有影响吗?

  •  1
  • Gavin Portwood  · 技术社区  · 10 年前

    伙计们,我打电话给你们 LAPACKE_dptsv

    如果所有参数都是1d数组,那么调用数据是否重要 LAPACK_ROW_MAJOR LAPACK_COL_MAJOR ?

    1 回复  |  直到 7 年前
        1
  •  1
  •   francis    10 年前

    函数 LAPACKE_dptsv() 对应于lapack函数 dptsv() ,不具有 LAPACK_ROW_MAJOR LAPACK_COL_MAJOR . dptsv() 用于列主排序, corresponding to matrices in Fortran ,而大多数C矩阵是行主矩阵。所以 LAPACKE_dptsv(LAPACK_ROW_MAJOR,...) 执行以下步骤:

    • 调换右端侧 b
    • 呼叫 dptsv() 拉普克的
    • 转换响应(即 b 再次)

    你可以在Lapacke的来源中查看,在 /lapacke/src/lapacke_dptsv_work.c .

    还有一个问题: *这在很大程度上影响了挂钟时间吗* 正在查看 dpttrs_8f_source , 这是可能的 :分解 L*D*L**T 由单个for循环(+循环展开)执行。因此,需要一段代码来回答这个问题。以下代码由编译 gcc main.c -o main -llapacke -llapack -lblas

    #include <stdio.h>
    #include "lapacke.h"
    #include <malloc.h>
    #include <time.h>
    
    int main ()
    {
        //double a[3][2] = {{1,0},{1,1},{1,2}};
    
        double **outputArray;
        int designs=3;
        int i,j;
        lapack_int info,n,ldb,nrhs;
    
        n = 420000;
        nrhs = 42;
    
        //double outputArray[3][1] = {{6},{0},{0}};
        double* ad=malloc(n*sizeof(double));
        if(ad==NULL){printf("malloc failed\n");exit(1);}
        for(i=0;i<n;i++){
            ad[i]=3;
        }
        double* ae=malloc((n-1)*sizeof(double));
        if(ae==NULL){printf("malloc failed\n");exit(1);}
        for(i=0;i<n-1;i++){
            ae[i]=-1;
        }
    
        double* b=malloc(n*nrhs* sizeof(double));
        if(b==NULL){printf("malloc failed\n");exit(1);}
    
        for(j=0;j<nrhs;j++){
            for(i=0;i<n;i++){
                b[i*nrhs+j]=i+2*j;
            }
        }
    
        ldb=nrhs;
    
        clock_t t;
        t = clock();
        info = LAPACKE_dptsv(LAPACK_ROW_MAJOR,n,nrhs,ad,ae,b,ldb);
        if(info!=0){printf("failed, info %d\n",info);}
        t = clock() - t;
        printf ("LAPACK_ROW_MAJOR :  %d clicks (%f seconds).\n",t,((float)t)/CLOCKS_PER_SEC);
    
        for(i=0;i<n;i++){
            ad[i]=3;
        }
        if(ae==NULL){printf("malloc failed\n");exit(1);}
        for(i=0;i<n-1;i++){
            ae[i]=-1;
        }
    
        double* b2=malloc(n*nrhs* sizeof(double));
        if(b2==NULL){printf("malloc failed\n");exit(1);}
        for(j=0;j<nrhs;j++){
            for(i=0;i<n;i++){
                b2[j*n+i]=i+2*j;
            }
        }
    
        t = clock();
        ldb=n;
        info = LAPACKE_dptsv(LAPACK_COL_MAJOR,n,nrhs,ad,ae,b2,ldb);
        if(info!=0){printf("failed, info %d\n",info);}
        t = clock() - t;
        printf ("LAPACK_COL_MAJOR :  %d clicks (%f seconds).\n",t,((float)t)/CLOCKS_PER_SEC);
    
        double delta=0,temp,deltal=0;
        for(i=0;i<n;i++){
            deltal=0;
            for(j=0;j<nrhs;j++){
                temp=(b[i*nrhs+j]-b2[j*n+i]);
                deltal+=temp*temp;
            }
            delta+=deltal;
        }
        printf("delta %g\n",delta);
        free(ad);
        free(ae);
        free(b);
        free(b2);
        return (info);
    } 
    

    我的输出是:

    LAPACK_ROW_MAJOR:770000次点击(0.770000秒)。

    LAPACK_COL_MAYOR:310000次点击(0.310000秒)。

    所以 LAPACKE_dptsv() 跑步速度快了几乎两倍 LAPACK_COL_MAJOR公司 其中`nbrhs=42

    如果rhs的数量减少到1(并且 n 较大) :

    LAPACK_ROW_MAJOR:250000次点击(0.250000秒)。

    LAPACK_COL_MAYOR:18000次点击(0.180000秒)。

    LAPACK_COL_MAJOR公司 LAPACK_ROW_MAJOR公司 导致与单个RHS大致相同的墙上时钟时间。输出是相同的。

    我还没有在我的电脑上安装英特尔mkl,我很好奇它如何改变这个测试的结论。。。