C语言中如何调用LAPACK函数
#1
去过北极
发表于 05-13-2006 - 12:09
精准.石油.论坛 forum.petro-china.com
...
extern void__stdcall CGESVD(.............);
......
CGESVD(..........);
....
但编译的时候老是报错:syntax error before ‘CGESVD’
请各位大侠指点,谢谢!
----
来源: 精准石油论坛 - 推进信息共享,提升科技水平
#4 Guest_blueocean_*
Guest_blueocean_*
发表于 05-13-2006 - 12:54
精准.石油.论坛 forum.petro-china.com
http://www.netlib.or...omplex/cgesvd.f
要下载所有有关的程序, 包括BLAS程序. 把这些程序做成库.
因为是SVD是FORTRAN, 你用C调用的时候还得加上Fortran转到C的语句, 以前我用过, 现在记不清楚了.
----
来源: 精准石油论坛 - 推进信息共享,提升科技水平
#5
sandstone
发表于 05-13-2006 - 15:49
精准.石油.论坛 forum.petro-china.com
引用框(blueocean @ 2006-05-12, 08:54 PM)
http://www.netlib.or...omplex/cgesvd.f
要下载所有有关的程序, 包括BLAS程序. 把这些程序做成库.
因为是SVD是FORTRAN, 你用C调用的时候还得加上Fortran转到C的语句, 以前我用过, 现在记不清楚了.
Fortran和C函数在编译成库文件后,也就是在2进制意义上是无差别的。
我现在能想起来的就是2个问题:
1。 call convention
2。 如果数组的index作为参数的化,C和Fortran是不一样的(zero based or one based)。这个在矩阵操作函数中比较常见。
----
来源: 精准石油论坛 - 推进信息共享,提升科技水平
#6
去过北极
发表于 05-13-2006 - 17:02
精准.石油.论坛 forum.petro-china.com
:blink: 怎么办? 继续虚心请教各位大哥
----
来源: 精准石油论坛 - 推进信息共享,提升科技水平
#7
rpms
发表于 05-13-2006 - 19:33
精准.石油.论坛 forum.petro-china.com
# Makefile for ...su/main
include $(CWPROOT)/src/Makefile.config
D = $L/libcwp.a $L/libpar.a $L/libsu.a
B = ../bin
LFLAGS= $(PRELFLAGS) -L$L -lsu -lpar -lcwp -llapack -lg2c -lfrtbegin -lm $(POSTLFLAGS)
PROGS = $B/××××××××
INSTALL : $(PROGS)
@-rm -f INSTALL
@touch $@
$(PROGS): $(CTARGET) $D
-$(CC) $(CFLAGS) $(@F).c $(LFLAGS) -o $@
@$(MCHMODLINE)
@echo $(@F) installed in $B
remake :
-rm -f $(PROGS) INSTALL
$(MAKE)
clean::
rm -f a.out junk* JUNK* core
主要是编译的时候加上 -llapack -lg2c -lfrtbegin 这三个选项。
写程序的时候这样声明:
int sgesv_(int *n, int *nrhs, float *a, int *lda, int *ipiv, float *b, int *ldb, int *info);
调用的时候这样调:
sgesv_(&n, &nrhs, a, &n, ipiv, b, &n, &info);
要加一个下划线,因为lapack是fortran写的,c里面调用fortran生成的库函数就这么调用。
----
来源: 精准石油论坛 - 推进信息共享,提升科技水平
#9
去过北极
发表于 05-15-2006 - 08:25
精准.石油.论坛 forum.petro-china.com
引用框(rpms @ 2006-05-13, 03:33 AM)
# Makefile for ...su/main
include $(CWPROOT)/src/Makefile.config
D = $L/libcwp.a $L/libpar.a $L/libsu.a
B = ../bin
LFLAGS= $(PRELFLAGS) -L$L -lsu -lpar -lcwp -llapack -lg2c -lfrtbegin -lm $(POSTLFLAGS)
PROGS = $B/××××××××
INSTALL : $(PROGS)
@-rm -f INSTALL
@touch $@
$(PROGS): $(CTARGET) $D
-$(CC) $(CFLAGS) $(@F).c $(LFLAGS) -o $@
@$(MCHMODLINE)
@echo $(@F) installed in $B
remake :
-rm -f $(PROGS) INSTALL
$(MAKE)
clean::
rm -f a.out junk* JUNK* core
实在是很抱歉,小弟最近刚开始操作LINUX,水平有限,还需要请教一下
1 这个Makefile是随便在哪里创建都可以么? 还是必须要在su文件夹里?
2 PROGS =$B/×××××××× 这里的XXXXXXX是什么阿?
有劳各位大牛了 :P
----
来源: 精准石油论坛 - 推进信息共享,提升科技水平
#10
blueocean
发表于 05-15-2006 - 12:31
精准.石油.论坛 forum.petro-china.com
引用框(去过北极 @ 2006-05-14, 04:25 PM)
1 这个Makefile是随便在哪里创建都可以么? 还是必须要在su文件夹里?
2 PROGS =$B/×××××××× 这里的XXXXXXX是什么阿?
有劳各位大牛了 :P
去过北极, 如果想了解 Make 文件, 还是到百度或google上搜索一下, 了解Make最基本的用法.
rpms 只是给了一个SU的Make file的例子, 你自己可以随便建.
$B 是调用 参数B, 后面的XXXXX, 是省略的可执行文件名. (你还是先看看Make file 的介绍吧).
----
来源: 精准石油论坛 - 推进信息共享,提升科技水平
#11
sandstone
发表于 05-15-2006 - 14:34
精准.石油.论坛 forum.petro-china.com
引用框(去过北极 @ 2006-05-14, 04:25 PM)
1 这个Makefile是随便在哪里创建都可以么? 还是必须要在su文件夹里?
2 PROGS =$B/×××××××× 这里的XXXXXXX是什么阿?
有劳各位大牛了 :P
仔细研究一下makefile还是很有必要的。建议研读一下文献
http://www.stlchina....m/LearnMakefile
----
来源: 精准石油论坛 - 推进信息共享,提升科技水平
#12
rpms
发表于 05-15-2006 - 18:25
精准.石油.论坛 forum.petro-china.com
引用框(blueocean @ 2006-05-14, 08:31 PM)
引用框(去过北极 @ 2006-05-14, 04:25 PM)
1 这个Makefile是随便在哪里创建都可以么? 还是必须要在su文件夹里?
2 PROGS =$B/×××××××× 这里的XXXXXXX是什么阿?
有劳各位大牛了 :P
去过北极, 如果想了解 Make 文件, 还是到百度或google上搜索一下, 了解Make最基本的用法.
rpms 只是给了一个SU的Make file的例子, 你自己可以随便建.
$B 是调用 参数B, 后面的XXXXX, 是省略的可执行文件名. (你还是先看看Make file 的介绍吧).
同意!建议北极把B=../bin 换成B=.(表示生成可执行文件放在当前目录下),然后把×××××换成你要编译的源文件名,例如源文件sunmo.c,这里的×××××就是sunmo,然后把整个文件存成Makefile放在源程序文件夹里面,一个make命令就可以了。
----
来源: 精准石油论坛 - 推进信息共享,提升科技水平
#13
去过北极
发表于 05-16-2006 - 08:35
精准.石油.论坛 forum.petro-china.com
f95 -u -f -dalign -native -xO5 -xarch=v8plusa -c slasq3.f
f95: 无法识别的选项‘-native’
f95: 语言 arch=v8plusa 未能被识别
f95: 语言 arch=v8plusa 未能被识别
f95: slasq3.f:未使用链接器输入文件,因为链接尚未完成
然后我查看Makefile的内容,发现是include的make.inc里有错,主要是这条命令:
LOADOPTS = -f -dalign -native -xO5 -xarch=v8plusa
ARCH = ar
这是怎么回事呢? 要不我按照rpms兄教的那样自己重新写个Makefile来编译?
----
来源: 精准石油论坛 - 推进信息共享,提升科技水平
#15
去过北极
发表于 05-16-2006 - 12:58
精准.石油.论坛 forum.petro-china.com
../../lapack_SUN4SOL2.a(stzrqf.o)(.text+0x202): In function `stzrqf_':
stzrqf.f: undefined reference to `scopy_'
../../lapack_SUN4SOL2.a(stzrqf.o)(.text+0x273):stzrqf.f: undefined reference to `sgemv_'
../../lapack_SUN4SOL2.a(stzrqf.o)(.text+0x2bb):stzrqf.f: undefined reference to `saxpy_'
../../lapack_SUN4SOL2.a(stzrqf.o)(.text+0x331):stzrqf.f: undefined reference to `sger_'
疯掉了....
----
来源: 精准石油论坛 - 推进信息共享,提升科技水平
#16 Guest_blueocean_*
Guest_blueocean_*
发表于 05-16-2006 - 13:10
精准.石油.论坛 forum.petro-china.com
引用框(去过北极 @ 2006-05-15, 08:58 PM)
../../lapack_SUN4SOL2.a(stzrqf.o)(.text+0x202): In function `stzrqf_':
stzrqf.f: undefined reference to `scopy_'
../../lapack_SUN4SOL2.a(stzrqf.o)(.text+0x273):stzrqf.f: undefined reference to `sgemv_'
../../lapack_SUN4SOL2.a(stzrqf.o)(.text+0x2bb):stzrqf.f: undefined reference to `saxpy_'
../../lapack_SUN4SOL2.a(stzrqf.o)(.text+0x331):stzrqf.f: undefined reference to `sger_'
疯掉了....
去过北极, 其实你没必要把所有的LAPACK 下载下来, 只需下载我所说的SVD主运行程序和相关的子程序, 这些一共没多少大. 把这些子程序做成库, 然后在MAKEFILE里面把库连进去. (简单的说, SVD不过是你要调用的子程序)
另, MAKEFILE可以自己写.
你删除文件的时候, 为避免文件太多(不用每次confirmation, 如写y or yes), 可以用命令
\rm *
或
\rm -r *
来删除文件或文件夹, 用这个命令要特别小心!!!
----
来源: 精准石油论坛 - 推进信息共享,提升科技水平
#17
去过北极
发表于 05-18-2006 - 21:47
精准.石油.论坛 forum.petro-china.com
首先, 我发现似乎有个C版本的LAPACK(叫做CLAPACK),然后兴冲冲地下载回来,仔细一看,发现没有CGESVD子函数,当场一盆冷水浇下来.......
没办法,继续捣鼓LAPACK. 仔细研究了一下USER MANUAL, 尝试着只编译库函数部分,不作各种测试等等,经过一番努力(此处省略描写若干千字,水平差真是没办法呀),成功编译出了CGESVD.O :P 接着我先单独把它编译成库,然后用nm查看,把所有U打头的函数都和CGESVD.O重新链结进了一个库libcgesvd.so里,丢到/USR/LIB里. 开始在主程序里加入头文件,这时出现了第一个问题: 我的头文件是这样写的
/* cgesvd.h */
void CGESVD_(char *JC,char *JO,int *M,int SVDN,complex *A,int *LDA,float *S,complex *U,int *LDU,complex *VT,int *LDVT,complex *WORK,int *LWORK,float *RWORK,int *INFO);
结果编译报错: cgesvd.h:3: 错误:syntax error before ‘complex’ 找了半天,不知道错在什么地方,一怒之下改成void CGESVD_( ); 这下不报错了,可是第二个问题来了
我是这样编译的: gcc test_complex.c -o test_complex -O2 -lm -lcgesvd 结果它居然还是不认识我的函数:
In function `main':
test_complex.c: undefined reference to `CGESVD_'
/usr/lib/gcc/i386-redhat-linux/4.0.0/../../../libcgesvd.so: undefined reference to `slartg_'
/usr/lib/gcc/i386-redhat-linux/4.0.0/../../../libcgesvd.so: undefined reference to `clarft_'
/usr/lib/gcc/i386-redhat-linux/4.0.0/../../../libcgesvd.so: undefined reference to `clarfb_'
/usr/lib/gcc/i386-redhat-linux/4.0.0/../../../libcgesvd.so: undefined reference to `cgebd2_'
........
这到底是怎么回事啊??
----
来源: 精准石油论坛 - 推进信息共享,提升科技水平
#18
blueocean
发表于 05-19-2006 - 00:08
精准.石油.论坛 forum.petro-china.com
虽然我不是用C调用LAPACK, 我就说说怎么样连接库.
1. 首先把SVD的所有相关子程序编译一下, 写一个shell script 文件, 例如 compile_svd
f90 -c c***.f
f90 -c c***.f
f90 -c c***.f
.....
.....
上面的c***要写成你自己的程序名, 不一定是c开头
2. 然后 用sh compile_svd, 运行一下, 得到各个目标文件 .o 文件
3. 把这些 .o 文件连成库文件, 再建一个文件, 例如, make_svd
敲入如下 命令
ar -ruv ./lapack_svd.a \
./c***.o \
./c***.o \
...... \
...... \
上面的路径可以根据文件的位置, 自己选择. c***.o 应改成自己的 .o 文件
4. 运行sh make_svd , 你就可以得到 lapack_svd.a 的库
作完这个库, 就看自己怎么调用了.
我用SUN 调用的时候, 在MAKEFILE里是用 -lsocket /../../lapack_svd.a
因为你是用C调用, 情况应该不一样. 你可以问问周围有没有用C调用LAPACK的朋友
----
来源: 精准石油论坛 - 推进信息共享,提升科技水平
#20
page
发表于 05-19-2006 - 10:12
精准.石油.论坛 forum.petro-china.com
引用框(去过北极 @ 2006-05-18, 05:54 PM)
还有,为什么要把SVD做成静态库呢? 好像gcc默认是调用动态库呀?
去过北极, blueocean前面所说的连接,
http://www.netlib.or...omplex/cgesvd.f
就应该把所有CGESVD相关的程序都下载下来了.
----
来源: 精准石油论坛 - 推进信息共享,提升科技水平

登录
注册
帮助

多重回复