diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index abe3d20ad..624191e24 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -707,3 +707,38 @@ jobs: make check TESTS= -j SHMEM_DEBUG=1 SHMEM_INFO=1 make VERBOSE=1 TEST_RUNNER="${SOS_PM} -np 2" check ${SOS_PM} -np 1 modules/tests-sos/test/unit/hello + + mmap_only: + runs-on: ubuntu-20.04 + strategy: + fail-fast: false + matrix: + include: + - config_name: transport_none + sos_config: [--enable-mmap --enable-shr-atomics --enable-error-checking --enable-pmi-simple] + + steps: + - name: Checking OS version + run: | + echo "OS_NAME=$(lsb_release -si)-$(ls_release -sr)" >> $GITHUB_ENV + - uses: actions/checkout@v2 + - name: Install dependencies + run: | + sudo apt-get install -y gfortran mpich libmpich-dev libev-dev libev-libevent-dev + sudo sysctl -w kernel.yama.ptrace_scope=0 + sudo sysctl -w kernel.randomize_va_space=0 + + # SOS + - name: Build SOS (${{ matrix.name }}) + run: | + ./autogen.sh + mkdir build; cd build + ../configure --prefix=${SOS_INSTALL_DIR} ${{ matrix.sos_config }} + make -j + make install + - name: Test SOS (${{ matrix.name }}) + run: | + cd build + make check TESTS= -j + SHMEM_DEBUG=1 SHMEM_INFO=1 make VERBOSE=1 TEST_RUNNER="${SOS_PM} -np 2" check + cat modules/tests-sos/test/unit/hello.log diff --git a/configure.ac b/configure.ac index bd55391ab..82b1bf705 100755 --- a/configure.ac +++ b/configure.ac @@ -307,6 +307,10 @@ AC_ARG_ENABLE([memcpy], [AC_HELP_STRING([--enable-memcpy], [Use memcpy to perform local put/get operations (default:disabled)])]) +AC_ARG_ENABLE([mmap], + [AC_HELP_STRING([--enable-mmap], + [Use mmap to share symmetric data and heap segments in shared memory (default:disabled)])]) + AC_ARG_ENABLE([ofi-fence], [AC_HELP_STRING([--enable-ofi-fence], [Use FI_FENCE feature to optimize put-with-signal operations. (default: disabled)])]) @@ -476,7 +480,7 @@ else transport_portals4="no" transport_ofi="no" transport_ucx="no" - AC_MSG_WARN([No transport requested]) + AC_MSG_WARN([No network transport requested]) fi AM_CONDITIONAL([USE_PORTALS4], [test "$transport_portals4" = "yes"]) @@ -491,29 +495,49 @@ CHECK_CMA( [transport_cma="yes"], [transport_cma="no"]) -# If both XPMEM and CMA requested, user needs to choose one: -if test -n "$with_xpmem" -a "$with_xpmem" != "no" -a -n "$with_cma" -a "$with_cma" != "no" ; then - AC_MSG_ERROR([Cannot choose both XPMEM and CMA transports, see --help for details]) -# Check which was requested, XPMEM or CMA: + +num_shared_transports=0 +if test -n "$with_xpmem" -a "$with_xpmem" != "no" ; then + ((num_shared_transports+=1)) +fi +if test -n "$with_cma" -a "$with_cma" != "no" ; then + ((num_shared_transports+=1)) +fi +if test -n "$enable_mmap" -a "$enable_mmap" != "no" ; then + ((num_shared_transports+=1)) +fi + +# If more than one shared memory transport requested, user needs to choose one: +if [[ $num_shared_transports -gt 1 ]] ; then + echo "Selected" $num_shared_transports "shared memory transports, please choose one." + AC_MSG_ERROR([Only one shared memory transport is allowed (mmap, XPMEM, or CMA), see --help for details]) +elif test -n "$enable_mmap" -a "$enable_mmap" != "no" ; then + transport_mmap="yes" + transport_cma="no" + transport_xpmem="no" + AC_DEFINE([USE_MMAP], [1], [Define if mmap transport is active]) + AC_CHECK_LIB(rt, shm_open, [MMAP_LDFLAGS="-lrt"]) + AC_SUBST([MMAP_LDFLAGS]) elif test -n "$with_xpmem" -a "$with_xpmem" != "no" ; then + transport_mmap="no" transport_cma="no" AC_DEFINE([USE_XPMEM], [1], [Define if XPMEM transport is active]) elif test -n "$with_cma" -a "$with_cma" != "no" ; then + transport_mmap="no" transport_xpmem="no" AC_DEFINE([USE_CMA], [1], [Define if Cross Memory Attach transport is active]) AC_DEFINE([_GNU_SOURCE], [1], [CMA transport header requires global definition of _GNU_SOURCE]) -# If neither, disable XPMEM and CMA: else + transport_mmap="no" transport_xpmem="no" transport_cma="no" - AC_MSG_RESULT([Neither XPMEM nor CMA transport requested]) - + AC_MSG_RESULT([Shared memory transport not requested]) fi -if test "$enable_memcpy" = "yes" -a "$transport_xpmem" = "no" -a "$transport_cma" = "no" ; then +if test "$enable_memcpy" = "yes" -a "$transport_xpmem" = "no" -a "$transport_cma" = "no" -a "$transport_mmap" = "no" ; then transport_memcpy="yes" AC_DEFINE([USE_MEMCPY], [1], [Define to use memcpy for local put/get communication]) -elif test "$transport_xpmem" = "yes" -o "$transport_cma" = "yes" ; then +elif test "$transport_xpmem" = "yes" -o "$transport_cma" = "yes" -o "$transport_mmap" = "yes" ; then transport_memcpy="yes" else transport_memcpy="no" @@ -521,8 +545,9 @@ fi AM_CONDITIONAL([USE_XPMEM], [test "$transport_xpmem" = "yes"]) AM_CONDITIONAL([USE_CMA], [test "$transport_cma" = "yes"]) +AM_CONDITIONAL([USE_MMAP], [test "$transport_mmap" = "yes"]) -AS_IF([test "$transport_xpmem" = "yes" -o "$transport_cma" = "yes"], +AS_IF([test "$transport_xpmem" = "yes" -o "$transport_cma" = "yes" -o "$transport_mmap" = "yes"], [AC_DEFINE([USE_ON_NODE_COMMS], [1], [Define if any on-node comm transport is available]) AC_DEFINE([ENABLE_HARD_POLLING], [1], [Enable hard polling]) ]) @@ -533,7 +558,7 @@ else transport_shr_atomics="no" fi -if test "$enable_shr_atomics" != "no" -a "$transport_xpmem" = "yes" -a "$transport" = "none"; then +if [[[ "$enable_shr_atomics" != "no" && ( "$transport_xpmem" = "yes" || "$transport_mmap" = "yes" ) && "$transport" = "none" ]]]; then transport_shr_atomics="yes" AC_DEFINE([USE_SHR_ATOMICS], [1], [If defined, the shared memory layer will perform processor atomics.]) fi @@ -870,6 +895,9 @@ fi if test -n "$with_xpmem" -a "$with_xpmem" != "no" -a "$with_xpmem" != "yes" ; then DISTCHECK_CONFIGURE_FLAGS="$DISTCHECK_CONFIGURE_FLAGS --with-xpmem=${with_xpmem}" fi +if test -n "$enable_mmap" -a "$enable_mmap" != "no" -a "$enable_mmap" != "yes" ; then + DISTCHECK_CONFIGURE_FLAGS="$DISTCHECK_CONFIGURE_FLAGS --enable-mmap=${enable_mmap}" +fi if test -n "$with_pmi" -a "$with_pmi" != "no" -a "$with_pmi" != "yes" ; then DISTCHECK_CONFIGURE_FLAGS="$DISTCHECK_CONFIGURE_FLAGS --with-pmi=${with_pmi}" fi @@ -932,6 +960,13 @@ fi if test -n "opal_hwloc_LDFLAGS"; then WRAPPER_COMPILER_EXTRA_LDFLAGS="$WRAPPER_COMPILER_EXTRA_LDFLAGS $opal_hwloc_LDFLAGS" fi +if test "$transport_mmap" = "yes" ; then + CPPFLAGS="$CPPFLAGS $MMAP_CPPFLAGS" + LDFLAGS="$LDFLAGS $MMAP_LDFLAGS" + LIBS="$LIBS $MMAP_LIBS" + WRAPPER_COMPILER_EXTRA_LDFLAGS="$MMAP_LDFLAGS" + WRAPPER_COMPILER_EXTRA_LIBS="$MMAP_LIBS" +fi CPPFLAGS="$CPPFLAGS $pmi_CPPFLAGS" LDFLAGS="$LDFLAGS $pmi_LDFLAGS $aslr_LDFLAGS" @@ -985,7 +1020,7 @@ AS_IF([test "$enable_pmi_mpi" != "yes" -a "$enable_pmi_simple" != "yes" -a "$opa [AC_MSG_ERROR([No PMI client interface was configured, consider --enable-pmi-simple or --with-pmi])]) AS_IF([test -z "$num_transports"], - [AC_MSG_WARN([No transport found, resulting library will be unable to exchange messages])]) + [AC_MSG_WARN([No network transport found, library will be unable to exchange remote messages])]) AS_IF([test "$shmem_cv_c11_works" != "yes"], [AC_MSG_WARN([C compiler does not support _Generic, unable to verify and test C11 bindings])]) @@ -1025,6 +1060,7 @@ echo "" echo "On Node Communication:" echo " XPMEM: $transport_xpmem" echo " CMA: $transport_cma" +echo " mmap: $transport_mmap" echo " memcpy (self): $transport_memcpy" echo " Shr. atomics: $transport_shr_atomics" echo "" diff --git a/src/Makefile.am b/src/Makefile.am index 427b0387e..f3ee55bd1 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -128,6 +128,12 @@ libsma_la_SOURCES += \ transport_cma.c endif +if USE_MMAP +libsma_la_SOURCES += \ + transport_mmap.h \ + transport_mmap.c +endif + if USE_PMI_SIMPLE AM_CPPFLAGS += -I$(top_srcdir)/pmi-simple libsma_la_SOURCES += \ diff --git a/src/shmem_remote_pointer.h b/src/shmem_remote_pointer.h index 9ca618316..e9cacb694 100644 --- a/src/shmem_remote_pointer.h +++ b/src/shmem_remote_pointer.h @@ -34,6 +34,8 @@ shmem_internal_ptr(const void *target, int pe) if (-1 != (node_rank = shmem_internal_get_shr_rank(pe))) { #if USE_XPMEM return shmem_transport_xpmem_ptr(target, pe, node_rank); +#elif USE_MMAP + return shmem_transport_mmap_ptr(target, pe, node_rank); #else return NULL; #endif diff --git a/src/shr_transport.h4 b/src/shr_transport.h4 index 9379ef2e5..7916fcbf9 100644 --- a/src/shr_transport.h4 +++ b/src/shr_transport.h4 @@ -27,6 +27,10 @@ include(shmem_bind_c.m4)dnl #include "transport_cma.h" #endif +#ifdef USE_MMAP +#include "transport_mmap.h" +#endif + static inline int shmem_shr_transport_init(void) { @@ -41,6 +45,11 @@ shmem_shr_transport_init(void) ret = shmem_transport_cma_init(); if (0 != ret) RETURN_ERROR_MSG("CMA init failed (%d)\n", ret); + +#elif USE_MMAP + ret = shmem_transport_mmap_init(); + if (0 != ret) + RETURN_ERROR_MSG("mmap init failed (%d)\n", ret); #endif return ret; @@ -63,6 +72,12 @@ shmem_shr_transport_startup(void) if (0 != ret) { RETURN_ERROR_MSG("CMA startup failed (%d)\n", ret); } + +#elif USE_MMAP + ret = shmem_transport_mmap_startup(); + if (0 != ret) { + RETURN_ERROR_MSG("mmap startup failed (%d)\n", ret); + } #endif return ret; @@ -76,6 +91,8 @@ shmem_shr_transport_fini(void) shmem_transport_xpmem_fini(); #elif USE_CMA shmem_transport_cma_fini(); +#elif USE_MMAP + shmem_transport_mmap_fini(); #endif } @@ -87,6 +104,8 @@ shmem_shr_transport_ptr(void *target, int noderank, void **local_ptr) { #if USE_XPMEM XPMEM_GET_REMOTE_ACCESS(target, noderank, *local_ptr); +#elif USE_MMAP + MMAP_GET_REMOTE_ACCESS(target, noderank, *local_ptr); #else RAISE_ERROR_MSG("No path to peer (%d)\n", noderank); #endif @@ -147,6 +166,10 @@ shmem_shr_transport_put_scalar(shmem_ctx_t ctx, void *target, #elif USE_CMA shmem_transport_cma_put(target, source, len, pe, shmem_internal_get_shr_rank(pe)); + +#elif USE_MMAP + shmem_transport_mmap_put(target, source, len, pe, + shmem_internal_get_shr_rank(pe)); #else RAISE_ERROR_STR("No path to peer"); #endif @@ -165,6 +188,10 @@ shmem_shr_transport_put(shmem_ctx_t ctx, void *target, const void *source, #elif USE_CMA shmem_transport_cma_put(target, source, len, pe, shmem_internal_get_shr_rank(pe)); + +#elif USE_MMAP + shmem_transport_mmap_put(target, source, len, pe, + shmem_internal_get_shr_rank(pe)); #else RAISE_ERROR_STR("No path to peer"); #endif @@ -183,6 +210,10 @@ shmem_shr_transport_get(shmem_ctx_t ctx, void *target, const void *source, #elif USE_CMA shmem_transport_cma_get(target, source, len, pe, shmem_internal_get_shr_rank(pe)); + +#elif USE_MMAP + shmem_transport_mmap_get(target, source, len, pe, + shmem_internal_get_shr_rank(pe)); #else RAISE_ERROR_STR("No path to peer"); #endif @@ -577,6 +608,12 @@ shmem_shr_transport_put_signal(shmem_ctx_t ctx, void *target, shmem_internal_get_shr_rank(pe)); shmem_internal_membar_acq_rel(); /* Memory fence to ensure target PE observes stores in the correct order */ +#elif USE_MMAP + shmem_transport_mmap_put(target, source, len, pe, + shmem_internal_get_shr_rank(pe)); + shmem_internal_membar_acq_rel(); /* Memory fence to ensure target PE observes + stores in the correct order */ + #if USE_SHR_ATOMICS if (sig_op == SHMEM_SIGNAL_ADD) shmem_shr_transport_atomic(ctx, sig_addr, &signal, sizeof(uint64_t), diff --git a/src/transport_mmap.c b/src/transport_mmap.c new file mode 100644 index 000000000..d15728a02 --- /dev/null +++ b/src/transport_mmap.c @@ -0,0 +1,295 @@ +/* -*- C -*- + * + * Copyright 2011 Sandia Corporation. Under the terms of Contract + * DE-AC04-94AL85000 with Sandia Corporation, the U.S. Government + * retains certain rights in this software. + * + * Copyright (c) 2023 Intel Corporation. All rights reserved. + * This software is available to you under the BSD license. + * + * This file is part of the Sandia OpenSHMEM software package. For license + * information, see the LICENSE file in the top level directory of the + * distribution. + * + */ + +#include "config.h" + +#include +#include +#include +#include +#include +#include + +#define SHMEM_INTERNAL_INCLUDE +#include "shmem.h" +#include "shmem_internal.h" +#include "shmem_comm.h" +#include "runtime.h" +#include "transport_mmap.h" + +#define MPIDI_OFI_SHMGR_NAME_MAXLEN (128) +#define MPIDI_OFI_SHMGR_NAME_PREFIX "/sos_shm_mmap_area" + + +static void shm_create_key(char *key, size_t max_size, unsigned pe, size_t num) { + snprintf(key, max_size, "%s-%u-%zu", MPIDI_OFI_SHMGR_NAME_PREFIX, pe, num); +} + + +static void *shm_create_region(char* base, const char *key, int shm_size) { + if (shm_size == 0) return NULL; + + shm_unlink(key); + int fd = shm_open(key, O_RDWR | O_CREAT | O_TRUNC, 0666); + if (fd == -1) { + fprintf(stderr, "mmap_init error shm_open with errno(%s)\n", strerror(errno)); + exit(0); + } + + if (ftruncate(fd, shm_size) == -1) { + fprintf(stderr, "mmap_init error ftruncate\n"); + exit(0); + } + + void *shm_base_addr = mmap(base, shm_size, PROT_READ | PROT_WRITE, MAP_SHARED | MAP_FIXED, fd, 0); + if (MAP_FAILED == shm_base_addr) { + fprintf(stderr, "mmap_init error mmap %s size %d\n", key, shm_size); + exit(0); + } + + return shm_base_addr; +} + + +static void *shm_create_region_data_seg(char* base, const char *key, int shm_size) { + if (shm_size == 0) return NULL; + + shm_unlink(key); + int fd = shm_open(key, O_RDWR | O_CREAT | O_TRUNC, 0666); + if (fd == -1) { + fprintf(stderr, "mmap_init data_seg error shm_open with errno(%s)\n", strerror(errno)); + exit(1); + } + + /* Write all current contents of the data segment to the file */ + FILE *fp = fdopen(fd, "wb"); + size_t ret = fwrite(base, shm_size, 1, fp); + + if (ret == 0) { + fprintf(stderr, "mmap_init error fwrite\n"); + exit(1); + } + + if (ftruncate(fd, shm_size) == -1) { + fprintf(stderr, "mmap_init error ftruncate with errno(%s)\n", strerror(errno)); + exit(1); + } + + void *shm_base_addr = mmap(base, shm_size, PROT_READ | PROT_WRITE, MAP_SHARED | MAP_FIXED, fd, 0); + if (MAP_FAILED == shm_base_addr) { + fprintf(stderr, "mmap_init error mmap %s size %d\n", key, shm_size); + exit(1); + } + + fclose(fp); + + return shm_base_addr; +} + + +static void *shm_attach_region(char* base, const char *key, int shm_size) { + if (shm_size == 0) return NULL; + + int fd = shm_open(key, O_RDWR, 0); + if (fd == -1) { + fprintf(stderr, "mmap_init error shm_open\n"); + exit(0); + } + void *shm_base_addr = mmap(NULL, shm_size, PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0); + if (MAP_FAILED == shm_base_addr) { + fprintf(stderr, "mmap_init error mmap %s size %d\n", key, shm_size); + exit(0); + } + return shm_base_addr; +} + + +struct share_info_t { + size_t data_len; + size_t data_off; + size_t heap_len; + size_t heap_off; +}; + +struct shmem_transport_mmap_peer_info_t *shmem_transport_mmap_peers = NULL; +static struct share_info_t my_info; + +#define FIND_BASE(ptr, page_size) ((char*) (((uintptr_t) ptr / page_size) * page_size)) +#define FIND_LEN(ptr, len, page_size) ((((char*) ptr - FIND_BASE(ptr, page_size) + len - 1) / \ + page_size + 1) * page_size) + +int +shmem_transport_mmap_init(void) +{ + long page_size = sysconf(_SC_PAGESIZE); + char *base; + size_t len; + int ret; + char key_prefix[MPIDI_OFI_SHMGR_NAME_MAXLEN-10]; + char key[MPIDI_OFI_SHMGR_NAME_MAXLEN]; + + /* setup data region */ + base = FIND_BASE(shmem_internal_data_base, page_size); + len = FIND_LEN(shmem_internal_data_base, shmem_internal_data_length, page_size); + shm_create_key(key_prefix, MPIDI_OFI_SHMGR_NAME_MAXLEN-10, shmem_internal_my_pe, 1); + snprintf(key, MPIDI_OFI_SHMGR_NAME_MAXLEN, "%s-data", key_prefix); + void* myaddr_data = shm_create_region_data_seg(base, key, len); + if (myaddr_data == NULL) return 1; + + my_info.data_off = (char*) shmem_internal_data_base - (char*) base; + my_info.data_len = len; + + /* setup heap region */ + base = FIND_BASE(shmem_internal_heap_base, page_size); + len = FIND_LEN(shmem_internal_heap_base, shmem_internal_heap_length, page_size); + shm_create_key(key_prefix, MPIDI_OFI_SHMGR_NAME_MAXLEN-10, shmem_internal_my_pe, 2); + snprintf(key, MPIDI_OFI_SHMGR_NAME_MAXLEN, "%s-heap", key_prefix); + void* myaddr_heap = shm_create_region(base, key, len); + if (myaddr_heap == NULL) return 1; + + my_info.heap_off = (char*) shmem_internal_heap_base - (char*) base; + my_info.heap_len = len; + + ret = shmem_runtime_put("mmap-segids", &my_info, sizeof(struct share_info_t)); + if (0 != ret) { + RETURN_ERROR_MSG("runtime_put failed: %d\n", ret); + return 1; + } + + return 0; +} + + +int +shmem_transport_mmap_startup(void) +{ + int ret, peer_num, num_on_node; + char errmsg[256]; + struct share_info_t info; + //struct mmap_addr addr; + long page_size = sysconf(_SC_PAGESIZE); + + num_on_node = shmem_runtime_get_node_size(); + + /* allocate space for local peers */ + shmem_transport_mmap_peers = calloc(num_on_node, + sizeof(struct shmem_transport_mmap_peer_info_t)); + if (NULL == shmem_transport_mmap_peers) return 1; + + /* get local peer info and map into our address space ... */ + for (int i = 0 ; i < shmem_internal_num_pes; ++i) { + peer_num = shmem_runtime_get_node_rank(i); + if (-1 == peer_num) continue; + + if (shmem_internal_my_pe == i) { + shmem_transport_mmap_peers[peer_num].data_ptr = + shmem_internal_data_base; + shmem_transport_mmap_peers[peer_num].heap_ptr = + shmem_internal_heap_base; + } else { + ret = shmem_runtime_get(i, "mmap-segids", &info, sizeof(struct share_info_t)); + if (0 != ret) { + RETURN_ERROR_MSG("runtime_get failed: %d\n", ret); + return 1; + } + + char key_prefix[MPIDI_OFI_SHMGR_NAME_MAXLEN-10]; + char key[MPIDI_OFI_SHMGR_NAME_MAXLEN]; + int len = 0; + + /* Attach data segment to neighbors: */ + len = FIND_LEN(shmem_internal_data_base, shmem_internal_data_length, page_size); + shm_create_key(key_prefix, MPIDI_OFI_SHMGR_NAME_MAXLEN-10, i, 1); + snprintf(key, MPIDI_OFI_SHMGR_NAME_MAXLEN, "%s-data", key_prefix); + shmem_transport_mmap_peers[peer_num].data_attach_ptr = shm_attach_region(NULL, key, len); + + if (shmem_transport_mmap_peers[peer_num].data_attach_ptr == NULL) { + RETURN_ERROR_MSG("could not get data segment: %s\n", + shmem_util_strerror(errno, errmsg, 256)); + return 1; + } + shmem_transport_mmap_peers[peer_num].data_ptr = + (char*) shmem_transport_mmap_peers[peer_num].data_attach_ptr + info.data_off; + + /* Attach heap segment to neighbors: */ + len = FIND_LEN(shmem_internal_heap_base, shmem_internal_heap_length, page_size); + shm_create_key(key_prefix, MPIDI_OFI_SHMGR_NAME_MAXLEN-10, i, 2); + snprintf(key, MPIDI_OFI_SHMGR_NAME_MAXLEN, "%s-heap", key_prefix); + shmem_transport_mmap_peers[peer_num].heap_attach_ptr = shm_attach_region(NULL, key, len); + + if (shmem_transport_mmap_peers[peer_num].heap_attach_ptr == NULL) { + RETURN_ERROR_MSG("could not get heap segment: %s\n", + shmem_util_strerror(errno, errmsg, 256)); + return 1; + } + shmem_transport_mmap_peers[peer_num].heap_ptr = + (char*) shmem_transport_mmap_peers[peer_num].heap_attach_ptr + info.heap_off; + } + } + + return 0; +} + + +int +shmem_transport_mmap_fini(void) +{ + int i, peer_num, ret; + char errmsg[256]; + size_t data_len, heap_len; + char key_prefix[MPIDI_OFI_SHMGR_NAME_MAXLEN-10]; + char key[MPIDI_OFI_SHMGR_NAME_MAXLEN]; + long page_size = sysconf(_SC_PAGESIZE); + + data_len = FIND_LEN(shmem_internal_data_base, shmem_internal_data_length, page_size); + heap_len = FIND_LEN(shmem_internal_heap_base, shmem_internal_heap_length, page_size); + + shm_create_key(key_prefix, MPIDI_OFI_SHMGR_NAME_MAXLEN-10, shmem_internal_my_pe, 1); + snprintf(key, MPIDI_OFI_SHMGR_NAME_MAXLEN, "%s-data", key_prefix); + + ret = shm_unlink(key); + if (ret != 0) { + RETURN_ERROR_MSG("could not get data segment: %s\n", \ + shmem_util_strerror(errno, errmsg, 256)); + } + + shm_create_key(key_prefix, MPIDI_OFI_SHMGR_NAME_MAXLEN-10, shmem_internal_my_pe, 2); + snprintf(key, MPIDI_OFI_SHMGR_NAME_MAXLEN, "%s-heap", key_prefix); + + ret = shm_unlink(key); + if (ret != 0) { + RETURN_ERROR_MSG("could not get heap segment: %s\n", \ + shmem_util_strerror(errno, errmsg, 256)); + } + + if (NULL != shmem_transport_mmap_peers) { + for (i = 0 ; i < shmem_internal_num_pes; ++i) { + peer_num = shmem_runtime_get_node_rank(i); + if (-1 == peer_num) continue; + if (shmem_internal_my_pe == i) continue; + + if (NULL != shmem_transport_mmap_peers[peer_num].data_attach_ptr) { + munmap(shmem_transport_mmap_peers[peer_num].data_attach_ptr, data_len); + } + + if (NULL != shmem_transport_mmap_peers[peer_num].heap_attach_ptr) { + munmap(shmem_transport_mmap_peers[peer_num].heap_attach_ptr, heap_len); + } + } + free(shmem_transport_mmap_peers); + } + + return 0; +} diff --git a/src/transport_mmap.h b/src/transport_mmap.h new file mode 100644 index 000000000..cf4b9c373 --- /dev/null +++ b/src/transport_mmap.h @@ -0,0 +1,114 @@ +/* -*- C -*- + * + * Copyright 2011 Sandia Corporation. Under the terms of Contract + * DE-AC04-94AL85000 with Sandia Corporation, the U.S. Government + * retains certain rights in this software. + * + * Copyright (c) 2023 Intel Corporation. All rights reserved. + * This software is available to you under the BSD license. + * + * This file is part of the Sandia OpenSHMEM software package. For license + * information, see the LICENSE file in the top level directory of the + * distribution. + * + */ + +#ifndef TRANSPORT_MMAP_H +#define TRANSPORT_MMAP_H + +#include +#include + +struct shmem_transport_mmap_peer_info_t { + void *data_attach_ptr; + void *heap_attach_ptr; + void *data_ptr; + void *heap_ptr; +}; + +extern struct shmem_transport_mmap_peer_info_t *shmem_transport_mmap_peers; + +#ifdef ENABLE_ERROR_CHECKING +#define MMAP_GET_REMOTE_ACCESS(target, rank, ptr) \ + do { \ + if (((void*) target > shmem_internal_data_base) && \ + ((char*) target < (char*) shmem_internal_data_base + shmem_internal_data_length)) { \ + ptr = (char*) target - (char*) shmem_internal_data_base + \ + (char*) shmem_transport_mmap_peers[rank].data_ptr; \ + } else if (((void*) target >= shmem_internal_heap_base) && \ + ((char*) target < (char*) shmem_internal_heap_base + shmem_internal_heap_length)) { \ + ptr = (char*) target - (char*) shmem_internal_heap_base + \ + (char*) shmem_transport_mmap_peers[rank].heap_ptr; \ + } else { \ + ptr = NULL; \ + } \ + } while (0) +#else +#define MMAP_GET_REMOTE_ACCESS(target, rank, ptr) \ + do { \ + if ((void*) target < shmem_internal_heap_base) { \ + ptr = (char*) target - (char*) shmem_internal_data_base + \ + (char*) shmem_transport_mmap_peers[rank].data_ptr; \ + } else { \ + ptr = (char*) target - (char*) shmem_internal_heap_base + \ + (char*) shmem_transport_mmap_peers[rank].heap_ptr; \ + } \ + } while (0) +#endif + +int shmem_transport_mmap_init(void); + +int shmem_transport_mmap_startup(void); + +int shmem_transport_mmap_fini(void); + + +static inline +void * +shmem_transport_mmap_ptr(const void *target, int pe, int noderank) +{ + char *remote_ptr; + + MMAP_GET_REMOTE_ACCESS(target, noderank, remote_ptr); + return remote_ptr; +} + + +static inline +void +shmem_transport_mmap_put(void *target, const void *source, size_t len, + int pe, int noderank) +{ + char *remote_ptr; + + MMAP_GET_REMOTE_ACCESS(target, noderank, remote_ptr); +#ifdef ENABLE_ERROR_CHECKING + if (NULL == remote_ptr) { + RAISE_ERROR_MSG("target (0x%"PRIXPTR") outside of symmetric areas\n", + (uintptr_t) target); + } +#endif + + memcpy(remote_ptr, source, len); +} + + +static inline +void +shmem_transport_mmap_get(void *target, const void *source, size_t len, + int pe, int noderank) +{ + char *remote_ptr; + + MMAP_GET_REMOTE_ACCESS(source, noderank, remote_ptr); +#ifdef ENABLE_ERROR_CHECKING + if (NULL == remote_ptr) { + RAISE_ERROR_MSG("target (0x%"PRIXPTR") outside of symmetric areas\n", + (uintptr_t) target); + } +#endif + + memcpy(target, remote_ptr, len); +} + +#endif diff --git a/src/transport_xpmem.c b/src/transport_xpmem.c index 4a2bdf129..538b3f5fa 100644 --- a/src/transport_xpmem.c +++ b/src/transport_xpmem.c @@ -26,6 +26,7 @@ #include "shmem_internal.h" #include "shmem_comm.h" #include "runtime.h" +#include "transport_xpmem.h" struct share_info_t { xpmem_segid_t data_seg; diff --git a/src/transport_xpmem.h b/src/transport_xpmem.h index ba795d2f6..8d9fbe8a8 100644 --- a/src/transport_xpmem.h +++ b/src/transport_xpmem.h @@ -38,7 +38,7 @@ extern struct shmem_transport_xpmem_peer_info_t *shmem_transport_xpmem_peers; ((char*) target < (char*) shmem_internal_data_base + shmem_internal_data_length)) { \ ptr = (char*) target - (char*) shmem_internal_data_base + \ (char*) shmem_transport_xpmem_peers[rank].data_ptr; \ - } else if (((void*) target > shmem_internal_heap_base) && \ + } else if (((void*) target >= shmem_internal_heap_base) && \ ((char*) target < (char*) shmem_internal_heap_base + shmem_internal_heap_length)) { \ ptr = (char*) target - (char*) shmem_internal_heap_base + \ (char*) shmem_transport_xpmem_peers[rank].heap_ptr; \