Repository: open-mpi/ompi
Pull request #13204: aarch64 op: Enable two‑stage SVE detection in component configuration
Author: login: vogma
Labels: name: Target: main
Created: 2025-04-22T10:23:15Z | Merged: 2025-05-07T21:07:51Z

This pull request refactors the build configuration for the OpenMPI aarch64 op component, aligning it with the existing approach used by the avx component.

Currently, the avx component configuration systematically tests SIMD instruction support (e.g., AVX2, AVX512) by incrementally applying compiler flags until compilation succeeds, independent from the host CPU's capabilities. In contrast, the existing aarch64 configuration lacks this mechanism, performing only basic compilation checks without utilizing additional flags or function attributes.

To address this gap, this pull request enhances the aarch64 configuration by incorporating checks using compiler function attributes (specifically, `__attribute__((__target__("+sve")))`). This enables SVE code and includes it in OpenMPI regardless of compiler flags provided explicitly via the command line, just like the avx component already does.

If compilation via function attribute is successful, the attribute is automatically inserted via macro into the SVE function templates within op_aarch64_functions.c. Runtime detection of processor capabilities (NEON or SVE) remains unchanged. No API's have been changed, only the build systems is modified along with a macro definition in the source files.

There is a discussion that goes into more detail in the [developer user group](https://groups.google.com/a/lists.open-mpi.org/g/devel/c/_s2VZF3jJAs/m/x4QA0ssSDwAJ).


Diff:
diff --git a/ompi/mca/op/aarch64/configure.m4 b/ompi/mca/op/aarch64/configure.m4
index 08d62b2e2f8..cf052900e7d 100644
--- a/ompi/mca/op/aarch64/configure.m4
+++ b/ompi/mca/op/aarch64/configure.m4
@@ -13,7 +13,7 @@
 #
 
 # MCA_ompi_op_arm_CONFIG([action-if-can-compile],
-#		         [action-if-cant-compile])
+#                        [action-if-cant-compile])
 # ------------------------------------------------
 AC_DEFUN([MCA_ompi_op_aarch64_CONFIG],[
     AC_CONFIG_FILES([ompi/mca/op/aarch64/Makefile])
@@ -74,33 +74,70 @@ AC_DEFUN([MCA_ompi_op_aarch64_CONFIG],[
            #
            # Check for SVE support
            #
-           AC_CACHE_CHECK([for SVE support], op_cv_sve_support,
-                 [AS_IF([test "$op_cv_neon_support" = "yes"],
-                        [
-                          AC_LINK_IFELSE(
-                              [AC_LANG_PROGRAM([[
+          AC_CACHE_CHECK([for SVE support], [op_cv_sve_support], [
+              AC_MSG_RESULT([])      
+              # initialize result variables
+              op_cv_sve_support=no
+              op_cv_sve_add_flags=no
+
+              # first attempt: no extra flags
+              AC_MSG_CHECKING([for SVE support (no additional flags)])
+              AC_LINK_IFELSE(
+                  [AC_LANG_SOURCE([[
 #if defined(__aarch64__) && defined(__ARM_FEATURE_SVE)
 #include <arm_sve.h>
 #else
 #error "No support for __aarch64__ or SVE"
 #endif
-                                             ]],
-                                             [[
-#if defined(__aarch64__) && defined(_ARM_FEATURE_SVE)
-    svfloat32_t vA;
-    vA = svdup_n_f32(0)
+
+int main(void) {
+  svfloat32_t vA;
+  vA = svdup_n_f32(0);
+  return 0;
+}
+               ]])],
+               [ op_cv_sve_support=yes
+                 AC_MSG_RESULT([yes]) ],
+               [ AC_MSG_RESULT([no ]) ]
+             )
+
+            # second attempt: use +sve attribute
+            AS_IF([test "$op_cv_sve_support" = "no"],[
+                AC_MSG_CHECKING([for SVE support (with +sve)])
+                AC_LINK_IFELSE(
+                    [AC_LANG_SOURCE([[
+#if defined(__aarch64__) && defined(__linux__)
+  #include <arm_sve.h>
+#else
+  #error "this feature is only supported on aarch64 + linux platforms"
 #endif
-                                             ]])],
-                      [op_cv_sve_support=yes],
-                      [op_cv_sve_support=no])])])
-          ])
 
+__attribute__((__target__("+sve")))
+int main(void) {
+  svbool_t    pg = svptrue_b32();
+  svuint32_t  a  = svdup_u32(0);
+  svuint32_t  b  = svdup_u32(0);
+  svuint32_t  c  = svadd_u32_m(pg, a, b);
+  return (int)svaddv_u32(pg, c);
+}
+                 ]])],
+                 [ op_cv_sve_support=yes
+                   op_cv_sve_add_flags=yes
+                   AC_MSG_RESULT([yes]) ],
+                 [ AC_MSG_RESULT([no ]) ]
+               )
+             ])
+           ])
+
+           AC_LANG_POP
+])
     AM_CONDITIONAL([MCA_BUILD_ompi_op_has_neon_support],
                    [test "$op_cv_neon_support" = "yes"])
     AM_CONDITIONAL([MCA_BUILD_ompi_op_has_neon_fp_support],
                    [test "$op_cv_neon_fp_support" = "yes"])
     AM_CONDITIONAL([MCA_BUILD_ompi_op_has_sve_support],
                    [test "$op_cv_sve_support" = "yes"])
+
     AC_SUBST(MCA_BUILD_ompi_op_has_neon_support)
     AC_SUBST(MCA_BUILD_ompi_op_has_neon_fp_support)
     AC_SUBST(MCA_BUILD_ompi_op_has_sve_support)
@@ -111,9 +148,12 @@ AC_DEFUN([MCA_ompi_op_aarch64_CONFIG],[
           [AC_DEFINE([OMPI_MCA_OP_HAVE_NEON_FP], [1],[NEON FP supported in the current build])])
     AS_IF([test "$op_cv_sve_support" = "yes"],
           [AC_DEFINE([OMPI_MCA_OP_HAVE_SVE], [1],[SVE supported in the current build])])
+    AS_IF([test "$op_cv_sve_add_flags" = "yes"],
+          [AC_DEFINE([OMPI_MCA_OP_SVE_EXTRA_FLAGS], [1],[SVE supported with additional compile attributes])],
+          [AC_DEFINE([OMPI_MCA_OP_SVE_EXTRA_FLAGS], [0],[SVE not supported])])
 
-    # If we have at least support for Neon
-    AS_IF([test "$op_cv_neon_support" = "yes"],
+    # If we have at least support for Neon or SVE
+    AS_IF([test "$op_cv_neon_support" = "yes" || test "$op_cv_sve_support" = "yes" ],
           [$1],
           [$2])
 ])dnl
diff --git a/ompi/mca/op/aarch64/op_aarch64.h b/ompi/mca/op/aarch64/op_aarch64.h
index 22be89614c6..4b6699df189 100644
--- a/ompi/mca/op/aarch64/op_aarch64.h
+++ b/ompi/mca/op/aarch64/op_aarch64.h
@@ -24,6 +24,12 @@
 
 BEGIN_C_DECLS
 
+#if OMPI_MCA_OP_SVE_EXTRA_FLAGS
+#define OMPI_SVE_ATTR __attribute__ ((__target__ ("+sve")))
+#else
+#define OMPI_SVE_ATTR
+#endif
+
 /**
  * Derive a struct from the base op component struct, allowing us to
  * cache some component-specific information on our well-known
diff --git a/ompi/mca/op/aarch64/op_aarch64_component.c b/ompi/mca/op/aarch64/op_aarch64_component.c
index 92bf4fa3656..b01ef427c84 100644
--- a/ompi/mca/op/aarch64/op_aarch64_component.c
+++ b/ompi/mca/op/aarch64/op_aarch64_component.c
@@ -101,7 +101,7 @@ static int mca_op_aarch64_component_close(void)
 /*
  * Register MCA params.
  */
-static int mca_op_aarch64_component_register(void)
+OMPI_SVE_ATTR static int mca_op_aarch64_component_register(void)
 {
 
     mca_op_aarch64_component.hardware_available = 1;  /* Check for Neon */
diff --git a/ompi/mca/op/aarch64/op_aarch64_functions.c b/ompi/mca/op/aarch64/op_aarch64_functions.c
index 5515ddb9567..58866024866 100644
--- a/ompi/mca/op/aarch64/op_aarch64_functions.c
+++ b/ompi/mca/op/aarch64/op_aarch64_functions.c
@@ -137,6 +137,7 @@ _Generic((*(out)), \
     }
 #elif defined(GENERATE_SVE_CODE)
 #define OP_AARCH64_FUNC(name, type_name, type_size, type_cnt, type, op)           \
+    OMPI_SVE_ATTR                                                                 \
     static void OP_CONCAT(ompi_op_aarch64_2buff_##name##_##type##type_size##_t, APPEND) \
                             (const void *_in, void *_out, int *count,             \
                              struct ompi_datatype_t **dtype,                      \
@@ -303,6 +304,7 @@ static void OP_CONCAT(ompi_op_aarch64_3buff_##name##_##type##type_size##_t, APPE
 }
 #elif defined(GENERATE_SVE_CODE)
 #define OP_AARCH64_FUNC_3BUFF(name, type_name, type_size, type_cnt, type, op)             \
+OMPI_SVE_ATTR                                                                             \
 static void OP_CONCAT(ompi_op_aarch64_3buff_##name##_##type##type_size##_t, APPEND)       \
                              (const void *_in1, const void *_in2, void *_out, int *count, \
                               struct ompi_datatype_t **dtype,                             \


Reviews:
user: login: jsquyres
body: Unless I'm missing something, it looks ok to squash the code changes in this PR down to a single commit.

If you'd like to preserve your whitespace changes, please separate those into a separate commit and label them as such (e.g., 11ff7f07ce1c885d2bdd7c52fe90bb51cf679892).
state: COMMENTED
author_association: MEMBER
submitted_at: 2025-04-22T13:42:30Z
user: login: bosilca
state: COMMENTED
author_association: MEMBER
submitted_at: 2025-04-22T13:47:27Z
user: login: vogma
state: COMMENTED
author_association: CONTRIBUTOR
submitted_at: 2025-04-22T17:14:03Z
user: login: vogma
state: COMMENTED
author_association: CONTRIBUTOR
submitted_at: 2025-04-22T17:18:59Z
user: login: vogma
state: COMMENTED
author_association: CONTRIBUTOR
submitted_at: 2025-04-22T17:20:34Z
user: login: vogma
state: COMMENTED
author_association: CONTRIBUTOR
submitted_at: 2025-04-22T17:20:58Z
user: login: vogma
state: COMMENTED
author_association: CONTRIBUTOR
submitted_at: 2025-04-22T17:22:38Z
user: login: bosilca
state: DISMISSED
author_association: MEMBER
submitted_at: 2025-04-22T18:21:49Z
user: login: vogma
state: COMMENTED
author_association: CONTRIBUTOR
submitted_at: 2025-04-22T18:27:54Z
user: login: jsquyres
state: COMMENTED
author_association: MEMBER
submitted_at: 2025-05-03T15:28:17Z
user: login: jsquyres
body: @vogma The macos CI error appears to be legitimate -- I can reproduce it manually.  When I build on my Mac (M3) and try to run the ring_c example:

```
$ mpirun --map-by ppr:1:core examples/ring_c
--------------------------------------------------------------------------
prterun noticed that process rank 8 with PID 60263 on node Little-Beezle exited on
signal 4 (Illegal instruction: 4).
--------------------------------------------------------------------------
```

Can you investigate?
state: CHANGES_REQUESTED
author_association: MEMBER
submitted_at: 2025-05-03T15:38:32Z
user: login: vogma
state: COMMENTED
author_association: CONTRIBUTOR
submitted_at: 2025-05-05T15:20:31Z
user: login: jsquyres
state: COMMENTED
author_association: MEMBER
submitted_at: 2025-05-05T17:48:14Z
user: login: vogma
state: COMMENTED
author_association: CONTRIBUTOR
submitted_at: 2025-05-05T19:00:28Z
user: login: vogma
state: COMMENTED
author_association: CONTRIBUTOR
submitted_at: 2025-05-05T19:00:50Z
user: login: jsquyres
state: APPROVED
author_association: MEMBER
submitted_at: 2025-05-05T20:14:12Z
user: login: bosilca
body: Seems to run just fine on both M3 and grace.
state: APPROVED
author_association: MEMBER
submitted_at: 2025-05-07T21:07:44Z

Review comments:
diff_hunk: @@ -71,49 +72,95 @@ AC_DEFUN([MCA_ompi_op_aarch64_CONFIG],[
                             [op_cv_neon_fp_support=yes],
                             [op_cv_neon_fp_support=no])])])
 
-           #
+    
+                  #
path: ompi/mca/op/aarch64/configure.m4
user: login: jsquyres
body: Nit: spurious whitespace changes.
created_at: 2025-04-22T13:31:02Z
author_association: MEMBER
diff_hunk: @@ -71,49 +72,95 @@ AC_DEFUN([MCA_ompi_op_aarch64_CONFIG],[
                             [op_cv_neon_fp_support=yes],
                             [op_cv_neon_fp_support=no])])])
 
