3 #include "sll_assert.h" 
    4 #include "sll_memory.h" 
    5 #include "sll_working_precision.h" 
   15       mpi_double_precision, &
 
   89 #define SLL_MAX_NUM_PORTS 4096 
   90 #define BUFFER_PADDING 4 
   99       sll_real64, 
dimension(:), 
pointer :: 
data 
  114       sll_int32 :: other_rank = -1
 
  115       sll_int32 :: other_port = 0
 
  122       sll_int32 :: comm_size = 0
 
  123       sll_int32 :: rank = -1
 
  124       sll_int32 :: num_ports
 
  125       sll_int32 :: buffer_size
 
  133 #define GET_MPI_REQUEST( comm, port ) \ 
  134    comm%ports(port)%buffer(comm%ports(port)%bit + 1)%request
 
  147       sll_int32, 
intent(in)          :: port
 
  150          'bit: ', comm%ports(port)%bit, &
 
  151          'other_rank: ', comm%ports(port)%other_rank, &
 
  152          'other_port: ', comm%ports(port)%other_port, &
 
  153          'buffer(1)%data: ', comm%ports(port)%buffer(1)%data, &
 
  154          'buffer(1)%request: ', comm%ports(port)%buffer(1)%request, &
 
  155          'buffer(2)%data: ', comm%ports(port)%buffer(2)%data, &
 
  156          'buffer(2)%request: ', comm%ports(port)%buffer(2)%request
 
  161       sll_int32, 
intent(in) :: bit
 
  164       sll_assert((bit == 0) .or. (bit == 1))
 
  168       else if (bit == 1) 
then 
  176       sll_int32, 
intent(in)          :: port
 
  179       sll_assert(
associated(comm))
 
  181       bit = comm%ports(port)%bit
 
  182       comm%ports(port)%bit = 
flip_bit(bit)
 
  188       sll_int32, 
intent(in)          :: port
 
  190       sll_assert(
associated(comm))
 
  195          bit = comm%ports(port)%bit
 
  213       sll_int32 :: other_port
 
  221       lower = ior(ishft(bit, 8), iand(my_port, int(z
'3fff', i32)))
 
  222       higher = ior(ishft(
flip_bit(bit), 8), iand(other_port, int(z
'3fff', i32)))
 
  228 #ifdef __INTEL_COMPILER 
  239       sll_int32 :: other_port
 
  243       lower = ior(ishft(
flip_bit(bit), 8), iand(other_port, int(z
'3fff', i32)))
 
  244       higher = ior(ishft(bit, 8), iand(my_port, int(z
'3fff', i32)))
 
  246       send_tag = ior(ishft(higher, 15), lower)
 
  248 #ifdef __INTEL_COMPILER 
  255       sll_int32, 
intent(in)            :: num_elems
 
  257       sll_allocate(buff%data(num_elems + buffer_padding), ierr)
 
  258       buff%request = mpi_request_null
 
  263       sll_int32, 
intent(in)          :: buf_num_elems
 
  265       sll_assert(buf_num_elems >= 0)
 
  266       sll_allocate(port%buffer(2), ierr)
 
  273       sll_int32, 
intent(in) :: 
size 
  274       sll_assert(
associated(comm))
 
  275       if (
size > comm%buffer_size) 
then 
  276          print *, 
'comm module error, wrong size passed to check_buffer_size()' 
  283       sll_int32, 
intent(in) :: port
 
  284       if ((port < 1) .or. (port > comm%num_ports)) 
then 
  285          print *, 
'comm module error, check_port(): ', &
 
  286             'requested port is out of range' 
  294       sll_int32, 
intent(in)          :: port
 
  296       sll_assert(
associated(comm))
 
  298       if (get_mpi_request(comm, port) .ne. mpi_request_null) 
then 
  307       sll_int32, 
intent(in) :: other_rank
 
  309       if ((other_rank < 0) .or. (other_rank >= comm%comm_size)) 
then 
  310          print *, 
'comm module error, check_other_rank(): invalid remote rank' 
  319       sll_assert(
associated(comm))
 
  326       sll_assert(
associated(comm))
 
  332       sll_int32, 
intent(in)           :: num_ports
 
  333       sll_int32, 
