Perhaps even better, you could set an invalid default value inside the type
definition:
type, BIND(C) :: MPI_Comm
integer :: MPI_VAL = some_invalid_value
end type MPI_Comm
Otherwise, they’ll likely be “initialised” to whatever value was already at
that location in memory – which for stack-allocated variables could easily be a
valid handle from a previous invocation of that function…
Ben
From: users [mailto:[email protected]] On Behalf Of Jeff Hammond
Sent: Monday, 22 August 2016 1:21 PM
To: Open MPI Users <[email protected]>
Subject: Re: [OMPI users] mpi_f08 Question: set comm on declaration error, and
other questions
On Sunday, August 21, 2016, Ben Menadue <[email protected]
<mailto:[email protected]> > wrote:
Hi,
In Fortran, using uninitialised variables is undefined behaviour. In this case,
it’s being initialised to zero (either by the compiler or by virtue of being in
untouched memory), and so equivalent to MPI_COMM_WORLD in OpenMPI. Other MPI
libraries don’t have MPI_COMM_WORLD .eq. 0 and so the same program would fail.
Similarly, if the same memory has previously been stored to (and so non-zero)
and the compiler doesn’t zero-initialise the variable (most won’t unless you
explicitly ask for it), it will fail with OpenMPI.
Such false successes are a (the?) reason why MPI libraries should not define
valid handles to default initializers, whether they be standardized or
implementation-specific...
Jeff
Just keep in mind that the same is true for *all* variables in Fortran; even
integers and reals have undefined value until they’re first stored to. This can
be quite annoying as specifying the initial value when declaring them also
gives them the SAVE attribute…
Cheers,
Ben
From: users [mailto:[email protected]
<javascript:_e(%7B%7D,'cvml','[email protected]');> ] On Behalf
Of Matt Thompson
Sent: Sunday, 21 August 2016 3:07 AM
To: Open MPI Users <[email protected]
<javascript:_e(%7B%7D,'cvml','[email protected]');> >
Subject: Re: [OMPI users] mpi_f08 Question: set comm on declaration error, and
other questions
On Fri, Aug 19, 2016 at 8:54 PM, Jeff Squyres (jsquyres) <[email protected]
<javascript:_e(%7B%7D,'cvml','[email protected]');> > wrote:
On Aug 19, 2016, at 6:32 PM, Matt Thompson <[email protected]
<javascript:_e(%7B%7D,'cvml','[email protected]');> > wrote:
> > that the comm == MPI_COMM_WORLD evaluates to .TRUE.? I discovered that once
> > when I was printing some stuff.
>
> That might well be a coincidence. type(MPI_Comm) is not a boolean type, so
> I'm not sure how you compared it to .true.
>
> Well, I made a program like:
>
> (208) $ cat test2.F90
> program whoami
> use mpi_f08
> implicit none
> type(MPI_Comm) :: comm
> if (comm == MPI_COMM_WORLD) write (*,*) "I am MPI_COMM_WORLD"
> if (comm == MPI_COMM_NULL) write (*,*) "I am MPI_COMM_NULL"
> end program whoami
> (209) $ mpifort test2.F90
> (210) $ mpirun -np 4 ./a.out
> I am MPI_COMM_WORLD
> I am MPI_COMM_WORLD
> I am MPI_COMM_WORLD
> I am MPI_COMM_WORLD
>
> I think if you print comm, you get 0 and MPI_COMM_WORLD=0 and MPI_COMM_NULL=2
> so...I guess I'm surprised. I'd have thought MPI_Comm would have been
> undefined until defined.
I don't know the rules here for what happens in Fortran when comparing an
uninitialized derived type. The results could be undefined...?
> Instead you can write a program like this:
>
> (226) $ cat helloWorld.mpi3.F90
> program hello_world
>
> use mpi_f08
>
> implicit none
>
> type(MPI_Comm) :: comm
> integer :: myid, npes, ierror
> integer :: name_length
>
> character(len=MPI_MAX_PROCESSOR_NAME) :: processor_name
>
> call mpi_init(ierror)
>
> call MPI_Comm_Rank(comm,myid,ierror)
> write (*,*) 'ierror: ', ierror
> call MPI_Comm_Size(comm,npes,ierror)
> call MPI_Get_Processor_Name(processor_name,name_length,ierror)
>
> write (*,'(A,X,I4,X,A,X,I4,X,A,X,A)') "Process", myid, "of", npes, "is
> on", trim(processor_name)
>
> call MPI_Finalize(ierror)
>
> end program hello_world
> (227) $ mpifort helloWorld.mpi3.F90
> (228) $ mpirun -np 4 ./a.out
> ierror: 0
> ierror: 0
> ierror: 0
> ierror: 0
> Process 2 of 4 is on compy
> Process 1 of 4 is on compy
> Process 3 of 4 is on compy
> Process 0 of 4 is on copy
That does seem to be odd output. What is the hostname on your machine?
Oh well, I (badly) munged the hostname on the computer I ran on because it had
the IP address within. I figured better safe than sorry and not broadcast that
out there. :)
FWIW, I changed your write statement to:
print *, "Process", myid, "of", npes, "is on", trim(processor_name)
and after I added a "comm = MPI_COMM_WORLD" before the call to MPI_COMM_RANK,
the output prints properly for me (i.e., I see my hostname).
> This seems odd to me. I haven't passed in MPI_COMM_WORLD as the communicator
> to MPI_Comm_Rank, and yet, it worked and the error code was 0 (which I'd take
> as success). Even if you couldn't detect this at compile time, I'm surprised
> it doesn't trigger a run-time error. Is this the correct behavior according
> to the Standard?
I think you're passing an undefined value, so the results will be undefined.
It's quite possible that the comm%mpi_val inside the comm is (randomly?)
assigned to 0, which is the same value as mpif.f's MPI_COMM_WORLD, and
therefore your comm is effectively the same as mpi_f08's MPI_COMM_WORLD --
which is why MPI_COMM_RANK and MPI_COMM_SIZE worked for you.
Indeed, when I run your program, I get:
-----
$ ./foo
[savbu-usnic-a:31774] *** An error occurred in MPI_Comm_rank
[savbu-usnic-a:31774] *** reported by process [756088833,0]
[savbu-usnic-a:31774] *** on communicator MPI_COMM_WORLD
[savbu-usnic-a:31774] *** MPI_ERR_COMM: invalid communicator
[savbu-usnic-a:31774] *** MPI_ERRORS_ARE_FATAL (processes in this communicator
will now abort,
[savbu-usnic-a:31774] *** and potentially your MPI job)
-----
I.e., MPI_COMM_RANK is aborting because the communicator being passed in is
invalid.
Huh. I guess I'd assumed that the MPI Standard would have made sure a declared
communicator that hasn't been filled would have been an error to use.
When I get back on Monday, I'll try out some other compilers as well as try
different compiler options (e.g., -g -O0, say). Maybe this is just an undefined
behavior, but it's not one I'm too pleased about. I'd have expected the result
you got. Now I'm scared that somewhere in my code, in the future, there could
be a rogue comm declared and never nulled out, so I think it's executing on
some subcomm, but it runs on MCW.
Welp, maybe for safety it's time to make a vim macro that does:
type(MPI_Comm) :: comm
comm = MPI_COMM_NULL
I'm pretty sure that will *never* execute anything on that comm until I fill it
with what I want later on. Just wish I could do that in one statement.
--
Matt Thompson
Man Among Men
Fulcrum of History
--
Jeff Hammond
[email protected] <mailto:[email protected]>
http://jeffhammond.github.io/
_______________________________________________
users mailing list
[email protected]
https://rfd.newmexicoconsortium.org/mailman/listinfo/users