通过 Intel Visual fortran Windows 调用 SuperLU

Calling SuperLU via Intel Visual fortran Windows

提问人:realbabilu 提问时间:3/17/2022 最后编辑:realbabilu 更新时间:3/23/2022 访问量:201

问:

我通过 Intel Visual Fortran (Intel Parallel Studio Windows) --> SuperLU.lib 创建了静态库 SuperLU 5.3。 源 = https://github.com/xiaoyeli/superlu/archive/refs/tags/v5.3.0.zip

它是基于 c 的。

我想测试它以使用 Fortran 子程序调用它,因为它需要 BLAS 函数之一,所以我改用 MKL。 而且还需要先编译。我编译了, 当我编译它时,我得到了,并且使用 cmd 控制台模式或 Visual Studio IDE 的 MKL,它仍然有错误链接。f77_main.fhbcode1.fdtrsv.cc_fortran_dgssv.cicx/c c_fortran_dgssv.cc_fortran_dgssv.objf77_main.fhbcode1.fsuperlu.libc_fortran_dgssv.obj/Qmkl

示例:我尝试在不创建静态库的情况下进行编译:

cd c:\Superlu\SRC
icl/c *.c 
copy *.obj *.h c:\SuperLu\Fortran
cd c:\SuperLU\Fortran
icl/c c_fortran_dgssv.c 
ifort f77_main.f hbcode1.f *.obj /Qmkl

error LNK2019: unresolved external symbol C_FORTRAN_DGSSV referenced in function MAIN__     f77_main.obj        

Fortran 文件夹 v5.3.0 中的 f77_main.f.zip

program f77_main 
      call c_fortran_dgssv( iopt, n, nnz, nrhs, values, rowind, colptr, 
     $                      b, ldb, factors, info )

而 c_fortran_dgssv.c 在 src 文件夹 v5.3.0 中.zip

void
c_fortran_dgssv_(int *iopt, int *n, int *nnz, int *nrhs, 
                 double *values, int *rowind, int *colptr,
                 double *b, int *ldb,
         fptr *f_factors, /* a handle containing the address
                     pointing to the factored matrices */
         int *info)

看起来我遇到了从 fortran 调用 C 的链接器问题。 我尝试了ifort /names:lowercase或/names:UPPERCASE同样的问题

SuperLU src 上的 Slu_cnames.h 具有许多计算机类型的许多符号。

#ifndef __SUPERLU_CNAMES /* allow multiple inclusions */
#define __SUPERLU_CNAMES


#define ADD_       0
#define ADD__      1
#define NOCHANGE   2
#define UPCASE     3
#define OLD_CRAY   4
#define C_CALL     5

#ifdef UpCase
#define F77_CALL_C  UPCASE
#endif

#ifdef NoChange
#define F77_CALL_C  NOCHANGE
#endif

#ifdef Add_
#define F77_CALL_C  ADD_
#endif

#ifdef Add__
#define F77_CALL_C  ADD__
#endif

#ifdef _CRAY
#define F77_CALL_C  OLD_CRAY
#endif
...
visual-studio visual-c++ 链接器错误 intel-fortran

评论

0赞 Vladimir F Героям слава 3/17/2022
请参阅最小可重复示例
0赞 realbabilu 3/18/2022
我需要 HOWTO 才能在英特尔 Fortran Windows 环境中使用 SuperLU。从 Fortran 调用 SuperLU。
0赞 Vladimir F Героям слава 3/18/2022
这个网站不太适合发布通用的 HOWTO,但它在解决特定问题方面非常好。这就是为什么在出现错误之前,我们需要尽可能多的关于您正在做的事情的详细信息。通常,它需要制作一个小的代码示例和特定的编译器命令,这些命令会随代码一起生成错误。
0赞 realbabilu 3/18/2022
更新了详细问题
0赞 Vladimir F Героям слава 3/18/2022
请显示完整的设置。请显示主 Fortran 程序的更多代码。似乎您以某种方式禁用了正常的名称修改。在这种情况下,您将需要,但最好修复您的设置。真的,我们需要确切的具体细节,而不仅仅是几行。一个真正的最小可重复的例子call c_fortran_dgssv_

答:

0赞 realbabilu 3/23/2022 #1

