I have a large Fortran program that communicates with external software via TCP/IP. It does this by launching the external software itself and specifying a port number to use (via
call system). I’m working on reconfiguring the software to use coarray fortran to run multiple simulations at once.
To support parallelization via coarrays, each image needs to get its own port unique number. To do this, I’m currently using code similar to below. For the first loop, each image runs through
connect inside a
critical block to ensure each image gets a unique port number (subsequent loops can reuse the same port number). The functions
client_start are written in C and compile directly with the Fortran.
The problem I’m encountering is that the program stalls at the
critical block for a long time. It’ll typically get through 3-4 images right away, but it’ll then take several minutes to get through the next few (assuming 8 images total).
subroutine tcpconnect implicit none character(len=256) :: cmd integer :: port_number = -1 integer :: status = -1 if (port_number == -1) port_number = find_open_port() write (cmd,'(a,i0)') '/path/to/other ',port_number call system(cmd) status = client_start(port_number) if (status /= 0) then ! bad error stop "CONNECTION FAILED" end if end subroutine
subroutine io_manager logical :: pass1 = .true. if (pass1) then pass1 = .false. critical call tcpconnect end critical else call tcpconnect end if end subroutine
Everything runs fine if I replace
port_number = find_open_port() with
port_number = 2100 + this_image() and remove the
critical block. This guarantees different port numbers but I don’t want to hardcode the port.
Could this be an issue with the compiler not knowing how to handle C-code inside a
Is there a better way to do this? Should I be using
event_type instead of
Using ifort 2020.4.