Blame test/mpi/f77/spawn/connaccf.f

Packit 0848f5
C -*- Mode: Fortran; -*- 
Packit 0848f5
C
Packit 0848f5
C  (C) 2003 by Argonne National Laboratory.
Packit 0848f5
C      See COPYRIGHT in top-level directory.
Packit 0848f5
C
Packit 0848f5
      program main
Packit 0848f5
      implicit none
Packit 0848f5
      include 'mpif.h'
Packit 0848f5
      integer size, rank, ierr, errs, eclass
Packit 0848f5
      integer color, comm, intercomm
Packit 0848f5
      integer s1, s2
Packit 0848f5
      character*(MPI_MAX_PORT_NAME) portname
Packit 0848f5
Packit 0848f5
      errs = 0
Packit 0848f5
      call mtest_init( ierr )
Packit 0848f5
Packit 0848f5
      call mpi_comm_size( MPI_COMM_WORLD, size, ierr )
Packit 0848f5
      call mpi_comm_rank( MPI_COMM_WORLD, rank, ierr )
Packit 0848f5
      if (size .lt. 2) then
Packit 0848f5
         print *, 'This example must have at least 2 processes'
Packit 0848f5
         call mpi_abort( MPI_COMM_WORLD, 1, ierr )
Packit 0848f5
      endif
