fortran - derived data types with MPI -
fortran - derived data types with MPI -
i'm learning bcasting info types in fortran , have code takes 2 values terminal , displays them on each process. combination value1/value2 of type integer/integer , integer/real works, combination integer/real*8 fails.
the code is:
use mpi implicit none integer :: ierror, pid, ncpu, root = 0 integer :: counts, newtype, extent integer, dimension(2) :: oldtypes, blockcounts, offsets type value integer :: value1 = 0 real*8 :: value2 end type type (value) input phone call mpi_init(ierror) phone call mpi_comm_rank(mpi_comm_world, pid, ierror) phone call mpi_comm_size(mpi_comm_world, ncpu, ierror) ! setup of 1 mpi_integer field: value1 offsets(1) = 0 oldtypes(1) = mpi_integer blockcounts(1) = 1 ! setup of 1 mpi_real8 field: value2 phone call mpi_type_extent(mpi_integer, extent, ierror) !determine offset of mpi_integer offsets(2) = blockcounts(1)*extent !offset 1 mpi_integer extents oldtypes(2) = mpi_real8 blockcounts(2) = 1 ! define struct type , commit counts = 2 !for mpi_integer + mpi_real8 phone call mpi_type_struct(counts, blockcounts, offsets, & oldtypes, newtype, ierror) phone call mpi_type_commit(newtype, ierror) while (input%value1 >= 0) if (pid == root) read(*,*) input write(*,*) 'input was: ', input end if phone call mpi_bcast(input, 1, newtype, & root, mpi_comm_world, ierror) write(*,*), 'process ', pid, 'received: ', input end phone call mpi_type_free(newtype, ierror) phone call mpi_finalize(ierror)
it can checked integer/integer , integer/real work fine changing corresponding declaration , oldtype. combination integer/real*8 fails e.g. inputs -1 2.0 generating:
input was: -1 2.0000000000000000 process 0 received: -1 2.0000000000000000 process 1 received: -1 0.0000000000000000 process 2 received: -1 0.0000000000000000 process 3 received: -1 0.0000000000000000
this thread similar issue suggest using mpi_type_extent not right there might additional padding not taken account. unfortunately havent been able prepare problem , hope here can enlighten me.
thx in advance
you have basic thought right - you've created structure, you're assuming double precision value stored next integer value, , isn't correct. hristo's reply link gives reply in c.
the issue compiler align info construction fields you. systems can read/write values aligned in memory much faster can perform non-aligned accesses, if can perform @ all. typically, requirement alignment on element sizes; 8-byte double precision number have aligned 8-byte boundaries (that is, address of it's first byte 0 modulo 8) whereas integer has 4-byte aligned. means there 4 bytes of padding between integer , double.
in many cases can cajole compiler relaxing behaviour - in fortran, can utilize sequence
keyword require info stored contiguously. either way, performance point of view (which why you're using fortran , mpi, 1 assumes) never right thing do, can useful byte-to-byte compatibility other externally imposed info types or formats.
given imposed padding performance reasons, assume alignment , hardcode program; isn't right thing do, either; if add together other fields, or alter kind of real number 4-byte single precision number, etc, code wrong again. best utilize mpi_get_address
explicitly find locations , calculate right offsets yourself:
integer(kind=mpi_address_kind) :: startloc, endloc integer :: counts, newtype integer, dimension(2) :: oldtypes, blockcounts, offsets type value integer :: value1 = 0 double precision :: value2 end type type (value) :: input !... ! setup of 1 mpi_integer field: value1 phone call mpi_get_address(input, startloc, ierror) oldtypes(1) = mpi_integer blockcounts(1) = 1 phone call mpi_get_address(input%value1, endloc, ierror) offsets(1) = endloc - startloc oldtypes(2) = mpi_double_precision blockcounts(2) = 1 phone call mpi_get_address(input%value2, endloc, ierror) offsets(2) = endloc - startloc if (pid == 0) print *,'offsets are: ', offsets endif
note if had array of such derived types, cover case of padding between lastly element of 1 item , start of next, you'd want explicitly measure that, well, , set overall size of type - offset between start of 1 fellow member of type , start of next - mpi_type_create_resized
.
types fortran mpi
Comments
Post a Comment