Gather-scatter communication using OpenSHMEM one-sided puts with per-rank signaling for completion (OpenSHMEM 1.5).
More...
|
| procedure, pass(this) | init (this, send_pe, recv_pe) |
| | Initialise OpenSHMEM based communication method.
|
| |
| procedure, pass(this) | free (this) |
| | Deallocate OpenSHMEM based communication method.
|
| |
| procedure, pass(this) | nbsend (this, u, n, tag, deps, strm) |
| | Pack the gathered shared dofs into the symmetric send buffer and issue non-blocking puts with signaling to each neighbor's recv buffer. Before each put, wait for the receiver's ack of our previous round so we never overwrite a buffer the receiver hasn't consumed yet.
|
| |
| procedure, pass(this) | nbrecv (this, tag) |
| | No-op: receives are completed via remote put-with-signal.
|
| |
| procedure, pass(this) | nbwait (this, u, n, op, strm) |
| | Wait per-neighbor for the signal indicating that data has landed, apply the gather-scatter operation from the recv buffer into u, and ack the sender so they may overwrite the buffer in the next round.
|
| |
| procedure, pass(this) | nbsend_vec (this, u, n, nc, tag, deps, strm) |
| | Fused nc-component send: pack nc contiguous component blocks per peer slab and put nc*ndofs reals with a single signal. Buffer indexing and put size scale by nc; the per-rank signalling is unchanged.
|
| |
| procedure, pass(this) | nbrecv_vec (this, tag, nc) |
| | No-op: receives are completed via remote put-with-signal.
|
| |
| procedure, pass(this) | nbwait_vec (this, u, n, nc, op, strm) |
| | Fused nc-component wait/reduce: per peer, wait on the data signal and reduce nc component blocks into u, then ack the sender.
|
| |
| procedure(gs_comm_init), deferred, pass | init gs_comm_init |
| |
| procedure(gs_comm_free), deferred, pass | free gs_comm_free |
| |
| procedure(gs_nbsend), deferred, pass | nbsend gs_nbsend |
| |
| procedure(gs_nbrecv), deferred, pass | nbrecv gs_nbrecv |
| |
| procedure(gs_nbwait), deferred, pass | nbwait gs_nbwait |
| |
| procedure, pass(this) | init_dofs (this) |
| |
| procedure, pass(this) | free_dofs (this) |
| |
| procedure, pass(this) | init_order (this, send_pe, recv_pe) |
| | Obtains which ranks to send and receive data from.
|
| |
| procedure, pass(this) | free_order (this) |
| |
| procedure, pass(this) | take_schedule (this, src) |
| | Take over the gather-scatter schedule (dof lists and peer order) of src, avoiding a second (expensive) pass over the connectivity. The data is moved rather than copied, so src is left without a schedule and must not be used for communication afterwards (it can still be freed). No communication resources are set up here; complete the handover with init_schedule once src has been freed, so that the two backends never hold their resources at the same time.
|
| |
| procedure, pass(this) | init_schedule (this) |
| | Set up this communication method for the schedule taken over by take_schedule. Collective, as init is.
|
| |
| procedure, pass(this) | init_vec (this) |
| | Fused vector halo exchange. Default implementations abort; backends that set vec_supported = .true. override them.
|
| |
| procedure, pass(this) | nbsend_vec (this, u, n, nc, tag, deps, strm) |
| | Default fused vector send. Abort unless a backend overrides it.
|
| |
| procedure, pass(this) | nbrecv_vec (this, tag, nc) |
| | Default fused vector receive. Abort unless a backend overrides it.
|
| |
| procedure, pass(this) | nbwait_vec (this, u, n, nc, op, strm) |
| | Default fused vector wait/reduce. Abort unless a backend overrides it.
|
| |
|
| type(gs_shmem_buf_t) | send_buf |
| |
| type(gs_shmem_buf_t) | recv_buf |
| |
| type(c_ptr) | data_signals_ptr = C_NULL_PTR |
| |
| type(c_ptr) | ack_signals_ptr = C_NULL_PTR |
| |
| integer(kind=i8) | iter = 0 |
| |
| type(stack_i4_t), dimension(:), allocatable | send_dof |
| | A list of stacks of dof indices local to this process to send to rank_i.
|
| |
| type(stack_i4_t), dimension(:), allocatable | recv_dof |
| | recv_dof(rank_i) is a stack of dof indices local to this process to receive from rank_i. size(recv_dof) == pe_size
|
| |
| integer, dimension(:), allocatable | send_pe |
| | Array of ranks that this process should send to.
|
| |
| integer, dimension(:), allocatable | recv_pe |
| | array of ranks that this process will receive messages from
|
| |
| logical | vec_supported = .false. |
| | Whether this backend implements the fused vector (multi-component) halo exchange (nbsend_vec/nbrecv_vec/nbwait_vec). When .false., the gs_op_r3 caller falls back to nc independent scalar exchanges.
|
| |
| logical | vec_ready = .false. |
| | Whether the buffers the fused vector exchange needs are in place. They are sized GS_VEC_NC times the halo, quadrupling what the backend holds, and only gs_op_r3 ever touches them, so a backend that can allocate them on its own defers that to the first fused exchange (see init_vec) rather than paying for it in every run. A backend whose vector buffers are part of an allocation the whole run has to agree on – symmetric memory, coarrays, registered memory, an RMA window – cannot defer, since a rank with no shared dofs never reaches the first fused exchange; those allocate in init and set this there.
|
| |
Each PE allocates symmetric send and recv buffers sized to the global maximum number of dofs (so puts can target a well-defined offset on the remote PE's recv buffer) plus two symmetric uint64 arrays of size pe_size, indexed by the remote PE's rank: data_signals[r] holds an "iter" value written by PE r when it has put data into our recv buffer (via shmem_putmem_signal_nbi); ack_signals[r] holds an "iter" value written by PE r after it has consumed our most recent put (via shmem_uint64_atomic_set). The sender waits on its own ack_signals[dst] before each put so a fast sender cannot overwrite a buffer the receiver hasn't consumed.
Per-rank slot indexing avoids the slot-exchange handshake that a neighbor-list-position scheme would require, which is fragile because send_pe and recv_pe are pushed independently in gs_schedule and may differ in size and ordering.
Under OpenMP the pack and unpack loops are work-shared across the calling team. The send path additionally farms the whole per-peer protocol out to the threads when the library provides SHMEM_THREAD_MULTIPLE (see gs_shmem_thread_multiple); otherwise, and always on the receive side, the SHMEM calls are issued by the master thread alone.
Definition at line 116 of file gs_shmem.F90.