SHMEM_PUT64_NBI(3)

πŸ’… SHMEM_PUT64_NBI β€” the whole nonblocking put family, bestie

okay so this is shmem_put64_nbi(3) from the Open MPI manual, and honestly it's a whole family page β€” like one of those group chats where everyone's related. The title line at the top lists the entire squad: shmem_putmem_nbi(3), shmem_char_put_nbi(3), shmem_short_put_nbi(3), shmem_int_put_nbi(3), shmem_long_put_nbi(3), shmem_longlong_put_nbi(3), shmem_float_put_nbi(3), shmem_double_put_nbi(3), shmem_longdouble_put_nbi(3), shmem_put8_nbi(3), shmem_put16_nbi(3), shmem_put32_nbi(3), shmem_put64_nbi(3), shmem_put128_nbi(3) β€” and what do they all do? The nonblocking put routines give you a way to copy data from a contiguous local data object to a data object on a specified PE. That's the whole vibe. 🫢


✨ SYNOPSIS ✨

πŸ“ C or C++

#include <mpp/shmem.h>

void shmem_putmem_nbi(void *dest, const void *source,
  size_t nelems, int pe)

void shmem_char_put(char *dest, const char *source,
  size_t nelems, int pe)

void shmem_short_put(short *dest, const short *source,
  size_t nelems, int pe)

void shmem_int_put(int *dest, const int *source,
  size_t nelems, int pe)

void shmem_long_put(long *dest, const long *source,
  size_t nelems, int pe)

void shmem_longlong_put(long long *dest, const long long *source,
  size_t nelems, int pe)

void shmem_float_put(float *dest, const float *source,
  size_t nelems, int pe)

void shmem_double_put(double *dest, const double *source,
  size_t nelems, int pe)

void shmem_longdouble_put(long double *dest, const long double *source,
  size_t nelems, int pe)

void shmem_put8(void *dest, const void *source,
  size_t nelems, int pe)

void shmem_put16(void *dest, const void *source,
  size_t nelems, int pe)

void shmem_put32(void *dest, const void *source,
  size_t nelems, int pe)

void shmem_put64(void *dest, const void *source,
  size_t nelems, int pe)

void shmem_put128(void *dest, const void *source,
  size_t nelems, int pe)

like yes, that's a lot of signatures. copy them exactly, bestie, don't get creative with the types. πŸ’€

🧚 Fortran

INCLUDE "mpp/shmem.fh"

INTEGER nelems, pe

CALL SHMEM_PUTMEM_NBI(dest, source, nelems, pe)

CALL SHMEM_CHARACTER_PUT_NBI(dest, source, nelems, pe)

CALL SHMEM_COMPLEX_PUT_NBI(dest, source, nelems, pe)

CALL SHMEM_DOUBLE_PUT_NBI(dest, source, nelems, pe)

CALL SHMEM_INTEGER_PUT_NBI(dest, source, nelems, pe)

CALL SHMEM_LOGICAL_PUT_NBI(dest, source, nelems, pe)

CALL SHMEM_REAL_PUT_NBI(dest, source, nelems, pe)

CALL SHMEM_PUT4_NBI(dest, source, nelems, pe)

CALL SHMEM_PUT8_NBI(dest, source, nelems, pe)

CALL SHMEM_PUT32_NBI(dest, source, nelems, pe)

CALL SHMEM_PUT64_NBI(dest, source, nelems, pe)

CALL SHMEM_PUT128_NBI(dest, source, nelems, pe)

🌸 DESCRIPTION 🌸

okay here's the actual tea β˜• β€” these routines return after posting the operation. Not after it's done, just after it's posted. So the operation is considered complete only after a subsequent call to shmem_quiet. At the completion of shmem_quiet, the data has been copied into the dest array on the destination PE.

⚠️ and like, the delivery of data words into the data object on the destination PE may occur in any order. Not a vibe, just facts.

Furthermore β€” and this is the part people forget β€” two successive put routines may deliver data out of order unless a call to shmem_fence is introduced between the two calls. so like. fence your puts. periodt. 🧚

the arguments, one by one πŸ’–

  • dest β€” the data object to be updated on the remote PE. this one must be remotely accessible, no exceptions bestie.
  • source β€” the data object containing the data to be copied.
  • nelems β€” number of elements in the dest and source arrays. for C, nelems must be of type size_t. if you're in Fortran, it must be a constant, variable, or array element of default integer type.
  • pe β€” PE number of the remote PE. pe must be of type integer. if you're doing Fortran, it must be a constant, variable, or array element of default integer type.

and if you're using Fortran, data types must be of default size. for example, a real variable has to be declared as REAL, REAL*4, or REAL(KIND=4). that's the rule, iykyk. ✨


πŸ¦‹ NOTES πŸ¦‹

if you're sitting there like "what even is remotely accessible" β€” same, but the answer is right there: see intro_shmem(3) for a definition of the term. slay. πŸ’…


πŸŽ€ EXAMPLES πŸŽ€

consider this simple example for C. it's giving main character energy:

#include <stdio.h>
#include <mpp/shmem.h>

main()
{
  long source[10] = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 };
  static long target[10];
  shmem_init();

  if (shmem_my_pe() == 0) {
    /* put 10 words into target on PE 1 */
    shmem_long_put_nbi(target, source, 10, 1);
    shmem_quiet();
  }
  shmem_barrier_all();  /* sync sender and receiver */
  if (shmem_my_pe() == 1)
    shmem_udcflush();  /* not required on Altix systems */
  printf("target[0] on PE %d is %d\n", shmem_my_pe(), target[0]);
}

like look at that β€” put, quiet, barrier, done. the shmem_udcflush() call is literally annotated /* not required on Altix systems */ so don't come for me. πŸ™ˆ


🌈 SEE ALSO 🌈

go read those, fr fr. πŸ“š


2003-2026, The Open MPI Community


and that's the page, bestie! πŸ«ΆπŸ’– this iconic little manual was served up on May 14, 2026, brought to you by Open MPI β€” go forth and put nonblocking, and remember: quiet before you read. βœ¨πŸŽ€πŸ¦‹

πŸ“¦ where this page comes from