The final argument MPI_FILE_WRITE_ALL before the error output argument is an MPI status object, not an MPI information object. Thus, a call with MPI_INFO_NULL is erroneous. If you are not interested in the status of the write operation, you must pass MPI_STATUS_IGNORE . Making a call using MPI_INFO_NULL may work in some MPI implementations due to the specifics of defining both constants, but then fail in others.
For example, in Open MPI, MPI_INFO_NULL declared as:
parameter (MPI_INFO_NULL=0)
When passed instead of MPI_STATUS_IGNORE it calls C MPI_FILE_WRITE_ALL with a status argument that points to a read-only memory location that contains the value MPI_INFO_NULL (the way Fortran implements constant passing by address). When the C function is finished, it tries to populate the state object, which leads to an attempt to write to read-only memory and ultimately leads to a segmentation error.
When writing new Fortran programs, it is recommended that you do not use the very old mpif.h interface, since it does not provide error checking. Rather, you should use the mpi module or even mpi_f08 when more MPI implementations become compatible with MPI-3.0. Therefore, the beginning of your program should look like this:
program test use mpi implicit none ... end program test
Once you use the mpi module instead of mpif.h , the compiler can check the parameter types for some MPI calls, including MPI_FILE_SET_VIEW , and determine the error:
test.f90(34): error #6285: There is no matching specific subroutine for this generic subroutine call. [MPI_FILE_SET_VIEW] call MPI_File_Set_View(fhandle, 0, MPI_DOUBLE_PRECISION, written_arr & -------^ compilation aborted for test.f90 (code 1)
The reason is that the second argument MPI_FILE_SET_VIEW is of type INTEGER(KIND=MPI_OFFSET_KIND) , which is 64-bit on most modern platforms. The constant 0 is just an INTEGER type and therefore is 32-bit on most platforms. It happens that with mpif.h compiler passes a pointer to an INTEGER constant with a value of 0 , but the routine interprets this as a pointer to a larger integer and interprets neighboring values as part of the constant value. So the zero that you pass as the offset inside the file ends with a non-zero value.
Replace 0 in the MPI_FILE_SET_VIEW call with 0_MPI_OFFSET_KIND or declare a constant of type INTEGER(KIND=MPI_OFFSET_KIND) and a value of zero, and then pass it.
call MPI_File_Set_View(fhandle, 0_MPI_OFFSET_KIND, MPI_DOUBLE_PRECISION, ...
or
integer(kind=MPI_OFFSET_KIND), parameter :: zero_off = 0 ... call MPI_File_Set_View(fhandle, zero_off, MPI_DOUBLE_PRECISION, ...
Both methods result in an output file of 3200 bytes in size (as expected).