精准石油论坛: C语言中如何调用LAPACK函数 - 精准石油论坛

跳转到内容

  • (2 页)
  • +
  • 1
  • 2
  • 您无法发起一个新主题
  • 您无法回复此主题

C语言中如何调用LAPACK函数 主题评价: -----

#1 已离线   去过北极 

  • 业余侠客
  • 图像
  • 群组: 认证会员
  • 主题数: 180
  • 注册日期: 05-11-2006

主题图像  去过北极 发表于 05-13-2006 - 12:09
精准.石油.论坛 forum.petro-china.com

小弟不才,最近做大作业时遇到一个问题,就是在C语言的程序中要调用LAPACK库中的一个SUBROUTINE对一个复矩阵做SVD, 按照网上找到的方法我是这样调用SUBROUTINE的:
...
extern void__stdcall CGESVD(.............);
......
CGESVD(..........);
....
但编译的时候老是报错:syntax error before ‘CGESVD’
请各位大侠指点,谢谢!
精准.石油.论坛 forum.petro-china.com






----
来源: 精准石油论坛 - 推进信息共享,提升科技水平
0

#2 已离线   blueocean 

  • 武林名宿
  • 图像
  • 群组: 管理员
  • 主题数: 870
  • 注册日期: 02-11-2006

blueocean 发表于 05-13-2006 - 12:33
精准.石油.论坛 forum.petro-china.com

看起来, "extern void__stdcall "这句造成错误. 如果你把所有的SVD有关的程序都下载下来了(LAPACK有介绍, 主程序和相关的子程序), 你应该直接可以调用, 不用加上面那句话. 不过你要把LAPACK的库连接过去(加在MAKE文件里面).

我用FORTRAN调用LAPACK的SVD的程序, 没有问题.

精准.石油.论坛 forum.petro-china.com






----
来源: 精准石油论坛 - 推进信息共享,提升科技水平
0

#3 已离线   sandstone 

  • 武林尊者
  • 图像
  • 群组: 管理员
  • 主题数: 2,366
  • 注册日期: 10-03-2005

sandstone 发表于 05-13-2006 - 12:37
精准.石油.论坛 forum.petro-china.com

可能是call convention错了。

在unix/linux下使用 void

windows下使用 void __stdcall
精准.石油.论坛 forum.petro-china.com






----
来源: 精准石油论坛 - 推进信息共享,提升科技水平
0

#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的语句, 以前我用过, 现在记不清楚了.
精准.石油.论坛 forum.petro-china.com






----
来源: 精准石油论坛 - 推进信息共享,提升科技水平
0

#5 已离线   sandstone 

  • 武林尊者
  • 图像
  • 群组: 管理员
  • 主题数: 2,366
  • 注册日期: 10-03-2005

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)。这个在矩阵操作函数中比较常见。
精准.石油.论坛 forum.petro-china.com






----
来源: 精准石油论坛 - 推进信息共享,提升科技水平
0

#6 已离线   去过北极 

  • 业余侠客
  • 图像
  • 群组: 认证会员
  • 主题数: 180
  • 注册日期: 05-11-2006

去过北极 发表于 05-13-2006 - 17:02
精准.石油.论坛 forum.petro-china.com