用于在 Windows 中使用 Visual Studio 或命令提示符使用英特尔编译器(不带 Makefile)进行编译。它需要删除与 fortran 兼容的符号。 修改后的 slu_Cnames.h 需要编译 SuperLu 库。

问题解决了!我在 Superlu C 标头源代码上看到了 slu_cnames.h。我需要删除 if 符号调用不必要的方法。仅使用适当的,原来的“ifmethod”不起作用。这是适用于英特尔编译器窗口的 slu_cnames.h。

转到 src,相应地编辑 slu_cnames.h。

/* slu_cnames.h */
#define __SUPERLU_CNAMES

/* BLAS */
#define sswap_    SSWAP
#define saxpy_    SAXPY
#define sasum_    SASUM
#define isamax_   ISAMAX
#define scopy_    SCOPY
#define sscal_    SSCAL
#define sger_     SGER
#define snrm2_    SNRM2
#define ssymv_    SSYMV
#define sdot_     SDOT
#define saxpy_    SAXPY
#define ssyr2_    SSYR2
#define srot_     SROT
#define sgemv_    SGEMV
#define strsv_    STRSV
#define sgemm_    SGEMM
#define strsm_    STRSM

#define dswap_    DSWAP
#define daxpy_    DAXPY
#define dasum_    DASUM
#define idamax_   IDAMAX
#define dcopy_    DCOPY
#define dscal_    DSCAL
#define dger_     DGER
#define dnrm2_    DNRM2
#define dsymv_    DSYMV
#define ddot_     DDOT
#define dsyr2_    DSYR2
#define drot_     DROT
#define dgemv_    DGEMV
#define dtrsv_    DTRSV
#define dgemm_    DGEMM
#define dtrsm_    DTRSM

#define cswap_    CSWAP
#define caxpy_    CAXPY
#define scasum_   SCASUM
#define icamax_   ICAMAX
#define ccopy_    CCOPY
#define cscal_    CSCAL
#define scnrm2_   SCNRM2
#define cgemv_    CGEMV
#define ctrsv_    CTRSV
#define cgemm_    CGEMM
#define ctrsm_    CTRSM
#define cgerc_    CGERC
#define chemv_    CHEMV
#define cher2_    CHER2

#define zswap_    ZSWAP
#define zaxpy_    ZAXPY
#define dzasum_   DZASUM
#define izamax_   IZAMAX
#define zcopy_    ZCOPY
#define zscal_    ZSCAL
#define dznrm2_   DZNRM2
#define zgemv_    ZGEMV
#define ztrsv_    ZTRSV
#define zgemm_    ZGEMM
#define ztrsm_    ZTRSM
#define zgerc_    ZGERC
#define zhemv_    ZHEMV
#define zher2_    ZHER2

/* LAPACK */
#define dlacon_   DLACON
#define slacon_   SLACON
#define icmax1_   ICMAX1
#define scsum1_   SCSUM1
#define clacon_   CLACON
#define dzsum1_   DZSUM1
#define izmax1_   IZMAX1
#define zlacon_   ZLACON

/* Fortran interface */
#define c_bridge_dgssv_ C_BRIDGE_DGSSV
#define c_fortran_sgssv_ C_FORTRAN_SGSSV
#define c_fortran_dgssv_ C_FORTRAN_DGSSV
#define c_fortran_cgssv_ C_FORTRAN_CGSSV
#define c_fortran_zgssv_ C_FORTRAN_ZGSSV

然后编译并测试SuperLU

icl /c *.c /O3
lib *.obj /OUT:superlu53.lib /NODEFAULTLIB /INCLUDE:colamd.h /INCLUDE:f2c.h /INCLUDE:slu_cdefs.h /INCLUDE:slu_Cnames.h /INCLUDE:slu_dcomplex.h /INCLUDE:slu_ddefs.h /INCLUDE:slu_scomplex.h /INCLUDE:slu_util.h /INCLUDE:slu_sdefs.h /INCLUDE:slu_zdefs.h /INCLUDE:superlu_enum_consts.h /INCLUDE:supermatrix.h /VERBOSE /NODEFAULTLIB /MACHINE:x64
icl /c c_fortran_dgssv.c /O3 /NODEFAULTLIB 
ifort f77_main.f hbcode1.f superlu53.lib /O3 /Qmkl