从Python调用Coarray Fortran共享库

时间:2019-02-16 08:21:09

标签: python fortran mpi intel-fortran fortran-coarrays

我试图了解如何从Python调用Coarray Fortran DLL。考虑以下示例Fortran模块文件example_mod.f90,稍后将从Python调用该文件:

module example_mod
    use iso_c_binding
    implicit none
#ifdef COARRAY_ENABLED
    integer :: co_int[*]
#endif
    interface
    module subroutine sqr_2d_arr(nd, val, comm) BIND(C, NAME='sqr_2d_arr')
        !DEC$ ATTRIBUTES DLLEXPORT :: sqr_2d_arr
        integer, intent(in)     :: nd
        integer, intent(inout)  :: val(nd, nd), comm
    end subroutine sqr_2d_arr
    end interface
contains
end module example_mod

带有子模块文件example_mod@sub_smod.f90中给出的子例程的实现:

submodule (example_mod) sub_smod
    implicit none
contains
    module procedure sqr_2d_arr

        use mpi
        integer :: rank, size, ierr

        integer :: i, j

        call MPI_Comm_size(comm, size, ierr)
        call MPI_Comm_rank(comm, rank, ierr)
        write(*,"(*(g0,:,' '))") "Hello from Fortran MPI! I am process", rank, "of", size, ', comm:', comm

        write(*,"(*(g0,:,' '))") "Hello from Fortran COARRAY! I am image ", this_image(), " out of", num_images(), "images."
        sync all

        do j = 1, nd
            do i = 1, nd
                val(i, j) = (val(i, j) + val(j, i)) ** 2
            enddo
        enddo

    end procedure sqr_2d_arr
end submodule sub_smod

该子例程还包含对MPI库的调用,以便与Coarray进行比较。我用以下ifort标志编译此代码:

mpiifort /Qcoarray=distributed /Od /debug:full /fpp -c example_mod.f90
mpiifort /Qcoarray=distributed /Od /debug:full /fpp -c example_mod@sub_smod.f90
mpiifort /Qcoarray=distributed /Od /debug:full /fpp /dll /libs:dll /threads example_mod.obj example_mod@sub_smod.obj

现在,我有以下Python2脚本,该脚本调用了上面生成的DLL:

#!/usr/bin/env python

from __future__ import print_function
from mpi4py import MPI


comm = MPI.COMM_WORLD
fcomm = MPI.COMM_WORLD.py2f()
print("Hello from Python! I'm rank %d from %d running in total..." % (comm.rank, comm.size))

comm.Barrier()   # wait for everybody to synchronize _here_

######################

import ctypes as ct
import numpy as np

# import the dll
fortlib = ct.CDLL('example_mod.dll')

# setup the data
N = 2
nd = ct.pointer( ct.c_int(N) )          # setup the pointer
pyarr = np.arange(0, N, dtype=int) * 5  # setup the N-long
for i in range(1, N):                   # concatenate columns until it is N x N
    pyarr = np.c_[pyarr, np.arange(0, N, dtype=int) * 5]

# call the function by passing the ctypes pointer using the numpy function:
fcomm_pt = ct.pointer( ct.c_int(fcomm) )
_ = fortlib.sqr_2d_arr(nd, np.ctypeslib.as_ctypes(pyarr),fcomm_pt)

print(pyarr)

使用以下命令运行此脚本:

mpiexec -np 4 python main.py

产生以下输出:

Hello from Fortran MPI! I am process 1 of 4 , comm: 1140850688
Hello from Fortran MPI! I am process 3 of 4 , comm: 1140850688
Hello from Fortran COARRAY! I am image  1  out of 0 images.
Hello from Fortran MPI! I am process 0 of 4 , comm: 1140850688
Hello from Fortran COARRAY! I am image  1  out of 0 images.
Hello from Fortran MPI! I am process 2 of 4 , comm: 1140850688
Hello from Fortran COARRAY! I am image  1  out of 0 images.
Hello from Fortran COARRAY! I am image  1  out of 0 images.
Hello from Python! I'm rank 3 from 4 running in total...
[[  0  25]
 [900 100]]
Hello from Python! I'm rank 0 from 4 running in total...
[[  0  25]
 [900 100]]
Hello from Python! I'm rank 1 from 4 running in total...
[[  0  25]
 [900 100]]
Hello from Python! I'm rank 2 from 4 running in total...
[[  0  25]
 [900 100]]

在这组代码中执行的计算与此处的讨论无关紧要。但是,我不明白为什么MPI等级正确输出,而Coarray num_images()对于所有进程都是零。作为一个更广泛的问题,编写可从其他语言(如Python)调用的Coarray Fortran应用程序的最佳策略是什么?

0 个答案:

没有答案