intent(in)           :: buffer_size
 
  337       sll_int32                       :: max_num_ports
 
  339       if (.not. 
associated(collective)) 
then 
  340          print *, 
'sll_f_new_comm_real64(), passed collective pointer not associated.' 
  343       if (buffer_size < 0) 
then 
  344          print *, 
'sll_f_new_comm_real64(), passed negative buffer size.' 
  348       sll_allocate(comm, ierr)
 
  349       comm%collective => collective
 
  350       comm%num_ports = num_ports
 
  353       comm%buffer_size = buffer_size
 
  357       max_num_ports = ishft(1, 8)
 
  359       sll_allocate(comm%ports(num_ports), ierr)
 
  372       sll_int32, 
intent(in)          :: port
 
  373       sll_int32, 
intent(in)          :: remote
 
  374       sll_int32, 
intent(in)          :: remote_port
 
  387          print *, 
'comm module error: connect_ports(), port to connect is busy' 
  391       if (comm%ports(port)%other_rank >= 0) 
then 
  392          print *, 
'comm connect error; port already in use' 
  396       comm%ports(port)%other_rank = remote
 
  397       comm%ports(port)%other_port = remote_port
 
  398       bit = comm%ports(port)%bit
 
  399       tag = 
receive_tag(bit, port, comm%ports(port)%other_port)
 
  410          comm%ports(port)%buffer(bit + 1)%data, &
 
  411          comm%buffer_size + buffer_padding, &
 
  412          mpi_double_precision, &
 
  413          comm%ports(port)%other_rank, &
 
  415          comm%collective%comm, &
 
  416          get_mpi_request(comm, port), &
 
  424       sll_int32, 
intent(in)          :: port
 
  425       sll_int32, 
intent(in)          :: 
size 
  431       if (comm%ports(port)%other_rank < 0) 
then 
  432          print *, 
'sll_s_comm_send_real64(), error, port not connected, rank = ', &
 
  433             comm%rank, 
' other_rank = ', comm%ports(port)%other_rank, &
 
  434             ' port = ', port, 
'size = ', 
size 
  438       bit = comm%ports(port)%bit
 
  439       tag = 
send_tag(bit, port, comm%ports(port)%other_port)
 
  447          comm%ports(port)%buffer(bit + 1)%data, &
 
  448          size + buffer_padding, &
 
  449          mpi_double_precision, &
 
  450          comm%ports(port)%other_rank, &
 
  452          comm%collective%comm, &
 
  453          get_mpi_request(comm, port), &
 
  455       if (ierr .ne. mpi_success) 
then 
  456          print *, 
'sll_s_comm_send_real64() error in mpi call' 
  465       sll_int32, 
intent(in)          :: port
 
  466       sll_int32, 
intent(out)         :: count
 
  467       sll_int32, 
dimension(MPI_STATUS_SIZE) :: stat
 
  470       sll_int32 :: local_count 
 
  475          print *, 
'sll_s_comm_receive_real64() error: port', port, 
' is not busy; ', &
 
  476             'there are imbalanced send and receive calls.' 
  485       call mpi_wait(get_mpi_request(comm, port), stat, ierr)
 
  486       if (ierr .ne. mpi_success) 
then 
  487          print *, 
'sll_s_comm_receive_real64(), MPI_Wait error' 
  491       call mpi_get_count(stat, mpi_double_precision, local_count, ierr)
 
  492       if (ierr .ne. mpi_success) 
then 
  493          print *, 
'sll_s_comm_receive_real64(), MPI_Get_Count() error' 
  501          print *, 
'sll_s_comm_receive_real64() error: imbalanced send and receive calls' 
  506       call mpi_wait(get_mpi_request(comm, port), mpi_status_ignore, ierr)
 
  507       if (ierr .ne. mpi_success) 
then 
  508          print *, 
'sll_s_comm_receive_real64(), MPI_Wait error in second call.' 
  512       tag = 
receive_tag(comm%ports(port)%bit, port, comm%ports(port)%other_port)
 
  513       bit = comm%ports(port)%bit
 
  516          comm%ports(port)%buffer(bit + 1)%data, &
 
  517          comm%buffer_size + buffer_padding, &
 
  518          mpi_double_precision, &
 
  519          comm%ports(port)%other_rank, &
 
  521          comm%collective%comm, &
 
  522          get_mpi_request(comm, port), &
 
  527       count = local_count - buffer_padding
 
  533       sll_int32 :: num_ports
 
  536       if (.not. 
associated(comm)) 
then 
  537          print *, 
