如何用PGI编译器与nvcc编译CUDA调用OpenACC Fortran代码?
解决CUDA调用OpenACC Fortran代码的链接错误问题
我来帮你搞定这个未解析外部符号的问题,主要有两个核心点需要修正:Fortran代码的接口错误,以及链接阶段缺少PGI运行时库的引用。
1. 修正Fortran代码的数组声明错误
你的saxpy.f90里数组的声明重复了维度定义,这会导致C-Fortran接口不匹配,是潜在的问题根源:
! 错误写法:重复了dimension(n)和x(n) real(kind=c_float), dimension(n), intent(in) :: x(n) real(kind=c_float), dimension(n), intent(inout) :: y(n) ! 正确写法:只需要在类型后指定dimension(n) real(kind=c_float), dimension(n), intent(in) :: x real(kind=c_float), dimension(n), intent(inout) :: y
修正后的完整saxpy.f90:
subroutine saxpy(n, a, x, y) bind(c, name="saxpy") use iso_c_binding, only: c_int, c_float integer(kind=c_int), intent(in) :: n real(kind=c_float), intent(in) :: a real(kind=c_float), dimension(n), intent(in) :: x real(kind=c_float), dimension(n), intent(inout) :: y !$acc parallel deviceptr(x, y) do i = 1, n y(i) = y(i) + a*x(i) end do !$acc end parallel end subroutine
2. 正确的编译与链接步骤
你遇到的未解析符号问题,本质是nvcc默认不会链接PGI的OpenACC/CUDA运行时库。PGI编译的目标文件依赖自己的运行时组件,所以需要用PGI的驱动编译器来完成链接,或者在nvcc命令中手动指定所需库。
方法一:用pgc++作为链接器(推荐)
先编译Fortran文件为目标文件:
pgf90 -ta=tesla:cc35 -acc saxpy.f90 -c
然后用pgc链接CUDA代码和Fortran目标文件(pgc会自动处理PGI运行时库的依赖):
nvcc -arch=sm_35 -c main.cu -o main.o pgc++ -ta=tesla:cc35 main.o saxpy.o -lcudart -o saxpy_test
方法二:nvcc手动指定PGI库路径与库文件
如果你坚持用nvcc链接,需要找到PGI的库路径(通常在$PGI/lib64),并添加必要的库:
nvcc -arch=sm_35 -ccbin pgc++ main.cu saxpy.o -L$PGI/lib64 -laccapi -laccg -laccn -laccg2 -ldl -lcudadevice -lcudart -o saxpy_test
3. 验证运行结果
运行生成的可执行文件,应该输出:
2.000000, 2.000000
内容的提问来源于stack exchange,提问作者Chiel
相关产品推荐
相关产品推荐

