LAPACK C (mkl) dptsv row major/column 专业:它对向量有影响吗?
LAPACK C (mkl) dptsv row major/column major: does it make a difference for vectors?
各位,我打电话给LAPACKE_dptsv
如果所有参数都是一维数组,我调用数据 LAPACK_ROW_MAJOR
还是 LAPACK_COL_MAJOR
有关系吗?
函数LAPACKE_dptsv()
对应lapack函数dptsv()
,没有LAPACK_ROW_MAJOR
和LAPACK_COL_MAJOR
之间的切换。 dptsv()
用于列优先排序,corresponding to matrices in Fortran,而大多数 C 矩阵是行优先的。所以 LAPACKE_dptsv(LAPACK_ROW_MAJOR,...)
执行以下步骤:
- 转置右端
b
- 调用Lapack
dptsv()
- 转置响应(即再次
b
)
您可以在 /lapacke/src/lapacke_dptsv_work.c
.
中的 Lapacke 源代码中查看
还有一个问题:*它对挂钟时间有很大影响吗? * 查看 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 clicks (0.770000 seconds).
LAPACK_COL_MAJOR : 310000 clicks (0.310000 seconds).
所以 LAPACKE_dptsv()
使用 LAPACK_COL_MAJOR
和 `nbrhs=42
运行速度几乎快两倍
如果rhs的个数减少到1(并且n
变大):
LAPACK_ROW_MAJOR : 250000 clicks (0.250000 seconds).
LAPACK_COL_MAJOR : 180000 clicks (0.180000 seconds).
LAPACK_COL_MAJOR
和 LAPACK_ROW_MAJOR
导致与单个 RHS 大致相同的挂钟时间。并且输出是一样的。
我没有在我的电脑上安装 intel mkl,我很好奇它如何改变这个测试的结论...
各位,我打电话给LAPACKE_dptsv
如果所有参数都是一维数组,我调用数据 LAPACK_ROW_MAJOR
还是 LAPACK_COL_MAJOR
有关系吗?
函数LAPACKE_dptsv()
对应lapack函数dptsv()
,没有LAPACK_ROW_MAJOR
和LAPACK_COL_MAJOR
之间的切换。 dptsv()
用于列优先排序,corresponding to matrices in Fortran,而大多数 C 矩阵是行优先的。所以 LAPACKE_dptsv(LAPACK_ROW_MAJOR,...)
执行以下步骤:
- 转置右端
b
- 调用Lapack
dptsv()
- 转置响应(即再次
b
)
您可以在 /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 clicks (0.770000 seconds).
LAPACK_COL_MAJOR : 310000 clicks (0.310000 seconds).
所以 LAPACKE_dptsv()
使用 LAPACK_COL_MAJOR
和 `nbrhs=42
如果rhs的个数减少到1(并且n
变大):
LAPACK_ROW_MAJOR : 250000 clicks (0.250000 seconds).
LAPACK_COL_MAJOR : 180000 clicks (0.180000 seconds).
LAPACK_COL_MAJOR
和 LAPACK_ROW_MAJOR
导致与单个 RHS 大致相同的挂钟时间。并且输出是一样的。
我没有在我的电脑上安装 intel mkl,我很好奇它如何改变这个测试的结论...