Search code examples
mpifortran90intel-fortran

compilation error with MPI_type_create_resized in Fortran 90


I need to scatter a 2D array with non-contiguous blocks in a Fortran 90 code. The code need to call MPI_TYPE_CREATE_RESIZED to change the bounds and extend of the new vector type before calling MPI_SCATTER. The compiler I use is Intel XE 12.1.

When using the Intel MPI, the code compiles well but with a warning message, which I don't think it should be there:

mpiifort -c test.f90
test.f90(21): warning #6075: The data type of the actual argument does not match the definition.   [EXTENT]
call MPI_TYPE_CREATE_RESIZED(oldtype, 1, extent, newtype, ierr)
-----------------------------------------^

When using the OpenMPI, the compilation terminates with an error:

mpif90 -c test.f90 
test.f90(21): error #6285: There is no matching specific subroutine for this generic subroutine call.   [MPI_TYPE_CREATE_RESIZED]
call MPI_TYPE_CREATE_RESIZED(oldtype, 1, extent, newtype, ierr)
-----^
compilation aborted for test.f90 (code 1)

Is this a bug in OpenMPI? Does anybody know how to fix it? Thanks.

The test code is pasted below:

program test
!
USE MPI
implicit none
!
integer :: numprocs, ierr, status(MPI_STATUS_SIZE)
integer ::  rows, cols
integer :: typesize, extent, oldtype, newtype
!=============================================================
!
call MPI_INIT( ierr )
call MPI_COMM_SIZE( MPI_COMM_WORLD, numprocs, ierr )
!
cols = 8
!
rows = cols
!
call MPI_TYPE_VECTOR(cols, rows/numprocs, rows, MPI_REAL8, oldtype, ierr) 
call MPI_TYPE_SIZE(MPI_REAL8, typesize, ierr)
extent = rows/numprocs*typesize
call MPI_TYPE_CREATE_RESIZED(oldtype, 1, extent, newtype, ierr)
call MPI_TYPE_COMMIT(newtype, ierr)
!
call MPI_TYPE_FREE(oldtype, ierr)
call MPI_TYPE_FREE(newtype, ierr)
call MPI_FINALIZE(ierr)

stop
end

Solution

  • This is the compiler being picky about the types of arguments, which is a good thing; lower bound and extent here have to be integers of kind MPI_ADDRESS_KIND. So this works:

    program test
    !
    USE MPI
    implicit none
    !
    integer :: numprocs, ierr, status(MPI_STATUS_SIZE)
    integer ::  rows, cols, typesize
    integer(kind=mpi_address_kind) :: lb, extent
    integer :: oldtype, newtype
    !=============================================================
    !
    call MPI_INIT( ierr )
    call MPI_COMM_SIZE( MPI_COMM_WORLD, numprocs, ierr )
    !
    cols = 8
    !
    rows = cols
    !
    call MPI_TYPE_VECTOR(cols, rows/numprocs, rows, MPI_REAL8, oldtype, ierr)
    call MPI_TYPE_SIZE(MPI_REAL8, typesize, ierr)
    extent = rows/numprocs*typesize
    lb = 1
    call MPI_TYPE_CREATE_RESIZED(oldtype, lb, extent, newtype, ierr)
    call MPI_TYPE_COMMIT(newtype, ierr)
    !
    call MPI_TYPE_FREE(oldtype, ierr)
    call MPI_TYPE_FREE(newtype, ierr)
    call MPI_FINALIZE(ierr)
    
    stop
    end