-           #
+    
+                  #
            # Check for SVE support
            #
-           AC_CACHE_CHECK([for SVE support], op_cv_sve_support,
-                 [AS_IF([test "$op_cv_neon_support" = "yes"],
-                        [
-                          AC_LINK_IFELSE(
-                              [AC_LANG_PROGRAM([[
+           AC_CACHE_CHECK([for SVE support], [op_cv_sve_support], [
+             AC_MSG_RESULT([])      
path: ompi/mca/op/aarch64/configure.m4
user: login: jsquyres
body: Please use 4-space tabs consistently to match the style of the rest of the Open MPI code base.
created_at: 2025-04-22T13:32:46Z
author_association: MEMBER
diff_hunk: @@ -71,49 +72,95 @@ AC_DEFUN([MCA_ompi_op_aarch64_CONFIG],[
                             [op_cv_neon_fp_support=yes],
                             [op_cv_neon_fp_support=no])])])
 
-           #
+    
+                  #
            # Check for SVE support
            #
-           AC_CACHE_CHECK([for SVE support], op_cv_sve_support,
-                 [AS_IF([test "$op_cv_neon_support" = "yes"],
-                        [
-                          AC_LINK_IFELSE(
-                              [AC_LANG_PROGRAM([[
+           AC_CACHE_CHECK([for SVE support], [op_cv_sve_support], [
+             AC_MSG_RESULT([])      
+             # initialize result variables
+             op_cv_sve_support=no
+             op_cv_sve_add_flags=no
+
+             # first attempt: no extra flags
+             AC_MSG_CHECKING([for SVE support (no additional flags)])
+             AC_LINK_IFELSE(
+               [AC_LANG_SOURCE([[
 #if defined(__aarch64__) && defined(__ARM_FEATURE_SVE)
-#include <arm_sve.h>
+  #include <arm_sve.h>
 #else
-#error "No support for __aarch64__ or SVE"
+  #error "No support for __aarch64__ or SVE"
 #endif
-                                             ]],
-                                             [[
-#if defined(__aarch64__) && defined(_ARM_FEATURE_SVE)
-    svfloat32_t vA;
-    vA = svdup_n_f32(0)
+
+int main(void) {
+  svfloat32_t vA;
+  vA = svdup_n_f32(0);
+  return 0;
+}
+               ]])],
+               [ op_cv_sve_support=yes
+                 AC_MSG_RESULT([yes]) ],
+               [ AC_MSG_RESULT([no ]) ]
+             )
+
+             # second attempt: use +sve attribute
+             AS_IF([test "$op_cv_sve_support" = "no"],[
+               AC_MSG_CHECKING([for SVE support (with +sve)])
+               AC_LINK_IFELSE(
+                 [AC_LANG_SOURCE([[
+#if defined(__aarch64__)
+  #include <arm_sve.h>
+#else
+  #error "not on aarch64"
 #endif
-                                             ]])],
-                      [op_cv_sve_support=yes],
-                      [op_cv_sve_support=no])])])
-          ])
 
+__attribute__((__target__("+sve")))
+int main(void) {
+  svbool_t    pg = svptrue_b32();
+  svuint32_t  a  = svdup_u32(0);
+  svuint32_t  b  = svdup_u32(0);
+  svuint32_t  c  = svadd_u32_m(pg, a, b);
+  return (int)svaddv_u32(pg, c);
+}
+                 ]])],
+                 [ op_cv_sve_support=yes
+                   op_cv_sve_add_flags=yes
+                   AC_MSG_RESULT([yes]) ],
+                 [ AC_MSG_RESULT([no ]) ]
+               )
+             ])
+           ])
+
+           # restore the language after our C tests
+           AC_LANG_POP
+])
     AM_CONDITIONAL([MCA_BUILD_ompi_op_has_neon_support],
                    [test "$op_cv_neon_support" = "yes"])
     AM_CONDITIONAL([MCA_BUILD_ompi_op_has_neon_fp_support],
                    [test "$op_cv_neon_fp_support" = "yes"])
     AM_CONDITIONAL([MCA_BUILD_ompi_op_has_sve_support],
                    [test "$op_cv_sve_support" = "yes"])
+    AM_CONDITIONAL([MCA_BUILD_ompi_op_sve_add_flags],
+                   [test "$op_cv_sve_add_flags" = "yes"])
+
     AC_SUBST(MCA_BUILD_ompi_op_has_neon_support)
     AC_SUBST(MCA_BUILD_ompi_op_has_neon_fp_support)
     AC_SUBST(MCA_BUILD_ompi_op_has_sve_support)
+    AC_SUBST(MCA_BUILD_ompi_op_sve_add_flags)
 
     AS_IF([test "$op_cv_neon_support" = "yes"],
           [AC_DEFINE([OMPI_MCA_OP_HAVE_NEON], [1],[NEON supported in the current build])])
     AS_IF([test "$op_cv_neon_fp_support" = "yes"],
           [AC_DEFINE([OMPI_MCA_OP_HAVE_NEON_FP], [1],[NEON FP supported in the current build])])
     AS_IF([test "$op_cv_sve_support" = "yes"],
           [AC_DEFINE([OMPI_MCA_OP_HAVE_SVE], [1],[SVE supported in the current build])])
+    AS_IF([test "$op_cv_sve_add_flags" = "yes"],
+          [AC_DEFINE([OMPI_MCA_OP_SVE_EXTRA_FLAGS], [1],[SVE supported with additional compile attributes])])
path: ompi/mca/op/aarch64/configure.m4
user: login: jsquyres
body: I see you're extending the style of how it was already done in this component, but our style guide specifically states that we should *always* define boolean macros to 0 or 1 (vs. define them or not define them): https://docs.open-mpi.org/en/v5.0.x/developers/source-code.html#c-c
created_at: 2025-04-22T13:35:46Z
author_association: MEMBER
diff_hunk: @@ -136,24 +136,25 @@ _Generic((*(out)), \
         }                                                                                     \
     }
 #elif defined(GENERATE_SVE_CODE)
-#define OP_AARCH64_FUNC(name, type_name, type_size, type_cnt, type, op)           \
+#define OP_AARCH64_FUNC(name, type_name, type_size, type_cnt, type, op)                 \
+    SVE_ATTR                                                                            \    
     static void OP_CONCAT(ompi_op_aarch64_2buff_##name##_##type##type_size##_t, APPEND) \
-                            (const void *_in, void *_out, int *count,             \
-                             struct ompi_datatype_t **dtype,                      \
-                             struct ompi_op_base_module_1_0_0_t *module)          \
-    {                                                                             \
-        const int types_per_step = svcnt(*((type##type_size##_t *) _in));         \
-        const int cnt = *count;                                                   \
-        type##type_size##_t *in = (type##type_size##_t *) _in,                    \
-                            *out = (type##type_size##_t *) _out;                  \
-        OP_CONCAT(OMPI_OP_TYPE_PREPEND, type##type_size##_t) vsrc, vdst;          \
-        for (int idx=0; idx < cnt; idx += types_per_step) {                    \
-            svbool_t pred = svwhilelt_b##type_size(idx, cnt);                     \
-            vsrc = svld1(pred, &in[idx]);                                         \
-            vdst = svld1(pred, &out[idx]);                                        \
-            vdst = OP_CONCAT(OMPI_OP_OP_PREPEND, op##_x)(pred, vdst, vsrc);       \
-            OP_CONCAT(OMPI_OP_OP_PREPEND, st1)(pred, &out[idx], vdst);            \
-        }                                                                         \
+                            (const void *_in, void *_out, int *count,                   \
+                             struct ompi_datatype_t **dtype,                            \
+                             struct ompi_op_base_module_1_0_0_t *module)                \
+    {                                                                                   \
+        const int types_per_step = svcnt(*((type##type_size##_t *) _in));               \
+        const int cnt = *count;                                                         \
+        type##type_size##_t *in = (type##type_size##_t *) _in,                          \
+                            *out = (type##type_size##_t *) _out;                        \
+        OP_CONCAT(OMPI_OP_TYPE_PREPEND, type##type_size##_t) vsrc, vdst;                \
+        for (int idx=0; idx < cnt; idx += types_per_step) {                             \
+            svbool_t pred = svwhilelt_b##type_size(idx, cnt);                           \
+            vsrc = svld1(pred, &in[idx]);                                               \
+            vdst = svld1(pred, &out[idx]);                                              \
+            vdst = OP_CONCAT(OMPI_OP_OP_PREPEND, op##_x)(pred, vdst, vsrc);             \
+            OP_CONCAT(OMPI_OP_OP_PREPEND, st1)(pred, &out[idx], vdst);                  \
+        }                                                                               \
path: ompi/mca/op/aarch64/op_aarch64_functions.c
user: login: jsquyres
body: Is there a reason for this whitespace change?
created_at: 2025-04-22T13:36:48Z
author_association: MEMBER
diff_hunk: @@ -302,25 +303,26 @@ static void OP_CONCAT(ompi_op_aarch64_3buff_##name##_##type##type_size##_t, APPE
     }                                                                                     \
 }
 #elif defined(GENERATE_SVE_CODE)
-#define OP_AARCH64_FUNC_3BUFF(name, type_name, type_size, type_cnt, type, op)             \
-static void OP_CONCAT(ompi_op_aarch64_3buff_##name##_##type##type_size##_t, APPEND)       \
-                             (const void *_in1, const void *_in2, void *_out, int *count, \
-                              struct ompi_datatype_t **dtype,                             \
-                              struct ompi_op_base_module_1_0_0_t *module)                 \
-{                                                                                         \
-    const int types_per_step = svcnt(*((type##type_size##_t *) _in1));                    \
-    type##type_size##_t *in1 = (type##type_size##_t *) _in1,                              \
-                        *in2 = (type##type_size##_t *) _in2,                              \
-                        *out = (type##type_size##_t *) _out;                              \
-    const int cnt = *count;                                                               \
-    OP_CONCAT(OMPI_OP_TYPE_PREPEND, type##type_size##_t) vsrc, vdst;                      \
-    for (int idx=0; idx < cnt; idx += types_per_step) {                                   \
-        svbool_t pred = svwhilelt_b##type_size(idx, cnt);                                 \
-        vsrc = svld1(pred, &in1[idx]);                                                    \
-        vdst = svld1(pred, &in2[idx]);                                                    \
-        vdst = OP_CONCAT(OMPI_OP_OP_PREPEND, op##_x)(pred, vdst, vsrc);                   \
-        OP_CONCAT(OMPI_OP_OP_PREPEND, st1)(pred, &out[idx], vdst);                        \
-    }                                                                                     \
+#define OP_AARCH64_FUNC_3BUFF(name, type_name, type_size, type_cnt, type, op)                   \
+    SVE_ATTR                                                                                    \
+    static void OP_CONCAT(ompi_op_aarch64_3buff_##name##_##type##type_size##_t, APPEND)         \
+                             (const void *_in1, const void *_in2, void *_out, int *count,       \
+                              struct ompi_datatype_t **dtype,                                   \
+                              struct ompi_op_base_module_1_0_0_t *module)                       \
+{                                                                                               \
+    const int types_per_step = svcnt(*((type##type_size##_t *) _in1));                          \
+    type##type_size##_t *in1 = (type##type_size##_t *) _in1,                                    \
+                        *in2 = (type##type_size##_t *) _in2,                                    \
+                        *out = (type##type_size##_t *) _out;                                    \
+    const int cnt = *count;                                                                     \
+    OP_CONCAT(OMPI_OP_TYPE_PREPEND, type##type_size##_t) vsrc, vdst;                            \
+    for (int idx=0; idx < cnt; idx += types_per_step) {                                         \
+        svbool_t pred = svwhilelt_b##type_size(idx, cnt);                                       \
+        vsrc = svld1(pred, &in1[idx]);                                                          \
+        vdst = svld1(pred, &in2[idx]);                                                          \
+        vdst = OP_CONCAT(OMPI_OP_OP_PREPEND, op##_x)(pred, vdst, vsrc);                         \
+        OP_CONCAT(OMPI_OP_OP_PREPEND, st1)(pred, &out[idx], vdst);                              \
+    }                                                                                           \
path: ompi/mca/op/aarch64/op_aarch64_functions.c
user: login: jsquyres
body: Is there a code change here (besides the addition of `SVE_ATTR`), or is this just a whitespace change?

Whitespace changes are fine, but please put them in standalone commits where the commit message makes it clear that there are no code or logic changes.  Otherwise, it makes it difficult to code review these changes (i.e., we have to minutely compare the two blocks to see if anything changed).
created_at: 2025-04-22T13:38:44Z
author_association: MEMBER
diff_hunk: @@ -136,24 +136,25 @@ _Generic((*(out)), \
         }                                                                                     \
     }
 #elif defined(GENERATE_SVE_CODE)
-#define OP_AARCH64_FUNC(name, type_name, type_size, type_cnt, type, op)           \
+#define OP_AARCH64_FUNC(name, type_name, type_size, type_cnt, type, op)                 \
+    SVE_ATTR                                                                            \
path: ompi/mca/op/aarch64/op_aarch64_functions.c
user: login: bosilca
body: Please don't change the indentation, it makes the patch look much bigger than it is. At the end, the only difference here is that you added SVE_ATTR in from of the function definition.
created_at: 2025-04-22T13:46:25Z
author_association: MEMBER
diff_hunk: @@ -71,49 +72,95 @@ AC_DEFUN([MCA_ompi_op_aarch64_CONFIG],[
                             [op_cv_neon_fp_support=yes],
                             [op_cv_neon_fp_support=no])])])
 
-           #
+    
+                  #
path: ompi/mca/op/aarch64/configure.m4
user: login: vogma
body: Fixed, thanks
created_at: 2025-04-22T17:14:03Z
author_association: CONTRIBUTOR
diff_hunk: @@ -71,49 +72,95 @@ AC_DEFUN([MCA_ompi_op_aarch64_CONFIG],[
                             [op_cv_neon_fp_support=yes],
                             [op_cv_neon_fp_support=no])])])
 
-           #
+    
+                  #
            # Check for SVE support
            #
-           AC_CACHE_CHECK([for SVE support], op_cv_sve_support,
-                 [AS_IF([test "$op_cv_neon_support" = "yes"],
-                        [
-                          AC_LINK_IFELSE(
-                              [AC_LANG_PROGRAM([[
+           AC_CACHE_CHECK([for SVE support], [op_cv_sve_support], [
+             AC_MSG_RESULT([])      
+             # initialize result variables
+             op_cv_sve_support=no
+             op_cv_sve_add_flags=no
+
+             # first attempt: no extra flags
+             AC_MSG_CHECKING([for SVE support (no additional flags)])
+             AC_LINK_IFELSE(
+               [AC_LANG_SOURCE([[
 #if defined(__aarch64__) && defined(__ARM_FEATURE_SVE)
-#include <arm_sve.h>
+  #include <arm_sve.h>
 #else
-#error "No support for __aarch64__ or SVE"
+  #error "No support for __aarch64__ or SVE"
 #endif
-                                             ]],
-                                             [[
-#if defined(__aarch64__) && defined(_ARM_FEATURE_SVE)
-    svfloat32_t vA;
-    vA = svdup_n_f32(0)
+
+int main(void) {
+  svfloat32_t vA;
+  vA = svdup_n_f32(0);
+  return 0;
+}
+               ]])],
+               [ op_cv_sve_support=yes
+                 AC_MSG_RESULT([yes]) ],
+               [ AC_MSG_RESULT([no ]) ]
+             )
+
+             # second attempt: use +sve attribute
+             AS_IF([test "$op_cv_sve_support" = "no"],[
+               AC_MSG_CHECKING([for SVE support (with +sve)])
+               AC_LINK_IFELSE(
+                 [AC_LANG_SOURCE([[
+#if defined(__aarch64__)
+  #include <arm_sve.h>
+#else
+  #error "not on aarch64"
 #endif
-                                             ]])],
-                      [op_cv_sve_support=yes],
-                      [op_cv_sve_support=no])])])
-          ])
 
+__attribute__((__target__("+sve")))
+int main(void) {
+  svbool_t    pg = svptrue_b32();
+  svuint32_t  a  = svdup_u32(0);
+  svuint32_t  b  = svdup_u32(0);
+  svuint32_t  c  = svadd_u32_m(pg, a, b);
+  return (int)svaddv_u32(pg, c);
+}
+                 ]])],
+                 [ op_cv_sve_support=yes
+                   op_cv_sve_add_flags=yes
+                   AC_MSG_RESULT([yes]) ],
+                 [ AC_MSG_RESULT([no ]) ]
+               )
+             ])
+           ])
+
+           # restore the language after our C tests
+           AC_LANG_POP
+])
     AM_CONDITIONAL([MCA_BUILD_ompi_op_has_neon_support],
                    [test "$op_cv_neon_support" = "yes"])
     AM_CONDITIONAL([MCA_BUILD_ompi_op_has_neon_fp_support],
                    [test "$op_cv_neon_fp_support" = "yes"])
     AM_CONDITIONAL([MCA_BUILD_ompi_op_has_sve_support],
                    [test "$op_cv_sve_support" = "yes"])
+    AM_CONDITIONAL([MCA_BUILD_ompi_op_sve_add_flags],
+                   [test "$op_cv_sve_add_flags" = "yes"])
+
     AC_SUBST(MCA_BUILD_ompi_op_has_neon_support)
     AC_SUBST(MCA_BUILD_ompi_op_has_neon_fp_support)
     AC_SUBST(MCA_BUILD_ompi_op_has_sve_support)
+    AC_SUBST(MCA_BUILD_ompi_op_sve_add_flags)
 
     AS_IF([test "$op_cv_neon_support" = "yes"],
           [AC_DEFINE([OMPI_MCA_OP_HAVE_NEON], [1],[NEON supported in the current build])])
     AS_IF([test "$op_cv_neon_fp_support" = "yes"],
           [AC_DEFINE([OMPI_MCA_OP_HAVE_NEON_FP], [1],[NEON FP supported in the current build])])
     AS_IF([test "$op_cv_sve_support" = "yes"],
           [AC_DEFINE([OMPI_MCA_OP_HAVE_SVE], [1],[SVE supported in the current build])])
+    AS_IF([test "$op_cv_sve_add_flags" = "yes"],
+          [AC_DEFINE([OMPI_MCA_OP_SVE_EXTRA_FLAGS], [1],[SVE supported with additional compile attributes])])
path: ompi/mca/op/aarch64/configure.m4
user: login: vogma
body: I added the definition of the macro with 0 and adjusted the header file to check via `#if ...`
But if I understand correctly, all macros inside the aarch64 `configuration.m4` file should always be defined and checked in the source code via `#if ...` and not `#if defined(...)`. If so, do you prefer these changes in this PR or should I open another one?   
created_at: 2025-04-22T17:18:58Z
author_association: CONTRIBUTOR
diff_hunk: @@ -302,25 +303,26 @@ static void OP_CONCAT(ompi_op_aarch64_3buff_##name##_##type##type_size##_t, APPE
     }                                                                                     \
 }
 #elif defined(GENERATE_SVE_CODE)
-#define OP_AARCH64_FUNC_3BUFF(name, type_name, type_size, type_cnt, type, op)             \
-static void OP_CONCAT(ompi_op_aarch64_3buff_##name##_##type##type_size##_t, APPEND)       \
-                             (const void *_in1, const void *_in2, void *_out, int *count, \
-                              struct ompi_datatype_t **dtype,                             \
-                              struct ompi_op_base_module_1_0_0_t *module)                 \
-{                                                                                         \
-    const int types_per_step = svcnt(*((type##type_size##_t *) _in1));                    \
-    type##type_size##_t *in1 = (type##type_size##_t *) _in1,                              \
-                        *in2 = (type##type_size##_t *) _in2,                              \
-                        *out = (type##type_size##_t *) _out;                              \
-    const int cnt = *count;                                                               \
-    OP_CONCAT(OMPI_OP_TYPE_PREPEND, type##type_size##_t) vsrc, vdst;                      \
-    for (int idx=0; idx < cnt; idx += types_per_step) {                                   \
-        svbool_t pred = svwhilelt_b##type_size(idx, cnt);                                 \
-        vsrc = svld1(pred, &in1[idx]);                                                    \
-        vdst = svld1(pred, &in2[idx]);                                                    \
-        vdst = OP_CONCAT(OMPI_OP_OP_PREPEND, op##_x)(pred, vdst, vsrc);                   \
-        OP_CONCAT(OMPI_OP_OP_PREPEND, st1)(pred, &out[idx], vdst);                        \
-    }                                                                                     \
+#define OP_AARCH64_FUNC_3BUFF(name, type_name, type_size, type_cnt, type, op)                   \
+    SVE_ATTR                                                                                    \
+    static void OP_CONCAT(ompi_op_aarch64_3buff_##name##_##type##type_size##_t, APPEND)         \
+                             (const void *_in1, const void *_in2, void *_out, int *count,       \
+                              struct ompi_datatype_t **dtype,                                   \
+                              struct ompi_op_base_module_1_0_0_t *module)                       \
+{                                                                                               \
+    const int types_per_step = svcnt(*((type##type_size##_t *) _in1));                          \
+    type##type_size##_t *in1 = (type##type_size##_t *) _in1,                                    \
+                        *in2 = (type##type_size##_t *) _in2,                                    \
+                        *out = (type##type_size##_t *) _out;                                    \
+    const int cnt = *count;                                                                     \
+    OP_CONCAT(OMPI_OP_TYPE_PREPEND, type##type_size##_t) vsrc, vdst;                            \
+    for (int idx=0; idx < cnt; idx += types_per_step) {                                         \
+        svbool_t pred = svwhilelt_b##type_size(idx, cnt);                                       \
+        vsrc = svld1(pred, &in1[idx]);                                                          \
+        vdst = svld1(pred, &in2[idx]);                                                          \
+        vdst = OP_CONCAT(OMPI_OP_OP_PREPEND, op##_x)(pred, vdst, vsrc);                         \
+        OP_CONCAT(OMPI_OP_OP_PREPEND, st1)(pred, &out[idx], vdst);                              \
+    }                                                                                           \
path: ompi/mca/op/aarch64/op_aarch64_functions.c
user: login: vogma
body: Absolutely agree! Sorry for the confusion. I reverted the code so that only the `SVE_ATTR` line is changed
created_at: 2025-04-22T17:20:34Z
author_association: CONTRIBUTOR
diff_hunk: @@ -136,24 +136,25 @@ _Generic((*(out)), \
         }                                                                                     \
     }
 #elif defined(GENERATE_SVE_CODE)
-#define OP_AARCH64_FUNC(name, type_name, type_size, type_cnt, type, op)           \
+#define OP_AARCH64_FUNC(name, type_name, type_size, type_cnt, type, op)                 \
+    SVE_ATTR                                                                            \
path: ompi/mca/op/aarch64/op_aarch64_functions.c
user: login: vogma
body: Agree, thanks for the feedback
created_at: 2025-04-22T17:20:58Z
author_association: CONTRIBUTOR
diff_hunk: @@ -136,24 +136,25 @@ _Generic((*(out)), \
         }                                                                                     \
     }
 #elif defined(GENERATE_SVE_CODE)
-#define OP_AARCH64_FUNC(name, type_name, type_size, type_cnt, type, op)           \
+#define OP_AARCH64_FUNC(name, type_name, type_size, type_cnt, type, op)                 \
+    SVE_ATTR                                                                            \    
     static void OP_CONCAT(ompi_op_aarch64_2buff_##name##_##type##type_size##_t, APPEND) \
-                            (const void *_in, void *_out, int *count,             \
-                             struct ompi_datatype_t **dtype,                      \
-                             struct ompi_op_base_module_1_0_0_t *module)          \
-    {                                                                             \
-        const int types_per_step = svcnt(*((type##type_size##_t *) _in));         \
-        const int cnt = *count;                                                   \
-        type##type_size##_t *in = (type##type_size##_t *) _in,                    \
-                            *out = (type##type_size##_t *) _out;                  \
-        OP_CONCAT(OMPI_OP_TYPE_PREPEND, type##type_size##_t) vsrc, vdst;          \
-        for (int idx=0; idx < cnt; idx += types_per_step) {                    \
-            svbool_t pred = svwhilelt_b##type_size(idx, cnt);                     \
-            vsrc = svld1(pred, &in[idx]);                                         \
-            vdst = svld1(pred, &out[idx]);                                        \
-            vdst = OP_CONCAT(OMPI_OP_OP_PREPEND, op##_x)(pred, vdst, vsrc);       \
-            OP_CONCAT(OMPI_OP_OP_PREPEND, st1)(pred, &out[idx], vdst);            \
-        }                                                                         \
+                            (const void *_in, void *_out, int *count,                   \
+                             struct ompi_datatype_t **dtype,                            \
+                             struct ompi_op_base_module_1_0_0_t *module)                \
+    {                                                                                   \
+        const int types_per_step = svcnt(*((type##type_size##_t *) _in));               \
+        const int cnt = *count;                                                         \
+        type##type_size##_t *in = (type##type_size##_t *) _in,                          \
+                            *out = (type##type_size##_t *) _out;                        \
+        OP_CONCAT(OMPI_OP_TYPE_PREPEND, type##type_size##_t) vsrc, vdst;                \
+        for (int idx=0; idx < cnt; idx += types_per_step) {                             \
+            svbool_t pred = svwhilelt_b##type_size(idx, cnt);                           \
+            vsrc = svld1(pred, &in[idx]);                                               \
+            vdst = svld1(pred, &out[idx]);                                              \
+            vdst = OP_CONCAT(OMPI_OP_OP_PREPEND, op##_x)(pred, vdst, vsrc);             \
+            OP_CONCAT(OMPI_OP_OP_PREPEND, st1)(pred, &out[idx], vdst);                  \
+        }                                                                               \
path: ompi/mca/op/aarch64/op_aarch64_functions.c
user: login: vogma
body: Not really, now only my modification should be in the changelist
created_at: 2025-04-22T17:22:38Z
author_association: CONTRIBUTOR
diff_hunk: @@ -71,49 +72,95 @@ AC_DEFUN([MCA_ompi_op_aarch64_CONFIG],[
                             [op_cv_neon_fp_support=yes],
                             [op_cv_neon_fp_support=no])])])
 
-           #
+    
+                  #
            # Check for SVE support
            #
-           AC_CACHE_CHECK([for SVE support], op_cv_sve_support,
-                 [AS_IF([test "$op_cv_neon_support" = "yes"],
-                        [
-                          AC_LINK_IFELSE(
-                              [AC_LANG_PROGRAM([[
+           AC_CACHE_CHECK([for SVE support], [op_cv_sve_support], [
+             AC_MSG_RESULT([])      
path: ompi/mca/op/aarch64/configure.m4
user: login: vogma
body: i tried to use 4-space tabs in the code that i added to the `configure.m4` file. If i have missed any let me know 
created_at: 2025-04-22T18:27:54Z
author_association: CONTRIBUTOR
diff_hunk: @@ -71,49 +72,95 @@ AC_DEFUN([MCA_ompi_op_aarch64_CONFIG],[
                             [op_cv_neon_fp_support=yes],
                             [op_cv_neon_fp_support=no])])])
 
-           #
+    
+                  #
            # Check for SVE support
            #
-           AC_CACHE_CHECK([for SVE support], op_cv_sve_support,
-                 [AS_IF([test "$op_cv_neon_support" = "yes"],
-                        [
-                          AC_LINK_IFELSE(
-                              [AC_LANG_PROGRAM([[
+           AC_CACHE_CHECK([for SVE support], [op_cv_sve_support], [
+             AC_MSG_RESULT([])      
+             # initialize result variables
+             op_cv_sve_support=no
+             op_cv_sve_add_flags=no
+
+             # first attempt: no extra flags
+             AC_MSG_CHECKING([for SVE support (no additional flags)])
+             AC_LINK_IFELSE(
+               [AC_LANG_SOURCE([[
 #if defined(__aarch64__) && defined(__ARM_FEATURE_SVE)
-#include <arm_sve.h>
+  #include <arm_sve.h>
 #else
-#error "No support for __aarch64__ or SVE"
+  #error "No support for __aarch64__ or SVE"
 #endif
-                                             ]],
-                                             [[
-#if defined(__aarch64__) && defined(_ARM_FEATURE_SVE)
-    svfloat32_t vA;
-    vA = svdup_n_f32(0)
+
+int main(void) {
+  svfloat32_t vA;
+  vA = svdup_n_f32(0);
+  return 0;
+}
+               ]])],
+               [ op_cv_sve_support=yes
+                 AC_MSG_RESULT([yes]) ],
+               [ AC_MSG_RESULT([no ]) ]
+             )
+
+             # second attempt: use +sve attribute
+             AS_IF([test "$op_cv_sve_support" = "no"],[
+               AC_MSG_CHECKING([for SVE support (with +sve)])
+               AC_LINK_IFELSE(
+                 [AC_LANG_SOURCE([[
+#if defined(__aarch64__)
+  #include <arm_sve.h>
+#else
+  #error "not on aarch64"
 #endif
-                                             ]])],
-                      [op_cv_sve_support=yes],
-                      [op_cv_sve_support=no])])])
-          ])
 
+__attribute__((__target__("+sve")))
+int main(void) {
+  svbool_t    pg = svptrue_b32();
+  svuint32_t  a  = svdup_u32(0);
+  svuint32_t  b  = svdup_u32(0);
+  svuint32_t  c  = svadd_u32_m(pg, a, b);
+  return (int)svaddv_u32(pg, c);
+}
+                 ]])],
+                 [ op_cv_sve_support=yes
+                   op_cv_sve_add_flags=yes
+                   AC_MSG_RESULT([yes]) ],
+                 [ AC_MSG_RESULT([no ]) ]
+               )
+             ])
+           ])
+
+           # restore the language after our C tests
+           AC_LANG_POP
+])
     AM_CONDITIONAL([MCA_BUILD_ompi_op_has_neon_support],
                    [test "$op_cv_neon_support" = "yes"])
     AM_CONDITIONAL([MCA_BUILD_ompi_op_has_neon_fp_support],
                    [test "$op_cv_neon_fp_support" = "yes"])
     AM_CONDITIONAL([MCA_BUILD_ompi_op_has_sve_support],
                    [test "$op_cv_sve_support" = "yes"])
+    AM_CONDITIONAL([MCA_BUILD_ompi_op_sve_add_flags],
+                   [test "$op_cv_sve_add_flags" = "yes"])
+
     AC_SUBST(MCA_BUILD_ompi_op_has_neon_support)
     AC_SUBST(MCA_BUILD_ompi_op_has_neon_fp_support)
     AC_SUBST(MCA_BUILD_ompi_op_has_sve_support)
+    AC_SUBST(MCA_BUILD_ompi_op_sve_add_flags)
 
     AS_IF([test "$op_cv_neon_support" = "yes"],
           [AC_DEFINE([OMPI_MCA_OP_HAVE_NEON], [1],[NEON supported in the current build])])
     AS_IF([test "$op_cv_neon_fp_support" = "yes"],
           [AC_DEFINE([OMPI_MCA_OP_HAVE_NEON_FP], [1],[NEON FP supported in the current build])])
     AS_IF([test "$op_cv_sve_support" = "yes"],
           [AC_DEFINE([OMPI_MCA_OP_HAVE_SVE], [1],[SVE supported in the current build])])
+    AS_IF([test "$op_cv_sve_add_flags" = "yes"],
+          [AC_DEFINE([OMPI_MCA_OP_SVE_EXTRA_FLAGS], [1],[SVE supported with additional compile attributes])])
path: ompi/mca/op/aarch64/configure.m4
user: login: jsquyres
body: I totally missed your comment here, sorry for the delay!

Yes, let's separate the change-the-style for the old macros.  I don't have much of an opinion as to whether that's a separate commit on this PR or a separate PR -- whichever is easier for you.

Thanks!
created_at: 2025-05-03T15:28:17Z
author_association: MEMBER
diff_hunk: @@ -71,49 +72,95 @@ AC_DEFUN([MCA_ompi_op_aarch64_CONFIG],[
                             [op_cv_neon_fp_support=yes],
                             [op_cv_neon_fp_support=no])])])
 
-           #
+    
+                  #
            # Check for SVE support
            #
-           AC_CACHE_CHECK([for SVE support], op_cv_sve_support,
-                 [AS_IF([test "$op_cv_neon_support" = "yes"],
-                        [
-                          AC_LINK_IFELSE(
-                              [AC_LANG_PROGRAM([[
+           AC_CACHE_CHECK([for SVE support], [op_cv_sve_support], [
+             AC_MSG_RESULT([])      
+             # initialize result variables
+             op_cv_sve_support=no
+             op_cv_sve_add_flags=no
+
+             # first attempt: no extra flags
+             AC_MSG_CHECKING([for SVE support (no additional flags)])
+             AC_LINK_IFELSE(
+               [AC_LANG_SOURCE([[
 #if defined(__aarch64__) && defined(__ARM_FEATURE_SVE)
-#include <arm_sve.h>
+  #include <arm_sve.h>
 #else
-#error "No support for __aarch64__ or SVE"
+  #error "No support for __aarch64__ or SVE"
 #endif
-                                             ]],
-                                             [[
-#if defined(__aarch64__) && defined(_ARM_FEATURE_SVE)
-    svfloat32_t vA;
-    vA = svdup_n_f32(0)
+
+int main(void) {
+  svfloat32_t vA;
+  vA = svdup_n_f32(0);
+  return 0;
+}
+               ]])],
+               [ op_cv_sve_support=yes
+                 AC_MSG_RESULT([yes]) ],
+               [ AC_MSG_RESULT([no ]) ]
+             )
+
+             # second attempt: use +sve attribute
+             AS_IF([test "$op_cv_sve_support" = "no"],[
+               AC_MSG_CHECKING([for SVE support (with +sve)])
+               AC_LINK_IFELSE(
+                 [AC_LANG_SOURCE([[
+#if defined(__aarch64__)
+  #include <arm_sve.h>
+#else
+  #error "not on aarch64"
 #endif
-                                             ]])],
-                      [op_cv_sve_support=yes],
-                      [op_cv_sve_support=no])])])
-          ])
 
+__attribute__((__target__("+sve")))
+int main(void) {
+  svbool_t    pg = svptrue_b32();
+  svuint32_t  a  = svdup_u32(0);
+  svuint32_t  b  = svdup_u32(0);
+  svuint32_t  c  = svadd_u32_m(pg, a, b);
+  return (int)svaddv_u32(pg, c);
+}
+                 ]])],
+                 [ op_cv_sve_support=yes
+                   op_cv_sve_add_flags=yes
+                   AC_MSG_RESULT([yes]) ],
+                 [ AC_MSG_RESULT([no ]) ]
+               )
+             ])
+           ])
+
+           # restore the language after our C tests
+           AC_LANG_POP
+])
     AM_CONDITIONAL([MCA_BUILD_ompi_op_has_neon_support],
                    [test "$op_cv_neon_support" = "yes"])
     AM_CONDITIONAL([MCA_BUILD_ompi_op_has_neon_fp_support],
                    [test "$op_cv_neon_fp_support" = "yes"])
     AM_CONDITIONAL([MCA_BUILD_ompi_op_has_sve_support],
                    [test "$op_cv_sve_support" = "yes"])
+    AM_CONDITIONAL([MCA_BUILD_ompi_op_sve_add_flags],
+                   [test "$op_cv_sve_add_flags" = "yes"])
+
     AC_SUBST(MCA_BUILD_ompi_op_has_neon_support)
     AC_SUBST(MCA_BUILD_ompi_op_has_neon_fp_support)
     AC_SUBST(MCA_BUILD_ompi_op_has_sve_support)
+    AC_SUBST(MCA_BUILD_ompi_op_sve_add_flags)
 
     AS_IF([test "$op_cv_neon_support" = "yes"],
           [AC_DEFINE([OMPI_MCA_OP_HAVE_NEON], [1],[NEON supported in the current build])])
     AS_IF([test "$op_cv_neon_fp_support" = "yes"],
           [AC_DEFINE([OMPI_MCA_OP_HAVE_NEON_FP], [1],[NEON FP supported in the current build])])
     AS_IF([test "$op_cv_sve_support" = "yes"],
           [AC_DEFINE([OMPI_MCA_OP_HAVE_SVE], [1],[SVE supported in the current build])])
+    AS_IF([test "$op_cv_sve_add_flags" = "yes"],
+          [AC_DEFINE([OMPI_MCA_OP_SVE_EXTRA_FLAGS], [1],[SVE supported with additional compile attributes])])
path: ompi/mca/op/aarch64/configure.m4
user: login: vogma
body: I will create a separate PR
created_at: 2025-05-05T15:20:31Z
author_association: CONTRIBUTOR
diff_hunk: @@ -24,6 +24,12 @@
 
 BEGIN_C_DECLS
 
+#if OMPI_MCA_OP_SVE_EXTRA_FLAGS
+#define SVE_ATTR __attribute__ ((__target__ ("+sve")))
+#else
+#define SVE_ATTR
path: ompi/mca/op/aarch64/op_aarch64.h
user: login: jsquyres
body: We tend to prefix our macros so that we know that they were created / set by Open MPI-specific logic.

```suggestion
#define OMPI_SVE_ATTR __attribute__ ((__target__ ("+sve")))
#else
#define OMPI_SVE_ATTR
```
created_at: 2025-05-05T17:46:18Z
author_association: MEMBER
diff_hunk: @@ -111,9 +148,14 @@ AC_DEFUN([MCA_ompi_op_aarch64_CONFIG],[
           [AC_DEFINE([OMPI_MCA_OP_HAVE_NEON_FP], [1],[NEON FP supported in the current build])])
     AS_IF([test "$op_cv_sve_support" = "yes"],
           [AC_DEFINE([OMPI_MCA_OP_HAVE_SVE], [1],[SVE supported in the current build])])
+    AS_IF([test "$op_cv_sve_add_flags" = "yes"],
+          [AC_DEFINE([OMPI_MCA_OP_SVE_EXTRA_FLAGS], [1],[SVE supported with additional compile attributes])],
+          [AC_DEFINE([OMPI_MCA_OP_SVE_EXTRA_FLAGS], [0],[SVE not supported])])
 
-    # If we have at least support for Neon
-    AS_IF([test "$op_cv_neon_support" = "yes"],
+
+
path: ompi/mca/op/aarch64/configure.m4
user: login: jsquyres
body: Nit: probably only need 1 blank line between these blocks, not 3.
created_at: 2025-05-05T17:47:12Z
author_association: MEMBER
diff_hunk: @@ -111,9 +148,14 @@ AC_DEFUN([MCA_ompi_op_aarch64_CONFIG],[
           [AC_DEFINE([OMPI_MCA_OP_HAVE_NEON_FP], [1],[NEON FP supported in the current build])])
     AS_IF([test "$op_cv_sve_support" = "yes"],
           [AC_DEFINE([OMPI_MCA_OP_HAVE_SVE], [1],[SVE supported in the current build])])
+    AS_IF([test "$op_cv_sve_add_flags" = "yes"],
+          [AC_DEFINE([OMPI_MCA_OP_SVE_EXTRA_FLAGS], [1],[SVE supported with additional compile attributes])],
+          [AC_DEFINE([OMPI_MCA_OP_SVE_EXTRA_FLAGS], [0],[SVE not supported])])
 
-    # If we have at least support for Neon
-    AS_IF([test "$op_cv_neon_support" = "yes"],
+
+
path: ompi/mca/op/aarch64/configure.m4
user: login: vogma
body: Fixed
created_at: 2025-05-05T19:00:28Z
author_association: CONTRIBUTOR
diff_hunk: @@ -24,6 +24,12 @@
 
 BEGIN_C_DECLS
 
+#if OMPI_MCA_OP_SVE_EXTRA_FLAGS
+#define SVE_ATTR __attribute__ ((__target__ ("+sve")))
+#else
+#define SVE_ATTR
path: ompi/mca/op/aarch64/op_aarch64.h
user: login: vogma
body: Makes sense
created_at: 2025-05-05T19:00:50Z
author_association: CONTRIBUTOR

PR comments:
user: login: vogma
created_at: 2025-04-22T19:16:16Z
body: I'm working on the failed test. On my AWS Graviton Instance the Tests run fine but i get an Illegal Instruction error when openmpi was compiled with lower -march flags.  Looking into it..
EDIT: Actually i have accidentally set the -march parameter too high, with `-march=armv8-a` the examples run  
author_association: CONTRIBUTOR
user: login: vogma
created_at: 2025-05-04T15:45:57Z
body: Thank you for testing it on your machine! I will try to find out why this happens.
author_association: CONTRIBUTOR
user: login: vogma
created_at: 2025-05-05T15:23:26Z
body: I do not have access to Apple hardware but the macOS failure likely stems from executing this line in user mode:

`__asm__("mrs %0, ID_AA64PFR0_EL1" : "=r"(id_aa64pfr0_el1));`

On AArch64, `MRS …, ID_AA64PFR0_EL1` is a privileged EL1 register access and will raise SIGILL if executed from EL0.

Linux’s kernel transparently traps SIGILL for certain system registers (including the SVE feature bits) and emulates their values in user space (see https://www.kernel.org/doc/html/latest/arch/arm64/cpu-feature-registers.html#implementation). To my knowledge macOS offers no equivalent SIGILL‐hook emulation of EL1 registers, so any direct MRS ID_AA64PFR0_EL1 from user code will fault. In this PR, the build-system refactoring enabled runtime SVE detection even when the hardware used during compilation did not support it, exercising the inline-asm path that was previously bypassed - hence the new SIGILL.

I updated the configure logic to skip the EL1‐based runtime feature probe on Apple platforms and tested the failed examples in the CI/CD pipeline on all available AWS Graviton generations (Graviton 2-4) and had no problems. 

Could you rerun the tests please? 
author_association: CONTRIBUTOR
user: login: jsquyres
created_at: 2025-05-05T17:48:44Z
body: Also, could you squash down to 1 commit?  We prefer rebasing and squashing over merging from `main`.  Thanks!
author_association: MEMBER
user: login: jsquyres
created_at: 2025-05-05T17:54:37Z
body: I forgot to mention: testing with the PR code today works on my Mac M3.  🎉 
author_association: MEMBER
user: login: jsquyres
created_at: 2025-05-05T20:12:43Z
body: Latest PR works for me on my Mac.

@bosilca Can you review?
author_association: MEMBER
user: login: jsquyres
created_at: 2025-05-07T21:21:52Z
body: @vogma Can you file a PR with a cherry-pick to the v5.0.x PR?  (`git cherry-pick -x ...hash from this PR...`)

Thanks!
author_association: MEMBER