Packit 0848f5
C
Packit 0848f5
C Part of this test is to ensure that lookups cleanly fail when
Packit 0848f5
C a name is not present.  This code is used to ensure that the
Packit 0848f5
C name is not in use  before the test.
Packit 0848f5
C The MPI Standard (10.4.4 Name Publishing) requires that a process that
Packit 0848f5
C has published a name unpublish it before it exits.  
Packit 0848f5
C This code attempts to lookup the name that we want to use as the
Packit 0848f5
C service name for this example.  If it is found (it should not be, but
Packit 0848f5
C might if an MPI program with this service name exits without unpublishing
Packit 0848f5
C the servicename, and the runtime that provides the name publishing
Packit 0848f5
C leaves the servicename in use.  This block of code should not be necessary
Packit 0848f5
C in a robust MPI implementation, but should not cause problems for a correct.
Packit 0848f5
C
Packit 0848f5
      call mpi_barrier( MPI_COMM_WORLD, ierr )
Packit 0848f5
      call mpi_comm_set_errhandler( MPI_COMM_WORLD, MPI_ERRORS_RETURN, 
Packit 0848f5
     &     ierr )
Packit 0848f5
      call mpi_lookup_name( "fservtest", MPI_INFO_NULL, portname, ierr )
Packit 0848f5
      if (ierr .eq. MPI_SUCCESS) then
Packit 0848f5
          call mpi_unpublish_name( "fservtest", MPI_INFO_NULL, portname, 
Packit 0848f5
     &        ierr )
Packit 0848f5
      endif
Packit 0848f5
      call mpi_barrier( MPI_COMM_WORLD, ierr )
Packit 0848f5
C Ignore errors from unpublish_name (such as name-not-found)      
Packit 0848f5
      call mpi_comm_set_errhandler( MPI_COMM_WORLD, 
Packit 0848f5
     &     MPI_ERRORS_ARE_FATAL, ierr )
Packit 0848f5
C
Packit 0848f5
C The server (accept) side is rank < size/2 and the client (connect)
Packit 0848f5
C side is rank >= size/2
Packit 0848f5
      color = 0
Packit 0848f5
      if (rank .ge. size/2) color = 1
Packit 0848f5
      call mpi_comm_split( MPI_COMM_WORLD, color, rank, comm, ierr )
Packit 0848f5
C
Packit 0848f5
      if (rank .lt. size/2) then
Packit 0848f5
C        Server
Packit 0848f5
         call mpi_barrier( MPI_COMM_WORLD, ierr )
Packit 0848f5
         if (rank .eq. 0) then
Packit 0848f5
             call mpi_open_port( MPI_INFO_NULL, portname, ierr )
Packit 0848f5
             call mpi_publish_name( "fservtest", MPI_INFO_NULL, 
Packit 0848f5
     &            portname, ierr )
Packit 0848f5
         endif
Packit 0848f5
         call mpi_barrier( MPI_COMM_WORLD, ierr )
Packit 0848f5
         call mpi_comm_accept( portname, MPI_INFO_NULL, 0, comm, 
Packit 0848f5
     &                         intercomm, ierr )
Packit 0848f5
Packit 0848f5
         if (rank .eq. 0) then 
Packit 0848f5
            call mpi_close_port( portname, ierr )
Packit 0848f5
            call mpi_unpublish_name( "fservtest", MPI_INFO_NULL,
Packit 0848f5
     &            portname, ierr )
Packit 0848f5
         endif
Packit 0848f5
Packit 0848f5
      else
Packit 0848f5
C        Client
Packit 0848f5
         call mpi_comm_set_errhandler( MPI_COMM_WORLD,MPI_ERRORS_RETURN, 
Packit 0848f5
     &                                 ierr )
Packit 0848f5
         ierr = MPI_SUCCESS
Packit 0848f5
         call mpi_lookup_name( "fservtest", MPI_INFO_NULL, 
Packit 0848f5
     &                         portname, ierr )
Packit 0848f5
         if (ierr .eq. MPI_SUCCESS) then
Packit 0848f5
            errs = errs + 1
Packit 0848f5
            print *, 'lookup name returned a value before published'
Packit 0848f5
         else
Packit 0848f5
            call mpi_error_class( ierr, eclass, ierr )
Packit 0848f5
            if (eclass .ne. MPI_ERR_NAME) then
Packit 0848f5
               errs = errs + 1
Packit 0848f5
               print *, ' Wrong error class, is ', eclass, ' must be ',
Packit 0848f5
     &          MPI_ERR_NAME
Packit 0848f5
C              See the MPI-2 Standard, 5.4.4
Packit 0848f5
            endif
Packit 0848f5
         endif
Packit 0848f5
         call mpi_comm_set_errhandler( MPI_COMM_WORLD, 
Packit 0848f5
     &            MPI_ERRORS_ARE_FATAL, ierr )
Packit 0848f5
         call mpi_barrier( MPI_COMM_WORLD, ierr )
Packit 0848f5
         call mpi_barrier( MPI_COMM_WORLD, ierr )
Packit 0848f5
         call mpi_lookup_name( "fservtest", MPI_INFO_NULL, 
Packit 0848f5
     &                         portname, ierr )
Packit 0848f5
C        This should not happen (ERRORS_ARE_FATAL), but just in case...
Packit 0848f5
         if (ierr .ne. MPI_SUCCESS) then
Packit 0848f5
            errs = errs + 1
Packit 0848f5
            print *, ' Major error: errors_are_fatal set but returned'
Packit 0848f5
            print *, ' non MPI_SUCCESS value.  Details:'
Packit 0848f5
            call MTestPrintErrorMsg( ' Unable to lookup fservtest port', 
Packit 0848f5
     &                               ierr )
Packit 0848f5
C           Unable to continue without a valid port
Packit 0848f5
            call mpi_abort( MPI_COMM_WORLD, 1, ierr )
Packit 0848f5
         endif
Packit 0848f5
         call mpi_comm_connect( portname, MPI_INFO_NULL, 0, comm, 
Packit 0848f5
     &                          intercomm, ierr )
Packit 0848f5
      endif
Packit 0848f5
C
Packit 0848f5
C Check that this is an acceptable intercomm
Packit 0848f5
      call mpi_comm_size( intercomm, s1, ierr )
Packit 0848f5
      call mpi_comm_remote_size( intercomm, s2, ierr )
Packit 0848f5
      if (s1 + s2 .ne. size) then
Packit 0848f5
         errs = errs + 1
Packit 0848f5
         print *, ' Wrong size for intercomm = ', s1+s2
Packit 0848f5
      endif
Packit 0848f5
Packit 0848f5
      call mpi_comm_free(comm, ierr)
Packit 0848f5
C Everyone can now abandon the new intercomm      
Packit 0848f5
      call mpi_comm_disconnect( intercomm, ierr )
Packit 0848f5
Packit 0848f5
      call mtest_finalize( errs )
Packit 0848f5
      call mpi_finalize( ierr )
Packit 0848f5
Packit 0848f5
      end