You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何用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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.07 07:32:46