From d3c78dfa6933fd30471a75a33c33a24d35e75972 Mon Sep 17 00:00:00 2001 From: Joseph Schuchart Date: Fri, 24 Oct 2025 13:44:14 -0400 Subject: [PATCH 01/19] First draft and TODOs for notified comm Signed-off-by: Joseph Schuchart --- ompi/mca/osc/osc.h | 2 ++ ompi/mca/osc/sm/osc_sm.h | 4 ++++ ompi/mca/osc/sm/osc_sm_comm.c | 35 ++++++++++++++++++++++++++++++ ompi/mca/osc/sm/osc_sm_component.c | 2 ++ 4 files changed, 43 insertions(+) diff --git a/ompi/mca/osc/osc.h b/ompi/mca/osc/osc.h index 39063ef0914..c8f77404c1c 100644 --- a/ompi/mca/osc/osc.h +++ b/ompi/mca/osc/osc.h @@ -370,6 +370,8 @@ typedef int (*ompi_osc_base_module_flush_local_all_fn_t)(struct ompi_win_t *win) * free to create a structure that inherits this one for use as the * module structure. */ + + // TODO: extend the struct and add pointers to put/get_with_notify functions struct ompi_osc_base_module_4_0_0_t { ompi_osc_base_module_win_shared_query_fn_t osc_win_shared_query; diff --git a/ompi/mca/osc/sm/osc_sm.h b/ompi/mca/osc/sm/osc_sm.h index 363d3429a63..23afacd7d49 100644 --- a/ompi/mca/osc/sm/osc_sm.h +++ b/ompi/mca/osc/sm/osc_sm.h @@ -79,6 +79,8 @@ struct ompi_osc_sm_module_t { size_t *sizes; void **bases; ptrdiff_t *disp_units; + uint64_t **notify_counters; + ompi_group_t *start_group; ompi_group_t *post_group; @@ -105,6 +107,8 @@ int ompi_osc_sm_detach(struct ompi_win_t *win, const void *base); int ompi_osc_sm_free(struct ompi_win_t *win); +// TODO: add put/get_with_notify prototypes + int ompi_osc_sm_put(const void *origin_addr, size_t origin_count, struct ompi_datatype_t *origin_dt, diff --git a/ompi/mca/osc/sm/osc_sm_comm.c b/ompi/mca/osc/sm/osc_sm_comm.c index bbd5873bf96..f9bae370870 100644 --- a/ompi/mca/osc/sm/osc_sm_comm.c +++ b/ompi/mca/osc/sm/osc_sm_comm.c @@ -267,6 +267,41 @@ ompi_osc_sm_get(void *origin_addr, } +int +ompi_osc_sm_get_with_notify(void *origin_addr, + size_t origin_count, + struct ompi_datatype_t *origin_dt, + int target, + ptrdiff_t target_disp, + size_t target_count, + struct ompi_datatype_t *target_dt, + int notify, + struct ompi_win_t *win) +{ + int ret; + ompi_osc_sm_module_t *module = + (ompi_osc_sm_module_t*) win->w_osc_module; + void *remote_address; + + OPAL_OUTPUT_VERBOSE((50, ompi_osc_base_framework.framework_output, + "get: 0x%lx, %zu, %s, %d, %d, %zu, %s, 0x%lx", + (unsigned long) origin_addr, origin_count, + origin_dt->name, target, (int) target_disp, + target_count, target_dt->name, + (unsigned long) win)); + + remote_address = ((char*) (module->bases[target])) + module->disp_units[target] * target_disp; + + ret = ompi_datatype_sndrcv(remote_address, target_count, target_dt, + origin_addr, origin_count, origin_dt); + // TODO: do the same for put_with_notify + opal_atomic_rmb(); + opal_atomic_add(&module->notify_counters[target][notify], 1); + + return ret; +} + + int ompi_osc_sm_accumulate(const void *origin_addr, size_t origin_count, diff --git a/ompi/mca/osc/sm/osc_sm_component.c b/ompi/mca/osc/sm/osc_sm_component.c index ad2b3cae25a..1ad9a48cfd2 100644 --- a/ompi/mca/osc/sm/osc_sm_component.c +++ b/ompi/mca/osc/sm/osc_sm_component.c @@ -70,6 +70,8 @@ ompi_osc_sm_component_t mca_osc_sm_component = { MCA_BASE_COMPONENT_INIT(ompi, osc, sm) +// TODO: extend the struct and add pointers to put/get_with_notify functions +// TODO: extend it to rput/rget_with_notify as well ompi_osc_sm_module_t ompi_osc_sm_module_template = { { .osc_win_shared_query = ompi_osc_sm_shared_query, From 152c28ca7c6e47373770e5ef0ce2fea4a27ba9ab Mon Sep 17 00:00:00 2001 From: Joseph Antony Date: Tue, 4 Nov 2025 04:42:00 +0000 Subject: [PATCH 02/19] osc/sm: Add notification support for put/get operations This commit adds notification support to the OSC SM component by implementing the put_with_notify, get_with_notify, rput_with_notify, and rget_with_notify functions. These functions perform the same operations as their non-notify counterparts but also increment notification counters after the data transfer completes. The changes include: - Added function pointer types for notify variants in osc.h - Added function prototypes in osc_sm.h - Implemented the notify functions in osc_sm_comm.c - Updated the module template to register the new functions - Removed TODO comments that have been addressed Signed-off-by: Joseph Antony --- ompi/mca/osc/osc.h | 44 +++++++++- ompi/mca/osc/sm/osc_sm.h | 42 ++++++++++ ompi/mca/osc/sm/osc_sm_comm.c | 130 ++++++++++++++++++++++++++++- ompi/mca/osc/sm/osc_sm_component.c | 6 +- 4 files changed, 217 insertions(+), 5 deletions(-) diff --git a/ompi/mca/osc/osc.h b/ompi/mca/osc/osc.h index c8f77404c1c..bd05a6f11b7 100644 --- a/ompi/mca/osc/osc.h +++ b/ompi/mca/osc/osc.h @@ -216,6 +216,15 @@ typedef int (*ompi_osc_base_module_put_fn_t)(const void *origin_addr, struct ompi_datatype_t *target_dt, struct ompi_win_t *win); +typedef int (*ompi_osc_base_module_put_with_notify_fn_t)(const void *origin_addr, + size_t origin_count, + struct ompi_datatype_t *origin_dt, + int target, + ptrdiff_t target_disp, + size_t target_count, + struct ompi_datatype_t *target_dt, + int notify, + struct ompi_win_t *win); typedef int (*ompi_osc_base_module_get_fn_t)(void *origin_addr, size_t origin_count, @@ -226,6 +235,15 @@ typedef int (*ompi_osc_base_module_get_fn_t)(void *origin_addr, struct ompi_datatype_t *target_dt, struct ompi_win_t *win); +typedef int (*ompi_osc_base_module_get_with_notify_fn_t)(void *origin_addr, + size_t origin_count, + struct ompi_datatype_t *origin_dt, + int target, + ptrdiff_t target_disp, + size_t target_count, + struct ompi_datatype_t *target_dt, + int notify, + struct ompi_win_t *win); typedef int (*ompi_osc_base_module_accumulate_fn_t)(const void *origin_addr, size_t origin_count, @@ -276,6 +294,17 @@ typedef int (*ompi_osc_base_module_rput_fn_t)(const void *origin_addr, struct ompi_win_t *win, struct ompi_request_t **request); +typedef int (*ompi_osc_base_module_rput_with_notify_fn_t)(const void *origin_addr, + size_t origin_count, + struct ompi_datatype_t *origin_dt, + int target, + ptrdiff_t target_disp, + size_t target_count, + struct ompi_datatype_t *target_dt, + int notify, + struct ompi_win_t *win, + struct ompi_request_t **request); + typedef int (*ompi_osc_base_module_rget_fn_t)(void *origin_addr, size_t origin_count, struct ompi_datatype_t *origin_dt, @@ -286,6 +315,16 @@ typedef int (*ompi_osc_base_module_rget_fn_t)(void *origin_addr, struct ompi_win_t *win, struct ompi_request_t **request); +typedef int (*ompi_osc_base_module_rget_with_notify_fn_t)(void *origin_addr, + size_t origin_count, + struct ompi_datatype_t *origin_dt, + int target, + ptrdiff_t target_disp, + size_t target_count, + struct ompi_datatype_t *target_dt, + int notify, + struct ompi_win_t *win, + struct ompi_request_t **request); typedef int (*ompi_osc_base_module_raccumulate_fn_t)(const void *origin_addr, size_t origin_count, @@ -371,7 +410,6 @@ typedef int (*ompi_osc_base_module_flush_local_all_fn_t)(struct ompi_win_t *win) * module structure. */ - // TODO: extend the struct and add pointers to put/get_with_notify functions struct ompi_osc_base_module_4_0_0_t { ompi_osc_base_module_win_shared_query_fn_t osc_win_shared_query; @@ -380,14 +418,18 @@ struct ompi_osc_base_module_4_0_0_t { ompi_osc_base_module_free_fn_t osc_free; ompi_osc_base_module_put_fn_t osc_put; + ompi_osc_base_module_put_with_notify_fn_t osc_put_with_notify; ompi_osc_base_module_get_fn_t osc_get; + ompi_osc_base_module_get_with_notify_fn_t osc_get_with_notify; ompi_osc_base_module_accumulate_fn_t osc_accumulate; ompi_osc_base_module_compare_and_swap_fn_t osc_compare_and_swap; ompi_osc_base_module_fetch_and_op_fn_t osc_fetch_and_op; ompi_osc_base_module_get_accumulate_fn_t osc_get_accumulate; ompi_osc_base_module_rput_fn_t osc_rput; + ompi_osc_base_module_rput_with_notify_fn_t osc_rput_with_notify; ompi_osc_base_module_rget_fn_t osc_rget; + ompi_osc_base_module_rget_with_notify_fn_t osc_rget_with_notify; ompi_osc_base_module_raccumulate_fn_t osc_raccumulate; ompi_osc_base_module_rget_accumulate_fn_t osc_rget_accumulate; diff --git a/ompi/mca/osc/sm/osc_sm.h b/ompi/mca/osc/sm/osc_sm.h index 23afacd7d49..b7d6dadfd49 100644 --- a/ompi/mca/osc/sm/osc_sm.h +++ b/ompi/mca/osc/sm/osc_sm.h @@ -118,6 +118,16 @@ int ompi_osc_sm_put(const void *origin_addr, struct ompi_datatype_t *target_dt, struct ompi_win_t *win); + int ompi_osc_sm_put_with_notify(const void *origin_addr, + size_t origin_count, + struct ompi_datatype_t *origin_dt, + int target, + ptrdiff_t target_disp, + size_t target_count, + struct ompi_datatype_t *target_dt, + int notify, + struct ompi_win_t *win); + int ompi_osc_sm_get(void *origin_addr, size_t origin_count, struct ompi_datatype_t *origin_dt, @@ -127,6 +137,16 @@ int ompi_osc_sm_get(void *origin_addr, struct ompi_datatype_t *target_dt, struct ompi_win_t *win); +int ompi_osc_sm_get_with_notify(void *origin_addr, + size_t origin_count, + struct ompi_datatype_t *origin_dt, + int target, + ptrdiff_t target_disp, + size_t target_count, + struct ompi_datatype_t *target_dt, + int notify, + struct ompi_win_t *win); + int ompi_osc_sm_accumulate(const void *origin_addr, size_t origin_count, struct ompi_datatype_t *origin_dt, @@ -176,6 +196,17 @@ int ompi_osc_sm_rput(const void *origin_addr, struct ompi_win_t *win, struct ompi_request_t **request); +int ompi_osc_sm_rput_with_notify(const void *origin_addr, + size_t origin_count, + struct ompi_datatype_t *origin_dt, + int target, + ptrdiff_t target_disp, + size_t target_count, + struct ompi_datatype_t *target_dt, + int notify, + struct ompi_win_t *win, + struct ompi_request_t **request); + int ompi_osc_sm_rget(void *origin_addr, size_t origin_count, struct ompi_datatype_t *origin_dt, @@ -186,6 +217,17 @@ int ompi_osc_sm_rget(void *origin_addr, struct ompi_win_t *win, struct ompi_request_t **request); +int ompi_osc_sm_rget_with_notify(void *origin_addr, + size_t origin_count, + struct ompi_datatype_t *origin_dt, + int target, + ptrdiff_t target_disp, + size_t target_count, + struct ompi_datatype_t *target_dt, + int notify, + struct ompi_win_t *win, + struct ompi_request_t **request); + int ompi_osc_sm_raccumulate(const void *origin_addr, size_t origin_count, struct ompi_datatype_t *origin_dt, diff --git a/ompi/mca/osc/sm/osc_sm_comm.c b/ompi/mca/osc/sm/osc_sm_comm.c index f9bae370870..a2e3a5cce1f 100644 --- a/ompi/mca/osc/sm/osc_sm_comm.c +++ b/ompi/mca/osc/sm/osc_sm_comm.c @@ -59,6 +59,49 @@ ompi_osc_sm_rput(const void *origin_addr, return OMPI_SUCCESS; } +int +ompi_osc_sm_rput_with_notify(const void *origin_addr, + size_t origin_count, + struct ompi_datatype_t *origin_dt, + int target, + ptrdiff_t target_disp, + size_t target_count, + struct ompi_datatype_t *target_dt, + int notify, + struct ompi_win_t *win, + struct ompi_request_t **ompi_req) +{ + int ret; + ompi_osc_sm_module_t *module = + (ompi_osc_sm_module_t*) win->w_osc_module; + void *remote_address; + + OPAL_OUTPUT_VERBOSE((50, ompi_osc_base_framework.framework_output, + "rput_notify: 0x%lx, %zu, %s, %d, %d, %zu, %s, %d, 0x%lx", + (unsigned long) origin_addr, origin_count, + origin_dt->name, target, (int) target_disp, + target_count, target_dt->name, + notify, + (unsigned long) win)); + + remote_address = ((char*) (module->bases[target])) + module->disp_units[target] * target_disp; + + ret = ompi_datatype_sndrcv((void *)origin_addr, origin_count, origin_dt, + remote_address, target_count, target_dt); + if (OMPI_SUCCESS != ret) { + return ret; + } + + /* the only valid field of RMA request status is the MPI_ERROR field. + * ompi_request_empty has status MPI_SUCCESS and indicates the request is + * complete. */ + *ompi_req = &ompi_request_empty; + + opal_atomic_wmb(); + opal_atomic_add(&module->notify_counters[target][notify], 1); + + return OMPI_SUCCESS; +} int ompi_osc_sm_rget(void *origin_addr, @@ -99,6 +142,49 @@ ompi_osc_sm_rget(void *origin_addr, return OMPI_SUCCESS; } +int +ompi_osc_sm_rget_with_notify(void *origin_addr, + size_t origin_count, + struct ompi_datatype_t *origin_dt, + int target, + ptrdiff_t target_disp, + size_t target_count, + struct ompi_datatype_t *target_dt, + int notify, + struct ompi_win_t *win, + struct ompi_request_t **ompi_req) +{ + int ret; + ompi_osc_sm_module_t *module = + (ompi_osc_sm_module_t*) win->w_osc_module; + void *remote_address; + + OPAL_OUTPUT_VERBOSE((50, ompi_osc_base_framework.framework_output, + "rget_notify: 0x%lx, %zu, %s, %d, %d, %zu, %s, %d, 0x%lx", + (unsigned long) origin_addr, origin_count, + origin_dt->name, target, (int) target_disp, + target_count, target_dt->name, + notify, + (unsigned long) win)); + + remote_address = ((char*) (module->bases[target])) + module->disp_units[target] * target_disp; + + ret = ompi_datatype_sndrcv(remote_address, target_count, target_dt, + origin_addr, origin_count, origin_dt); + if (OMPI_SUCCESS != ret) { + return ret; + } + + /* the only valid field of RMA request status is the MPI_ERROR field. + * ompi_request_empty has status MPI_SUCCESS and indicates the request is + * complete. */ + *ompi_req = &ompi_request_empty; + + opal_atomic_rmb(); + opal_atomic_add(&module->notify_counters[target][notify], 1); + + return OMPI_SUCCESS; +} int ompi_osc_sm_raccumulate(const void *origin_addr, @@ -236,6 +322,44 @@ ompi_osc_sm_put(const void *origin_addr, } +int +ompi_osc_sm_put_with_notify(const void *origin_addr, + size_t origin_count, + struct ompi_datatype_t *origin_dt, + int target, + ptrdiff_t target_disp, + size_t target_count, + struct ompi_datatype_t *target_dt, + int notify, + struct ompi_win_t *win) +{ +int ret; +ompi_osc_sm_module_t *module = + (ompi_osc_sm_module_t*) win->w_osc_module; +void *remote_address; + +OPAL_OUTPUT_VERBOSE((50, ompi_osc_base_framework.framework_output, + "put_notify: 0x%lx, %zu, %s, %d, %d, %zu, %s, %d, 0x%lx", + (unsigned long) origin_addr, origin_count, + origin_dt->name, target, (int) target_disp, + target_count, target_dt->name, + notify, + (unsigned long) win)); + +remote_address = ((char*) (module->bases[target])) + module->disp_units[target] * target_disp; + +ret = ompi_datatype_sndrcv((void *)origin_addr, origin_count, origin_dt, + remote_address, target_count, target_dt); +if (OMPI_SUCCESS != ret) { + return ret; +} + +opal_atomic_wmb(); +opal_atomic_add(&module->notify_counters[target][notify], 1); + +return ret; +} + int ompi_osc_sm_get(void *origin_addr, size_t origin_count, @@ -294,7 +418,9 @@ ompi_osc_sm_get_with_notify(void *origin_addr, ret = ompi_datatype_sndrcv(remote_address, target_count, target_dt, origin_addr, origin_count, origin_dt); - // TODO: do the same for put_with_notify + if (OMPI_SUCCESS != ret) { + return ret; + } opal_atomic_rmb(); opal_atomic_add(&module->notify_counters[target][notify], 1); @@ -473,4 +599,4 @@ ompi_osc_sm_fetch_and_op(const void *origin_addr, opal_atomic_unlock(&module->node_states[target].accumulate_lock); return OMPI_SUCCESS;; -} +} \ No newline at end of file diff --git a/ompi/mca/osc/sm/osc_sm_component.c b/ompi/mca/osc/sm/osc_sm_component.c index 1ad9a48cfd2..11f0ccc2e47 100644 --- a/ompi/mca/osc/sm/osc_sm_component.c +++ b/ompi/mca/osc/sm/osc_sm_component.c @@ -70,8 +70,6 @@ ompi_osc_sm_component_t mca_osc_sm_component = { MCA_BASE_COMPONENT_INIT(ompi, osc, sm) -// TODO: extend the struct and add pointers to put/get_with_notify functions -// TODO: extend it to rput/rget_with_notify as well ompi_osc_sm_module_t ompi_osc_sm_module_template = { { .osc_win_shared_query = ompi_osc_sm_shared_query, @@ -81,14 +79,18 @@ ompi_osc_sm_module_t ompi_osc_sm_module_template = { .osc_free = ompi_osc_sm_free, .osc_put = ompi_osc_sm_put, + .osc_put_with_notify = ompi_osc_sm_put_with_notify, .osc_get = ompi_osc_sm_get, + .osc_get_with_notify = ompi_osc_sm_get_with_notify, .osc_accumulate = ompi_osc_sm_accumulate, .osc_compare_and_swap = ompi_osc_sm_compare_and_swap, .osc_fetch_and_op = ompi_osc_sm_fetch_and_op, .osc_get_accumulate = ompi_osc_sm_get_accumulate, .osc_rput = ompi_osc_sm_rput, + .osc_rput_with_notify = ompi_osc_sm_rput_with_notify, .osc_rget = ompi_osc_sm_rget, + .osc_rget_with_notify = ompi_osc_sm_rget_with_notify, .osc_raccumulate = ompi_osc_sm_raccumulate, .osc_rget_accumulate = ompi_osc_sm_rget_accumulate, From f1e07c8db42207bd888a89fcd531f1962cdc81a8 Mon Sep 17 00:00:00 2001 From: Joseph Antony Date: Tue, 4 Nov 2025 17:03:59 +0000 Subject: [PATCH 03/19] osc/sm: Nit picking edits Signed-off-by: Joseph Antony --- ompi/mca/osc/sm/osc_sm_comm.c | 52 +++++++++++++++++------------------ 1 file changed, 26 insertions(+), 26 deletions(-) diff --git a/ompi/mca/osc/sm/osc_sm_comm.c b/ompi/mca/osc/sm/osc_sm_comm.c index a2e3a5cce1f..ba19d8c08cf 100644 --- a/ompi/mca/osc/sm/osc_sm_comm.c +++ b/ompi/mca/osc/sm/osc_sm_comm.c @@ -333,31 +333,31 @@ ompi_osc_sm_put_with_notify(const void *origin_addr, int notify, struct ompi_win_t *win) { -int ret; -ompi_osc_sm_module_t *module = - (ompi_osc_sm_module_t*) win->w_osc_module; -void *remote_address; - -OPAL_OUTPUT_VERBOSE((50, ompi_osc_base_framework.framework_output, - "put_notify: 0x%lx, %zu, %s, %d, %d, %zu, %s, %d, 0x%lx", - (unsigned long) origin_addr, origin_count, - origin_dt->name, target, (int) target_disp, - target_count, target_dt->name, - notify, - (unsigned long) win)); - -remote_address = ((char*) (module->bases[target])) + module->disp_units[target] * target_disp; - -ret = ompi_datatype_sndrcv((void *)origin_addr, origin_count, origin_dt, - remote_address, target_count, target_dt); -if (OMPI_SUCCESS != ret) { - return ret; -} + int ret; + ompi_osc_sm_module_t *module = + (ompi_osc_sm_module_t*) win->w_osc_module; + void *remote_address; + + OPAL_OUTPUT_VERBOSE((50, ompi_osc_base_framework.framework_output, + "put_notify: 0x%lx, %zu, %s, %d, %d, %zu, %s, %d, 0x%lx", + (unsigned long) origin_addr, origin_count, + origin_dt->name, target, (int) target_disp, + target_count, target_dt->name, + notify, + (unsigned long) win)); + + remote_address = ((char*) (module->bases[target])) + module->disp_units[target] * target_disp; + + ret = ompi_datatype_sndrcv((void *)origin_addr, origin_count, origin_dt, + remote_address, target_count, target_dt); + if (OMPI_SUCCESS != ret) { + return ret; + } -opal_atomic_wmb(); -opal_atomic_add(&module->notify_counters[target][notify], 1); + opal_atomic_wmb(); + opal_atomic_add(&module->notify_counters[target][notify], 1); -return ret; + return ret; } int @@ -419,7 +419,7 @@ ompi_osc_sm_get_with_notify(void *origin_addr, ret = ompi_datatype_sndrcv(remote_address, target_count, target_dt, origin_addr, origin_count, origin_dt); if (OMPI_SUCCESS != ret) { - return ret; + return ret; } opal_atomic_rmb(); opal_atomic_add(&module->notify_counters[target][notify], 1); @@ -598,5 +598,5 @@ ompi_osc_sm_fetch_and_op(const void *origin_addr, done: opal_atomic_unlock(&module->node_states[target].accumulate_lock); - return OMPI_SUCCESS;; -} \ No newline at end of file + return OMPI_SUCCESS; +} From 06d61ed8d36dded674f9789928a831ae954cdaaa Mon Sep 17 00:00:00 2001 From: Joseph Antony Date: Wed, 19 Nov 2025 12:29:14 -0500 Subject: [PATCH 04/19] Public APIs for: put_with_notify get_with_notify Signed-off-by: Joseph Antony --- ompi/include/mpi.h.in | 29 ++++++++ ompi/include/mpif-values.py | 1 + ompi/mca/osc/osc.h | 16 ++--- ompi/mca/osc/sm/osc_sm.h | 10 +-- ompi/mca/osc/sm/osc_sm_comm.c | 8 +-- ompi/mca/osc/sm/osc_sm_component.c | 8 +-- ompi/mpi/bindings/ompi_bindings/consts.py | 1 + ompi/mpi/c/Makefile.am | 2 + ompi/mpi/c/get_notify.c.in | 77 ++++++++++++++++++++++ ompi/mpi/c/put_notify.c.in | 80 +++++++++++++++++++++++ ompi/runtime/ompi_spc.c | 2 + ompi/runtime/ompi_spc.h | 2 + 12 files changed, 215 insertions(+), 21 deletions(-) create mode 100644 ompi/mpi/c/get_notify.c.in create mode 100644 ompi/mpi/c/put_notify.c.in diff --git a/ompi/include/mpi.h.in b/ompi/include/mpi.h.in index 43e9006257e..1e5d56d9f91 100644 --- a/ompi/include/mpi.h.in +++ b/ompi/include/mpi.h.in @@ -767,6 +767,7 @@ enum { #define MPI_ERR_ERRHANDLER 80 #define MPI_T_ERR_NOT_ACCESSIBLE 81 #define MPI_T_ERR_NOT_SUPPORTED 82 +#define MPI_ERR_NOTIFY_IDX 83 /* Per MPI-3 p349 47, MPI_ERR_LASTCODE must be >= the last predefined MPI_ERR_ code. Set the last code to allow some room for adding @@ -1921,6 +1922,14 @@ OMPI_DECLSPEC int MPI_Get_c(void *origin_addr, MPI_Count origin_count, MPI_Datatype origin_datatype, int target_rank, MPI_Aint target_disp, MPI_Count target_count, MPI_Datatype target_datatype, MPI_Win win); +OMPI_DECLSPEC int MPI_Get_notify(void *origin_addr, int origin_count, + MPI_Datatype origin_datatype, int target_rank, + MPI_Aint target_disp, int target_count, + MPI_Datatype target_datatype, int notification_idx, MPI_Win win); +OMPI_DECLSPEC int MPI_Get_notify_c(void *origin_addr, MPI_Count origin_count, + MPI_Datatype origin_datatype, int target_rank, + MPI_Aint target_disp, MPI_Count target_count, + MPI_Datatype target_datatype, int notification_idx, MPI_Win win); OMPI_DECLSPEC int MPI_Get_accumulate(const void *origin_addr, int origin_count, MPI_Datatype origin_datatype, void *result_addr, int result_count, MPI_Datatype result_datatype, int target_rank, MPI_Aint target_disp, int target_count, @@ -2184,6 +2193,12 @@ OMPI_DECLSPEC int MPI_Put(const void *origin_addr, int origin_count, MPI_Dataty OMPI_DECLSPEC int MPI_Put_c(const void *origin_addr, MPI_Count origin_count, MPI_Datatype origin_datatype, int target_rank, MPI_Aint target_disp, MPI_Count target_count, MPI_Datatype target_datatype, MPI_Win win); +OMPI_DECLSPEC int MPI_Put_notify(const void *origin_addr, int origin_count, MPI_Datatype origin_datatype, + int target_rank, MPI_Aint target_disp, int target_count, + MPI_Datatype target_datatype, int notification_idx, MPI_Win win); +OMPI_DECLSPEC int MPI_Put_notify_c(const void *origin_addr, MPI_Count origin_count, MPI_Datatype origin_datatype, + int target_rank, MPI_Aint target_disp, MPI_Count target_count, + MPI_Datatype target_datatype, int notification_idx, MPI_Win win); OMPI_DECLSPEC int MPI_Query_thread(int *provided); OMPI_DECLSPEC int MPI_Raccumulate(const void *origin_addr, int origin_count, MPI_Datatype origin_datatype, int target_rank, MPI_Aint target_disp, int target_count, @@ -3095,6 +3110,14 @@ OMPI_DECLSPEC int PMPI_Get_c(void *origin_addr, MPI_Count origin_count, MPI_Datatype origin_datatype, int target_rank, MPI_Aint target_disp, MPI_Count target_count, MPI_Datatype target_datatype, MPI_Win win); +OMPI_DECLSPEC int PMPI_Get_notify(void *origin_addr, int origin_count, + MPI_Datatype origin_datatype, int target_rank, + MPI_Aint target_disp, int target_count, + MPI_Datatype target_datatype, int notification_idx, MPI_Win win); +OMPI_DECLSPEC int PMPI_Get_notify_c(void *origin_addr, MPI_Count origin_count, + MPI_Datatype origin_datatype, int target_rank, + MPI_Aint target_disp, MPI_Count target_count, + MPI_Datatype target_datatype, int notification_idx, MPI_Win win); OMPI_DECLSPEC int PMPI_Get_accumulate(const void *origin_addr, int origin_count, MPI_Datatype origin_datatype, void *result_addr, int result_count, MPI_Datatype result_datatype, int target_rank, MPI_Aint target_disp, int target_count, @@ -3358,6 +3381,12 @@ OMPI_DECLSPEC int PMPI_Put(const void *origin_addr, int origin_count, MPI_Datat OMPI_DECLSPEC int PMPI_Put_c(const void *origin_addr, MPI_Count origin_count, MPI_Datatype origin_datatype, int target_rank, MPI_Aint target_disp, MPI_Count target_count, MPI_Datatype target_datatype, MPI_Win win); +OMPI_DECLSPEC int PMPI_Put_notify(const void *origin_addr, int origin_count, MPI_Datatype origin_datatype, + int target_rank, MPI_Aint target_disp, int target_count, + MPI_Datatype target_datatype, int notification_idx, MPI_Win win); +OMPI_DECLSPEC int PMPI_Put_notify_c(const void *origin_addr, MPI_Count origin_count, MPI_Datatype origin_datatype, + int target_rank, MPI_Aint target_disp, MPI_Count target_count, + MPI_Datatype target_datatype, int notification_idx, MPI_Win win); OMPI_DECLSPEC int PMPI_Query_thread(int *provided); OMPI_DECLSPEC int PMPI_Raccumulate(const void *origin_addr, int origin_count, MPI_Datatype origin_datatype, int target_rank, MPI_Aint target_disp, int target_count, diff --git a/ompi/include/mpif-values.py b/ompi/include/mpif-values.py index 7cd50d7e9e4..af55b87baee 100755 --- a/ompi/include/mpif-values.py +++ b/ompi/include/mpif-values.py @@ -304,6 +304,7 @@ 'MPI_ERR_ERRHANDLER': 80, 'MPI_T_ERR_NOT_ACCESSIBLE': 81, 'MPI_T_ERR_NOT_SUPPORTED': 82, + 'MPI_ERR_NOTIFY_IDX': 83, 'MPI_ERR_LASTCODE': 92, 'MPI_IDENT': 0, 'MPI_CONGRUENT': 1, diff --git a/ompi/mca/osc/osc.h b/ompi/mca/osc/osc.h index bd05a6f11b7..83c7af9305e 100644 --- a/ompi/mca/osc/osc.h +++ b/ompi/mca/osc/osc.h @@ -216,7 +216,7 @@ typedef int (*ompi_osc_base_module_put_fn_t)(const void *origin_addr, struct ompi_datatype_t *target_dt, struct ompi_win_t *win); -typedef int (*ompi_osc_base_module_put_with_notify_fn_t)(const void *origin_addr, +typedef int (*ompi_osc_base_module_put_notify_fn_t)(const void *origin_addr, size_t origin_count, struct ompi_datatype_t *origin_dt, int target, @@ -235,7 +235,7 @@ typedef int (*ompi_osc_base_module_get_fn_t)(void *origin_addr, struct ompi_datatype_t *target_dt, struct ompi_win_t *win); -typedef int (*ompi_osc_base_module_get_with_notify_fn_t)(void *origin_addr, +typedef int (*ompi_osc_base_module_get_notify_fn_t)(void *origin_addr, size_t origin_count, struct ompi_datatype_t *origin_dt, int target, @@ -294,7 +294,7 @@ typedef int (*ompi_osc_base_module_rput_fn_t)(const void *origin_addr, struct ompi_win_t *win, struct ompi_request_t **request); -typedef int (*ompi_osc_base_module_rput_with_notify_fn_t)(const void *origin_addr, +typedef int (*ompi_osc_base_module_rput_notify_fn_t)(const void *origin_addr, size_t origin_count, struct ompi_datatype_t *origin_dt, int target, @@ -315,7 +315,7 @@ typedef int (*ompi_osc_base_module_rget_fn_t)(void *origin_addr, struct ompi_win_t *win, struct ompi_request_t **request); -typedef int (*ompi_osc_base_module_rget_with_notify_fn_t)(void *origin_addr, +typedef int (*ompi_osc_base_module_rget_notify_fn_t)(void *origin_addr, size_t origin_count, struct ompi_datatype_t *origin_dt, int target, @@ -418,18 +418,18 @@ struct ompi_osc_base_module_4_0_0_t { ompi_osc_base_module_free_fn_t osc_free; ompi_osc_base_module_put_fn_t osc_put; - ompi_osc_base_module_put_with_notify_fn_t osc_put_with_notify; + ompi_osc_base_module_put_notify_fn_t osc_put_notify; ompi_osc_base_module_get_fn_t osc_get; - ompi_osc_base_module_get_with_notify_fn_t osc_get_with_notify; + ompi_osc_base_module_get_notify_fn_t osc_get_notify; ompi_osc_base_module_accumulate_fn_t osc_accumulate; ompi_osc_base_module_compare_and_swap_fn_t osc_compare_and_swap; ompi_osc_base_module_fetch_and_op_fn_t osc_fetch_and_op; ompi_osc_base_module_get_accumulate_fn_t osc_get_accumulate; ompi_osc_base_module_rput_fn_t osc_rput; - ompi_osc_base_module_rput_with_notify_fn_t osc_rput_with_notify; + ompi_osc_base_module_rput_notify_fn_t osc_rput_notify; ompi_osc_base_module_rget_fn_t osc_rget; - ompi_osc_base_module_rget_with_notify_fn_t osc_rget_with_notify; + ompi_osc_base_module_rget_notify_fn_t osc_rget_notify; ompi_osc_base_module_raccumulate_fn_t osc_raccumulate; ompi_osc_base_module_rget_accumulate_fn_t osc_rget_accumulate; diff --git a/ompi/mca/osc/sm/osc_sm.h b/ompi/mca/osc/sm/osc_sm.h index b7d6dadfd49..200ec8b3de8 100644 --- a/ompi/mca/osc/sm/osc_sm.h +++ b/ompi/mca/osc/sm/osc_sm.h @@ -107,7 +107,7 @@ int ompi_osc_sm_detach(struct ompi_win_t *win, const void *base); int ompi_osc_sm_free(struct ompi_win_t *win); -// TODO: add put/get_with_notify prototypes +// TODO: add put/get_notify prototypes int ompi_osc_sm_put(const void *origin_addr, size_t origin_count, @@ -118,7 +118,7 @@ int ompi_osc_sm_put(const void *origin_addr, struct ompi_datatype_t *target_dt, struct ompi_win_t *win); - int ompi_osc_sm_put_with_notify(const void *origin_addr, + int ompi_osc_sm_put_notify(const void *origin_addr, size_t origin_count, struct ompi_datatype_t *origin_dt, int target, @@ -137,7 +137,7 @@ int ompi_osc_sm_get(void *origin_addr, struct ompi_datatype_t *target_dt, struct ompi_win_t *win); -int ompi_osc_sm_get_with_notify(void *origin_addr, +int ompi_osc_sm_get_notify(void *origin_addr, size_t origin_count, struct ompi_datatype_t *origin_dt, int target, @@ -196,7 +196,7 @@ int ompi_osc_sm_rput(const void *origin_addr, struct ompi_win_t *win, struct ompi_request_t **request); -int ompi_osc_sm_rput_with_notify(const void *origin_addr, +int ompi_osc_sm_rput_notify(const void *origin_addr, size_t origin_count, struct ompi_datatype_t *origin_dt, int target, @@ -217,7 +217,7 @@ int ompi_osc_sm_rget(void *origin_addr, struct ompi_win_t *win, struct ompi_request_t **request); -int ompi_osc_sm_rget_with_notify(void *origin_addr, +int ompi_osc_sm_rget_notify(void *origin_addr, size_t origin_count, struct ompi_datatype_t *origin_dt, int target, diff --git a/ompi/mca/osc/sm/osc_sm_comm.c b/ompi/mca/osc/sm/osc_sm_comm.c index ba19d8c08cf..4391a375ebc 100644 --- a/ompi/mca/osc/sm/osc_sm_comm.c +++ b/ompi/mca/osc/sm/osc_sm_comm.c @@ -60,7 +60,7 @@ ompi_osc_sm_rput(const void *origin_addr, } int -ompi_osc_sm_rput_with_notify(const void *origin_addr, +ompi_osc_sm_rput_notify(const void *origin_addr, size_t origin_count, struct ompi_datatype_t *origin_dt, int target, @@ -143,7 +143,7 @@ ompi_osc_sm_rget(void *origin_addr, } int -ompi_osc_sm_rget_with_notify(void *origin_addr, +ompi_osc_sm_rget_notify(void *origin_addr, size_t origin_count, struct ompi_datatype_t *origin_dt, int target, @@ -323,7 +323,7 @@ ompi_osc_sm_put(const void *origin_addr, int -ompi_osc_sm_put_with_notify(const void *origin_addr, +ompi_osc_sm_put_notify(const void *origin_addr, size_t origin_count, struct ompi_datatype_t *origin_dt, int target, @@ -392,7 +392,7 @@ ompi_osc_sm_get(void *origin_addr, int -ompi_osc_sm_get_with_notify(void *origin_addr, +ompi_osc_sm_get_notify(void *origin_addr, size_t origin_count, struct ompi_datatype_t *origin_dt, int target, diff --git a/ompi/mca/osc/sm/osc_sm_component.c b/ompi/mca/osc/sm/osc_sm_component.c index 11f0ccc2e47..e7613c86f6e 100644 --- a/ompi/mca/osc/sm/osc_sm_component.c +++ b/ompi/mca/osc/sm/osc_sm_component.c @@ -79,18 +79,18 @@ ompi_osc_sm_module_t ompi_osc_sm_module_template = { .osc_free = ompi_osc_sm_free, .osc_put = ompi_osc_sm_put, - .osc_put_with_notify = ompi_osc_sm_put_with_notify, + .osc_put_notify = ompi_osc_sm_put_notify, .osc_get = ompi_osc_sm_get, - .osc_get_with_notify = ompi_osc_sm_get_with_notify, + .osc_get_notify = ompi_osc_sm_get_notify, .osc_accumulate = ompi_osc_sm_accumulate, .osc_compare_and_swap = ompi_osc_sm_compare_and_swap, .osc_fetch_and_op = ompi_osc_sm_fetch_and_op, .osc_get_accumulate = ompi_osc_sm_get_accumulate, .osc_rput = ompi_osc_sm_rput, - .osc_rput_with_notify = ompi_osc_sm_rput_with_notify, + .osc_rput_notify = ompi_osc_sm_rput_notify, .osc_rget = ompi_osc_sm_rget, - .osc_rget_with_notify = ompi_osc_sm_rget_with_notify, + .osc_rget_notify = ompi_osc_sm_rget_notify, .osc_raccumulate = ompi_osc_sm_raccumulate, .osc_rget_accumulate = ompi_osc_sm_rget_accumulate, diff --git a/ompi/mpi/bindings/ompi_bindings/consts.py b/ompi/mpi/bindings/ompi_bindings/consts.py index 7a523d7670d..1477956ae83 100644 --- a/ompi/mpi/bindings/ompi_bindings/consts.py +++ b/ompi/mpi/bindings/ompi_bindings/consts.py @@ -23,6 +23,7 @@ 'MPI_SUCCESS', 'MPI_ERR_BUFFER', 'MPI_ERR_COUNT', + 'MPI_ERR_NOTIFY_IDX' 'MPI_ERR_TYPE', 'MPI_ERR_TAG', 'MPI_ERR_COMM', diff --git a/ompi/mpi/c/Makefile.am b/ompi/mpi/c/Makefile.am index f532121bf28..8e4c2bcd388 100644 --- a/ompi/mpi/c/Makefile.am +++ b/ompi/mpi/c/Makefile.am @@ -223,6 +223,7 @@ prototype_sources = \ get_accumulate.c.in \ get_address.c.in \ get.c.in \ + get_notify.c.in \ get_count.c.in \ get_elements.c.in \ get_elements_x.c.in \ @@ -341,6 +342,7 @@ prototype_sources = \ psend_init.c.in \ publish_name.c.in \ put.c.in \ + put_notify.c.in \ query_thread.c.in \ raccumulate.c.in \ recv.c.in \ diff --git a/ompi/mpi/c/get_notify.c.in b/ompi/mpi/c/get_notify.c.in new file mode 100644 index 00000000000..1bad16944ab --- /dev/null +++ b/ompi/mpi/c/get_notify.c.in @@ -0,0 +1,77 @@ +/* -*- Mode: C; c-basic-offset:4 ; indent-tabs-mode:nil -*- */ +/* + * Copyright (c) 2004-2007 The Trustees of Indiana University and Indiana + * University Research and Technology + * Corporation. All rights reserved. + * Copyright (c) 2004-2020 The University of Tennessee and The University + * of Tennessee Research Foundation. All rights + * reserved. + * Copyright (c) 2004-2008 High Performance Computing Center Stuttgart, + * University of Stuttgart. All rights reserved. + * Copyright (c) 2004-2005 The Regents of the University of California. + * All rights reserved. + * Copyright (c) 2015 Los Alamos National Security, LLC. All rights + * reserved. + * Copyright (c) 2015 Research Organization for Information Science + * and Technology (RIST). All rights reserved. + * Copyright (c) 2024 Triad National Security, LLC. All rights + * reserved. + * $COPYRIGHT$ + * + * Additional copyrights may follow + * + * $HEADER$ + */ +#include "ompi_config.h" +#include + +#include "ompi/mpi/c/bindings.h" +#include "ompi/runtime/params.h" +#include "ompi/communicator/communicator.h" +#include "ompi/errhandler/errhandler.h" +#include "ompi/win/win.h" +#include "ompi/mca/osc/osc.h" +#include "ompi/datatype/ompi_datatype.h" +#include "ompi/runtime/ompi_spc.h" + +PROTOTYPE ERROR_CLASS get_notify(BUFFER_OUT origin_addr, COUNT origin_count, + DATATYPE origin_datatype, INT target_rank, + AINT target_disp, COUNT target_count, + DATATYPE target_datatype, INT notification_idx, WIN win) +{ + int rc; + + SPC_RECORD(OMPI_SPC_GET_NOTIFY, 1); + + if (MPI_PARAM_CHECK) { + rc = OMPI_SUCCESS; + + OMPI_ERR_INIT_FINALIZE(FUNC_NAME); + + if (ompi_win_invalid(win)) { + return OMPI_ERRHANDLER_NOHANDLE_INVOKE(MPI_ERR_WIN, FUNC_NAME); + } else if (origin_count < 0 || target_count < 0) { + rc = MPI_ERR_COUNT; + } else if (ompi_win_peer_invalid(win, target_rank) && + (MPI_PROC_NULL != target_rank)) { + rc = MPI_ERR_RANK; + } else if ( MPI_WIN_FLAVOR_DYNAMIC != win->w_flavor && target_disp < 0 ) { + rc = MPI_ERR_DISP; + } else if (notification_idx < 0) { + rc = MPI_ERR_NOTIFY_IDX; + } else { + OMPI_CHECK_DATATYPE_FOR_ONE_SIDED(rc, origin_datatype, origin_count); + if (OMPI_SUCCESS == rc) { + OMPI_CHECK_DATATYPE_FOR_ONE_SIDED(rc, target_datatype, target_count); + } + } + OMPI_ERRHANDLER_CHECK(rc, win, rc, FUNC_NAME); + } + + if (MPI_PROC_NULL == target_rank) return MPI_SUCCESS; + + rc = win->w_osc_module->osc_get_notify(origin_addr, origin_count, origin_datatype, + target_rank, target_disp, target_count, + target_datatype, notification_idx, win); + OMPI_ERRHANDLER_RETURN(rc, win, rc, FUNC_NAME); +} diff --git a/ompi/mpi/c/put_notify.c.in b/ompi/mpi/c/put_notify.c.in new file mode 100644 index 00000000000..14ee5c7e365 --- /dev/null +++ b/ompi/mpi/c/put_notify.c.in @@ -0,0 +1,80 @@ +/* -*- Mode: C; c-basic-offset:4 ; indent-tabs-mode:nil -*- */ +/* + * Copyright (c) 2004-2007 The Trustees of Indiana University and Indiana + * University Research and Technology + * Corporation. All rights reserved. + * Copyright (c) 2004-2020 The University of Tennessee and The University + * of Tennessee Research Foundation. All rights + * reserved. + * Copyright (c) 2004-2008 High Performance Computing Center Stuttgart, + * University of Stuttgart. All rights reserved. + * Copyright (c) 2004-2005 The Regents of the University of California. + * All rights reserved. + * Copyright (c) 2006 Cisco Systems, Inc. All rights reserved. + * Copyright (c) 2013-2015 Los Alamos National Security, LLC. All rights + * reserved. + * Copyright (c) 2015 Research Organization for Information Science + * and Technology (RIST). All rights reserved. + * Copyright (c) 2024 Triad National Security, LLC. All rights + * reserved. + * $COPYRIGHT$ + * + * Additional copyrights may follow + * + * $HEADER$ + */ +#include "ompi_config.h" +#include + +#include "ompi/mpi/c/bindings.h" +#include "ompi/runtime/params.h" +#include "ompi/communicator/communicator.h" +#include "ompi/errhandler/errhandler.h" +#include "ompi/win/win.h" +#include "ompi/mca/osc/osc.h" +#include "ompi/datatype/ompi_datatype.h" +#include "ompi/runtime/ompi_spc.h" + +PROTOTYPE ERROR_CLASS put_notify(BUFFER origin_addr, COUNT origin_count, DATATYPE origin_datatype, + INT target_rank, AINT target_disp, COUNT target_count, + DATATYPE target_datatype, INT notification_idx, WIN win) +{ + int rc; + + SPC_RECORD(OMPI_SPC_PUT_NOTIFY, 1); + + if (MPI_PARAM_CHECK) { + rc = OMPI_SUCCESS; + + OMPI_ERR_INIT_FINALIZE(FUNC_NAME); + + if (ompi_win_invalid(win)) { + return OMPI_ERRHANDLER_NOHANDLE_INVOKE(MPI_ERR_WIN, FUNC_NAME); + } else if (origin_count < 0 || target_count < 0) { + rc = MPI_ERR_COUNT; + } else if (ompi_win_peer_invalid(win, target_rank) && + (MPI_PROC_NULL != target_rank)) { + rc = MPI_ERR_RANK; + } else if (NULL == target_datatype || + MPI_DATATYPE_NULL == target_datatype) { + rc = MPI_ERR_TYPE; + } else if ( MPI_WIN_FLAVOR_DYNAMIC != win->w_flavor && target_disp < 0 ) { + rc = MPI_ERR_DISP; + } else if (notification_idx < 0) { + rc = MPI_ERR_NOTIFY_IDX; + } else { + OMPI_CHECK_DATATYPE_FOR_ONE_SIDED(rc, origin_datatype, origin_count); + if (OMPI_SUCCESS == rc) { + OMPI_CHECK_DATATYPE_FOR_ONE_SIDED(rc, target_datatype, target_count); + } + } + OMPI_ERRHANDLER_CHECK(rc, win, rc, FUNC_NAME); + } + + if (MPI_PROC_NULL == target_rank) return MPI_SUCCESS; + + rc = win->w_osc_module->osc_put_notify(origin_addr, origin_count, origin_datatype, + target_rank, target_disp, target_count, + target_datatype, notification_idx, win); + OMPI_ERRHANDLER_RETURN(rc, win, rc, FUNC_NAME); +} diff --git a/ompi/runtime/ompi_spc.c b/ompi/runtime/ompi_spc.c index fb097ac6077..45cf81babd0 100644 --- a/ompi/runtime/ompi_spc.c +++ b/ompi/runtime/ompi_spc.c @@ -71,8 +71,10 @@ static const ompi_spc_event_t ompi_spc_events_desc[OMPI_SPC_NUM_COUNTERS] = { SET_COUNTER_ARRAY(OMPI_SPC_SENDRECV, "The number of times MPI_Sendrecv was called.", false, false), SET_COUNTER_ARRAY(OMPI_SPC_SENDRECV_REPLACE, "The number of times MPI_Sendrecv_replace was called.", false, false), SET_COUNTER_ARRAY(OMPI_SPC_PUT, "The number of times MPI_Put was called.", false, false), + SET_COUNTER_ARRAY(OMPI_SPC_PUT_NOTIFY, "The number of times MPI_Put_notify was called.", false, false), SET_COUNTER_ARRAY(OMPI_SPC_RPUT, "The number of times MPI_Rput was called.", false, false), SET_COUNTER_ARRAY(OMPI_SPC_GET, "The number of times MPI_Get was called.", false, false), + SET_COUNTER_ARRAY(OMPI_SPC_GET_NOTIFY, "The number of times MPI_Get was called.", false, false), SET_COUNTER_ARRAY(OMPI_SPC_RGET, "The number of times MPI_Rget was called.", false, false), SET_COUNTER_ARRAY(OMPI_SPC_PROBE, "The number of times MPI_Probe was called.", false, false), SET_COUNTER_ARRAY(OMPI_SPC_IPROBE, "The number of times MPI_Iprobe was called.", false, false), diff --git a/ompi/runtime/ompi_spc.h b/ompi/runtime/ompi_spc.h index ca61aa8a409..03f58dd2504 100644 --- a/ompi/runtime/ompi_spc.h +++ b/ompi/runtime/ompi_spc.h @@ -58,8 +58,10 @@ typedef enum ompi_spc_counters { OMPI_SPC_SENDRECV, OMPI_SPC_SENDRECV_REPLACE, OMPI_SPC_PUT, + OMPI_SPC_PUT_NOTIFY, OMPI_SPC_RPUT, OMPI_SPC_GET, + OMPI_SPC_GET_NOTIFY, OMPI_SPC_RGET, OMPI_SPC_PROBE, OMPI_SPC_IPROBE, From 90784701cd56ad64f7752d900c90714794837330 Mon Sep 17 00:00:00 2001 From: Joseph Antony Date: Mon, 22 Dec 2025 09:46:28 -0500 Subject: [PATCH 05/19] Edits for Public APIs: put_with_notify get_with_notify Signed-off-by: Joseph Antony --- ompi/mca/osc/sm/osc_sm.h | 1 - ompi/runtime/ompi_spc.c | 2 +- 2 files changed, 1 insertion(+), 2 deletions(-) diff --git a/ompi/mca/osc/sm/osc_sm.h b/ompi/mca/osc/sm/osc_sm.h index 200ec8b3de8..0aca3b50892 100644 --- a/ompi/mca/osc/sm/osc_sm.h +++ b/ompi/mca/osc/sm/osc_sm.h @@ -107,7 +107,6 @@ int ompi_osc_sm_detach(struct ompi_win_t *win, const void *base); int ompi_osc_sm_free(struct ompi_win_t *win); -// TODO: add put/get_notify prototypes int ompi_osc_sm_put(const void *origin_addr, size_t origin_count, diff --git a/ompi/runtime/ompi_spc.c b/ompi/runtime/ompi_spc.c index 45cf81babd0..e7653e27c39 100644 --- a/ompi/runtime/ompi_spc.c +++ b/ompi/runtime/ompi_spc.c @@ -74,7 +74,7 @@ static const ompi_spc_event_t ompi_spc_events_desc[OMPI_SPC_NUM_COUNTERS] = { SET_COUNTER_ARRAY(OMPI_SPC_PUT_NOTIFY, "The number of times MPI_Put_notify was called.", false, false), SET_COUNTER_ARRAY(OMPI_SPC_RPUT, "The number of times MPI_Rput was called.", false, false), SET_COUNTER_ARRAY(OMPI_SPC_GET, "The number of times MPI_Get was called.", false, false), - SET_COUNTER_ARRAY(OMPI_SPC_GET_NOTIFY, "The number of times MPI_Get was called.", false, false), + SET_COUNTER_ARRAY(OMPI_SPC_GET_NOTIFY, "The number of times MPI_Get_notify was called.", false, false), SET_COUNTER_ARRAY(OMPI_SPC_RGET, "The number of times MPI_Rget was called.", false, false), SET_COUNTER_ARRAY(OMPI_SPC_PROBE, "The number of times MPI_Probe was called.", false, false), SET_COUNTER_ARRAY(OMPI_SPC_IPROBE, "The number of times MPI_Iprobe was called.", false, false), From 26f568e4b6a431662d36e6f852b2c39652ad507c Mon Sep 17 00:00:00 2001 From: Joseph Antony Date: Tue, 3 Feb 2026 08:29:27 -0500 Subject: [PATCH 06/19] Notified RMA counters memory allocation in the shared memory segment for a single and multi rank window. Signed-off-by: Joseph Antony --- ompi/mca/osc/sm/osc_sm.h | 3 ++- ompi/mca/osc/sm/osc_sm_component.c | 18 +++++++++++++++++- 2 files changed, 19 insertions(+), 2 deletions(-) diff --git a/ompi/mca/osc/sm/osc_sm.h b/ompi/mca/osc/sm/osc_sm.h index 0aca3b50892..bf80c082ac8 100644 --- a/ompi/mca/osc/sm/osc_sm.h +++ b/ompi/mca/osc/sm/osc_sm.h @@ -22,6 +22,7 @@ typedef uint64_t osc_sm_post_type_t; typedef opal_atomic_uint64_t osc_sm_post_atomic_type_t; #define OSC_SM_POST_BITS 6 #define OSC_SM_POST_MASK 0x3f +#define OSC_SM_MAX_NOTIFY_COUNTERS 16 /* data shared across all peers */ struct ompi_osc_sm_global_state_t { @@ -79,7 +80,7 @@ struct ompi_osc_sm_module_t { size_t *sizes; void **bases; ptrdiff_t *disp_units; - uint64_t **notify_counters; + uint64_t *notify_counters; ompi_group_t *start_group; diff --git a/ompi/mca/osc/sm/osc_sm_component.c b/ompi/mca/osc/sm/osc_sm_component.c index e7613c86f6e..5500a2bb412 100644 --- a/ompi/mca/osc/sm/osc_sm_component.c +++ b/ompi/mca/osc/sm/osc_sm_component.c @@ -255,12 +255,17 @@ component_select(struct ompi_win_t *win, void **base, size_t size, ptrdiff_t dis module->posts = calloc (1, sizeof(module->posts[0]) + sizeof (module->posts[0][0])); if (NULL == module->posts) return OMPI_ERR_TEMP_OUT_OF_RESOURCE; module->posts[0] = (osc_sm_post_atomic_type_t *) (module->posts + 1); + + /* allocate notify counters for single process case */ + module->notify_counters = calloc(OSC_SM_MAX_NOTIFY_COUNTERS, sizeof(uint64_t)); + if (NULL == module->notify_counters) return OMPI_ERR_TEMP_OUT_OF_RESOURCE; } else { unsigned long total, *rbuf; int i, flag; size_t pagesize; size_t state_size; size_t posts_size, post_size = (comm_size + OSC_SM_POST_MASK) / (OSC_SM_POST_MASK + 1); + size_t notify_counters_size; size_t data_base_size; opal_output_verbose(MCA_BASE_VERBOSE_DEBUG, ompi_osc_base_framework.framework_output, @@ -316,7 +321,9 @@ component_select(struct ompi_win_t *win, void **base, size_t size, ptrdiff_t dis state_size += OPAL_ALIGN_PAD_AMOUNT(state_size, 64); posts_size = comm_size * post_size * sizeof (module->posts[0][0]); posts_size += OPAL_ALIGN_PAD_AMOUNT(posts_size, 64); - data_base_size = state_size + posts_size; + notify_counters_size = OSC_SM_MAX_NOTIFY_COUNTERS * sizeof(uint64_t); + notify_counters_size += OPAL_ALIGN_PAD_AMOUNT(notify_counters_size, 64); + data_base_size = state_size + posts_size + notify_counters_size; data_base_size += OPAL_ALIGN_PAD_AMOUNT(data_base_size, pagesize); if (0 == ompi_comm_rank (module->comm)) { char *data_file; @@ -377,6 +384,12 @@ component_select(struct ompi_win_t *win, void **base, size_t size, ptrdiff_t dis module->global_state = (ompi_osc_sm_global_state_t *) (module->posts[0] + comm_size * post_size); module->node_states = (ompi_osc_sm_node_state_t *) (module->global_state + 1); + /* set up notify counters in shared memory after node_states */ + module->notify_counters = (uint64_t *) ((char *)(module->node_states + comm_size) + + OPAL_ALIGN_PAD_AMOUNT((uintptr_t)(module->node_states + comm_size), 64)); + /* zero out notify counters */ + memset(module->notify_counters, 0, OSC_SM_MAX_NOTIFY_COUNTERS * sizeof(uint64_t)); + for (i = 0, total = data_base_size ; i < comm_size ; ++i) { if (i > 0) { module->posts[i] = module->posts[i - 1] + post_size; @@ -555,6 +568,7 @@ ompi_osc_sm_free(struct ompi_win_t *win) module->comm->c_coll->coll_barrier_module); opal_shmem_segment_detach (&module->seg_ds); + /* notify_counters points into shared memory segment, no separate free needed */ } else { free(module->node_states); free(module->global_state); @@ -562,6 +576,8 @@ ompi_osc_sm_free(struct ompi_win_t *win) mca_mpool_base_default_module->mpool_free(mca_mpool_base_default_module, module->bases[0]); } + /* free notify_counters for single process case */ + free(module->notify_counters); } free(module->disp_units); free(module->outstanding_locks); From 650ff8d80a70c225ac1c84b52b12df895aec7279 Mon Sep 17 00:00:00 2001 From: Joseph Antony Date: Wed, 4 Feb 2026 07:47:01 -0500 Subject: [PATCH 07/19] Editing Notified RMA implementation Signed-off-by: Joseph Antony --- ompi/mca/osc/sm/osc_sm_comm.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/ompi/mca/osc/sm/osc_sm_comm.c b/ompi/mca/osc/sm/osc_sm_comm.c index 4391a375ebc..6cc5384d750 100644 --- a/ompi/mca/osc/sm/osc_sm_comm.c +++ b/ompi/mca/osc/sm/osc_sm_comm.c @@ -98,7 +98,7 @@ ompi_osc_sm_rput_notify(const void *origin_addr, *ompi_req = &ompi_request_empty; opal_atomic_wmb(); - opal_atomic_add(&module->notify_counters[target][notify], 1); + opal_atomic_add(&module->notify_counters[notify], 1); return OMPI_SUCCESS; } @@ -181,7 +181,7 @@ ompi_osc_sm_rget_notify(void *origin_addr, *ompi_req = &ompi_request_empty; opal_atomic_rmb(); - opal_atomic_add(&module->notify_counters[target][notify], 1); + opal_atomic_add(&module->notify_counters[notify], 1); return OMPI_SUCCESS; } @@ -355,7 +355,7 @@ ompi_osc_sm_put_notify(const void *origin_addr, } opal_atomic_wmb(); - opal_atomic_add(&module->notify_counters[target][notify], 1); + opal_atomic_add(&module->notify_counters[notify], 1); return ret; } @@ -422,7 +422,7 @@ ompi_osc_sm_get_notify(void *origin_addr, return ret; } opal_atomic_rmb(); - opal_atomic_add(&module->notify_counters[target][notify], 1); + opal_atomic_add(&module->notify_counters[notify], 1); return ret; } From cf07e67f5e40115b5c9efaa0008bfd711afe3537 Mon Sep 17 00:00:00 2001 From: Joseph Antony Date: Wed, 18 Feb 2026 22:17:07 -0500 Subject: [PATCH 08/19] Editing Notified RMA implementation with new design Signed-off-by: Joseph Antony --- ompi/mca/osc/sm/osc_sm.h | 3 +++ ompi/mca/osc/sm/osc_sm_comm.c | 35 +++++++++++++++++++++++++---- ompi/mca/osc/sm/osc_sm_component.c | 36 ++++++++++++++++++++---------- 3 files changed, 58 insertions(+), 16 deletions(-) diff --git a/ompi/mca/osc/sm/osc_sm.h b/ompi/mca/osc/sm/osc_sm.h index bf80c082ac8..cb104e5df15 100644 --- a/ompi/mca/osc/sm/osc_sm.h +++ b/ompi/mca/osc/sm/osc_sm.h @@ -48,6 +48,9 @@ struct ompi_osc_sm_node_state_t { opal_atomic_int32_t complete_count; ompi_osc_sm_lock_t lock; opal_atomic_lock_t accumulate_lock; + uint32_t notify_counter_count; + uint64_t notify_counter_offset; /* offset from segment_base, not raw pointer */ + }; typedef struct ompi_osc_sm_node_state_t ompi_osc_sm_node_state_t; diff --git a/ompi/mca/osc/sm/osc_sm_comm.c b/ompi/mca/osc/sm/osc_sm_comm.c index 6cc5384d750..359cdf7147f 100644 --- a/ompi/mca/osc/sm/osc_sm_comm.c +++ b/ompi/mca/osc/sm/osc_sm_comm.c @@ -20,6 +20,17 @@ #include "osc_sm.h" +static inline uint64_t *osc_sm_target_notify_base(ompi_osc_sm_module_t *module, int target) +{ + if (NULL == module->segment_base) { + /* single-rank path: notify_counters is a regular local allocation */ + return module->notify_counters; + } + + return (uint64_t *) ((char *) module->segment_base + + module->node_states[target].notify_counter_offset); +} + int ompi_osc_sm_rput(const void *origin_addr, size_t origin_count, @@ -97,8 +108,12 @@ ompi_osc_sm_rput_notify(const void *origin_addr, * complete. */ *ompi_req = &ompi_request_empty; + if (notify < 0 || (uint32_t) notify >= module->node_states[target].notify_counter_count) { + return OMPI_ERR_BAD_PARAM; + } + opal_atomic_wmb(); - opal_atomic_add(&module->notify_counters[notify], 1); + opal_atomic_add(&osc_sm_target_notify_base(module, target)[notify], 1); return OMPI_SUCCESS; } @@ -180,8 +195,12 @@ ompi_osc_sm_rget_notify(void *origin_addr, * complete. */ *ompi_req = &ompi_request_empty; + if (notify < 0 || (uint32_t) notify >= module->node_states[target].notify_counter_count) { + return OMPI_ERR_BAD_PARAM; + } + opal_atomic_rmb(); - opal_atomic_add(&module->notify_counters[notify], 1); + opal_atomic_add(&osc_sm_target_notify_base(module, target)[notify], 1); return OMPI_SUCCESS; } @@ -354,8 +373,12 @@ ompi_osc_sm_put_notify(const void *origin_addr, return ret; } + if (notify < 0 || (uint32_t) notify >= module->node_states[target].notify_counter_count) { + return OMPI_ERR_BAD_PARAM; + } + opal_atomic_wmb(); - opal_atomic_add(&module->notify_counters[notify], 1); + opal_atomic_add(&osc_sm_target_notify_base(module, target)[notify], 1); return ret; } @@ -421,8 +444,12 @@ ompi_osc_sm_get_notify(void *origin_addr, if (OMPI_SUCCESS != ret) { return ret; } + if (notify < 0 || (uint32_t) notify >= module->node_states[target].notify_counter_count) { + return OMPI_ERR_BAD_PARAM; + } + opal_atomic_rmb(); - opal_atomic_add(&module->notify_counters[notify], 1); + opal_atomic_add(&osc_sm_target_notify_base(module, target)[notify], 1); return ret; } diff --git a/ompi/mca/osc/sm/osc_sm_component.c b/ompi/mca/osc/sm/osc_sm_component.c index 5500a2bb412..7954ef6963e 100644 --- a/ompi/mca/osc/sm/osc_sm_component.c +++ b/ompi/mca/osc/sm/osc_sm_component.c @@ -259,8 +259,10 @@ component_select(struct ompi_win_t *win, void **base, size_t size, ptrdiff_t dis /* allocate notify counters for single process case */ module->notify_counters = calloc(OSC_SM_MAX_NOTIFY_COUNTERS, sizeof(uint64_t)); if (NULL == module->notify_counters) return OMPI_ERR_TEMP_OUT_OF_RESOURCE; + module->node_states[0].notify_counter_count = OSC_SM_MAX_NOTIFY_COUNTERS; + module->node_states[0].notify_counter_offset = 0; } else { - unsigned long total, *rbuf; + unsigned long total, total_counters, gather_values[2], *rbuf; int i, flag; size_t pagesize; size_t state_size; @@ -274,7 +276,7 @@ component_select(struct ompi_win_t *win, void **base, size_t size, ptrdiff_t dis /* get the pagesize */ pagesize = opal_getpagesize(); - rbuf = malloc(sizeof(unsigned long) * comm_size); + rbuf = malloc(sizeof(unsigned long) * comm_size * 2 ); if (NULL == rbuf) return OMPI_ERR_TEMP_OUT_OF_RESOURCE; /* Note that the alloc_shared_noncontig info key only has @@ -298,9 +300,10 @@ component_select(struct ompi_win_t *win, void **base, size_t size, ptrdiff_t dis "allocating window using contiguous strategy"); } - total = size; - ret = module->comm->c_coll->coll_allgather(&total, 1, MPI_UNSIGNED_LONG, - rbuf, 1, MPI_UNSIGNED_LONG, + gather_values[0] = size; + gather_values[1] = OSC_SM_MAX_NOTIFY_COUNTERS; + ret = module->comm->c_coll->coll_allgather(gather_values, 2, MPI_UNSIGNED_LONG, + rbuf, 2, MPI_UNSIGNED_LONG, module->comm, module->comm->c_coll->coll_allgather_module); if (OMPI_SUCCESS != ret) { @@ -309,8 +312,10 @@ component_select(struct ompi_win_t *win, void **base, size_t size, ptrdiff_t dis } total = 0; + total_counters = 0; for (i = 0 ; i < comm_size ; ++i) { - total += rbuf[i]; + total += rbuf[2 * i]; + total_counters += rbuf[2 * i + 1]; if (module->noncontig) { total += OPAL_ALIGN_PAD_AMOUNT(total, pagesize); } @@ -321,7 +326,7 @@ component_select(struct ompi_win_t *win, void **base, size_t size, ptrdiff_t dis state_size += OPAL_ALIGN_PAD_AMOUNT(state_size, 64); posts_size = comm_size * post_size * sizeof (module->posts[0][0]); posts_size += OPAL_ALIGN_PAD_AMOUNT(posts_size, 64); - notify_counters_size = OSC_SM_MAX_NOTIFY_COUNTERS * sizeof(uint64_t); + notify_counters_size = total_counters * sizeof(uint64_t); notify_counters_size += OPAL_ALIGN_PAD_AMOUNT(notify_counters_size, 64); data_base_size = state_size + posts_size + notify_counters_size; data_base_size += OPAL_ALIGN_PAD_AMOUNT(data_base_size, pagesize); @@ -388,17 +393,23 @@ component_select(struct ompi_win_t *win, void **base, size_t size, ptrdiff_t dis module->notify_counters = (uint64_t *) ((char *)(module->node_states + comm_size) + OPAL_ALIGN_PAD_AMOUNT((uintptr_t)(module->node_states + comm_size), 64)); /* zero out notify counters */ - memset(module->notify_counters, 0, OSC_SM_MAX_NOTIFY_COUNTERS * sizeof(uint64_t)); + memset(module->notify_counters, 0, total_counters * sizeof(uint64_t)); - for (i = 0, total = data_base_size ; i < comm_size ; ++i) { + for (i = 0, total = data_base_size, total_counters = 0 ; i < comm_size ; ++i) { if (i > 0) { module->posts[i] = module->posts[i - 1] + post_size; } - module->sizes[i] = rbuf[i]; + module->node_states[i].notify_counter_count = (uint32_t) rbuf[2 * i + 1]; + module->node_states[i].notify_counter_offset = + (uint64_t) ((char *) (module->notify_counters + total_counters) - + (char *) module->segment_base); + total_counters += rbuf[2 * i + 1]; + + module->sizes[i] = rbuf[2 * i]; if (module->sizes[i] || !module->noncontig) { module->bases[i] = ((char *) module->segment_base) + total; - total += rbuf[i]; + total += rbuf[2 * i]; if (module->noncontig) { total += OPAL_ALIGN_PAD_AMOUNT(total, pagesize); } @@ -412,7 +423,8 @@ component_select(struct ompi_win_t *win, void **base, size_t size, ptrdiff_t dis /* initialize my state shared */ module->my_node_state = &module->node_states[ompi_comm_rank(module->comm)]; - memset (module->my_node_state, 0, sizeof(*module->my_node_state)); + module->my_node_state->complete_count = 0; + memset (&module->my_node_state->lock, 0, sizeof(module->my_node_state->lock)); *base = module->bases[ompi_comm_rank(module->comm)]; From cd5f1b9619aa0262670dcbdf43f9d616fac5192f Mon Sep 17 00:00:00 2001 From: Joseph Antony Date: Wed, 4 Mar 2026 13:19:28 -0500 Subject: [PATCH 09/19] Implementing Notify Query Signed-off-by: Joseph Antony --- ompi/include/mpi.h.in | 2 ++ ompi/mca/osc/osc.h | 5 ++++ ompi/mca/osc/sm/osc_sm.h | 4 +++ ompi/mca/osc/sm/osc_sm_comm.c | 19 +++++++++++++ ompi/mca/osc/sm/osc_sm_component.c | 1 + ompi/mca/osc/ubcl/osc_ubcl.c | 5 ++++ ompi/mpi/c/Makefile.am | 2 ++ ompi/mpi/c/win_get_notify_value.c.in | 41 ++++++++++++++++++++++++++++ 8 files changed, 79 insertions(+) create mode 100644 ompi/mpi/c/win_get_notify_value.c.in diff --git a/ompi/include/mpi.h.in b/ompi/include/mpi.h.in index 1e5d56d9f91..79695910bd2 100644 --- a/ompi/include/mpi.h.in +++ b/ompi/include/mpi.h.in @@ -2623,6 +2623,7 @@ OMPI_DECLSPEC int MPI_Win_get_errhandler(MPI_Win win, MPI_Errhandler *errhandle OMPI_DECLSPEC int MPI_Win_get_group(MPI_Win win, MPI_Group *group); OMPI_DECLSPEC int MPI_Win_get_info(MPI_Win win, MPI_Info *info_used); OMPI_DECLSPEC int MPI_Win_get_name(MPI_Win win, char *win_name, int *resultlen); +OMPI_DECLSPEC int MPI_Win_get_notify_value(MPI_Win win, int notification_idx, MPI_Count *value); OMPI_DECLSPEC int MPI_Win_lock(int lock_type, int rank, int mpi_assert, MPI_Win win); OMPI_DECLSPEC int MPI_Win_lock_all(int mpi_assert, MPI_Win win); OMPI_DECLSPEC int MPI_Win_post(MPI_Group group, int mpi_assert, MPI_Win win); @@ -3811,6 +3812,7 @@ OMPI_DECLSPEC int PMPI_Win_get_errhandler(MPI_Win win, MPI_Errhandler *errhandl OMPI_DECLSPEC int PMPI_Win_get_group(MPI_Win win, MPI_Group *group); OMPI_DECLSPEC int PMPI_Win_get_info(MPI_Win win, MPI_Info *info_used); OMPI_DECLSPEC int PMPI_Win_get_name(MPI_Win win, char *win_name, int *resultlen); +OMPI_DECLSPEC int PMPI_Win_get_notify_value(MPI_Win win, int notification_idx, MPI_Count *value); OMPI_DECLSPEC int PMPI_Win_lock(int lock_type, int rank, int mpi_assert, MPI_Win win); OMPI_DECLSPEC int PMPI_Win_lock_all(int mpi_assert, MPI_Win win); OMPI_DECLSPEC int PMPI_Win_post(MPI_Group group, int mpi_assert, MPI_Win win); diff --git a/ompi/mca/osc/osc.h b/ompi/mca/osc/osc.h index 83c7af9305e..b43757b9b5c 100644 --- a/ompi/mca/osc/osc.h +++ b/ompi/mca/osc/osc.h @@ -245,6 +245,10 @@ typedef int (*ompi_osc_base_module_get_notify_fn_t)(void *origin_addr, int notify, struct ompi_win_t *win); +typedef int (*ompi_osc_base_module_win_get_notify_value_fn_t)(struct ompi_win_t *win, + int notify, + MPI_Count *value); + typedef int (*ompi_osc_base_module_accumulate_fn_t)(const void *origin_addr, size_t origin_count, struct ompi_datatype_t *origin_dt, @@ -421,6 +425,7 @@ struct ompi_osc_base_module_4_0_0_t { ompi_osc_base_module_put_notify_fn_t osc_put_notify; ompi_osc_base_module_get_fn_t osc_get; ompi_osc_base_module_get_notify_fn_t osc_get_notify; + ompi_osc_base_module_win_get_notify_value_fn_t osc_win_get_notify_value; ompi_osc_base_module_accumulate_fn_t osc_accumulate; ompi_osc_base_module_compare_and_swap_fn_t osc_compare_and_swap; ompi_osc_base_module_fetch_and_op_fn_t osc_fetch_and_op; diff --git a/ompi/mca/osc/sm/osc_sm.h b/ompi/mca/osc/sm/osc_sm.h index cb104e5df15..f80c0116d73 100644 --- a/ompi/mca/osc/sm/osc_sm.h +++ b/ompi/mca/osc/sm/osc_sm.h @@ -149,6 +149,10 @@ int ompi_osc_sm_get_notify(void *origin_addr, struct ompi_datatype_t *target_dt, int notify, struct ompi_win_t *win); + +int ompi_osc_sm_win_get_notify_value(struct ompi_win_t *win, + int notify, + MPI_Count *value); int ompi_osc_sm_accumulate(const void *origin_addr, size_t origin_count, diff --git a/ompi/mca/osc/sm/osc_sm_comm.c b/ompi/mca/osc/sm/osc_sm_comm.c index 359cdf7147f..0597ecf3095 100644 --- a/ompi/mca/osc/sm/osc_sm_comm.c +++ b/ompi/mca/osc/sm/osc_sm_comm.c @@ -17,6 +17,7 @@ #include "ompi/mca/osc/osc.h" #include "ompi/mca/osc/base/base.h" #include "ompi/mca/osc/base/osc_base_obj_convert.h" +#include "ompi/communicator/communicator.h" #include "osc_sm.h" @@ -31,6 +32,24 @@ static inline uint64_t *osc_sm_target_notify_base(ompi_osc_sm_module_t *module, module->node_states[target].notify_counter_offset); } +int +ompi_osc_sm_win_get_notify_value(struct ompi_win_t *win, + int notify, + MPI_Count *value) +{ + ompi_osc_sm_module_t *module = (ompi_osc_sm_module_t *) win->w_osc_module; + int rank = ompi_comm_rank(module->comm); + + if (notify < 0 || (uint32_t) notify >= module->node_states[rank].notify_counter_count) { + return OMPI_ERR_BAD_PARAM; + } + + opal_atomic_rmb(); + *value = (MPI_Count) osc_sm_target_notify_base(module, rank)[notify]; + + return OMPI_SUCCESS; +} + int ompi_osc_sm_rput(const void *origin_addr, size_t origin_count, diff --git a/ompi/mca/osc/sm/osc_sm_component.c b/ompi/mca/osc/sm/osc_sm_component.c index 7954ef6963e..0a3f7002337 100644 --- a/ompi/mca/osc/sm/osc_sm_component.c +++ b/ompi/mca/osc/sm/osc_sm_component.c @@ -82,6 +82,7 @@ ompi_osc_sm_module_t ompi_osc_sm_module_template = { .osc_put_notify = ompi_osc_sm_put_notify, .osc_get = ompi_osc_sm_get, .osc_get_notify = ompi_osc_sm_get_notify, + .osc_win_get_notify_value = ompi_osc_sm_win_get_notify_value, .osc_accumulate = ompi_osc_sm_accumulate, .osc_compare_and_swap = ompi_osc_sm_compare_and_swap, .osc_fetch_and_op = ompi_osc_sm_fetch_and_op, diff --git a/ompi/mca/osc/ubcl/osc_ubcl.c b/ompi/mca/osc/ubcl/osc_ubcl.c index 5a81d0a763d..b55c96298ab 100644 --- a/ompi/mca/osc/ubcl/osc_ubcl.c +++ b/ompi/mca/osc/ubcl/osc_ubcl.c @@ -80,14 +80,19 @@ mca_osc_ubcl_module_t mca_osc_ubcl_module_template = { win_free, ompi_osc_ubcl_put, + NULL, ompi_osc_ubcl_get, + NULL, + NULL, ompi_osc_ubcl_accumulate, ompi_osc_ubcl_compare_and_swap, ompi_osc_ubcl_fetch_and_op, ompi_osc_ubcl_get_accumulate, ompi_osc_ubcl_rput, + NULL, ompi_osc_ubcl_rget, + NULL, ompi_osc_ubcl_raccumulate, ompi_osc_ubcl_rget_accumulate, diff --git a/ompi/mpi/c/Makefile.am b/ompi/mpi/c/Makefile.am index 8e4c2bcd388..ec260ede897 100644 --- a/ompi/mpi/c/Makefile.am +++ b/ompi/mpi/c/Makefile.am @@ -486,6 +486,7 @@ prototype_sources = \ win_get_group.c.in \ win_get_info.c.in \ win_get_name.c.in \ + win_get_notify_value.c.in \ win_lock_all.c.in \ win_lock.c.in \ win_post.c.in \ @@ -956,6 +957,7 @@ interface_profile_sources = \ win_get_group_generated.c \ win_get_info_generated.c \ win_get_name_generated.c \ + win_get_notify_value_generated.c \ win_lock_all_generated.c \ win_lock_generated.c \ win_post_generated.c \ diff --git a/ompi/mpi/c/win_get_notify_value.c.in b/ompi/mpi/c/win_get_notify_value.c.in new file mode 100644 index 00000000000..228999c13ea --- /dev/null +++ b/ompi/mpi/c/win_get_notify_value.c.in @@ -0,0 +1,41 @@ +/* -*- Mode: C; c-basic-offset:4 ; indent-tabs-mode:nil -*- */ +/* + * Copyright (c) 2026 Triad National Security, LLC. All rights + * reserved. + * $COPYRIGHT$ + * + * Additional copyrights may follow + * + * $HEADER$ + */ +#include "ompi_config.h" + +#include "ompi/mpi/c/bindings.h" +#include "ompi/runtime/params.h" +#include "ompi/errhandler/errhandler.h" +#include "ompi/win/win.h" +#include "ompi/mca/osc/osc.h" + +PROTOTYPE ERROR_CLASS win_get_notify_value(WIN win, INT notification_idx, ELEMENT_COUNT value) +{ + int rc; + + if (MPI_PARAM_CHECK) { + rc = OMPI_SUCCESS; + + OMPI_ERR_INIT_FINALIZE(FUNC_NAME); + + if (ompi_win_invalid(win)) { + return OMPI_ERRHANDLER_NOHANDLE_INVOKE(MPI_ERR_WIN, FUNC_NAME); + } else if (notification_idx < 0) { + rc = MPI_ERR_NOTIFY_IDX; + } else if (NULL == value) { + rc = MPI_ERR_ARG; + } + + OMPI_ERRHANDLER_CHECK(rc, win, rc, FUNC_NAME); + } + + rc = win->w_osc_module->osc_win_get_notify_value(win, notification_idx, value); + OMPI_ERRHANDLER_RETURN(rc, win, rc, FUNC_NAME); +} From 0c661b2466ea57ae3c326a3cbafb9b94a9a42675 Mon Sep 17 00:00:00 2001 From: Joseph Antony Date: Wed, 4 Mar 2026 13:39:55 -0500 Subject: [PATCH 10/19] Changes to Notify Query Signed-off-by: Joseph Antony --- ompi/mca/osc/osc.h | 2 +- ompi/mca/osc/sm/osc_sm.h | 2 +- ompi/mca/osc/sm/osc_sm_comm.c | 4 ++-- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/ompi/mca/osc/osc.h b/ompi/mca/osc/osc.h index b43757b9b5c..8aebf7446b1 100644 --- a/ompi/mca/osc/osc.h +++ b/ompi/mca/osc/osc.h @@ -247,7 +247,7 @@ typedef int (*ompi_osc_base_module_get_notify_fn_t)(void *origin_addr, typedef int (*ompi_osc_base_module_win_get_notify_value_fn_t)(struct ompi_win_t *win, int notify, - MPI_Count *value); + OMPI_MPI_COUNT_TYPE *value); typedef int (*ompi_osc_base_module_accumulate_fn_t)(const void *origin_addr, size_t origin_count, diff --git a/ompi/mca/osc/sm/osc_sm.h b/ompi/mca/osc/sm/osc_sm.h index f80c0116d73..c294cc7d1f6 100644 --- a/ompi/mca/osc/sm/osc_sm.h +++ b/ompi/mca/osc/sm/osc_sm.h @@ -152,7 +152,7 @@ int ompi_osc_sm_get_notify(void *origin_addr, int ompi_osc_sm_win_get_notify_value(struct ompi_win_t *win, int notify, - MPI_Count *value); + OMPI_MPI_COUNT_TYPE *value); int ompi_osc_sm_accumulate(const void *origin_addr, size_t origin_count, diff --git a/ompi/mca/osc/sm/osc_sm_comm.c b/ompi/mca/osc/sm/osc_sm_comm.c index 0597ecf3095..b0b3bde37f8 100644 --- a/ompi/mca/osc/sm/osc_sm_comm.c +++ b/ompi/mca/osc/sm/osc_sm_comm.c @@ -35,7 +35,7 @@ static inline uint64_t *osc_sm_target_notify_base(ompi_osc_sm_module_t *module, int ompi_osc_sm_win_get_notify_value(struct ompi_win_t *win, int notify, - MPI_Count *value) + OMPI_MPI_COUNT_TYPE *value) { ompi_osc_sm_module_t *module = (ompi_osc_sm_module_t *) win->w_osc_module; int rank = ompi_comm_rank(module->comm); @@ -45,7 +45,7 @@ ompi_osc_sm_win_get_notify_value(struct ompi_win_t *win, } opal_atomic_rmb(); - *value = (MPI_Count) osc_sm_target_notify_base(module, rank)[notify]; + *value = (OMPI_MPI_COUNT_TYPE) osc_sm_target_notify_base(module, rank)[notify]; return OMPI_SUCCESS; } From 45c2eda683cb63f044856e7fa449c3442f8313d5 Mon Sep 17 00:00:00 2001 From: Joseph Antony Date: Wed, 4 Mar 2026 18:24:42 -0500 Subject: [PATCH 11/19] Implemented Set Notify Query Signed-off-by: Joseph Antony --- ompi/include/mpi.h.in | 2 ++ ompi/mca/osc/osc.h | 5 ++++ ompi/mca/osc/sm/osc_sm.h | 4 +++ ompi/mca/osc/sm/osc_sm_comm.c | 21 +++++++++++++- ompi/mca/osc/sm/osc_sm_component.c | 1 + ompi/mpi/c/Makefile.am | 2 ++ ompi/mpi/c/win_set_notify_value.c.in | 41 ++++++++++++++++++++++++++++ 7 files changed, 75 insertions(+), 1 deletion(-) create mode 100644 ompi/mpi/c/win_set_notify_value.c.in diff --git a/ompi/include/mpi.h.in b/ompi/include/mpi.h.in index 79695910bd2..744dcbfe803 100644 --- a/ompi/include/mpi.h.in +++ b/ompi/include/mpi.h.in @@ -2624,6 +2624,7 @@ OMPI_DECLSPEC int MPI_Win_get_group(MPI_Win win, MPI_Group *group); OMPI_DECLSPEC int MPI_Win_get_info(MPI_Win win, MPI_Info *info_used); OMPI_DECLSPEC int MPI_Win_get_name(MPI_Win win, char *win_name, int *resultlen); OMPI_DECLSPEC int MPI_Win_get_notify_value(MPI_Win win, int notification_idx, MPI_Count *value); +OMPI_DECLSPEC int MPI_Win_set_notify_value(MPI_Win win, int notification_idx, MPI_Count value); OMPI_DECLSPEC int MPI_Win_lock(int lock_type, int rank, int mpi_assert, MPI_Win win); OMPI_DECLSPEC int MPI_Win_lock_all(int mpi_assert, MPI_Win win); OMPI_DECLSPEC int MPI_Win_post(MPI_Group group, int mpi_assert, MPI_Win win); @@ -3813,6 +3814,7 @@ OMPI_DECLSPEC int PMPI_Win_get_group(MPI_Win win, MPI_Group *group); OMPI_DECLSPEC int PMPI_Win_get_info(MPI_Win win, MPI_Info *info_used); OMPI_DECLSPEC int PMPI_Win_get_name(MPI_Win win, char *win_name, int *resultlen); OMPI_DECLSPEC int PMPI_Win_get_notify_value(MPI_Win win, int notification_idx, MPI_Count *value); +OMPI_DECLSPEC int PMPI_Win_set_notify_value(MPI_Win win, int notification_idx, MPI_Count value); OMPI_DECLSPEC int PMPI_Win_lock(int lock_type, int rank, int mpi_assert, MPI_Win win); OMPI_DECLSPEC int PMPI_Win_lock_all(int mpi_assert, MPI_Win win); OMPI_DECLSPEC int PMPI_Win_post(MPI_Group group, int mpi_assert, MPI_Win win); diff --git a/ompi/mca/osc/osc.h b/ompi/mca/osc/osc.h index 8aebf7446b1..ca3b9aac3ef 100644 --- a/ompi/mca/osc/osc.h +++ b/ompi/mca/osc/osc.h @@ -248,6 +248,10 @@ typedef int (*ompi_osc_base_module_get_notify_fn_t)(void *origin_addr, typedef int (*ompi_osc_base_module_win_get_notify_value_fn_t)(struct ompi_win_t *win, int notify, OMPI_MPI_COUNT_TYPE *value); + +typedef int (*ompi_osc_base_module_win_set_notify_value_fn_t)(struct ompi_win_t *win, + int notify, + OMPI_MPI_COUNT_TYPE value); typedef int (*ompi_osc_base_module_accumulate_fn_t)(const void *origin_addr, size_t origin_count, @@ -426,6 +430,7 @@ struct ompi_osc_base_module_4_0_0_t { ompi_osc_base_module_get_fn_t osc_get; ompi_osc_base_module_get_notify_fn_t osc_get_notify; ompi_osc_base_module_win_get_notify_value_fn_t osc_win_get_notify_value; + ompi_osc_base_module_win_set_notify_value_fn_t osc_win_set_notify_value; ompi_osc_base_module_accumulate_fn_t osc_accumulate; ompi_osc_base_module_compare_and_swap_fn_t osc_compare_and_swap; ompi_osc_base_module_fetch_and_op_fn_t osc_fetch_and_op; diff --git a/ompi/mca/osc/sm/osc_sm.h b/ompi/mca/osc/sm/osc_sm.h index c294cc7d1f6..cec3fa44bb2 100644 --- a/ompi/mca/osc/sm/osc_sm.h +++ b/ompi/mca/osc/sm/osc_sm.h @@ -153,6 +153,10 @@ int ompi_osc_sm_get_notify(void *origin_addr, int ompi_osc_sm_win_get_notify_value(struct ompi_win_t *win, int notify, OMPI_MPI_COUNT_TYPE *value); + +int ompi_osc_sm_win_set_notify_value(struct ompi_win_t *win, + int notify, + OMPI_MPI_COUNT_TYPE value); int ompi_osc_sm_accumulate(const void *origin_addr, size_t origin_count, diff --git a/ompi/mca/osc/sm/osc_sm_comm.c b/ompi/mca/osc/sm/osc_sm_comm.c index b0b3bde37f8..b3879c11949 100644 --- a/ompi/mca/osc/sm/osc_sm_comm.c +++ b/ompi/mca/osc/sm/osc_sm_comm.c @@ -44,8 +44,27 @@ ompi_osc_sm_win_get_notify_value(struct ompi_win_t *win, return OMPI_ERR_BAD_PARAM; } - opal_atomic_rmb(); + *value = (OMPI_MPI_COUNT_TYPE) osc_sm_target_notify_base(module, rank)[notify]; + opal_atomic_rmb(); + + return OMPI_SUCCESS; +} + +int +ompi_osc_sm_win_set_notify_value(struct ompi_win_t *win, + int notify, + OMPI_MPI_COUNT_TYPE value) +{ + ompi_osc_sm_module_t *module = (ompi_osc_sm_module_t *) win->w_osc_module; + int rank = ompi_comm_rank(module->comm); + + if (notify < 0 || (uint32_t) notify >= module->node_states[rank].notify_counter_count) { + return OMPI_ERR_BAD_PARAM; + } + + opal_atomic_wmb(); + osc_sm_target_notify_base(module, rank)[notify] = (uint64_t) value; return OMPI_SUCCESS; } diff --git a/ompi/mca/osc/sm/osc_sm_component.c b/ompi/mca/osc/sm/osc_sm_component.c index 0a3f7002337..e64d04d6130 100644 --- a/ompi/mca/osc/sm/osc_sm_component.c +++ b/ompi/mca/osc/sm/osc_sm_component.c @@ -83,6 +83,7 @@ ompi_osc_sm_module_t ompi_osc_sm_module_template = { .osc_get = ompi_osc_sm_get, .osc_get_notify = ompi_osc_sm_get_notify, .osc_win_get_notify_value = ompi_osc_sm_win_get_notify_value, + .osc_win_set_notify_value = ompi_osc_sm_win_set_notify_value, .osc_accumulate = ompi_osc_sm_accumulate, .osc_compare_and_swap = ompi_osc_sm_compare_and_swap, .osc_fetch_and_op = ompi_osc_sm_fetch_and_op, diff --git a/ompi/mpi/c/Makefile.am b/ompi/mpi/c/Makefile.am index ec260ede897..e2e32de0175 100644 --- a/ompi/mpi/c/Makefile.am +++ b/ompi/mpi/c/Makefile.am @@ -487,6 +487,7 @@ prototype_sources = \ win_get_info.c.in \ win_get_name.c.in \ win_get_notify_value.c.in \ + win_set_notify_value.c.in \ win_lock_all.c.in \ win_lock.c.in \ win_post.c.in \ @@ -958,6 +959,7 @@ interface_profile_sources = \ win_get_info_generated.c \ win_get_name_generated.c \ win_get_notify_value_generated.c \ + win_set_notify_value_generated.c \ win_lock_all_generated.c \ win_lock_generated.c \ win_post_generated.c \ diff --git a/ompi/mpi/c/win_set_notify_value.c.in b/ompi/mpi/c/win_set_notify_value.c.in new file mode 100644 index 00000000000..8a7d97567db --- /dev/null +++ b/ompi/mpi/c/win_set_notify_value.c.in @@ -0,0 +1,41 @@ +/* -*- Mode: C; c-basic-offset:4 ; indent-tabs-mode:nil -*- */ +/* + * Copyright (c) 2026 Triad National Security, LLC. All rights + * reserved. + * $COPYRIGHT$ + * + * Additional copyrights may follow + * + * $HEADER$ + */ +#include "ompi_config.h" + +#include "ompi/mpi/c/bindings.h" +#include "ompi/runtime/params.h" +#include "ompi/errhandler/errhandler.h" +#include "ompi/win/win.h" +#include "ompi/mca/osc/osc.h" + +PROTOTYPE ERROR_CLASS win_set_notify_value(WIN win, INT notification_idx, PARTITIONED_COUNT value) +{ + int rc; + + if (MPI_PARAM_CHECK) { + rc = OMPI_SUCCESS; + + OMPI_ERR_INIT_FINALIZE(FUNC_NAME); + + if (ompi_win_invalid(win)) { + return OMPI_ERRHANDLER_NOHANDLE_INVOKE(MPI_ERR_WIN, FUNC_NAME); + } else if (notification_idx < 0) { + rc = MPI_ERR_NOTIFY_IDX; + } else if (value < 0) { + rc = MPI_ERR_ARG; + } + + OMPI_ERRHANDLER_CHECK(rc, win, rc, FUNC_NAME); + } + + rc = win->w_osc_module->osc_win_set_notify_value(win, notification_idx, value); + OMPI_ERRHANDLER_RETURN(rc, win, rc, FUNC_NAME); +} From 193c10baaf62d576f634e9577c43143186810fcc Mon Sep 17 00:00:00 2001 From: Joseph Antony Date: Wed, 4 Mar 2026 18:25:43 -0500 Subject: [PATCH 12/19] Changes to Notify Query Signed-off-by: Joseph Antony --- ompi/mca/osc/sm/osc_sm_comm.c | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/ompi/mca/osc/sm/osc_sm_comm.c b/ompi/mca/osc/sm/osc_sm_comm.c index b3879c11949..5d9032e19ea 100644 --- a/ompi/mca/osc/sm/osc_sm_comm.c +++ b/ompi/mca/osc/sm/osc_sm_comm.c @@ -44,10 +44,9 @@ ompi_osc_sm_win_get_notify_value(struct ompi_win_t *win, return OMPI_ERR_BAD_PARAM; } - - *value = (OMPI_MPI_COUNT_TYPE) osc_sm_target_notify_base(module, rank)[notify]; opal_atomic_rmb(); - + *value = (OMPI_MPI_COUNT_TYPE) osc_sm_target_notify_base(module, rank)[notify]; + return OMPI_SUCCESS; } From e47983f302620d63bccd9288c5413a30adadf88a Mon Sep 17 00:00:00 2001 From: Joseph Antony Date: Wed, 11 Mar 2026 18:20:13 -0400 Subject: [PATCH 13/19] Configuring memory barries to propagate the update Signed-off-by: Joseph Antony --- ompi/mca/osc/sm/osc_sm_comm.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/ompi/mca/osc/sm/osc_sm_comm.c b/ompi/mca/osc/sm/osc_sm_comm.c index 5d9032e19ea..6d17d914283 100644 --- a/ompi/mca/osc/sm/osc_sm_comm.c +++ b/ompi/mca/osc/sm/osc_sm_comm.c @@ -44,8 +44,8 @@ ompi_osc_sm_win_get_notify_value(struct ompi_win_t *win, return OMPI_ERR_BAD_PARAM; } - opal_atomic_rmb(); *value = (OMPI_MPI_COUNT_TYPE) osc_sm_target_notify_base(module, rank)[notify]; + opal_atomic_rmb(); return OMPI_SUCCESS; } @@ -62,8 +62,8 @@ ompi_osc_sm_win_set_notify_value(struct ompi_win_t *win, return OMPI_ERR_BAD_PARAM; } - opal_atomic_wmb(); osc_sm_target_notify_base(module, rank)[notify] = (uint64_t) value; + opal_atomic_wmb(); return OMPI_SUCCESS; } From 095c99d2b8250f19a9a1bf395bdc69184b0c84cf Mon Sep 17 00:00:00 2001 From: Joseph Antony Date: Wed, 11 Mar 2026 19:26:11 -0400 Subject: [PATCH 14/19] Reset notify value Implementation Signed-off-by: Joseph Antony --- ompi/include/mpi.h.in | 2 ++ ompi/mca/osc/osc.h | 5 ++++ ompi/mca/osc/sm/osc_sm.h | 6 +++- ompi/mca/osc/sm/osc_sm_comm.c | 19 ++++++++++++ ompi/mca/osc/sm/osc_sm_component.c | 1 + ompi/mpi/c/Makefile.am | 2 ++ ompi/mpi/c/win_reset_notify_value.c.in | 41 ++++++++++++++++++++++++++ 7 files changed, 75 insertions(+), 1 deletion(-) create mode 100644 ompi/mpi/c/win_reset_notify_value.c.in diff --git a/ompi/include/mpi.h.in b/ompi/include/mpi.h.in index 744dcbfe803..182ecc807eb 100644 --- a/ompi/include/mpi.h.in +++ b/ompi/include/mpi.h.in @@ -2625,6 +2625,7 @@ OMPI_DECLSPEC int MPI_Win_get_info(MPI_Win win, MPI_Info *info_used); OMPI_DECLSPEC int MPI_Win_get_name(MPI_Win win, char *win_name, int *resultlen); OMPI_DECLSPEC int MPI_Win_get_notify_value(MPI_Win win, int notification_idx, MPI_Count *value); OMPI_DECLSPEC int MPI_Win_set_notify_value(MPI_Win win, int notification_idx, MPI_Count value); +OMPI_DECLSPEC int MPI_Win_reset_notify_value(MPI_Win win, int notification_idx, MPI_Count *value); OMPI_DECLSPEC int MPI_Win_lock(int lock_type, int rank, int mpi_assert, MPI_Win win); OMPI_DECLSPEC int MPI_Win_lock_all(int mpi_assert, MPI_Win win); OMPI_DECLSPEC int MPI_Win_post(MPI_Group group, int mpi_assert, MPI_Win win); @@ -3815,6 +3816,7 @@ OMPI_DECLSPEC int PMPI_Win_get_info(MPI_Win win, MPI_Info *info_used); OMPI_DECLSPEC int PMPI_Win_get_name(MPI_Win win, char *win_name, int *resultlen); OMPI_DECLSPEC int PMPI_Win_get_notify_value(MPI_Win win, int notification_idx, MPI_Count *value); OMPI_DECLSPEC int PMPI_Win_set_notify_value(MPI_Win win, int notification_idx, MPI_Count value); +OMPI_DECLSPEC int PMPI_Win_reset_notify_value(MPI_Win win, int notification_idx, MPI_Count *value); OMPI_DECLSPEC int PMPI_Win_lock(int lock_type, int rank, int mpi_assert, MPI_Win win); OMPI_DECLSPEC int PMPI_Win_lock_all(int mpi_assert, MPI_Win win); OMPI_DECLSPEC int PMPI_Win_post(MPI_Group group, int mpi_assert, MPI_Win win); diff --git a/ompi/mca/osc/osc.h b/ompi/mca/osc/osc.h index ca3b9aac3ef..6af72390f7f 100644 --- a/ompi/mca/osc/osc.h +++ b/ompi/mca/osc/osc.h @@ -253,6 +253,10 @@ typedef int (*ompi_osc_base_module_win_set_notify_value_fn_t)(struct ompi_win_t int notify, OMPI_MPI_COUNT_TYPE value); +typedef int (*ompi_osc_base_module_win_reset_notify_value_fn_t)(struct ompi_win_t *win, + int notify, + OMPI_MPI_COUNT_TYPE *value); + typedef int (*ompi_osc_base_module_accumulate_fn_t)(const void *origin_addr, size_t origin_count, struct ompi_datatype_t *origin_dt, @@ -431,6 +435,7 @@ struct ompi_osc_base_module_4_0_0_t { ompi_osc_base_module_get_notify_fn_t osc_get_notify; ompi_osc_base_module_win_get_notify_value_fn_t osc_win_get_notify_value; ompi_osc_base_module_win_set_notify_value_fn_t osc_win_set_notify_value; + ompi_osc_base_module_win_reset_notify_value_fn_t osc_win_reset_notify_value; ompi_osc_base_module_accumulate_fn_t osc_accumulate; ompi_osc_base_module_compare_and_swap_fn_t osc_compare_and_swap; ompi_osc_base_module_fetch_and_op_fn_t osc_fetch_and_op; diff --git a/ompi/mca/osc/sm/osc_sm.h b/ompi/mca/osc/sm/osc_sm.h index cec3fa44bb2..ca776bd59a0 100644 --- a/ompi/mca/osc/sm/osc_sm.h +++ b/ompi/mca/osc/sm/osc_sm.h @@ -157,7 +157,11 @@ int ompi_osc_sm_win_get_notify_value(struct ompi_win_t *win, int ompi_osc_sm_win_set_notify_value(struct ompi_win_t *win, int notify, OMPI_MPI_COUNT_TYPE value); - + +int ompi_osc_sm_win_reset_notify_value(struct ompi_win_t *win, + int notify, + OMPI_MPI_COUNT_TYPE *value); + int ompi_osc_sm_accumulate(const void *origin_addr, size_t origin_count, struct ompi_datatype_t *origin_dt, diff --git a/ompi/mca/osc/sm/osc_sm_comm.c b/ompi/mca/osc/sm/osc_sm_comm.c index 6d17d914283..40cbc9d2813 100644 --- a/ompi/mca/osc/sm/osc_sm_comm.c +++ b/ompi/mca/osc/sm/osc_sm_comm.c @@ -68,6 +68,25 @@ ompi_osc_sm_win_set_notify_value(struct ompi_win_t *win, return OMPI_SUCCESS; } +int +ompi_osc_sm_win_reset_notify_value(struct ompi_win_t *win, + int notify, + OMPI_MPI_COUNT_TYPE *value) +{ + ompi_osc_sm_module_t *module = (ompi_osc_sm_module_t *) win->w_osc_module; + int rank = ompi_comm_rank(module->comm); + + if (notify < 0 || (uint32_t) notify >= module->node_states[rank].notify_counter_count) { + return OMPI_ERR_BAD_PARAM; + } + + /* Atomically swap the counter to 0 and return the previous value */ + *value = (OMPI_MPI_COUNT_TYPE) opal_atomic_swap_64( + &osc_sm_target_notify_base(module, rank)[notify], 0); + + return OMPI_SUCCESS; +} + int ompi_osc_sm_rput(const void *origin_addr, size_t origin_count, diff --git a/ompi/mca/osc/sm/osc_sm_component.c b/ompi/mca/osc/sm/osc_sm_component.c index e64d04d6130..3ba892e0885 100644 --- a/ompi/mca/osc/sm/osc_sm_component.c +++ b/ompi/mca/osc/sm/osc_sm_component.c @@ -84,6 +84,7 @@ ompi_osc_sm_module_t ompi_osc_sm_module_template = { .osc_get_notify = ompi_osc_sm_get_notify, .osc_win_get_notify_value = ompi_osc_sm_win_get_notify_value, .osc_win_set_notify_value = ompi_osc_sm_win_set_notify_value, + .osc_win_reset_notify_value = ompi_osc_sm_win_reset_notify_value, .osc_accumulate = ompi_osc_sm_accumulate, .osc_compare_and_swap = ompi_osc_sm_compare_and_swap, .osc_fetch_and_op = ompi_osc_sm_fetch_and_op, diff --git a/ompi/mpi/c/Makefile.am b/ompi/mpi/c/Makefile.am index e2e32de0175..2d9c5c852ce 100644 --- a/ompi/mpi/c/Makefile.am +++ b/ompi/mpi/c/Makefile.am @@ -488,6 +488,7 @@ prototype_sources = \ win_get_name.c.in \ win_get_notify_value.c.in \ win_set_notify_value.c.in \ + win_reset_notify_value.c.in \ win_lock_all.c.in \ win_lock.c.in \ win_post.c.in \ @@ -960,6 +961,7 @@ interface_profile_sources = \ win_get_name_generated.c \ win_get_notify_value_generated.c \ win_set_notify_value_generated.c \ + win_reset_notify_value_generated.c \ win_lock_all_generated.c \ win_lock_generated.c \ win_post_generated.c \ diff --git a/ompi/mpi/c/win_reset_notify_value.c.in b/ompi/mpi/c/win_reset_notify_value.c.in new file mode 100644 index 00000000000..99aa1755a76 --- /dev/null +++ b/ompi/mpi/c/win_reset_notify_value.c.in @@ -0,0 +1,41 @@ +/* -*- Mode: C; c-basic-offset:4 ; indent-tabs-mode:nil -*- */ +/* + * Copyright (c) 2026 Triad National Security, LLC. All rights + * reserved. + * $COPYRIGHT$ + * + * Additional copyrights may follow + * + * $HEADER$ + */ +#include "ompi_config.h" + +#include "ompi/mpi/c/bindings.h" +#include "ompi/runtime/params.h" +#include "ompi/errhandler/errhandler.h" +#include "ompi/win/win.h" +#include "ompi/mca/osc/osc.h" + +PROTOTYPE ERROR_CLASS win_reset_notify_value(WIN win, INT notification_idx, ELEMENT_COUNT value) +{ + int rc; + + if (MPI_PARAM_CHECK) { + rc = OMPI_SUCCESS; + + OMPI_ERR_INIT_FINALIZE(FUNC_NAME); + + if (ompi_win_invalid(win)) { + return OMPI_ERRHANDLER_NOHANDLE_INVOKE(MPI_ERR_WIN, FUNC_NAME); + } else if (notification_idx < 0) { + rc = MPI_ERR_NOTIFY_IDX; + } else if (NULL == value) { + rc = MPI_ERR_ARG; + } + + OMPI_ERRHANDLER_CHECK(rc, win, rc, FUNC_NAME); + } + + rc = win->w_osc_module->osc_win_reset_notify_value(win, notification_idx, value); + OMPI_ERRHANDLER_RETURN(rc, win, rc, FUNC_NAME); +} From 9d4d06ca7fe3f656348c184ac832ecaa403ca6a8 Mon Sep 17 00:00:00 2001 From: Joseph Antony Date: Fri, 13 Mar 2026 11:43:20 -0400 Subject: [PATCH 15/19] Addressing review comments and bug fixes Signed-off-by: Joseph Antony --- ompi/mca/osc/osc.h | 14 +++++++------- ompi/mca/osc/sm/osc_sm_comm.c | 12 ++++++------ ompi/mca/osc/ubcl/osc_ubcl.c | 5 ----- 3 files changed, 13 insertions(+), 18 deletions(-) diff --git a/ompi/mca/osc/osc.h b/ompi/mca/osc/osc.h index 6af72390f7f..002866a69da 100644 --- a/ompi/mca/osc/osc.h +++ b/ompi/mca/osc/osc.h @@ -430,21 +430,14 @@ struct ompi_osc_base_module_4_0_0_t { ompi_osc_base_module_free_fn_t osc_free; ompi_osc_base_module_put_fn_t osc_put; - ompi_osc_base_module_put_notify_fn_t osc_put_notify; ompi_osc_base_module_get_fn_t osc_get; - ompi_osc_base_module_get_notify_fn_t osc_get_notify; - ompi_osc_base_module_win_get_notify_value_fn_t osc_win_get_notify_value; - ompi_osc_base_module_win_set_notify_value_fn_t osc_win_set_notify_value; - ompi_osc_base_module_win_reset_notify_value_fn_t osc_win_reset_notify_value; ompi_osc_base_module_accumulate_fn_t osc_accumulate; ompi_osc_base_module_compare_and_swap_fn_t osc_compare_and_swap; ompi_osc_base_module_fetch_and_op_fn_t osc_fetch_and_op; ompi_osc_base_module_get_accumulate_fn_t osc_get_accumulate; ompi_osc_base_module_rput_fn_t osc_rput; - ompi_osc_base_module_rput_notify_fn_t osc_rput_notify; ompi_osc_base_module_rget_fn_t osc_rget; - ompi_osc_base_module_rget_notify_fn_t osc_rget_notify; ompi_osc_base_module_raccumulate_fn_t osc_raccumulate; ompi_osc_base_module_rget_accumulate_fn_t osc_rget_accumulate; @@ -466,6 +459,13 @@ struct ompi_osc_base_module_4_0_0_t { ompi_osc_base_module_flush_all_fn_t osc_flush_all; ompi_osc_base_module_flush_local_fn_t osc_flush_local; ompi_osc_base_module_flush_local_all_fn_t osc_flush_local_all; + ompi_osc_base_module_put_notify_fn_t osc_put_notify; + ompi_osc_base_module_get_notify_fn_t osc_get_notify; + ompi_osc_base_module_win_get_notify_value_fn_t osc_win_get_notify_value; + ompi_osc_base_module_win_set_notify_value_fn_t osc_win_set_notify_value; + ompi_osc_base_module_win_reset_notify_value_fn_t osc_win_reset_notify_value; + ompi_osc_base_module_rput_notify_fn_t osc_rput_notify; + ompi_osc_base_module_rget_notify_fn_t osc_rget_notify; }; typedef struct ompi_osc_base_module_4_0_0_t ompi_osc_base_module_4_0_0_t; typedef ompi_osc_base_module_4_0_0_t ompi_osc_base_module_t; diff --git a/ompi/mca/osc/sm/osc_sm_comm.c b/ompi/mca/osc/sm/osc_sm_comm.c index 40cbc9d2813..7d7501dcabf 100644 --- a/ompi/mca/osc/sm/osc_sm_comm.c +++ b/ompi/mca/osc/sm/osc_sm_comm.c @@ -41,7 +41,7 @@ ompi_osc_sm_win_get_notify_value(struct ompi_win_t *win, int rank = ompi_comm_rank(module->comm); if (notify < 0 || (uint32_t) notify >= module->node_states[rank].notify_counter_count) { - return OMPI_ERR_BAD_PARAM; + return MPI_ERR_NOTIFY_IDX; } *value = (OMPI_MPI_COUNT_TYPE) osc_sm_target_notify_base(module, rank)[notify]; @@ -59,7 +59,7 @@ ompi_osc_sm_win_set_notify_value(struct ompi_win_t *win, int rank = ompi_comm_rank(module->comm); if (notify < 0 || (uint32_t) notify >= module->node_states[rank].notify_counter_count) { - return OMPI_ERR_BAD_PARAM; + return MPI_ERR_NOTIFY_IDX; } osc_sm_target_notify_base(module, rank)[notify] = (uint64_t) value; @@ -77,7 +77,7 @@ ompi_osc_sm_win_reset_notify_value(struct ompi_win_t *win, int rank = ompi_comm_rank(module->comm); if (notify < 0 || (uint32_t) notify >= module->node_states[rank].notify_counter_count) { - return OMPI_ERR_BAD_PARAM; + return MPI_ERR_NOTIFY_IDX; } /* Atomically swap the counter to 0 and return the previous value */ @@ -165,7 +165,7 @@ ompi_osc_sm_rput_notify(const void *origin_addr, *ompi_req = &ompi_request_empty; if (notify < 0 || (uint32_t) notify >= module->node_states[target].notify_counter_count) { - return OMPI_ERR_BAD_PARAM; + return MPI_ERR_NOTIFY_IDX; } opal_atomic_wmb(); @@ -252,7 +252,7 @@ ompi_osc_sm_rget_notify(void *origin_addr, *ompi_req = &ompi_request_empty; if (notify < 0 || (uint32_t) notify >= module->node_states[target].notify_counter_count) { - return OMPI_ERR_BAD_PARAM; + return MPI_ERR_NOTIFY_IDX; } opal_atomic_rmb(); @@ -430,7 +430,7 @@ ompi_osc_sm_put_notify(const void *origin_addr, } if (notify < 0 || (uint32_t) notify >= module->node_states[target].notify_counter_count) { - return OMPI_ERR_BAD_PARAM; + return MPI_ERR_NOTIFY_IDX; } opal_atomic_wmb(); diff --git a/ompi/mca/osc/ubcl/osc_ubcl.c b/ompi/mca/osc/ubcl/osc_ubcl.c index b55c96298ab..5a81d0a763d 100644 --- a/ompi/mca/osc/ubcl/osc_ubcl.c +++ b/ompi/mca/osc/ubcl/osc_ubcl.c @@ -80,19 +80,14 @@ mca_osc_ubcl_module_t mca_osc_ubcl_module_template = { win_free, ompi_osc_ubcl_put, - NULL, ompi_osc_ubcl_get, - NULL, - NULL, ompi_osc_ubcl_accumulate, ompi_osc_ubcl_compare_and_swap, ompi_osc_ubcl_fetch_and_op, ompi_osc_ubcl_get_accumulate, ompi_osc_ubcl_rput, - NULL, ompi_osc_ubcl_rget, - NULL, ompi_osc_ubcl_raccumulate, ompi_osc_ubcl_rget_accumulate, From 6719fbda67e6c64e0f2a38fc94d0590317445446 Mon Sep 17 00:00:00 2001 From: Joseph Antony Date: Fri, 13 Mar 2026 17:23:08 -0400 Subject: [PATCH 16/19] Removing Duplicate changes Signed-off-by: Joseph Antony --- ompi/include/mpi.h.in | 2 -- ompi/mca/osc/osc.h | 5 ---- ompi/mca/osc/sm/osc_sm.h | 4 --- ompi/mca/osc/sm/osc_sm_comm.c | 18 ------------ ompi/mca/osc/sm/osc_sm_component.c | 1 - ompi/mpi/c/Makefile.am | 2 -- ompi/mpi/c/win_set_notify_value.c.in | 41 ---------------------------- 7 files changed, 73 deletions(-) delete mode 100644 ompi/mpi/c/win_set_notify_value.c.in diff --git a/ompi/include/mpi.h.in b/ompi/include/mpi.h.in index 182ecc807eb..f600c66733b 100644 --- a/ompi/include/mpi.h.in +++ b/ompi/include/mpi.h.in @@ -2624,7 +2624,6 @@ OMPI_DECLSPEC int MPI_Win_get_group(MPI_Win win, MPI_Group *group); OMPI_DECLSPEC int MPI_Win_get_info(MPI_Win win, MPI_Info *info_used); OMPI_DECLSPEC int MPI_Win_get_name(MPI_Win win, char *win_name, int *resultlen); OMPI_DECLSPEC int MPI_Win_get_notify_value(MPI_Win win, int notification_idx, MPI_Count *value); -OMPI_DECLSPEC int MPI_Win_set_notify_value(MPI_Win win, int notification_idx, MPI_Count value); OMPI_DECLSPEC int MPI_Win_reset_notify_value(MPI_Win win, int notification_idx, MPI_Count *value); OMPI_DECLSPEC int MPI_Win_lock(int lock_type, int rank, int mpi_assert, MPI_Win win); OMPI_DECLSPEC int MPI_Win_lock_all(int mpi_assert, MPI_Win win); @@ -3815,7 +3814,6 @@ OMPI_DECLSPEC int PMPI_Win_get_group(MPI_Win win, MPI_Group *group); OMPI_DECLSPEC int PMPI_Win_get_info(MPI_Win win, MPI_Info *info_used); OMPI_DECLSPEC int PMPI_Win_get_name(MPI_Win win, char *win_name, int *resultlen); OMPI_DECLSPEC int PMPI_Win_get_notify_value(MPI_Win win, int notification_idx, MPI_Count *value); -OMPI_DECLSPEC int PMPI_Win_set_notify_value(MPI_Win win, int notification_idx, MPI_Count value); OMPI_DECLSPEC int PMPI_Win_reset_notify_value(MPI_Win win, int notification_idx, MPI_Count *value); OMPI_DECLSPEC int PMPI_Win_lock(int lock_type, int rank, int mpi_assert, MPI_Win win); OMPI_DECLSPEC int PMPI_Win_lock_all(int mpi_assert, MPI_Win win); diff --git a/ompi/mca/osc/osc.h b/ompi/mca/osc/osc.h index 002866a69da..b43f34ac3c5 100644 --- a/ompi/mca/osc/osc.h +++ b/ompi/mca/osc/osc.h @@ -249,10 +249,6 @@ typedef int (*ompi_osc_base_module_win_get_notify_value_fn_t)(struct ompi_win_t int notify, OMPI_MPI_COUNT_TYPE *value); -typedef int (*ompi_osc_base_module_win_set_notify_value_fn_t)(struct ompi_win_t *win, - int notify, - OMPI_MPI_COUNT_TYPE value); - typedef int (*ompi_osc_base_module_win_reset_notify_value_fn_t)(struct ompi_win_t *win, int notify, OMPI_MPI_COUNT_TYPE *value); @@ -462,7 +458,6 @@ struct ompi_osc_base_module_4_0_0_t { ompi_osc_base_module_put_notify_fn_t osc_put_notify; ompi_osc_base_module_get_notify_fn_t osc_get_notify; ompi_osc_base_module_win_get_notify_value_fn_t osc_win_get_notify_value; - ompi_osc_base_module_win_set_notify_value_fn_t osc_win_set_notify_value; ompi_osc_base_module_win_reset_notify_value_fn_t osc_win_reset_notify_value; ompi_osc_base_module_rput_notify_fn_t osc_rput_notify; ompi_osc_base_module_rget_notify_fn_t osc_rget_notify; diff --git a/ompi/mca/osc/sm/osc_sm.h b/ompi/mca/osc/sm/osc_sm.h index ca776bd59a0..85d250bfa18 100644 --- a/ompi/mca/osc/sm/osc_sm.h +++ b/ompi/mca/osc/sm/osc_sm.h @@ -154,10 +154,6 @@ int ompi_osc_sm_win_get_notify_value(struct ompi_win_t *win, int notify, OMPI_MPI_COUNT_TYPE *value); -int ompi_osc_sm_win_set_notify_value(struct ompi_win_t *win, - int notify, - OMPI_MPI_COUNT_TYPE value); - int ompi_osc_sm_win_reset_notify_value(struct ompi_win_t *win, int notify, OMPI_MPI_COUNT_TYPE *value); diff --git a/ompi/mca/osc/sm/osc_sm_comm.c b/ompi/mca/osc/sm/osc_sm_comm.c index 7d7501dcabf..fbd4f17856c 100644 --- a/ompi/mca/osc/sm/osc_sm_comm.c +++ b/ompi/mca/osc/sm/osc_sm_comm.c @@ -50,24 +50,6 @@ ompi_osc_sm_win_get_notify_value(struct ompi_win_t *win, return OMPI_SUCCESS; } -int -ompi_osc_sm_win_set_notify_value(struct ompi_win_t *win, - int notify, - OMPI_MPI_COUNT_TYPE value) -{ - ompi_osc_sm_module_t *module = (ompi_osc_sm_module_t *) win->w_osc_module; - int rank = ompi_comm_rank(module->comm); - - if (notify < 0 || (uint32_t) notify >= module->node_states[rank].notify_counter_count) { - return MPI_ERR_NOTIFY_IDX; - } - - osc_sm_target_notify_base(module, rank)[notify] = (uint64_t) value; - opal_atomic_wmb(); - - return OMPI_SUCCESS; -} - int ompi_osc_sm_win_reset_notify_value(struct ompi_win_t *win, int notify, diff --git a/ompi/mca/osc/sm/osc_sm_component.c b/ompi/mca/osc/sm/osc_sm_component.c index 3ba892e0885..259c0826017 100644 --- a/ompi/mca/osc/sm/osc_sm_component.c +++ b/ompi/mca/osc/sm/osc_sm_component.c @@ -83,7 +83,6 @@ ompi_osc_sm_module_t ompi_osc_sm_module_template = { .osc_get = ompi_osc_sm_get, .osc_get_notify = ompi_osc_sm_get_notify, .osc_win_get_notify_value = ompi_osc_sm_win_get_notify_value, - .osc_win_set_notify_value = ompi_osc_sm_win_set_notify_value, .osc_win_reset_notify_value = ompi_osc_sm_win_reset_notify_value, .osc_accumulate = ompi_osc_sm_accumulate, .osc_compare_and_swap = ompi_osc_sm_compare_and_swap, diff --git a/ompi/mpi/c/Makefile.am b/ompi/mpi/c/Makefile.am index 2d9c5c852ce..7aecd5a3411 100644 --- a/ompi/mpi/c/Makefile.am +++ b/ompi/mpi/c/Makefile.am @@ -487,7 +487,6 @@ prototype_sources = \ win_get_info.c.in \ win_get_name.c.in \ win_get_notify_value.c.in \ - win_set_notify_value.c.in \ win_reset_notify_value.c.in \ win_lock_all.c.in \ win_lock.c.in \ @@ -960,7 +959,6 @@ interface_profile_sources = \ win_get_info_generated.c \ win_get_name_generated.c \ win_get_notify_value_generated.c \ - win_set_notify_value_generated.c \ win_reset_notify_value_generated.c \ win_lock_all_generated.c \ win_lock_generated.c \ diff --git a/ompi/mpi/c/win_set_notify_value.c.in b/ompi/mpi/c/win_set_notify_value.c.in deleted file mode 100644 index 8a7d97567db..00000000000 --- a/ompi/mpi/c/win_set_notify_value.c.in +++ /dev/null @@ -1,41 +0,0 @@ -/* -*- Mode: C; c-basic-offset:4 ; indent-tabs-mode:nil -*- */ -/* - * Copyright (c) 2026 Triad National Security, LLC. All rights - * reserved. - * $COPYRIGHT$ - * - * Additional copyrights may follow - * - * $HEADER$ - */ -#include "ompi_config.h" - -#include "ompi/mpi/c/bindings.h" -#include "ompi/runtime/params.h" -#include "ompi/errhandler/errhandler.h" -#include "ompi/win/win.h" -#include "ompi/mca/osc/osc.h" - -PROTOTYPE ERROR_CLASS win_set_notify_value(WIN win, INT notification_idx, PARTITIONED_COUNT value) -{ - int rc; - - if (MPI_PARAM_CHECK) { - rc = OMPI_SUCCESS; - - OMPI_ERR_INIT_FINALIZE(FUNC_NAME); - - if (ompi_win_invalid(win)) { - return OMPI_ERRHANDLER_NOHANDLE_INVOKE(MPI_ERR_WIN, FUNC_NAME); - } else if (notification_idx < 0) { - rc = MPI_ERR_NOTIFY_IDX; - } else if (value < 0) { - rc = MPI_ERR_ARG; - } - - OMPI_ERRHANDLER_CHECK(rc, win, rc, FUNC_NAME); - } - - rc = win->w_osc_module->osc_win_set_notify_value(win, notification_idx, value); - OMPI_ERRHANDLER_RETURN(rc, win, rc, FUNC_NAME); -} From 1ff322d87ea1dde3643c78faec0158844d81fe23 Mon Sep 17 00:00:00 2001 From: Joseph Antony Date: Sun, 2 Aug 2026 00:01:50 -0400 Subject: [PATCH 17/19] ompi: rename MPI_ERR_NOTIFY_IDX to MPI_ERR_RMA_NOTIFICATION MPI-5.1 names the error class for an invalid notification index MPI_ERR_RMA_NOTIFICATION. Rename the placeholder used by the notified RMA work to match the standard. The class was never registered with the error code subsystem, so MPI_Error_string() and MPI_Error_class() did not know about it; add the missing CONSTRUCT_ERRCODE()/OBJ_DESTRUCT() pair in errcode.c. Also fix the binding generator's ERROR_CLASSES list, where the entry was inserted without a trailing comma and so was silently concatenated with the following 'MPI_ERR_TYPE' element rather than added as a class of its own. Signed-off-by: Joseph Antony --- ompi/errhandler/errcode.c | 3 +++ ompi/include/mpi.h.in | 2 +- ompi/include/mpif-values.py | 2 +- ompi/mca/osc/sm/osc_sm_comm.c | 10 +++++----- ompi/mpi/bindings/ompi_bindings/consts.py | 2 +- ompi/mpi/c/get_notify.c.in | 2 +- ompi/mpi/c/put_notify.c.in | 2 +- ompi/mpi/c/win_get_notify_value.c.in | 2 +- ompi/mpi/c/win_reset_notify_value.c.in | 2 +- 9 files changed, 15 insertions(+), 12 deletions(-) diff --git a/ompi/errhandler/errcode.c b/ompi/errhandler/errcode.c index 631f1483b12..d04b6f9069c 100644 --- a/ompi/errhandler/errcode.c +++ b/ompi/errhandler/errcode.c @@ -131,6 +131,7 @@ static ompi_mpi_errcode_t ompi_err_value_too_large; static ompi_mpi_errcode_t ompi_err_errhandler; static ompi_mpi_errcode_t ompi_t_err_not_accessible; static ompi_mpi_errcode_t ompi_t_err_not_supported; +static ompi_mpi_errcode_t ompi_err_rma_notification; static void ompi_mpi_errcode_construct(ompi_mpi_errcode_t* errcode); static void ompi_mpi_errcode_destruct(ompi_mpi_errcode_t* errcode); @@ -252,6 +253,7 @@ int ompi_mpi_errcode_init (void) CONSTRUCT_ERRCODE( ompi_err_errhandler, MPI_ERR_ERRHANDLER, "MPI_ERR_ERRHANDLER: Invalid error handler handle" ); CONSTRUCT_ERRCODE( ompi_t_err_not_accessible, MPI_T_ERR_NOT_ACCESSIBLE, "MPI_T_ERR_NOT_ACCESSIBLE: Requested functionality is not accessible" ); CONSTRUCT_ERRCODE( ompi_t_err_not_supported, MPI_T_ERR_NOT_SUPPORTED, "MPI_T_ERR_NOT_SUPPORTED: Requested functionality not supported" ); + CONSTRUCT_ERRCODE( ompi_err_rma_notification, MPI_ERR_RMA_NOTIFICATION, "MPI_ERR_RMA_NOTIFICATION: Invalid notification index passed to MPI call" ); /* Per MPI-3 p353:27-32, MPI_LASTUSEDCODE must be >= MPI_ERR_LASTCODE. So just start it as == MPI_ERR_LASTCODE. */ @@ -373,6 +375,7 @@ int ompi_mpi_errcode_finalize (void) OBJ_DESTRUCT(&ompi_err_errhandler); OBJ_DESTRUCT(&ompi_t_err_not_accessible); OBJ_DESTRUCT(&ompi_t_err_not_supported); + OBJ_DESTRUCT(&ompi_err_rma_notification); OBJ_DESTRUCT(&ompi_mpi_errcodes); ompi_mpi_errcode_lastpredefined = 0; opal_mutex_unlock(&errcode_lock); diff --git a/ompi/include/mpi.h.in b/ompi/include/mpi.h.in index f600c66733b..8d393da453b 100644 --- a/ompi/include/mpi.h.in +++ b/ompi/include/mpi.h.in @@ -767,7 +767,7 @@ enum { #define MPI_ERR_ERRHANDLER 80 #define MPI_T_ERR_NOT_ACCESSIBLE 81 #define MPI_T_ERR_NOT_SUPPORTED 82 -#define MPI_ERR_NOTIFY_IDX 83 +#define MPI_ERR_RMA_NOTIFICATION 83 /* Per MPI-3 p349 47, MPI_ERR_LASTCODE must be >= the last predefined MPI_ERR_ code. Set the last code to allow some room for adding diff --git a/ompi/include/mpif-values.py b/ompi/include/mpif-values.py index af55b87baee..62cd9c4e421 100755 --- a/ompi/include/mpif-values.py +++ b/ompi/include/mpif-values.py @@ -304,7 +304,7 @@ 'MPI_ERR_ERRHANDLER': 80, 'MPI_T_ERR_NOT_ACCESSIBLE': 81, 'MPI_T_ERR_NOT_SUPPORTED': 82, - 'MPI_ERR_NOTIFY_IDX': 83, + 'MPI_ERR_RMA_NOTIFICATION': 83, 'MPI_ERR_LASTCODE': 92, 'MPI_IDENT': 0, 'MPI_CONGRUENT': 1, diff --git a/ompi/mca/osc/sm/osc_sm_comm.c b/ompi/mca/osc/sm/osc_sm_comm.c index fbd4f17856c..78966b4d809 100644 --- a/ompi/mca/osc/sm/osc_sm_comm.c +++ b/ompi/mca/osc/sm/osc_sm_comm.c @@ -41,7 +41,7 @@ ompi_osc_sm_win_get_notify_value(struct ompi_win_t *win, int rank = ompi_comm_rank(module->comm); if (notify < 0 || (uint32_t) notify >= module->node_states[rank].notify_counter_count) { - return MPI_ERR_NOTIFY_IDX; + return MPI_ERR_RMA_NOTIFICATION; } *value = (OMPI_MPI_COUNT_TYPE) osc_sm_target_notify_base(module, rank)[notify]; @@ -59,7 +59,7 @@ ompi_osc_sm_win_reset_notify_value(struct ompi_win_t *win, int rank = ompi_comm_rank(module->comm); if (notify < 0 || (uint32_t) notify >= module->node_states[rank].notify_counter_count) { - return MPI_ERR_NOTIFY_IDX; + return MPI_ERR_RMA_NOTIFICATION; } /* Atomically swap the counter to 0 and return the previous value */ @@ -147,7 +147,7 @@ ompi_osc_sm_rput_notify(const void *origin_addr, *ompi_req = &ompi_request_empty; if (notify < 0 || (uint32_t) notify >= module->node_states[target].notify_counter_count) { - return MPI_ERR_NOTIFY_IDX; + return MPI_ERR_RMA_NOTIFICATION; } opal_atomic_wmb(); @@ -234,7 +234,7 @@ ompi_osc_sm_rget_notify(void *origin_addr, *ompi_req = &ompi_request_empty; if (notify < 0 || (uint32_t) notify >= module->node_states[target].notify_counter_count) { - return MPI_ERR_NOTIFY_IDX; + return MPI_ERR_RMA_NOTIFICATION; } opal_atomic_rmb(); @@ -412,7 +412,7 @@ ompi_osc_sm_put_notify(const void *origin_addr, } if (notify < 0 || (uint32_t) notify >= module->node_states[target].notify_counter_count) { - return MPI_ERR_NOTIFY_IDX; + return MPI_ERR_RMA_NOTIFICATION; } opal_atomic_wmb(); diff --git a/ompi/mpi/bindings/ompi_bindings/consts.py b/ompi/mpi/bindings/ompi_bindings/consts.py index 1477956ae83..4a249629079 100644 --- a/ompi/mpi/bindings/ompi_bindings/consts.py +++ b/ompi/mpi/bindings/ompi_bindings/consts.py @@ -23,7 +23,6 @@ 'MPI_SUCCESS', 'MPI_ERR_BUFFER', 'MPI_ERR_COUNT', - 'MPI_ERR_NOTIFY_IDX' 'MPI_ERR_TYPE', 'MPI_ERR_TAG', 'MPI_ERR_COMM', @@ -101,6 +100,7 @@ 'MPI_T_ERR_PVAR_NO_ATOMIC', 'MPI_T_ERR_NOT_ACCESSIBLE', 'MPI_T_ERR_NOT_SUPPORTED', + 'MPI_ERR_RMA_NOTIFICATION', 'MPI_ERR_LASTCODE', ] diff --git a/ompi/mpi/c/get_notify.c.in b/ompi/mpi/c/get_notify.c.in index 1bad16944ab..d9b8f5b68ef 100644 --- a/ompi/mpi/c/get_notify.c.in +++ b/ompi/mpi/c/get_notify.c.in @@ -58,7 +58,7 @@ PROTOTYPE ERROR_CLASS get_notify(BUFFER_OUT origin_addr, COUNT origin_count, } else if ( MPI_WIN_FLAVOR_DYNAMIC != win->w_flavor && target_disp < 0 ) { rc = MPI_ERR_DISP; } else if (notification_idx < 0) { - rc = MPI_ERR_NOTIFY_IDX; + rc = MPI_ERR_RMA_NOTIFICATION; } else { OMPI_CHECK_DATATYPE_FOR_ONE_SIDED(rc, origin_datatype, origin_count); if (OMPI_SUCCESS == rc) { diff --git a/ompi/mpi/c/put_notify.c.in b/ompi/mpi/c/put_notify.c.in index 14ee5c7e365..f278e16cb16 100644 --- a/ompi/mpi/c/put_notify.c.in +++ b/ompi/mpi/c/put_notify.c.in @@ -61,7 +61,7 @@ PROTOTYPE ERROR_CLASS put_notify(BUFFER origin_addr, COUNT origin_count, DATATYP } else if ( MPI_WIN_FLAVOR_DYNAMIC != win->w_flavor && target_disp < 0 ) { rc = MPI_ERR_DISP; } else if (notification_idx < 0) { - rc = MPI_ERR_NOTIFY_IDX; + rc = MPI_ERR_RMA_NOTIFICATION; } else { OMPI_CHECK_DATATYPE_FOR_ONE_SIDED(rc, origin_datatype, origin_count); if (OMPI_SUCCESS == rc) { diff --git a/ompi/mpi/c/win_get_notify_value.c.in b/ompi/mpi/c/win_get_notify_value.c.in index 228999c13ea..27df94e1e82 100644 --- a/ompi/mpi/c/win_get_notify_value.c.in +++ b/ompi/mpi/c/win_get_notify_value.c.in @@ -28,7 +28,7 @@ PROTOTYPE ERROR_CLASS win_get_notify_value(WIN win, INT notification_idx, ELEMEN if (ompi_win_invalid(win)) { return OMPI_ERRHANDLER_NOHANDLE_INVOKE(MPI_ERR_WIN, FUNC_NAME); } else if (notification_idx < 0) { - rc = MPI_ERR_NOTIFY_IDX; + rc = MPI_ERR_RMA_NOTIFICATION; } else if (NULL == value) { rc = MPI_ERR_ARG; } diff --git a/ompi/mpi/c/win_reset_notify_value.c.in b/ompi/mpi/c/win_reset_notify_value.c.in index 99aa1755a76..68b462a510e 100644 --- a/ompi/mpi/c/win_reset_notify_value.c.in +++ b/ompi/mpi/c/win_reset_notify_value.c.in @@ -28,7 +28,7 @@ PROTOTYPE ERROR_CLASS win_reset_notify_value(WIN win, INT notification_idx, ELEM if (ompi_win_invalid(win)) { return OMPI_ERRHANDLER_NOHANDLE_INVOKE(MPI_ERR_WIN, FUNC_NAME); } else if (notification_idx < 0) { - rc = MPI_ERR_NOTIFY_IDX; + rc = MPI_ERR_RMA_NOTIFICATION; } else if (NULL == value) { rc = MPI_ERR_ARG; } From d909605a01e76645e526a023427f06807dfd488b Mon Sep 17 00:00:00 2001 From: Joseph Antony Date: Sun, 2 Aug 2026 00:03:29 -0400 Subject: [PATCH 18/19] osc: add MPI_WIN_SET_NUM_NOTIFY and MPI_WIN_GET_NUM_NOTIFY Add the two remaining notification-management procedures from MPI-5.1 section 12.6.1: MPI_WIN_SET_NUM_NOTIFY is a blocking, synchronizing collective that sets the number of notification counters attached at the calling MPI process to exactly num_notifications and resets all of them to zero. MPI_WIN_GET_NUM_NOTIFY is local and returns the number of counters attached at target_rank. Both are wired through the osc framework as new module entry points, so components that do not implement them return MPI_ERR_UNSUPPORTED_OPERATION rather than crashing. The osc/sm implementation carves a fixed per-rank counter region out of the shared segment at window creation, which is therefore the effective MPI_WIN_NOTIFICATION_NUM_UB; a request beyond that capacity is rejected with MPI_ERR_ARG. Each rank publishes its own attached count into the shared segment, so the collective needs only a barrier -- no counts have to be exchanged -- and MPI_WIN_GET_NUM_NOTIFY is a plain shared-memory read. Also add the missing put_notify/get_notify entries to interface_profile_sources, which were omitted when those two procedures were introduced. Signed-off-by: Joseph Antony --- ompi/include/mpi.h.in | 4 ++ ompi/mca/osc/osc.h | 15 ++++++ ompi/mca/osc/sm/osc_sm.h | 8 ++++ ompi/mca/osc/sm/osc_sm_comm.c | 77 ++++++++++++++++++++++++++++++ ompi/mca/osc/sm/osc_sm_component.c | 2 + ompi/mpi/c/Makefile.am | 6 +++ ompi/mpi/c/win_get_num_notify.c.in | 43 +++++++++++++++++ ompi/mpi/c/win_set_num_notify.c.in | 48 +++++++++++++++++++ 8 files changed, 203 insertions(+) create mode 100644 ompi/mpi/c/win_get_num_notify.c.in create mode 100644 ompi/mpi/c/win_set_num_notify.c.in diff --git a/ompi/include/mpi.h.in b/ompi/include/mpi.h.in index 8d393da453b..71afc4cefbc 100644 --- a/ompi/include/mpi.h.in +++ b/ompi/include/mpi.h.in @@ -2625,6 +2625,8 @@ OMPI_DECLSPEC int MPI_Win_get_info(MPI_Win win, MPI_Info *info_used); OMPI_DECLSPEC int MPI_Win_get_name(MPI_Win win, char *win_name, int *resultlen); OMPI_DECLSPEC int MPI_Win_get_notify_value(MPI_Win win, int notification_idx, MPI_Count *value); OMPI_DECLSPEC int MPI_Win_reset_notify_value(MPI_Win win, int notification_idx, MPI_Count *value); +OMPI_DECLSPEC int MPI_Win_get_num_notify(MPI_Win win, int target_rank, int *num_notifications); +OMPI_DECLSPEC int MPI_Win_set_num_notify(MPI_Win win, MPI_Info info, int num_notifications); OMPI_DECLSPEC int MPI_Win_lock(int lock_type, int rank, int mpi_assert, MPI_Win win); OMPI_DECLSPEC int MPI_Win_lock_all(int mpi_assert, MPI_Win win); OMPI_DECLSPEC int MPI_Win_post(MPI_Group group, int mpi_assert, MPI_Win win); @@ -3815,6 +3817,8 @@ OMPI_DECLSPEC int PMPI_Win_get_info(MPI_Win win, MPI_Info *info_used); OMPI_DECLSPEC int PMPI_Win_get_name(MPI_Win win, char *win_name, int *resultlen); OMPI_DECLSPEC int PMPI_Win_get_notify_value(MPI_Win win, int notification_idx, MPI_Count *value); OMPI_DECLSPEC int PMPI_Win_reset_notify_value(MPI_Win win, int notification_idx, MPI_Count *value); +OMPI_DECLSPEC int PMPI_Win_get_num_notify(MPI_Win win, int target_rank, int *num_notifications); +OMPI_DECLSPEC int PMPI_Win_set_num_notify(MPI_Win win, MPI_Info info, int num_notifications); OMPI_DECLSPEC int PMPI_Win_lock(int lock_type, int rank, int mpi_assert, MPI_Win win); OMPI_DECLSPEC int PMPI_Win_lock_all(int mpi_assert, MPI_Win win); OMPI_DECLSPEC int PMPI_Win_post(MPI_Group group, int mpi_assert, MPI_Win win); diff --git a/ompi/mca/osc/osc.h b/ompi/mca/osc/osc.h index b43f34ac3c5..2f66c2ac107 100644 --- a/ompi/mca/osc/osc.h +++ b/ompi/mca/osc/osc.h @@ -253,6 +253,19 @@ typedef int (*ompi_osc_base_module_win_reset_notify_value_fn_t)(struct ompi_win_ int notify, OMPI_MPI_COUNT_TYPE *value); +/* MPI-5.1 section 12.6.1. Blocking, synchronizing collective; sets the number + * of notification counters attached at the calling MPI process to exactly + * num_notifications and resets every counter to zero. */ +typedef int (*ompi_osc_base_module_win_set_num_notify_fn_t)(struct ompi_win_t *win, + struct opal_info_t *info, + int num_notifications); + +/* MPI-5.1 section 12.6.1. Local; returns the number of notification counters + * attached at target_rank. */ +typedef int (*ompi_osc_base_module_win_get_num_notify_fn_t)(struct ompi_win_t *win, + int target_rank, + int *num_notifications); + typedef int (*ompi_osc_base_module_accumulate_fn_t)(const void *origin_addr, size_t origin_count, struct ompi_datatype_t *origin_dt, @@ -459,6 +472,8 @@ struct ompi_osc_base_module_4_0_0_t { ompi_osc_base_module_get_notify_fn_t osc_get_notify; ompi_osc_base_module_win_get_notify_value_fn_t osc_win_get_notify_value; ompi_osc_base_module_win_reset_notify_value_fn_t osc_win_reset_notify_value; + ompi_osc_base_module_win_set_num_notify_fn_t osc_win_set_num_notify; + ompi_osc_base_module_win_get_num_notify_fn_t osc_win_get_num_notify; ompi_osc_base_module_rput_notify_fn_t osc_rput_notify; ompi_osc_base_module_rget_notify_fn_t osc_rget_notify; }; diff --git a/ompi/mca/osc/sm/osc_sm.h b/ompi/mca/osc/sm/osc_sm.h index 85d250bfa18..d9ac9742f80 100644 --- a/ompi/mca/osc/sm/osc_sm.h +++ b/ompi/mca/osc/sm/osc_sm.h @@ -158,6 +158,14 @@ int ompi_osc_sm_win_reset_notify_value(struct ompi_win_t *win, int notify, OMPI_MPI_COUNT_TYPE *value); +int ompi_osc_sm_win_set_num_notify(struct ompi_win_t *win, + struct opal_info_t *info, + int num_notifications); + +int ompi_osc_sm_win_get_num_notify(struct ompi_win_t *win, + int target_rank, + int *num_notifications); + int ompi_osc_sm_accumulate(const void *origin_addr, size_t origin_count, struct ompi_datatype_t *origin_dt, diff --git a/ompi/mca/osc/sm/osc_sm_comm.c b/ompi/mca/osc/sm/osc_sm_comm.c index 78966b4d809..fdb598dff29 100644 --- a/ompi/mca/osc/sm/osc_sm_comm.c +++ b/ompi/mca/osc/sm/osc_sm_comm.c @@ -69,6 +69,83 @@ ompi_osc_sm_win_reset_notify_value(struct ompi_win_t *win, return OMPI_SUCCESS; } +int +ompi_osc_sm_win_set_num_notify(struct ompi_win_t *win, + struct opal_info_t *info, + int num_notifications) +{ + ompi_osc_sm_module_t *module = (ompi_osc_sm_module_t *) win->w_osc_module; + int rank = ompi_comm_rank(module->comm); + int ret; + + /* "mpi_assert_same_num_notifications" is an optimization hint only, and + * osc/sm reserves the same fixed number of counters at every rank + * regardless, so there is nothing to specialize on. */ + (void) info; + + if (num_notifications < 0) { + return MPI_ERR_ARG; + } + + /* A fixed region of OSC_SM_MAX_NOTIFY_COUNTERS counters per rank is carved + * out of the shared segment at window creation, so that is the effective + * MPI_WIN_NOTIFICATION_NUM_UB. Asking for more cannot be satisfied without + * re-creating the segment. */ + if (num_notifications > OSC_SM_MAX_NOTIFY_COUNTERS) { + return MPI_ERR_ARG; + } + + /* MPI-5.1 section 12.6.1: "A subsequent call to MPI_WIN_GET_NUM_NOTIFY will + * return the value given to MPI_WIN_SET_NUM_NOTIFY." The count is set to + * exactly what was asked for -- note this differs from earlier drafts of + * the chapter, which forbade decreasing it. + * + * "All notification counters (both existing and newly attached) are reset + * to zero by this call." Zero the whole reserved region rather than just + * the attached prefix, so that counters left over from a previous, larger + * attachment cannot resurface if the count is raised again. It is + * erroneous to call this while an access epoch is open, so no origin can be + * incrementing our counters concurrently and plain stores are sufficient. */ + memset((void *) osc_sm_target_notify_base(module, rank), 0, + OSC_SM_MAX_NOTIFY_COUNTERS * sizeof(int64_t)); + module->node_states[rank].notify_counter_count = (uint32_t) num_notifications; + opal_atomic_wmb(); + + /* "MPI_WIN_SET_NUM_NOTIFY is a blocking, synchronizing collective + * procedure; it will not return until all MPI processes in the group of the + * window have called the function and all processes have adjusted the + * number of notification counters attached to the window." Each rank + * publishes its own count into the shared segment above, so the barrier is + * all that is needed to make every rank's count visible to every other -- + * no counts have to be exchanged. */ + ret = module->comm->c_coll->coll_barrier(module->comm, + module->comm->c_coll->coll_barrier_module); + if (OMPI_SUCCESS != ret) { + return ret; + } + + return OMPI_SUCCESS; +} + +int +ompi_osc_sm_win_get_num_notify(struct ompi_win_t *win, + int target_rank, + int *num_notifications) +{ + ompi_osc_sm_module_t *module = (ompi_osc_sm_module_t *) win->w_osc_module; + + if (target_rank < 0 || target_rank >= ompi_comm_size(module->comm)) { + return MPI_ERR_RANK; + } + + /* MPI-5.1 section 12.6.1: local procedure returning the number of counters + * attached at target_rank. Every rank's count is published in the shared + * segment by MPI_WIN_SET_NUM_NOTIFY, so this is a plain read. */ + *num_notifications = (int) module->node_states[target_rank].notify_counter_count; + + return OMPI_SUCCESS; +} + int ompi_osc_sm_rput(const void *origin_addr, size_t origin_count, diff --git a/ompi/mca/osc/sm/osc_sm_component.c b/ompi/mca/osc/sm/osc_sm_component.c index 259c0826017..a50db388b3a 100644 --- a/ompi/mca/osc/sm/osc_sm_component.c +++ b/ompi/mca/osc/sm/osc_sm_component.c @@ -84,6 +84,8 @@ ompi_osc_sm_module_t ompi_osc_sm_module_template = { .osc_get_notify = ompi_osc_sm_get_notify, .osc_win_get_notify_value = ompi_osc_sm_win_get_notify_value, .osc_win_reset_notify_value = ompi_osc_sm_win_reset_notify_value, + .osc_win_set_num_notify = ompi_osc_sm_win_set_num_notify, + .osc_win_get_num_notify = ompi_osc_sm_win_get_num_notify, .osc_accumulate = ompi_osc_sm_accumulate, .osc_compare_and_swap = ompi_osc_sm_compare_and_swap, .osc_fetch_and_op = ompi_osc_sm_fetch_and_op, diff --git a/ompi/mpi/c/Makefile.am b/ompi/mpi/c/Makefile.am index 7aecd5a3411..50a16c9d134 100644 --- a/ompi/mpi/c/Makefile.am +++ b/ompi/mpi/c/Makefile.am @@ -488,6 +488,8 @@ prototype_sources = \ win_get_name.c.in \ win_get_notify_value.c.in \ win_reset_notify_value.c.in \ + win_get_num_notify.c.in \ + win_set_num_notify.c.in \ win_lock_all.c.in \ win_lock.c.in \ win_post.c.in \ @@ -702,6 +704,7 @@ interface_profile_sources = \ get_elements_x_generated.c \ get_hw_resource_info_generated.c \ get_library_version_generated.c \ + get_notify_generated.c \ get_processor_name_generated.c \ get_version_generated.c \ graph_create_generated.c \ @@ -815,6 +818,7 @@ interface_profile_sources = \ psend_init_generated.c \ publish_name_generated.c \ put_generated.c \ + put_notify_generated.c \ query_thread_generated.c \ raccumulate_generated.c \ recv_generated.c \ @@ -960,6 +964,8 @@ interface_profile_sources = \ win_get_name_generated.c \ win_get_notify_value_generated.c \ win_reset_notify_value_generated.c \ + win_get_num_notify_generated.c \ + win_set_num_notify_generated.c \ win_lock_all_generated.c \ win_lock_generated.c \ win_post_generated.c \ diff --git a/ompi/mpi/c/win_get_num_notify.c.in b/ompi/mpi/c/win_get_num_notify.c.in new file mode 100644 index 00000000000..9ec6b60b5bc --- /dev/null +++ b/ompi/mpi/c/win_get_num_notify.c.in @@ -0,0 +1,43 @@ +/* -*- Mode: C; c-basic-offset:4 ; indent-tabs-mode:nil -*- */ +/* + * Copyright (c) 2026 Triad National Security, LLC. All rights + * reserved. + * $COPYRIGHT$ + * + * Additional copyrights may follow + * + * $HEADER$ + */ +#include "ompi_config.h" + +#include "ompi/mpi/c/bindings.h" +#include "ompi/runtime/params.h" +#include "ompi/errhandler/errhandler.h" +#include "ompi/win/win.h" +#include "ompi/mca/osc/osc.h" + +PROTOTYPE ERROR_CLASS win_get_num_notify(WIN win, INT target_rank, INT_OUT num_notifications) +{ + int rc; + + if (MPI_PARAM_CHECK) { + rc = OMPI_SUCCESS; + + OMPI_ERR_INIT_FINALIZE(FUNC_NAME); + + if (ompi_win_invalid(win)) { + return OMPI_ERRHANDLER_NOHANDLE_INVOKE(MPI_ERR_WIN, FUNC_NAME); + } else if (NULL == num_notifications) { + rc = MPI_ERR_ARG; + } + + OMPI_ERRHANDLER_CHECK(rc, win, rc, FUNC_NAME); + } + + if (NULL == win->w_osc_module->osc_win_get_num_notify) { + return OMPI_ERRHANDLER_INVOKE(win, MPI_ERR_UNSUPPORTED_OPERATION, FUNC_NAME); + } + + rc = win->w_osc_module->osc_win_get_num_notify(win, target_rank, num_notifications); + OMPI_ERRHANDLER_RETURN(rc, win, rc, FUNC_NAME); +} diff --git a/ompi/mpi/c/win_set_num_notify.c.in b/ompi/mpi/c/win_set_num_notify.c.in new file mode 100644 index 00000000000..cc1d39a9e77 --- /dev/null +++ b/ompi/mpi/c/win_set_num_notify.c.in @@ -0,0 +1,48 @@ +/* -*- Mode: C; c-basic-offset:4 ; indent-tabs-mode:nil -*- */ +/* + * Copyright (c) 2026 Triad National Security, LLC. All rights + * reserved. + * $COPYRIGHT$ + * + * Additional copyrights may follow + * + * $HEADER$ + */ +#include "ompi_config.h" + +#include "ompi/mpi/c/bindings.h" +#include "ompi/runtime/params.h" +#include "ompi/errhandler/errhandler.h" +#include "ompi/win/win.h" +#include "ompi/info/info.h" +#include "ompi/mca/osc/osc.h" + +PROTOTYPE ERROR_CLASS win_set_num_notify(WIN win, INFO info, INT num_notifications) +{ + int rc; + + if (MPI_PARAM_CHECK) { + rc = OMPI_SUCCESS; + + OMPI_ERR_INIT_FINALIZE(FUNC_NAME); + + if (ompi_win_invalid(win)) { + return OMPI_ERRHANDLER_NOHANDLE_INVOKE(MPI_ERR_WIN, FUNC_NAME); + } else if (NULL != info && MPI_INFO_NULL != info && ompi_info_is_freed(info)) { + rc = MPI_ERR_INFO; + } else if (num_notifications < 0) { + rc = MPI_ERR_ARG; + } + + OMPI_ERRHANDLER_CHECK(rc, win, rc, FUNC_NAME); + } + + if (NULL == win->w_osc_module->osc_win_set_num_notify) { + return OMPI_ERRHANDLER_INVOKE(win, MPI_ERR_UNSUPPORTED_OPERATION, FUNC_NAME); + } + + rc = win->w_osc_module->osc_win_set_num_notify(win, + (NULL != info && MPI_INFO_NULL != info) ? &(info->super) : NULL, + num_notifications); + OMPI_ERRHANDLER_RETURN(rc, win, rc, FUNC_NAME); +} From 773703c1e23088b432c01e28cdb70a61cf2d4d7d Mon Sep 17 00:00:00 2001 From: Joseph Antony Date: Sun, 2 Aug 2026 00:03:55 -0400 Subject: [PATCH 19/19] osc/sm: fix notification counter ordering and index validation Three correctness problems in the osc/sm notified communication path: 1. The notification counters were plain uint64_t but are incremented concurrently by remote origins with opal_atomic_add() and polled by the local rank. Type them opal_atomic_int64_t so that the reads in MPI_WIN_GET_NOTIFY_VALUE are atomic and cannot be hoisted out of a caller's polling loop. 2. The notification index was validated *after* the data movement, so an erroneous call had already overwritten the target window (or, for get, the origin buffer) by the time the error was returned. MPI-5.1 section 12.6.1 makes referencing an out-of-range counter erroneous at initiation, so hoist the check above ompi_datatype_sndrcv() in all four notified operations. The check is factored into a helper, which also fixes MPI_GET_NOTIFY returning OMPI_ERR_BAD_PARAM instead of MPI_ERR_RMA_NOTIFICATION. 3. The get paths used opal_atomic_rmb() before incrementing the target's counter. The notification tells the target that the get has read the window, so the constraint is load-before-store, which a load-load fence does not express; opal_atomic_add() is relaxed and adds no ordering of its own. Use a full opal_atomic_mb(). In MPI_WIN_GET_NOTIFY_VALUE the barrier was likewise placed before the counter load, where it ordered nothing; move it after so that it gives the acquire semantics the caller needs. MPI_WIN_RESET_NOTIFY_VALUE also gains the trailing barrier for the same reason. Signed-off-by: Joseph Antony --- ompi/mca/osc/sm/osc_sm.h | 15 +++- ompi/mca/osc/sm/osc_sm_comm.c | 119 +++++++++++++++++++++-------- ompi/mca/osc/sm/osc_sm_component.c | 19 +++-- 3 files changed, 117 insertions(+), 36 deletions(-) diff --git a/ompi/mca/osc/sm/osc_sm.h b/ompi/mca/osc/sm/osc_sm.h index d9ac9742f80..88962891ecd 100644 --- a/ompi/mca/osc/sm/osc_sm.h +++ b/ompi/mca/osc/sm/osc_sm.h @@ -22,6 +22,12 @@ typedef uint64_t osc_sm_post_type_t; typedef opal_atomic_uint64_t osc_sm_post_atomic_type_t; #define OSC_SM_POST_BITS 6 #define OSC_SM_POST_MASK 0x3f + +/* Capacity of the per-rank notification counter region reserved in the shared + * segment at window creation, i.e. the effective + * MPI_WIN_NOTIFICATION_NUM_UB. How many of those counters are actually + * *attached* is a separate, per-rank quantity that starts at zero and is set by + * MPI_WIN_SET_NUM_NOTIFY (MPI-5.1 section 12.6.1). */ #define OSC_SM_MAX_NOTIFY_COUNTERS 16 /* data shared across all peers */ @@ -48,6 +54,10 @@ struct ompi_osc_sm_node_state_t { opal_atomic_int32_t complete_count; ompi_osc_sm_lock_t lock; opal_atomic_lock_t accumulate_lock; + /* Number of notification counters currently *attached* at this rank. Zero + * until MPI_WIN_SET_NUM_NOTIFY is called (MPI-5.1 section 12.6.1). Lives in + * the shared segment so that an origin can validate a notification index + * against the target's attached count without any communication. */ uint32_t notify_counter_count; uint64_t notify_counter_offset; /* offset from segment_base, not raw pointer */ @@ -83,7 +93,10 @@ struct ompi_osc_sm_module_t { size_t *sizes; void **bases; ptrdiff_t *disp_units; - uint64_t *notify_counters; + /* Base of the notification counter region. Typed atomic so that plain + * loads are atomic (and never hoisted out of a caller's polling loop) while + * remote origins increment the same location with opal_atomic_add(). */ + opal_atomic_int64_t *notify_counters; ompi_group_t *start_group; diff --git a/ompi/mca/osc/sm/osc_sm_comm.c b/ompi/mca/osc/sm/osc_sm_comm.c index fdb598dff29..a5b27b65fc4 100644 --- a/ompi/mca/osc/sm/osc_sm_comm.c +++ b/ompi/mca/osc/sm/osc_sm_comm.c @@ -21,15 +21,36 @@ #include "osc_sm.h" -static inline uint64_t *osc_sm_target_notify_base(ompi_osc_sm_module_t *module, int target) +static inline opal_atomic_int64_t * +osc_sm_target_notify_base(ompi_osc_sm_module_t *module, int target) { if (NULL == module->segment_base) { /* single-rank path: notify_counters is a regular local allocation */ return module->notify_counters; } - return (uint64_t *) ((char *) module->segment_base + - module->node_states[target].notify_counter_offset); + return (opal_atomic_int64_t *) ((char *) module->segment_base + + module->node_states[target].notify_counter_offset); +} + +/* MPI-5.1 section 12.6.1: "The notification counter referenced by a notified + * communication operation must be attached to the window at the target before + * the operation is initiated at the origin. Initiating a notified + * communication operation that references a notification counter that is out of + * range at the target is erroneous." + * + * The check is therefore against the *target's* attached count, and it must + * happen before any data is moved -- otherwise an erroneous call would still + * have overwritten the target window (or, for get, the origin buffer) by the + * time the error is reported. */ +static inline int +osc_sm_check_notify_idx(ompi_osc_sm_module_t *module, int target, int notify) +{ + if (notify < 0 || (uint32_t) notify >= module->node_states[target].notify_counter_count) { + return MPI_ERR_RMA_NOTIFICATION; + } + + return OMPI_SUCCESS; } int @@ -39,11 +60,24 @@ ompi_osc_sm_win_get_notify_value(struct ompi_win_t *win, { ompi_osc_sm_module_t *module = (ompi_osc_sm_module_t *) win->w_osc_module; int rank = ompi_comm_rank(module->comm); + int ret; - if (notify < 0 || (uint32_t) notify >= module->node_states[rank].notify_counter_count) { - return MPI_ERR_RMA_NOTIFICATION; + ret = osc_sm_check_notify_idx(module, rank, notify); + if (OMPI_SUCCESS != ret) { + return ret; } + /* Acquire ordering: sample the counter first, then fence, so that window + * loads issued by the caller after this call cannot be satisfied by values + * read before the notification was observed. A barrier placed ahead of the + * counter load would order nothing useful. MPI-5.1 section 12.6.2 requires + * this procedure to synchronize the public and private window copies as if + * MPI_WIN_SYNC had been called; osc/sm is a unified-memory-model component, + * so the barrier is the whole of that synchronization. + * + * The load itself is atomic because notify_counters is opal_atomic_int64_t: + * remote origins bump the same location concurrently, and the standard's + * usage model is to poll this procedure in a loop. */ *value = (OMPI_MPI_COUNT_TYPE) osc_sm_target_notify_base(module, rank)[notify]; opal_atomic_rmb(); @@ -57,14 +91,19 @@ ompi_osc_sm_win_reset_notify_value(struct ompi_win_t *win, { ompi_osc_sm_module_t *module = (ompi_osc_sm_module_t *) win->w_osc_module; int rank = ompi_comm_rank(module->comm); + int ret; - if (notify < 0 || (uint32_t) notify >= module->node_states[rank].notify_counter_count) { - return MPI_ERR_RMA_NOTIFICATION; + ret = osc_sm_check_notify_idx(module, rank, notify); + if (OMPI_SUCCESS != ret) { + return ret; } - /* Atomically swap the counter to 0 and return the previous value */ + /* Atomically swap the counter to 0 and return the previous value. Must be + * a single atomic so that increments arriving from other MPI processes + * between the read and the zeroing are not lost. */ *value = (OMPI_MPI_COUNT_TYPE) opal_atomic_swap_64( &osc_sm_target_notify_base(module, rank)[notify], 0); + opal_atomic_rmb(); return OMPI_SUCCESS; } @@ -210,6 +249,11 @@ ompi_osc_sm_rput_notify(const void *origin_addr, notify, (unsigned long) win)); + ret = osc_sm_check_notify_idx(module, target, notify); + if (OMPI_SUCCESS != ret) { + return ret; + } + remote_address = ((char*) (module->bases[target])) + module->disp_units[target] * target_disp; ret = ompi_datatype_sndrcv((void *)origin_addr, origin_count, origin_dt, @@ -218,18 +262,18 @@ ompi_osc_sm_rput_notify(const void *origin_addr, return ret; } + /* Release ordering: the data must be visible at the target before the + * notification is (MPI-5.1 section 12.3, "The notification counter will be + * updated at the target only after the completion of the data movement + * operation at the target"). */ + opal_atomic_wmb(); + opal_atomic_add(&osc_sm_target_notify_base(module, target)[notify], 1); + /* the only valid field of RMA request status is the MPI_ERROR field. * ompi_request_empty has status MPI_SUCCESS and indicates the request is * complete. */ *ompi_req = &ompi_request_empty; - if (notify < 0 || (uint32_t) notify >= module->node_states[target].notify_counter_count) { - return MPI_ERR_RMA_NOTIFICATION; - } - - opal_atomic_wmb(); - opal_atomic_add(&osc_sm_target_notify_base(module, target)[notify], 1); - return OMPI_SUCCESS; } @@ -297,6 +341,11 @@ ompi_osc_sm_rget_notify(void *origin_addr, notify, (unsigned long) win)); + ret = osc_sm_check_notify_idx(module, target, notify); + if (OMPI_SUCCESS != ret) { + return ret; + } + remote_address = ((char*) (module->bases[target])) + module->disp_units[target] * target_disp; ret = ompi_datatype_sndrcv(remote_address, target_count, target_dt, @@ -305,18 +354,20 @@ ompi_osc_sm_rget_notify(void *origin_addr, return ret; } + /* Full barrier, not opal_atomic_rmb(): the notification tells the target + * that this get has read the window, so the loads above must not be + * reordered after the counter increment below -- that is a load-before-store + * constraint, which a load-load fence does not express. opal_atomic_add() + * is relaxed (see opal/include/opal/sys/atomic_stdc.h) and supplies no + * ordering of its own. */ + opal_atomic_mb(); + opal_atomic_add(&osc_sm_target_notify_base(module, target)[notify], 1); + /* the only valid field of RMA request status is the MPI_ERROR field. * ompi_request_empty has status MPI_SUCCESS and indicates the request is * complete. */ *ompi_req = &ompi_request_empty; - if (notify < 0 || (uint32_t) notify >= module->node_states[target].notify_counter_count) { - return MPI_ERR_RMA_NOTIFICATION; - } - - opal_atomic_rmb(); - opal_atomic_add(&osc_sm_target_notify_base(module, target)[notify], 1); - return OMPI_SUCCESS; } @@ -480,6 +531,11 @@ ompi_osc_sm_put_notify(const void *origin_addr, notify, (unsigned long) win)); + ret = osc_sm_check_notify_idx(module, target, notify); + if (OMPI_SUCCESS != ret) { + return ret; + } + remote_address = ((char*) (module->bases[target])) + module->disp_units[target] * target_disp; ret = ompi_datatype_sndrcv((void *)origin_addr, origin_count, origin_dt, @@ -488,10 +544,10 @@ ompi_osc_sm_put_notify(const void *origin_addr, return ret; } - if (notify < 0 || (uint32_t) notify >= module->node_states[target].notify_counter_count) { - return MPI_ERR_RMA_NOTIFICATION; - } - + /* Release ordering: the data must be visible at the target before the + * notification is (MPI-5.1 section 12.3, "The notification counter will be + * updated at the target only after the completion of the data movement + * operation at the target"). */ opal_atomic_wmb(); opal_atomic_add(&osc_sm_target_notify_base(module, target)[notify], 1); @@ -552,6 +608,11 @@ ompi_osc_sm_get_notify(void *origin_addr, target_count, target_dt->name, (unsigned long) win)); + ret = osc_sm_check_notify_idx(module, target, notify); + if (OMPI_SUCCESS != ret) { + return ret; + } + remote_address = ((char*) (module->bases[target])) + module->disp_units[target] * target_disp; ret = ompi_datatype_sndrcv(remote_address, target_count, target_dt, @@ -559,11 +620,9 @@ ompi_osc_sm_get_notify(void *origin_addr, if (OMPI_SUCCESS != ret) { return ret; } - if (notify < 0 || (uint32_t) notify >= module->node_states[target].notify_counter_count) { - return OMPI_ERR_BAD_PARAM; - } - opal_atomic_rmb(); + /* Full barrier, not opal_atomic_rmb(): see ompi_osc_sm_rget_notify(). */ + opal_atomic_mb(); opal_atomic_add(&osc_sm_target_notify_base(module, target)[notify], 1); return ret; diff --git a/ompi/mca/osc/sm/osc_sm_component.c b/ompi/mca/osc/sm/osc_sm_component.c index a50db388b3a..9af4530c77c 100644 --- a/ompi/mca/osc/sm/osc_sm_component.c +++ b/ompi/mca/osc/sm/osc_sm_component.c @@ -260,8 +260,15 @@ component_select(struct ompi_win_t *win, void **base, size_t size, ptrdiff_t dis if (NULL == module->posts) return OMPI_ERR_TEMP_OUT_OF_RESOURCE; module->posts[0] = (osc_sm_post_atomic_type_t *) (module->posts + 1); - /* allocate notify counters for single process case */ - module->notify_counters = calloc(OSC_SM_MAX_NOTIFY_COUNTERS, sizeof(uint64_t)); + /* allocate notify counters for single process case. + * + * NOTE: osc/sm pre-attaches the full reserved capacity, whereas osc/ucx + * starts at zero and requires MPI_WIN_SET_NUM_NOTIFY before any counter + * may be referenced. MPI-5.1 section 12.6.1 does not state what the + * initial attached count is, so neither is provably wrong, but the + * divergence means a program that omits MPI_WIN_SET_NUM_NOTIFY works + * here and fails on ucx. Left as-is pending a decision. */ + module->notify_counters = calloc(OSC_SM_MAX_NOTIFY_COUNTERS, sizeof(int64_t)); if (NULL == module->notify_counters) return OMPI_ERR_TEMP_OUT_OF_RESOURCE; module->node_states[0].notify_counter_count = OSC_SM_MAX_NOTIFY_COUNTERS; module->node_states[0].notify_counter_offset = 0; @@ -394,10 +401,10 @@ component_select(struct ompi_win_t *win, void **base, size_t size, ptrdiff_t dis module->node_states = (ompi_osc_sm_node_state_t *) (module->global_state + 1); /* set up notify counters in shared memory after node_states */ - module->notify_counters = (uint64_t *) ((char *)(module->node_states + comm_size) + + module->notify_counters = (opal_atomic_int64_t *) ((char *)(module->node_states + comm_size) + OPAL_ALIGN_PAD_AMOUNT((uintptr_t)(module->node_states + comm_size), 64)); /* zero out notify counters */ - memset(module->notify_counters, 0, total_counters * sizeof(uint64_t)); + memset((void *) module->notify_counters, 0, total_counters * sizeof(int64_t)); for (i = 0, total = data_base_size, total_counters = 0 ; i < comm_size ; ++i) { if (i > 0) { @@ -593,7 +600,9 @@ ompi_osc_sm_free(struct ompi_win_t *win) module->bases[0]); } /* free notify_counters for single process case */ - free(module->notify_counters); + /* cast away the atomic/volatile qualifier for free(), as in + * opal/runtime/opal_progress.c */ + free((void *) module->notify_counters); } free(module->disp_units); free(module->outstanding_locks);