0.0 拉取 ubuntu:18.04 docker image:
sudo docker pull ubuntu:18.04
0.1 启动docker:
sudo docker run --name Lapack_running -it \
-v /dev:/dev -v /usr/src/:/usr/src -v /lib/modules/:/lib/modules --privileged --cap-add=ALL ubuntu:18.04
以下是docker内操作:
0.2 mv /etc/apt/sources.list /etc/apt/sources.list.backupLL
0.3 echo "deb http://mirrors.163.com/ubuntu/ bionic main restricted universe multiverse" > /etc/apt/sources.list
0.4 apt-get update && apt-get upgrade
0.5 .1 apt-get install vim
0.5.2 apt-get install build-essential
0.6 将下面的ubuntu18.04 163 源全部加入到 /etc/apt/sources.list 中: vim /etc/apt/sources.list
deb http://mirrors.163.com/ubuntu/ bionic main restricted universe multiverse
deb http://mirrors.163.com/ubuntu/ bionic-security main restricted universe multiverse
deb http://mirrors.163.com/ubuntu/ bionic-updates main restricted universe multiverse
deb http://mirrors.163.com/ubuntu/ bionic-proposed main restricted universe multiverse
deb http://mirrors.163.com/ubuntu/ bionic-backports main restricted universe multiverse
deb-src http://mirrors.163.com/ubuntu/ bionic main restricted universe multiverse
deb-src http://mirrors.163.com/ubuntu/ bionic-security main restricted universe multiverse
deb-src http://mirrors.163.com/ubuntu/ bionic-updates main restricted universe multiverse
deb-src http://mirrors.163.com/ubuntu/ bionic-proposed main restricted universe multiverse
deb-src http://mirrors.163.com/ubuntu/ bionic-backports main restricted universe multiverse
0.7 apt-get update && apt-get upgrade
0.8 安装必要软件:
apt-get install python3 gfortran wget make
0.8 mkdir 并且 cd 至源码目录
0.9 下载lapack包:
wget https://github.com/Reference-LAPACK/lapack/archive/refs/tags/v3.10.0.tar.gz
0.10 解压:
tar -zxvf v3.10.0.tar.gz
0.11 cd lapack-3.10.0
0.12 cp make.inc.example make.inc
0.13 vim Makefile 并且将12和13行修改为如下:
#lib: lapacklib tmglib
lib: blaslib variants lapacklib tmglib lapackelib lapacke_example
0.14 开始编译:
make -j32
0.15 cd LAPACKE #cd 进入LAPACKE文件夹,这里是lapack的C语言接口源码
0.16 编译LAPACKE:
sudo make -j32 # 编译lapacke
0.17 手动安装lapack:
cp include/*.h /usr/local/include #将lapacke的头文件复制到系统头文件目录
0.18 手动安装lapack:
cd .. #返回上级目录 lapack-3.10.0/
cp *.a /usr/local/lib # 将生成的所有库文件复制到系统库目录
0.19 使用示例:
在系统中任意文件夹中,将如下代码存储为 helloDgetrf.c
// LAPACK debug code
//compile with: gfortran helloDgetrf.c -llapack -lblas -o helloDgetrf
#include <stdio.h>
#include <lapacke.h>
//print matrix A(mxn)
lapack_int printMatrix(int matrix_layout, lapack_int m, lapack_int n, double* a_matrix, lapack_int lda){
if(matrix_layout == LAPACK_COL_MAJOR){
for(int i=0;i<m;i++){
printf("\n");
for(int j=0;j<n; j++){
printf(" %8.4f ",a_matrix[i + j*lda]);
}
}
}else if(matrix_layout == LAPACK_ROW_MAJOR){
for(int i=0;i<m;i++){
printf("\n");
for(int j=0;j<n; j++){
printf(" %8.4f ",a_matrix[i*lda + j]);
}
}
}else{
printf("Parameter matrix_layout is error!\n");
return -1;
}
return 0;
}
int main()
{
int dim = 2;
int nrhs = 1;
int LDA = dim;
int LDB = dim;
int info=dim+1;
double A[4] = {1.0, 1.0, 1.0, -1.0};
/** A*x = b **/
int ipiv[3]={0};
printf("Origin Matrix A=\n");
// lapack_int printMatrix(int matrix_layout, lapack_int m, lapack_int n, double* a_matrix, lapack_int lda)
printMatrix(LAPACK_COL_MAJOR, dim, dim, A, dim);
//lapack_int LAPACKE_dgetrf( int matrix_layout, lapack_int m, lapack_int n, double* a, lapack_int lda, lapack_int* ipiv )
//lapack_int LAPACKE_dgetri( int matrix_layout, lapack_int n, double* a, lapack_int lda, const lapack_int* ipiv )
info = LAPACKE_dgetrf(LAPACK_COL_MAJOR, dim, dim, A, LDA, ipiv);
if(info != 0){ printf("Singular Matrix, INFO = %d\n",info); }
info = LAPACKE_dgetri(LAPACK_COL_MAJOR, dim, A, dim, ipiv);
if(info != 0){ printf("Singular Matrix, INFO = %d\n",info); }
printf("info=%d\n LU_aa:\n",info);
printMatrix(LAPACK_COL_MAJOR, dim, dim, A, dim);
printf("\n\n");
return(0);
}
complex:
// LAPACK debug code
//gfortran hello_sgetrf_sgetri.c -llapacke -llapack -lrefblas -o hello_sgetrf_sgetri
#include <stdio.h>
#include <lapacke.h>
lapack_int printComplexMatrix(int matrix_layout, lapack_int m, lapack_int n, lapack_complex_float* a_matrix, lapack_int lda){
if(matrix_layout == LAPACK_COL_MAJOR){
int i=0;
for(i=0;i<m;i++){
printf("\n");
int j=0;
for(j=0;j<n; j++){
printf("%7.3f + %7.3fI ",__real__(a_matrix[i + j*lda]), __imag__(a_matrix[i + j*lda]));//__real__, __imag__
}
}
}else if(matrix_layout == LAPACK_ROW_MAJOR){
int i=0;
for(i=0;i<m;i++){
printf("\n");
int j=0;
for(j=0;j<n; j++){
printf("%7.3f + %7.3fI ",__real__(a_matrix[i*lda + j]), __imag__(a_matrix[i*lda + j]));
}
}
}else{
printf("Parameter matrix_layout is error!\n");
return -1;
}
return 0;
}
int main()
{
int dim = 3;
int nrhs = 1;
int LDA = dim;
int LDB = dim;
int info=dim+1;
//float _Complex is lapack_complex_float
lapack_complex_float A[18] = {
0.000f+0.000f*I, 0.300f+0.841f*I, 0.600f+0.909f*I,
0.700f+0.841f*I, 1.000f+0.909f*I, 1.300f+0.141f*I,
1.400f+0.909f*I, 1.700f+0.141f*I, 2.000f-0.757f*I
};
/** A*x = b **/
/** lapack_complex_float c1 = 3.1f + 3.2f*I; printf("==%f\n", __real__(c1)); **/
int ipiv[3]={0};
printf("Origin Matrix A=\n");
printComplexMatrix(LAPACK_COL_MAJOR, dim, dim, A, dim);
info = LAPACKE_cgetrf(LAPACK_COL_MAJOR, dim, dim, A, LDA, ipiv);
if(info != 0){ printf("Singular Matrix, INFO = %d\n",info); }
info = LAPACKE_cgetri(LAPACK_COL_MAJOR, dim, A, dim, ipiv);
if(info != 0){ printf("Singular Matrix, INFO = %d\n",info); }
printf("info=%d\n LU_aa:\n",info);
printComplexMatrix(LAPACK_COL_MAJOR, dim, dim, A, dim);
printf("\n\n");
return(0);
}
这个示例也不错:
//helloLapack.c
#include <stdio.h>
#include <lapacke.h>
int main (int argc, const char * argv[])
{
double a[5*3] = {1,2,3,4,5,1,3,5,2,4,1,4,2,5,3};
double b[5*2] = {-10,12,14,16,18,-3,14,12,16,16};
lapack_int info,m,n,lda,ldb,nrhs;
int i,j;
m = 5;
n = 3;
nrhs = 2;
lda = 5;
ldb = 5;
info = LAPACKE_dgels(LAPACK_COL_MAJOR,'N',m,n,nrhs,a,lda,b,ldb);
for(i=0;i<n;i++)
{
for(j=0;j<nrhs;j++)
{
printf("%lf ",b[i+ldb*j]);
}
printf("\n");
}
return(info);
}
0.20 上例使用gfortran进行编译:
gfortran helloLapack.c -llapacke -llapack -lrefblas -o helloLapack
0.21 执行示例:
./helloLapack
打印结果为:
2.000000 1.000000
1.000000 1.000000
1.000000 2.000000
来自一位国际友人的全方位的lapack示例:
0.22 git clone https://github.com/numericalalgorithmsgroup/LAPACK_Examples.git
0.23 vim 修改LAPACK_Examples/GNUmakefile,将其中的两个变量修改如下:
LIBLAPACK := /usr/local/lib/liblapack.a
LIBBLAS := /usr/local/lib/librefblas.a
0.24 编译示例: make -f GNUmakefile
0.25 运行示例:
#cd ..../LAPACK_Examples/BUILD_gfortran/EXECUTABLES/
#./dgetrf_example.exe
按照矩阵的列优先输入矩阵数据。
0.26 另外一个LU分解的示例,可以加入 LAPACKE/example/中,稍微改一下其中的Makefile,该示例调用sgetrf subrutine:
//helloSgetrf.c
#include <stdio.h>
#include <lapacke.h>
#include "lapacke_example_aux.h"
#define N 3
int main (int argc, const char * argv[])
{
float A[15] = {1, 2, 3, 2, 5, 1, 3, 2, 5};
lapack_int* ipiv[N] = {0};
lapack_int info,m,n,lda;
m = 3;
n = 3;
lda = 3;
print_matrix_colmajor_float( "Entry Matrix A", m, n, A, lda );
printf( "LAPACKE_sgetrf (col-major) Example Program Results\n" );
info = LAPACKE_sgetrf(LAPACK_COL_MAJOR, m, n, A, lda, ipiv);
print_matrix_colmajor_float( "Solution", m, n, A, lda );
print_vector("IPIV:", n, ipiv);
printf("info:%d\n",info);
printf( "\n" );
exit( info );
}
0.27 输出如下:
./helloSgetrf
Entry Matrix A
1.0000 2.0000 3.0000
2.0000 5.0000 2.0000
3.0000 1.0000 5.0000
LAPACKE_sgetrf (col-major) Example Program Results
Solution
3.0000 1.0000 5.0000
0.6667 4.3333 -1.3333
0.3333 0.3846 1.8462
IPIV:
3 2 3
info:0
-----------------------------------------------------------------------------------------------------------
debug:
如果要生成debug版本,则需要将前文提到的 make.inc中变量 CFLAGS 和 FFLAGS的值改为:(加入 -g )
CFLAGS = -O3 -g
FFLAGS = -O2 -frecursive -g
然后重复上述make -j32 ,这样,全部的example程序就可以debug了:
gdb ./lapack-3.10.0/LAPACKE/example/xexample_DGELS_colmajor
start
next
step
list
print x
等等。
掌握blas和lapack源码的资源,主要是其源码文件中的注释。
arm的数学库文档:
FFT:
https://blog.csdn.net/zouyu1746430162/article/details/53374693
https://blog.csdn.net/mlnotes/article/details/9676269
https://blog.csdn.net/yuanxing14/article/details/41744461
https://blog.csdn.net/chishuideyu/article/details/78351063
https://my.oschina.net/u/4325212/blog/3908072