我们有一个发展 Nvidia GPU 和 Intel Xeon Phi 的项目。主机代码和 GPU 代码用 Fortran 编写并由 pgfortran 编译。要将我们的一些工作卸载到 Phi,我们必须创建一个由 ifort 编译的共享库(静态链接无法工作)并从代码的 pgfortran 部分调用共享子例程。通过这样做,我们可以将数组从代码的 pgfortran 部分卸载到可以与 Xeon Phi 通信的 intel fortran 共享库。
现在我正在尝试将包含来自代码的 pgfortran 部分的可分配数组的派生类型传递给 ifort 共享库。看起来有些问题。
这是一个简单的例子(这里没有 Xeon Phi 卸载指令):
来电者.f90:
program caller
type cell
integer :: id
real, allocatable :: a(:)
real, allocatable :: b(:)
real, allocatable :: c(:)
end type cell
integer :: n,i,j
type(cell) :: cl(2)
n=10
do i=1,2
allocate(cl(i)%a(n))
allocate(cl(i)%b(n))
allocate(cl(i)%c(n))
end do
do j=1, 2
do i=1, n
cl(j)%a(i)=10*j+i
cl(j)%b(i)=10*i+j
end do
end do
call offload(cl(1))
print *, cl(1)%c
end program caller
称为.f90:
subroutine offload(cl)
type cell
integer :: id
real, allocatable :: a(:)
real, allocatable :: b(:)
real, allocatable :: c(:)
end type cell
type(cell) :: cl
integer :: n
print *, cl%a(1:10)
print *, cl%b(1:10)
end subroutine offload
生成文件:
run: caller.o libcalled.so
pgfortran -L. caller.o -lcalled -o $@
caller.o: caller.f90
pgfortran -c caller.f90
libcalled.so: called.f90
ifort -shared -fPIC $^ -o $@
注意cl%a(1:10)
这里的“”,没有“ (1:10)
”就不会打印任何内容。
这段代码最终打印出了 中的元素,cl(1)%a
然后在我试图打印出数组的下一行遇到了分段错误cl(1)%b
。
如果我将“ cl%a(1:10)
”更改为“cl%a(1:100)”,并删除“ print *, cl%b(1:10)
”。它将给出以下结果:
我们可以发现 b 数组中的元素在那里,但我无法通过“ cl%b(1:10)
”获取它们。
我知道这可能是不同编译器的不同派生类型结构造成的。但我真的想要一种我们可以在编译器之间传递这种派生类型的方法。有什么解决办法吗?
谢谢!