diff --git a/mpp/shmemx.h4 b/mpp/shmemx.h4 index 693be25c..6b8146d9 100644 --- a/mpp/shmemx.h4 +++ b/mpp/shmemx.h4 @@ -45,6 +45,18 @@ include(shmemx_c_func.h4)dnl /* C11 Generic Macros */ #elif (defined(__STDC_VERSION__) && __STDC_VERSION__ >= 201112L && !defined(SHMEM_INTERNAL_INCLUDE)) +#define shmemx_signal_set(...) \ + _Generic(SHMEM_C11_TYPE_EVAL_PTR_OR_SCALAR(SHMEM_C11_ARG0(__VA_ARGS__)), \ + shmem_ctx_t: shmemx_ctx_signal_set, \ + uint64_t*: shmemx_signal_set \ + )(__VA_ARGS__) + +#define shmemx_signal_add(...) \ + _Generic(SHMEM_C11_TYPE_EVAL_PTR_OR_SCALAR(SHMEM_C11_ARG0(__VA_ARGS__)), \ + shmem_ctx_t: shmemx_ctx_signal_add, \ + uint64_t*: shmemx_signal_add \ + )(__VA_ARGS__) + #endif /* C11 */ #endif /* SHMEMX_H */ diff --git a/mpp/shmemx_c_func.h4 b/mpp/shmemx_c_func.h4 index e1e28336..ffb6873e 100644 --- a/mpp/shmemx_c_func.h4 +++ b/mpp/shmemx_c_func.h4 @@ -35,6 +35,12 @@ SHMEM_FUNCTION_ATTRIBUTES void SHPRE()shmemx_pcntr_get_completed_read(shmem_ctx_ SHMEM_FUNCTION_ATTRIBUTES void SHPRE()shmemx_pcntr_get_completed_target(uint64_t *cntr_value); SHMEM_FUNCTION_ATTRIBUTES void SHPRE()shmemx_pcntr_get_all(shmem_ctx_t ctx, shmemx_pcntr_t *pcntr); +/* Signal extensions */ +SHMEM_FUNCTION_ATTRIBUTES void SHPRE()shmemx_signal_add(uint64_t *sig_addr, uint64_t signal, int pe); +SHMEM_FUNCTION_ATTRIBUTES void SHPRE()shmemx_ctx_signal_add(shmem_ctx_t ctx, uint64_t *sig_addr, uint64_t signal, int pe); +SHMEM_FUNCTION_ATTRIBUTES void SHPRE()shmemx_signal_set(uint64_t *sig_addr, uint64_t signal, int pe); +SHMEM_FUNCTION_ATTRIBUTES void SHPRE()shmemx_ctx_signal_set(shmem_ctx_t ctx, uint64_t *sig_addr, uint64_t signal, int pe); + /* Separate initializers */ SHMEM_FUNCTION_ATTRIBUTES void SHPRE()shmemx_heap_create(void *base, size_t size, int device_type, int device_index); SHMEM_FUNCTION_ATTRIBUTES void SHPRE()shmemx_heap_preinit(); diff --git a/src/data_c.c4 b/src/data_c.c4 index 2083fb0b..71a99127 100644 --- a/src/data_c.c4 +++ b/src/data_c.c4 @@ -245,6 +245,14 @@ SHMEM_PROF_DEF_CTX_PUT_N_SIGNAL_NBI(`mem') #define shmemx_ct_wait pshmemx_ct_wait #pragma weak shmem_signal_fetch = pshmem_signal_fetch #define shmem_signal_fetch pshmem_signal_fetch +#pragma weak shmemx_signal_add = pshmemx_signal_add +#define shmemx_signal_add pshmemx_signal_add +#pragma weak shmemx_signal_set = pshmemx_signal_set +#define shmemx_signal_set pshmemx_signal_set +#pragma weak shmemx_ctx_signal_add = pshmemx_ctx_signal_add +#define shmemx_ctx_signal_add pshmemx_ctx_signal_add +#pragma weak shmemx_ctx_signal_set = pshmemx_ctx_signal_set +#define shmemx_ctx_signal_set pshmemx_ctx_signal_set #endif /* ENABLE_PROFILING */ @@ -700,6 +708,52 @@ shmem_signal_fetch(const uint64_t* sig_addr) return val; } +void SHMEM_FUNCTION_ATTRIBUTES +shmemx_signal_add(uint64_t *sig_addr, uint64_t signal, int pe) +{ + SHMEM_ERR_CHECK_INITIALIZED(); + SHMEM_ERR_CHECK_PE(pe); + SHMEM_ERR_CHECK_SYMMETRIC(sig_addr, sizeof(uint64_t)); + + shmem_internal_atomic(SHMEM_CTX_DEFAULT, sig_addr, &signal, sizeof(uint64_t), + pe, SHM_INTERNAL_SUM, SHM_INTERNAL_UINT64); +} + +void SHMEM_FUNCTION_ATTRIBUTES +shmemx_ctx_signal_add(shmem_ctx_t ctx, uint64_t *sig_addr, uint64_t signal, int pe) +{ + SHMEM_ERR_CHECK_INITIALIZED(); + SHMEM_ERR_CHECK_PE(pe); + SHMEM_ERR_CHECK_CTX(ctx); + SHMEM_ERR_CHECK_SYMMETRIC(sig_addr, sizeof(uint64_t)); + + shmem_internal_atomic(ctx, sig_addr, &signal, sizeof(uint64_t), + pe, SHM_INTERNAL_SUM, SHM_INTERNAL_UINT64); +} + +void SHMEM_FUNCTION_ATTRIBUTES +shmemx_signal_set(uint64_t *sig_addr, uint64_t signal, int pe) +{ + SHMEM_ERR_CHECK_INITIALIZED(); + SHMEM_ERR_CHECK_PE(pe); + SHMEM_ERR_CHECK_SYMMETRIC(sig_addr, sizeof(uint64_t)); + + shmem_internal_atomic_set(SHMEM_CTX_DEFAULT, (void *) sig_addr, &signal, + sizeof(uint64_t), pe, SHM_INTERNAL_UINT64); +} + +void SHMEM_FUNCTION_ATTRIBUTES +shmemx_ctx_signal_set(shmem_ctx_t ctx, uint64_t *sig_addr, uint64_t signal, int pe) +{ + SHMEM_ERR_CHECK_INITIALIZED(); + SHMEM_ERR_CHECK_PE(pe); + SHMEM_ERR_CHECK_CTX(ctx); + SHMEM_ERR_CHECK_SYMMETRIC(sig_addr, sizeof(uint64_t)); + + shmem_internal_atomic_set(ctx, (void *) sig_addr, &signal, + sizeof(uint64_t), pe, SHM_INTERNAL_UINT64); +} + void SHMEM_FUNCTION_ATTRIBUTES shmemx_getmem_ct(shmemx_ct_t ct, void *target, const void *source, size_t nelems, int pe) { diff --git a/test/shmemx/Makefile.am b/test/shmemx/Makefile.am index adb276e5..6d014216 100644 --- a/test/shmemx/Makefile.am +++ b/test/shmemx/Makefile.am @@ -22,6 +22,8 @@ if SHMEMX_TESTS check_PROGRAMS += \ perf_counter \ shmemx_team_node \ + signal_add \ + signal_set \ shmem_malloc_with_hints if HAVE_PTHREADS diff --git a/test/shmemx/signal_add.c b/test/shmemx/signal_add.c new file mode 100644 index 00000000..5e6c1353 --- /dev/null +++ b/test/shmemx/signal_add.c @@ -0,0 +1,83 @@ +/* + * Copyright (c) 2024 Intel Corporation. All rights reserved. + * This software is available to you under the BSD license below: + * + * Redistribution and use in source and binary forms, with or + * without modification, are permitted provided that the following + * conditions are met: + * + * - Redistributions of source code must retain the above + * copyright notice, this list of conditions and the following + * disclaimer. + * + * - Redistributions in binary form must reproduce the above + * copyright notice, this list of conditions and the following + * disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS + * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN + * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +/* + * Validate signal_add operation +*/ + +#include +#include +#include +#include + +#define MSG_SZ 10 + +int main(int argc, char *argv[]) +{ + long source[MSG_SZ]; + long *target; + int me, npes, i; + int errors = 0; + + static uint64_t sig_addr = 0; + + shmem_init(); + + me = shmem_my_pe(); + npes = shmem_n_pes(); + + for (i = 0; i < MSG_SZ; i++) + source[i] = i; + + target = (long *) shmem_calloc(MSG_SZ, sizeof(long)); + if (!target) { + fprintf(stderr, "Failed to allocate target pointer\n"); + shmem_global_exit(1); + } + + shmem_barrier_all(); + for (i = 0; i < npes; i++) { + shmem_long_put(target, source, MSG_SZ, i); + shmem_fence(); + shmemx_signal_add(&sig_addr, me, i); + } + + shmem_signal_wait_until(&sig_addr, SHMEM_CMP_EQ, (uint64_t) ((npes * (npes - 1)) / 2)); + + for (i = 0; i < MSG_SZ; i++) { + if (target[i] != source[i]) { + fprintf(stderr, "%10d: target[%d] = %ld not matching %ld with SHMEM_SIGNAL_ADD\n", + me, i, target[i], source[i]); + errors++; + } + } + + shmem_free(target); + shmem_finalize(); + + return errors; +} diff --git a/test/shmemx/signal_set.c b/test/shmemx/signal_set.c new file mode 100644 index 00000000..8ff7bf75 --- /dev/null +++ b/test/shmemx/signal_set.c @@ -0,0 +1,87 @@ +/* + * Copyright (c) 2024 Intel Corporation. All rights reserved. + * This software is available to you under the BSD license below: + * + * Redistribution and use in source and binary forms, with or + * without modification, are permitted provided that the following + * conditions are met: + * + * - Redistributions of source code must retain the above + * copyright notice, this list of conditions and the following + * disclaimer. + * + * - Redistributions in binary form must reproduce the above + * copyright notice, this list of conditions and the following + * disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS + * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN + * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +/* + * Validate signal_set operation +*/ + +#include +#include +#include +#include + +#define MSG_SZ 10 + +int main(int argc, char *argv[]) +{ + long source[MSG_SZ]; + long *target; + int me, npes, i, dest_pe; + int errors = 0; + + static uint64_t sig_addr = 0; + + shmem_init(); + + me = shmem_my_pe(); + npes = shmem_n_pes(); + dest_pe = (me + 1) % npes; + + for (i = 0; i < MSG_SZ; i++) + source[i] = me + i; + + target = (long *) shmem_calloc(MSG_SZ, sizeof(long)); + if (!target) { + fprintf(stderr, "Failed to allocate target pointer\n"); + shmem_global_exit(1); + } + + shmem_barrier_all(); + if (me == 0) { + shmem_long_put_nbi(target, source, MSG_SZ, dest_pe); + shmemx_signal_set(SHMEM_CTX_DEFAULT, &sig_addr, me + 1, dest_pe); + shmem_signal_wait_until(&sig_addr, SHMEM_CMP_EQ, npes); + } else { + shmem_signal_wait_until(&sig_addr, SHMEM_CMP_EQ, me); + shmem_long_put_nbi(target, source, MSG_SZ, dest_pe); + shmemx_signal_set(SHMEM_CTX_DEFAULT, &sig_addr, me + 1, dest_pe); + } + shmem_barrier_all(); + + for (i = 0; i < MSG_SZ; i++) { + if (target[i] != (long)(((me + npes - 1) % npes) + i)) { + fprintf(stderr, "%10d: target[%d] = %ld not matching %ld with SHMEM_SIGNAL_SET\n", + me, i, target[i], (long)(((me + npes - 1) % npes) + i)); + errors++; + } + } + + shmem_free(target); + shmem_finalize(); + + return errors; +}