'comm module error: sll_s_delete_comm_real64() received a ', &
 
  538             'non-associated pointer argument.' 
  541       num_ports = comm%num_ports
 
  547             call mpi_wait(get_mpi_request(comm, i), mpi_status_ignore, ierr)
 
  554             call mpi_request_free(get_mpi_request(comm, i), ierr)
 
  560          sll_deallocate(comm%ports(i)%buffer(1)%data, ierr)
 
  561          sll_deallocate(comm%ports(i)%buffer(2)%data, ierr)
 
  568       sll_int32, 
intent(in) :: num
 
  569       if ((num .le. 0) .or. (num .ge. sll_max_num_ports)) 
then 
  597       sll_int32, 
intent(in)  :: rank
 
  598       sll_int32, 
intent(in)  :: nprocx
 
  599       sll_int32, 
intent(out) :: i
 
  600       sll_int32, 
intent(out) :: j
 
  607       sll_int32, 
intent(in)  :: nprocx
 
  608       sll_int32, 
intent(in) :: i
 
  609       sll_int32, 
intent(in) :: j
 
  615       sll_int32, 
intent(in) :: nprocx
 
  616       sll_int32, 
intent(in) :: nprocy
 
  626       call find_ij(rank, nprocx, iloc, jloc)
 
  627       left = mod(iloc + nprocx - 1, nprocx)
 
  628       right = mod(iloc + nprocx + 1, nprocx)
 
  629       bottom = mod(jloc + nprocy - 1, nprocy)
 
  630       top = mod(jloc + nprocy + 1, nprocy)
 
  645    function sll_get_comm_parent(com)
 
  647    end function sll_get_comm_parent
 
  651    function sll_get_comm_num_ports(com)
 
  653    end function sll_get_com_num_ports
 
  657    function sll_get_comm_buffer_size(com)
 
  659    end function sll_get_comm_buffer_size
 
  685    function sll_new_comm_fan(col, root, buf_size)
 
  687    end function sll_new_comm_fan
 
  691 #undef SLL_MAX_NUM_PORTS 
  692 #undef BUFFER_PADDING 
  693 #undef GET_MPI_REQUEST 
integer(kind=i32) function, public sll_f_get_collective_rank(col)
Determines the rank of the calling process in the communicator.
subroutine, public sll_s_collective_barrier(col)
Blocks until all processes in the communicator have reached this routine.
subroutine, public sll_s_test_mpi_error(ierr, descriptor)
Checks the good execution of collective instruction.
integer(kind=i32) function, public sll_f_get_collective_size(col)
Determines the size of the group associated with a communicator.
function send_tag(bit, my_port, other_port)
subroutine find_ij(rank, nprocx, i, j)
integer(kind=i32) function flip_bit(bit)
function get_buffer_size(comm)
logical function port_num_is_valid(num)
integer(kind=i32) function receive_tag(bit, my_port, other_port)
subroutine, public sll_s_view_port(comm, port)
subroutine flip_buffer(comm, port)
subroutine connect_ports(comm, port, remote, remote_port)
integer(kind=i32) function rank_index(nprocx, i, j)
subroutine, public sll_s_configure_comm_real64_torus_2d(comm, nprocx, nprocy)
subroutine check_port(comm, port)
subroutine initialize_buffer_real64(buff, num_elems)
function get_num_ports(comm)
subroutine initialize_port_real64(port, buf_num_elems)
real(kind=f64) function, dimension(:), pointer, public sll_f_get_buffer(comm, port)
subroutine, public sll_s_create_comm_real64_ring(comm)
subroutine, public sll_s_delete_comm_real64(comm)
subroutine, public sll_s_comm_receive_real64(comm, port, count)
logical function port_is_busy(comm, port)
subroutine check_buffer_size(comm, size)
subroutine check_other_rank(comm, other_rank)
subroutine, public sll_s_comm_send_real64(comm, port, size)
type(sll_t_p2p_comm_real64) function, pointer, public sll_f_new_comm_real64(collective, num_ports, buffer_size)
Wrapper around the communicator.