现在把调用方式改成了extern void CGESVD(...........) 类型错误是没有了,可是它居然说undefined reference to `CGESVD' 我明明已经安装过blas和lapack的RPM包了阿~~ 莫非要把cgesvd.f include进头文件里? 可是试了一下这样一弄满屏都是错误,
:blink: 怎么办? 继续虚心请教各位大哥
精准.石油.论坛 forum.petro-china.com






----
来源: 精准石油论坛 - 推进信息共享,提升科技水平
0

#7 已离线   rpms 

  • 初级游侠
  • 图像
  • 群组: 版主
  • 主题数: 148
  • 注册日期: 01-08-2006

rpms 发表于 05-13-2006 - 19:33
精准.石油.论坛 forum.petro-china.com

给你个Makefile,在su环境下的:

# 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生成的库函数就这么调用。
精准.石油.论坛 forum.petro-china.com






----
来源: 精准石油论坛 - 推进信息共享,提升科技水平
0

#8 已离线   page 

  • 武林尊者
  • 图像
  • 群组: 版主
  • 主题数: 2,262
  • 注册日期: 09-25-2005

page 发表于 05-14-2006 - 02:45
精准.石油.论坛 forum.petro-china.com

good job!
精准.石油.论坛 forum.petro-china.com






----
来源: 精准石油论坛 - 推进信息共享,提升科技水平
0

#9 已离线   去过北极 

  • 业余侠客
  • 图像
  • 群组: 认证会员
  • 主题数: 180
  • 注册日期: 05-11-2006

去过北极 发表于 05-15-2006 - 08:25
精准.石油.论坛 forum.petro-china.com

引用框(rpms @ 2006-05-13, 03:33 AM)

给你个Makefile,在su环境下的:

# 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
精准.石油.论坛 forum.petro-china.com






----
来源: 精准石油论坛 - 推进信息共享,提升科技水平
0

#10 已离线   blueocean 

  • 武林名宿
  • 图像
  • 群组: 管理员
  • 主题数: 870
  • 注册日期: 02-11-2006

blueocean 发表于 05-15-2006 - 12:31
精准.石油.论坛 forum.petro-china.com

引用框(去过北极 @ 2006-05-14, 04:25 PM)

实在是很抱歉,小弟最近刚开始操作LINUX,水平有限,还需要请教一下
1 这个Makefile是随便在哪里创建都可以么? 还是必须要在su文件夹里?
2 PROGS =$B/×××××××× 这里的XXXXXXX是什么阿?
有劳各位大牛了 :P

去过北极, 如果想了解 Make 文件, 还是到百度或google上搜索一下, 了解Make最基本的用法.

rpms 只是给了一个SU的Make file的例子, 你自己可以随便建.
$B 是调用 参数B, 后面的XXXXX, 是省略的可执行文件名. (你还是先看看Make file 的介绍吧).

精准.石油.论坛 forum.petro-china.com






----
来源: 精准石油论坛 - 推进信息共享,提升科技水平
0

#11 已离线   sandstone 

  • 武林尊者
  • 图像
  • 群组: 管理员
  • 主题数: 2,366
  • 注册日期: 10-03-2005

sandstone 发表于 05-15-2006 - 14:34
精准.石油.论坛 forum.petro-china.com

引用框(去过北极 @ 2006-05-14, 04:25 PM)

实在是很抱歉,小弟最近刚开始操作LINUX,水平有限,还需要请教一下
1 这个Makefile是随便在哪里创建都可以么? 还是必须要在su文件夹里?
2 PROGS =$B/×××××××× 这里的XXXXXXX是什么阿?
有劳各位大牛了 :P

仔细研究一下makefile还是很有必要的。建议研读一下文献

http://www.stlchina....m/LearnMakefile
精准.石油.论坛 forum.petro-china.com






----
来源: 精准石油论坛 - 推进信息共享,提升科技水平
0

#12 已离线   rpms 

  • 初级游侠
  • 图像
  • 群组: 版主
  • 主题数: 148
  • 注册日期: 01-08-2006

rpms 发表于 05-15-2006 - 18:25
精准.石油.论坛 forum.petro-china.com

引用框(blueocean @ 2006-05-14, 08:31 PM)

引用框(去过北极 @ 2006-05-14, 04:25 PM)

实在是很抱歉,小弟最近刚开始操作LINUX,水平有限,还需要请教一下
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命令就可以了。
精准.石油.论坛 forum.petro-china.com






----
来源: 精准石油论坛 - 推进信息共享,提升科技水平
0

#13 已离线   去过北极 

  • 业余侠客
  • 图像
  • 群组: 认证会员
  • 主题数: 180
  • 注册日期: 05-11-2006

去过北极 发表于 05-16-2006 - 08:35
精准.石油.论坛 forum.petro-china.com

谢谢大家的指点. 其实我下过LAPACK的gz包了,解压缩再解归档之后生成了一个LAPACK的文件夹,里面已经有MAKEFILE文件了,可是我敲"make"进去之后它报了一大堆相同的错误:
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来编译?
精准.石油.论坛 forum.petro-china.com






----
来源: 精准石油论坛 - 推进信息共享,提升科技水平
0

#14 已离线   去过北极 

  • 业余侠客
  • 图像
  • 群组: 认证会员
  • 主题数: 180
  • 注册日期: 05-11-2006

去过北极 发表于 05-16-2006 - 08:40
精准.石油.论坛 forum.petro-china.com

刚才突然灵机一动,把"-native -xO5 -xarch=v8plusa"全删了, 可以编译了... :P
精准.石油.论坛 forum.petro-china.com






----
来源: 精准石油论坛 - 推进信息共享,提升科技水平
0

#15 已离线   去过北极 

  • 业余侠客
  • 图像
  • 群组: 认证会员
  • 主题数: 180
  • 注册日期: 05-11-2006

去过北极 发表于 05-16-2006 - 12:58
精准.石油.论坛 forum.petro-china.com

编译出了3G多的.o文件, 然后开始链结的时候出现无数错误 :blink: 都是诸如此类的错误:
../../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_'
疯掉了....
精准.石油.论坛 forum.petro-china.com






----
来源: 精准石油论坛 - 推进信息共享,提升科技水平
0

#16 Guest_blueocean_*

  • 群组: 论坛游客

Guest_blueocean_* 发表于 05-16-2006 - 13:10
精准.石油.论坛 forum.petro-china.com

引用框(去过北极 @ 2006-05-15, 08:58 PM)

编译出了3G多的.o文件, 然后开始链结的时候出现无数错误  :blink:  都是诸如此类的错误:
../../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 *

来删除文件或文件夹, 用这个命令要特别小心!!!

精准.石油.论坛 forum.petro-china.com






----
来源: 精准石油论坛 - 推进信息共享,提升科技水平
0

#17 已离线   去过北极 

  • 业余侠客
  • 图像
  • 群组: 认证会员
  • 主题数: 180
  • 注册日期: 05-11-2006

去过北极 发表于 05-18-2006 - 21:47
精准.石油.论坛 forum.petro-china.com

BLUE大哥, 不妨先听听我这两天屡败屡战的经过.
首先, 我发现似乎有个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_'
........
这到底是怎么回事啊??
精准.石油.论坛 forum.petro-china.com






----
来源: 精准石油论坛 - 推进信息共享,提升科技水平
0

#18 已离线   blueocean 

  • 武林名宿
  • 图像
  • 群组: 管理员
  • 主题数: 870
  • 注册日期: 02-11-2006

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的朋友

精准.石油.论坛 forum.petro-china.com






----
来源: 精准石油论坛 - 推进信息共享,提升科技水平
0

#19 已离线   去过北极 

  • 业余侠客
  • 图像
  • 群组: 认证会员
  • 主题数: 180
  • 注册日期: 05-11-2006

去过北极 发表于 05-19-2006 - 09:54
精准.石油.论坛 forum.petro-china.com

问题就在于如何确定CGESVD里调用了什么子程序, CGESVD有3000多行,不可能一行一行看啊.先把它单独编译成库然后用nm查看的办法行不行?
还有,为什么要把SVD做成静态库呢? 好像gcc默认是调用动态库呀?
精准.石油.论坛 forum.petro-china.com






----
来源: 精准石油论坛 - 推进信息共享,提升科技水平
0

#20 已离线   page 

  • 武林尊者
  • 图像
  • 群组: 版主
  • 主题数: 2,262
  • 注册日期: 09-25-2005

page 发表于 05-19-2006 - 10:12
精准.石油.论坛 forum.petro-china.com

引用框(去过北极 @ 2006-05-18, 05:54 PM)

问题就在于如何确定CGESVD里调用了什么子程序, CGESVD有3000多行,不可能一行一行看啊.先把它单独编译成库然后用nm查看的办法行不行?
还有,为什么要把SVD做成静态库呢? 好像gcc默认是调用动态库呀?

去过北极, blueocean前面所说的连接,
http://www.netlib.or...omplex/cgesvd.f

就应该把所有CGESVD相关的程序都下载下来了.
精准.石油.论坛 forum.petro-china.com






----
来源: 精准石油论坛 - 推进信息共享,提升科技水平
0

  • (2 页)
  • +
  • 1
  • 2
  • 您无法发起一个新主题
  • 您无法回复此主题