我要加入 登录
声振论坛 返回首页

impulse的个人空间 http://home.vibunion.com/?41382 [收藏] [复制] [分享] [RSS]

日志

BLAS和 LAPACK库的编译

已有 1083 次阅读2011-9-12 20:41

1、使用MinGW(转自---http://hi.baidu.com/xuyungui/blog/item/678ab7988bd4240e6f068cef.html

Compile LAPACK and BLAS as DLL on Windows

BLAS (Basic Linear Algebra Subprograms) is a library that provides standard routines for basic vector and matrix operations.

LAPACK is a library that provides functions for solving systems of linear equations, matrix factorizations, solving eigenvalue and singular value problems. LAPACK library have dependency to BLAS library because of the LAPACK functions using BLAS functions to work.

Both of those libraries are written in Fortran77 and no binaries provided for windows. The sources are downloadable from netlib site. So you can compile and use their libraries. However makefile and make solutions for compiling under windows are cumbersome.

So I recommend compiling directly from the sources using a FORTRAN compiler. There is a free and open source FORTRAN compiler for Windows which is the port of gnu FORTRAN compiler for Windows. You could also use Cygwin and tools in cygwin but your dynamic library loader will have dependency to cygwin dlls. MinGW is a collection of tools that allows you to produce native Windows programs. G77, make, gcc are the common tools provided by Mingw.

Here are the steps to go to compilation

  • Download most current version of LAPACK from Netlib and extract the sources
  • Download almost all of the Mingw tools and extract the tools
  • Copy dlamch.f and slamch.f from INSTALL directory SRC directory
  • Set path to have mingw binaries
    • set PATH=c:\mingw\bin\;%PATH%
  • Go to root directory of the extracted folder and compile using g77
  • First compile BLAS. –shared option is needed in order to functions to be exposed from the dll. -O generates optimised code. -o filename is the output file
    • g77 –shared -o blas.dll BLAS\SRC\*.f –O
  • Compile LAPACK with BLAS dependency
    • g77 –shared -o lapack.dll src\*.f blas.dll -O

Here is the output:

c:\\lapack-3.1.1\\copy INSTALL\\dlamch.f SRC\\dlamch.f
1 file(s) copied.
c:\\lapack-3.1.1\\copy INSTALL\\slamch.f SRC\\slamch.f
1 file(s) copied.
c:\\lapack-3.1.1\\set PATH=c:\\tools\\mingw\\bin\\;%PATH%
c:\\lapack-3.1.1\\g77 --shared -o blas.dll BLAS\\SRC\\*.f -O
c:\\lapack-3.1.1\\g77 --shared -o lapack.dll src\\*.f blas.dll -O

 

2、使用VS(转自--- http://hi.baidu.com/kaien_space/blog/item/dcb84b8b96347bd4fd1f1011.html

如何在VC中调用CLAPACK

 

关于CLAPACK的使用网上的资料并不多。主要就是官方网站上的安装说明,以及LAPACK官方论坛上的一些资料。然而,国外一般科研使用的平台都是UNIXLINUX, 所以对于windows上使用CLAPACK的相关介绍就很少。幸运的是,官方提供了CLAPACKwindows版本,而且还有专门的VisualStudio工程包。所以,对于广大VS用户来说可谓非常之方便。

然而,即使如此,很多人在使用的过程中还是出现这样那样的问题。其中,多数的情况都是出在编译的时候。而且上网提问多数都没人能够解答。
鉴于此,本人就对如何在VC上编译和使用CLAPACK库,作下简单的说明。

1、什么是CLAPACK:
CLAPACK
LAPACKC语言接口。LAPACK的全称是Linear Algebra PACKage,是非常著名的线性代数库。原版的LAPACK是用Fortran写的,为了方便C/C++程序的使用,就有了LAPACKC接口CLAPACK

LAPACK的主页是 http://www.netlib.org/lapack/
CLAPACK
则在 http://www.netlib.org/clapack/

这两个库都是开源的,可以在官方网站免费下载和使用。

2CLAPACK的安装:
所谓的安装其实就是把源代码编译成我们可以调用的库.lib文件。

首先从主页上下载CLAPACK包。http://www.netlib.org/clapack/ 上有很多版本。我们选择
http://www.netlib.org/clapack/CLAPACK-3.1.1-VisualStudio.zip
大小: 42MB
版本: 3.1.1
是专门提供给VS用户的。
(注意:VS的版本不能太低。VC6.0是无法使用的。VS2005及以上都应该没问题。本人用的是VS2008。测试的时候发现工程文件版本太老,还需要转换一下呢。当然转换后运行也很正常。如果你坚持要使用VC++6.0那请下载http://www.netlib.org/clapack/CLAPACK3-Windows.zip 这是CLAPACK3.0版,比我介绍的版本3.1.1版要旧一些)

下载解压后,我们可以看到如下目录结构:
\SRC             CLAPACK
的源代码
\BLAS            BLAS
的源代码
\F2CLIBS       F2C
的源代码

\LIB                 编译后的库文件.lib
\INCLUDE      
头文件
\TESTING      
一些使用范例程序
\INSTALL       
里面有UNIX和其他平台下安装的文件和方法。lawn81.pdf文件是CLAPACK的使用说明,大家使用的时候可以看看。
这里我要提醒大家。虽然软件包里已经有编译好的.lib文件,就在\LIB中。但是我建议大家不要直接使用他们,还是自己编译一下再用才保险。很多人就是因为直接使用他们而出错的。这点非常重要!如果你就是直接调用他们失败的,那不妨先自己编译一下再试试。

另外,CLAPACK需要F2CLIBS库,并且使用了blastmglib这两个外部的库。这几个库都已经包含在了CLAPACK的安装包中。所以,大家无需另外下载。当然,使用前我们还是要重新编译一下的,原因上面已经说过了。

接下来,我详细地讲讲如何编译他们。
首先双击 clapack.vcproj打开工程项目文件。工程中已经包含了所有的子项目。
我们根据个人需要,编译成debug模式,或者release模式。为了能在自己的程序调用中方便的进行debug,我这里就以debug模式为例说明。我的系统是win32。如果你是64位系统也是支持的,操作方法类似。

首先编译F2CLIBS,用于将fortran转换为c语言。
选择libf2c子项目。直接生成之。编译过程中可能会有一些warning,不要理会他们。编译成功后,输出文件是libf2cd.lib。这里的d就是debug模式,如果是release模式就是libf2c.lib。输出文件默认路径是\LIB文件夹。注意,\LIB\Win32下已经有一些lib了。大家最好把他们都先删除了,以免新旧文件混淆。

接着编译tmglib。这是一个矩阵库。
这个库在TESTING\MATGEN里面。选择他生成就好了。
输出文件还是在\LIB里面。文件名是tmglibd.lib
然后是编译blas,选择项目blas, 编译之。输出文件BLASd.lib

最后是编译CLAPACK,生成clapackd.lib.

其他模式对应的输出文件大家可以参看下表。
这里需要注意的是,不同模式间不要混合使用。

Win 32

Configuration

F2c

Reference BLAS

CLAPACK

CBLASWRAP

F77BLASWRAP

TMGLIB

Win32 - Release

libf2c.lib

BLAS.lib

clapack.lib

cblaswrap.lib

f77blaswrap.lib

tmglib.lib

Win32 - Release no wrap

 

BLAS_nowrap.lib

clapack_nowrap.lib

 

 

tmglib_nowrap.lib

Win32 - Debug

libf2cd.lib

BLASd.lib

clapackd.lib

cblaswrapd.lib

f77blaswrapd.lib

tmglibd.lib

Win32 - Debug no wrap

 

BLASd_nowrap.lib

clapackd_nowrap.lib

 

 

tmglibd_nowrap.lib

x64

Configuration

F2c

Reference BLAS

CLAPACK

CBLASWRAP

F77BLASWRAP

TMGLIB

x64 - Release

libf2c.lib

BLAS.lib

clapack.lib

cblaswrap.lib

f77blaswrap.lib

tmglib.lib

x64 - Release no wrap

 

BLAS_nowrap.lib

clapack_nowrap.lib

 

 

tmglib_nowrap.lib

x64 - Debug

libf2cd.lib

BLASd.lib

clapackd.lib

cblaswrapd.lib

f77blaswrapd.lib

tmglibd.lib

x64 - Debug no wrap

 

BLASd_nowrap.lib

clapackd_nowrap.lib

 

 

tmglibd_nowrap.lib

3、如何调用CLAPACK:
前面,我们已经生成了CLAPACK的库文件了。那么如何在自己的程序中使用他们呢?
其实很简单。你所需要的只有两部分:
1)
头文件
头文件就是.h文件。存放在\INCLUDE中。在自己的工程里加入这个目录就行了。里面的文件最好不要作任何修改。程序中主要调用的头文件是clapack.hf2c.h

2)库文件
库文件就是我们前面编译生成的那些lib文件了。

这里,我就以一个具体的调用实例详细地说明如何在VC中设置和使用CLAPACK
首先,VC中项目的设置方式是:
项目的属性里。C/C++选项卡中,附加包含目录里添加\INCLUDE目录。
连接器选项卡中。附加库目录里添加\LIB\Win32目录。然后附加依赖项添加libf2cd.lib BLASd.lib clapackd.lib tmglibd.lib(根据不同的编译模式和个人需要以及系统需要选择库文件)

另外,如果想在调试时能对库函数进行源码级调试。那么需要在VS 工具--选项--项目和解决方案--VC++目录 中添加\SRC的目录。

本文,我们将调用CLAPACK的一个函数dgesvd_()来学习使用的方法。

注意: 包括此函数在内的所有的CLAPACK函数可以在\SRC下找到源代码,并在代码中有函数参数的说明信息。dgesvd_的代码文件就是dgesvd.c

dgesvd_
的函数声明:
int dgesvd_(char *jobu, char *jobvt, integer *m, integer *n,
doublereal *a, integer *lda, doublereal *s, doublereal *u, integer *
ldu, doublereal *vt, integer *ldvt, doublereal *work, integer *lwork,
integer *info)

dgesvd_
的功能是对一个实矩阵A进行SVD分解(singular value decomposition)
A = U * SIGMA * transpose(V)

dgesvd.c文件里有详细地函数说明和参数说明。
    SIGMA is an M-by-N matrix which is zero except for its  
    min(m,n) diagonal elements, U is an M-by-M orthogonal matrix, and  
    V is an N-by-N orthogonal matrix. The diagonal elements of SIGMA  
    are the singular values of A; they are real and non-negative, and  
    are returned in descending order. The first min(m,n) columns of  
    U and V are the left and right singular vectors of A.  

    Note that the routine returns V**T, not V.  
    .........................................

参数的具体说明也请参看这个文件的 Arguments部分

代码:
#include <stdio.h>
#include <process.h>

//因为程序是C++,而CLAPACKf2c程序转换的C语言版本,所以在此处用extern关键字调用
extern"C"
{
#include <f2c.h>
#include <clapack.h>
}

#define SIZE 4

int main()
{
     char JOBU;
     char JOBVT;

     int i;

     //数据类型integerfortran里的。这里在C++下可以使用的原因是f2c.h文件中已经作了定义
     integer M = SIZE;
     integer N = SIZE;
     integer LDA = M;
     integer LDU = M;
     integer LDVT = N;
     integer LWORK;
     integer INFO;
  
     integer mn = min( M, N );
   
     integer MN = max( M, N );
    
     double a[SIZE*SIZE] = { 16.0, 5.0, 9.0 , 4.0, 2.0, 11.0, 7.0 , 14.0, 3.0, 10.0, 6.0, 15.0, 13.0, 8.0, 12.0, 1.0};
     double s[SIZE];
     double wk[201];
     double uu[SIZE*SIZE];
     double vt[SIZE*SIZE];
    
       JOBU = 'A';
    
       JOBVT = 'A';
    
    LWORK = 201;
   
/* Subroutine int dgesvd_(char *jobu, char *jobvt, integer *m, integer *n,
        doublereal *a, integer *lda, doublereal *s, doublereal *u, integer *
        ldu, doublereal *vt, integer *ldvt, doublereal *work, integer *lwork,
        integer *info)
*/
    dgesvd_( &JOBU, &JOBVT, &M, &N, a, &LDA, s, uu, &LDU, vt, &LDVT, wk, &LWORK, &INFO);
         
    printf("INFO=%d \n", INFO );         

    for ( i= 0; i< SIZE; i++ ) {
        printf("s[ %d ] = %f\n", i, s[ i ] );
    }

    system("pause");

    return 0;
}    
运算结果输出:
INFO=0
s[ 0 ] = 34.000000
s[ 1 ] = 17.888544
s[ 2 ] = 4.472136
s[ 3 ] = 0.000000

注意:这个例子中我们使用的库是clapackd.lib
libf2cd.lib BLASd.lib tmglibd.lib
都没有用到。
总之需要什么库就用什么库。关键点是一定要自己编译生成这些.lib文件来使用。不要用现成的,以免出错。

 

 

 

评论 (0 个评论)

facelist doodle 涂鸦板

您需要登录后才可以评论 登录 | 我要加入

QQ|小黑屋|Archiver|手机版|联系我们|声振论坛

GMT+8, 2024-5-13 12:14 , Processed in 0.037454 second(s), 15 queries , Gzip On.

Powered by Discuz! X3.4

Copyright © 2001-2021, Tencent Cloud.

返回顶部