来源:LAPACKE官方文档
1.介绍
本文档描述了一个LAPACK的两级C接口,包括一个高级接口和一个中级接口。高级接口在内部处理所有工作空间内存分配,而中级接口要求用户像原始FORTRAN接口那样提供数组的工作空间。这两个接口都提供了对列主矩阵和行主矩阵的支持。这两个接口的原型、相关宏和类型定义都包含在头文件lapacke.h中。
1.1.命名方式
高级接口的命名方案是采用FORTRAN LAPACK例程名,使其小写,并添加前缀LAPACKE_。例如,LAPACK子例程DGETRF变成了LAPACKE_dgetrf。
中级接口的命名方案是采用FORTRAN LAPACK例程名,将其设置为小写,然后添加前缀LAPACKE_和后缀_work,后缀_work表示用户将提供工作空间。例如,LAPACK子例程DGETRF变成了LAPACKE_dgetrf_work。
1.2.复数类型
复数由宏lapack_complex_float和lapack_complex_double定义,它们分别表示单精度和双精度复杂数据类型。始终假设实分量和虚分量连续存储在内存中,实分量先存储。lapack_complex_float和lapack_complex_double宏可以是C99 _Complex类型、C结构定义的类型、c++ STL复杂类型或自定义复杂类型。更多细节请参见lapacke.h。
1.3.数组参数
数组是作为指针传递的,而不是作为指向指针的指针。所有使用一个或多个二维数组(矩阵)作为指针的LAPACKE例程都接收一个int类型的额外参数,这个参数必须等于LAPACK_ROW_MAJOR或LAPACK_COL_MAJOR,这两个参数在lapacke.h中定义,指定该数组中的矩阵是按行主顺序存储还是按列主顺序存储。如果一个例程有多个数组输入,它们必须都使用相同的顺序。
注意,使用行-主顺序可能比列-主顺序需要更多的内存和时间,因为例程必须将行-主顺序转换为底层LAPACK例程所需的列-主顺序。FORTRAN LAPACK例程中的每个二维数组参数都有一个额外的参数来指定其前导维数(leading dimension)。对于以行为主的2D数组,假设一行中的元素是连续的,并且假设一行与下一行的元素之间存在领先维度的间隔。对于以列为主的2D数组,假定列中的元素是连续的,并且假定从一列到下一列的元素之间相隔一个前导维。例如:以列主序存储M*N矩阵,用LDA表示leading dimension,则LDA = M,当M=0时,LDA=1。
1.4.参数别名
除非另外指定,只有输入参数(即通过值和const限定符指定的数组传递的标量)可以在调用LAPACK的C接口时合法地附加别名。
1.5.INFO参数
LAPACKE接口函数将它们的lapack_int返回值设置为INFO参数的值,该参数包含错误和退出条件等信息。这与LAPACK例程不同,后者以FORTRAN整数参数的形式返回此信息。在LAPACKE,INFO的使用和在LAPACK完全一样。如果INFO在FORTRAN中使用基于1的索引返回矩阵的行号或列号,则该值不会为基于0的索引进行调整。
1.6.NaN检查
高级接口包括一个可选的,默认的,在调用任何LAPACK例程之前对所有矩阵输入进行NaN检查。此选项影响所有例程。如果输入包含任何NaN,则输入参数对应的矩阵将被标记为信息参数错误。例如,如果发现第五个参数包含NaN,函数将返回值为-5。可以通过在lapacke.h中定义LAPACK_DISABLE_NAN_CHECK宏来禁用NaN检查和其他参数。中间层接口不包含NaN检查。
1.7.整型
在LAPACKE中,FORTRAN类型为整数的变量被转换为lapack_int。这符合可修改的整数类型大小,特别是给定的ILP64编程模型:将lapack_int重新定义为long int(8字节)将足以支持该模型,因为lapack_int默认定义为int(4字节),支持LP64编程模型。
1.8.逻辑值
FORTRAN逻辑值被转换为lapack_logical,它被定义为lapack_int。
1.9.内存管理
所有的内存管理都由函数LAPACKE_malloc和LAPACKE_free来处理。这允许用户通过修改lapacke.h中的定义来轻松使用他们自己的内存管理器,而不是默认的内存管理器。
这个接口应该是线程安全的,只要这些内存管理例程和底层的LAPACK例程是线程安全的。
1.10.新的错误代码
由于高级接口不使用工作数组,因此在用户耗尽内存时需要错误通知。如果不能分配工作数组,函数将返回LAPACK_WORK_MEMORY_ERROR;如果没有足够的内存来完成换位,则返回LAPACK_TRANSPOSE_MEMORY_ERROR。
2.举例
LAPACK原生接口:
subroutine dgeqrf( integer M,
integer N,
double precision,
dimension( lda, * ) A,
integer LDA,
double precision, dimension( * ) TAU,
double precision, dimension( * ) WORK,
integer LWORK,
integer INFO )
高层接口:
lapack_int m, n, lda, info;
double *a, *tau;
info = LAPACKE_dgeqrf( LAPACK_COL_MAJOR, m, n, a, lda, tau );
中层接口:
lapack_int m, n, lda, info, lwork;
double *a, *tau, *work;
info = LAPACKE_dgeqrf_work( LAPACK_COL_MAJOR, m, n, a, lda, tau, work, lwork);
其中,由于中层接口需要用户提供所需要的工作空间,由一个work数组表示工作空间,其长度用 lwork记录,最小为n。
网友评论