From 2b49d5fe76d2ea238b50b5250269d0606afa6d68 Mon Sep 17 00:00:00 2001 From: Ryan Padrone Date: Wed, 28 Jan 2026 10:45:03 -0800 Subject: [PATCH 01/15] Add integral-constant-expression validation for collapse, tile, cache, and gang clauses --- Tests/acc_integral_constant_expression.F90 | 337 +++++++++++++++++++++ Tests/acc_integral_constant_expression.c | 256 ++++++++++++++++ Tests/acc_integral_constant_expression.cpp | 253 ++++++++++++++++ 3 files changed, 846 insertions(+) create mode 100644 Tests/acc_integral_constant_expression.F90 create mode 100644 Tests/acc_integral_constant_expression.c create mode 100644 Tests/acc_integral_constant_expression.cpp diff --git a/Tests/acc_integral_constant_expression.F90 b/Tests/acc_integral_constant_expression.F90 new file mode 100644 index 0000000..979547e --- /dev/null +++ b/Tests/acc_integral_constant_expression.F90 @@ -0,0 +1,337 @@ +#ifndef T1 +!T1:syntax,collapse-clause,runtime,loop,V:3.4- + LOGICAL FUNCTION test1() + IMPLICIT NONE + INCLUDE "acc_testsuite.Fh" + INTEGER, PARAMETER :: M_T1 = 64, N_T1 = 16 + INTEGER :: i, j, idx, errors + REAL(8), DIMENSION(M_T1*N_T1) :: a, b, c + + errors = 0 + DO idx = 1, M_T1*N_T1 + a(idx) = DBLE(idx) + b(idx) = DBLE(2*idx) + c(idx) = 0.0D0 + END DO + + !$acc data copyin(a(1:M_T1*N_T1), b(1:M_T1*N_T1)) copy(c(1:M_T1*N_T1)) + !$acc parallel loop collapse(2) + DO i = 1, M_T1 + DO j = 1, N_T1 + idx = (i-1)*N_T1 + j + c(idx) = a(idx) + b(idx) + END DO + END DO + !$acc end parallel loop + !$acc end data + + DO idx = 1, M_T1*N_T1 + IF (ABS(c(idx)-(a(idx)+b(idx))) .GT. PRECISION) errors = errors + 1 + END DO + test1 = (errors .NE. 0) + END FUNCTION +#endif + + +#ifndef T2 +!T2:syntax,collapse-clause,runtime,loop,V:3.4- + LOGICAL FUNCTION test2() + IMPLICIT NONE + INCLUDE "acc_testsuite.Fh" + INTEGER, PARAMETER :: COLL_T2 = 1 + 1 + INTEGER, PARAMETER :: M_T2 = 48, N_T2 = 12 + INTEGER :: i, j, idx, errors + REAL(8), DIMENSION(M_T2*N_T2) :: a, b, c + + errors = 0 + DO idx = 1, M_T2*N_T2 + a(idx) = DBLE(idx+2) + b(idx) = DBLE(idx-1) + c(idx) = 0.0D0 + END DO + + !$acc data copyin(a(1:M_T2*N_T2), b(1:M_T2*N_T2)) copy(c(1:M_T2*N_T2)) + !$acc parallel loop collapse(COLL_T2) + DO i = 1, M_T2 + DO j = 1, N_T2 + idx = (i-1)*N_T2 + j + c(idx) = a(idx) + b(idx) + END DO + END DO + !$acc end parallel loop + !$acc end data + + DO idx = 1, M_T2*N_T2 + IF (ABS(c(idx)-(a(idx)+b(idx))) .GT. PRECISION) errors = errors + 1 + END DO + test2 = (errors .NE. 0) + END FUNCTION +#endif + + +#ifndef T3 +!T3:syntax,tile-clause,runtime,loop,V:3.4- + LOGICAL FUNCTION test3() + IMPLICIT NONE + INCLUDE "acc_testsuite.Fh" + INTEGER, PARAMETER :: M_T3 = 256 + INTEGER :: i, errors + REAL(8), DIMENSION(M_T3) :: a, c + + errors = 0 + DO i = 1, M_T3 + a(i) = DBLE(i) + c(i) = 0.0D0 + END DO + + !$acc data copyin(a(1:M_T3)) copy(c(1:M_T3)) + !$acc parallel loop tile(2) + DO i = 1, M_T3 + c(i) = 2.0D0 * a(i) + END DO + !$acc end parallel loop + !$acc end data + + DO i = 1, M_T3 + IF (ABS(c(i) - 2.0D0*a(i)) .GT. PRECISION) errors = errors + 1 + END DO + test3 = (errors .NE. 0) + END FUNCTION +#endif + + +#ifndef T4 +!T4:syntax,tile-clause,runtime,loop,V:3.4- + LOGICAL FUNCTION test4() + IMPLICIT NONE + INCLUDE "acc_testsuite.Fh" + INTEGER, PARAMETER :: TILE2_T4 = 2 + INTEGER, PARAMETER :: M_T4 = 64, N_T4 = 40 + INTEGER :: i, j, idx, errors + REAL(8), DIMENSION(M_T4*N_T4) :: a, b, c + + errors = 0 + DO idx = 1, M_T4*N_T4 + a(idx) = DBLE(idx+1) + b(idx) = DBLE(3*idx) + c(idx) = 0.0D0 + END DO + + !$acc data copyin(a(1:M_T4*N_T4), b(1:M_T4*N_T4)) copy(c(1:M_T4*N_T4)) + !$acc parallel loop tile(TILE2_T4, 2) + DO i = 1, M_T4 + DO j = 1, N_T4 + idx = (i-1)*N_T4 + j + c(idx) = a(idx) + b(idx) + END DO + END DO + !$acc end parallel loop + !$acc end data + + DO idx = 1, M_T4*N_T4 + IF (ABS(c(idx)-(a(idx)+b(idx))) .GT. PRECISION) errors = errors + 1 + END DO + test4 = (errors .NE. 0) + END FUNCTION +#endif + +#ifndef T5 +!T5:syntax,cache-directive,runtime,compute,V:3.4- + LOGICAL FUNCTION test5() + IMPLICIT NONE + INCLUDE "acc_testsuite.Fh" + INTEGER, PARAMETER :: M_T5 = 1024 + INTEGER, PARAMETER :: L_T5 = 16 + INTEGER, PARAMETER :: LO_T5 = 32 + INTEGER :: i, errors + REAL(8), DIMENSION(M_T5) :: p, cp + + errors = 0 + DO i = 1, M_T5 + p(i) = DBLE(i) + cp(i) = 0.0D0 + END DO + + !$acc data copyin(p(1:M_T5)) copy(cp(1:M_T5)) + + ! One-iteration loop: satisfies gfortran "cache must be inside loop" + ! and avoids Cray executing cache per-iteration in the real loop. + !$acc parallel loop + DO i = 1, 1 + !$acc cache(p(LO_T5:LO_T5+L_T5-1)) + cp(1) = cp(1) ! no-op + END DO + !$acc end parallel loop + + !$acc parallel loop + DO i = 1, M_T5 + cp(i) = p(i) + 1.0D0 + END DO + !$acc end parallel loop + + !$acc end data + + DO i = 1, M_T5 + IF (ABS(cp(i) - (p(i)+1.0D0)) .GT. PRECISION) errors = errors + 1 + END DO + test5 = (errors .NE. 0) + END FUNCTION +#endif + +#ifndef T6 +!T6:syntax,cache-directive,runtime,compute,V:3.4- + LOGICAL FUNCTION test6() + IMPLICIT NONE + INCLUDE "acc_testsuite.Fh" + INTEGER, PARAMETER :: M_T6 = 1024 + INTEGER, PARAMETER :: LO_T6 = 40 + INTEGER, PARAMETER :: LEN_T6 = 8 + INTEGER, PARAMETER :: HI_T6 = LO_T6 + LEN_T6 - 1 + INTEGER :: i, errors + REAL(8), DIMENSION(M_T6) :: q, cq + + errors = 0 + DO i = 1, M_T6 + q(i) = DBLE(i) + cq(i) = 0.0D0 + END DO + + !$acc data copyin(q(1:M_T6)) copy(cq(1:M_T6)) + + !$acc parallel loop + DO i = 1, 1 + !$acc cache(q(LO_T6:HI_T6)) + cq(1) = cq(1) ! no-op + END DO + !$acc end parallel loop + + !$acc parallel loop + DO i = 1, M_T6 + cq(i) = q(i) * 2.0D0 + END DO + !$acc end parallel loop + + !$acc end data + + DO i = 1, M_T6 + IF (ABS(cq(i) - 2.0D0*q(i)) .GT. PRECISION) errors = errors + 1 + END DO + test6 = (errors .NE. 0) + END FUNCTION +#endif + +#ifndef T7 +!T7:syntax,gang-clause,runtime,loop,V:3.4- +! gang(dim:DIM_T7) where dim is an integral constant expression (PARAMETER), must evaluate to 1..3 +! NOTE: Some compilers may not support the 'dim:' keyword form yet; keep this as spec conformance coverage. + LOGICAL FUNCTION test7() + IMPLICIT NONE + INCLUDE "acc_testsuite.Fh" + INTEGER, PARAMETER :: M_T7 = 512 + INTEGER, PARAMETER :: DIM_T7 = 2 + INTEGER :: i, errors + REAL(8), DIMENSION(M_T7) :: a, c + + errors = 0 + DO i = 1, M_T7 + a(i) = DBLE(i) + c(i) = 0.0D0 + END DO + + !$acc data copyin(a(1:M_T7)) copy(c(1:M_T7)) + !$acc parallel loop gang(dim:DIM_T7) + DO i = 1, M_T7 + c(i) = 2.0D0 * a(i) + END DO + !$acc end parallel loop + !$acc end data + + DO i = 1, M_T7 + IF (ABS(c(i) - 2.0D0*a(i)) .GT. PRECISION) errors = errors + 1 + END DO + + test7 = (errors .NE. 0) + END FUNCTION +#endif + + PROGRAM main + IMPLICIT NONE + INCLUDE "acc_testsuite.Fh" + INTEGER :: failcode, testrun + LOGICAL :: failed +#ifndef T1 + LOGICAL :: test1 +#endif +#ifndef T2 + LOGICAL :: test2 +#endif +#ifndef T3 + LOGICAL :: test3 +#endif +#ifndef T4 + LOGICAL :: test4 +#endif +#ifndef T5 + LOGICAL :: test5 +#endif +#ifndef T6 + LOGICAL :: test6 +#endif +#ifndef T7 + LOGICAL :: test7 +#endif + + failcode = 0 + +#ifndef T1 + failed = .FALSE. + DO testrun = 1, NUM_TEST_CALLS + failed = failed .OR. test1() + END DO + IF (failed) failcode = failcode + 2**0 +#endif +#ifndef T2 + failed = .FALSE. + DO testrun = 1, NUM_TEST_CALLS + failed = failed .OR. test2() + END DO + IF (failed) failcode = failcode + 2**1 +#endif +#ifndef T3 + failed = .FALSE. + DO testrun = 1, NUM_TEST_CALLS + failed = failed .OR. test3() + END DO + IF (failed) failcode = failcode + 2**2 +#endif +#ifndef T4 + failed = .FALSE. + DO testrun = 1, NUM_TEST_CALLS + failed = failed .OR. test4() + END DO + IF (failed) failcode = failcode + 2**3 +#endif +#ifndef T5 + failed = .FALSE. + DO testrun = 1, NUM_TEST_CALLS + failed = failed .OR. test5() + END DO + IF (failed) failcode = failcode + 2**4 +#endif +#ifndef T6 + failed = .FALSE. + DO testrun = 1, NUM_TEST_CALLS + failed = failed .OR. test6() + END DO + IF (failed) failcode = failcode + 2**5 +#endif +#ifndef T7 + failed = .FALSE. + DO testrun = 1, NUM_TEST_CALLS + failed = failed .OR. test7() + END DO + IF (failed) failcode = failcode + 2**6 +#endif + + CALL EXIT(failcode) + END PROGRAM diff --git a/Tests/acc_integral_constant_expression.c b/Tests/acc_integral_constant_expression.c new file mode 100644 index 0000000..13c841c --- /dev/null +++ b/Tests/acc_integral_constant_expression.c @@ -0,0 +1,256 @@ +// acc_integral_constant_expression.c +#include "acc_testsuite.h" +#include +#include +#include +#include + +// C integer constant expressions: enums + macros +enum { ICE_ENUM2 = 2, ICE_ENUM4 = 4, ICE_ENUM_LOWER = 3 }; +#define ICE_MACRO2 (1 + 1) +#define ICE_TILE1 (2) +#define ICE_TILE2 (ICE_MACRO2) // still ICE +#define ICE_LEN4 (4) + +static int check_vec_add(const real_t* a, const real_t* b, const real_t* c, int nloc){ + int err = 0; + for(int i=0;i PRECISION) err++; + } + return err; +} + +#ifndef T1 +//T1:syntax,collapse-clause,runtime,loop,V:3.4- +// collapse(2) literal ICE (positive, non-zero) +int test1(void){ + int err = 0; + const int M = 64, N = 16; + const int MN = M*N; + real_t *a=(real_t*)malloc((size_t)MN*sizeof(real_t)); + real_t *b=(real_t*)malloc((size_t)MN*sizeof(real_t)); + real_t *c=(real_t*)malloc((size_t)MN*sizeof(real_t)); + if(!a||!b||!c){ free(a); free(b); free(c); return 1; } + + for(int i=0;i PRECISION) err++; + } + free(a); free(c); + return err; +} +#endif + +#ifndef T4 +//T4:syntax,tile-clause,runtime,loop,V:3.4- +// tile(ICE_ENUM2, ICE_MACRO2) enum + macro ICE +int test4(void){ + int err = 0; + const int M = 64, N = 40; + const int MN = M*N; + real_t *a=(real_t*)malloc((size_t)MN*sizeof(real_t)); + real_t *b=(real_t*)malloc((size_t)MN*sizeof(real_t)); + real_t *c=(real_t*)malloc((size_t)MN*sizeof(real_t)); + if(!a||!b||!c){ free(a); free(b); free(c); return 1; } + + for(int i=0;i PRECISION) err++; + } + free(a); free(c); + return err; +} +#endif + +#ifndef T6 +//T6:syntax,cache-directive,runtime,loop,V:3.4- +// cache: subarray lower:length uses ICE lower + ICE length +int test6(void){ + int err = 0; + const int M = 512; + real_t *a=(real_t*)malloc((size_t)M*sizeof(real_t)); + real_t *c=(real_t*)malloc((size_t)M*sizeof(real_t)); + if(!a||!c){ free(a); free(c); return 1; } + + for(int i=0;i PRECISION) err++; + } + free(a); free(c); + return err; +} +#endif + +#ifndef T7 +//T7:syntax,gang-clause,runtime,loop,V:3.4- +// gang(dim:ICE_ENUM2) where dim is an integral-constant-expression (enum), must evaluate to 1..3 +// NOTE: Some compilers may not support the 'dim:' keyword form yet; keep this as spec conformance coverage. +int test7(void){ + int err = 0; + const int M = 512; + real_t *a=(real_t*)malloc((size_t)M*sizeof(real_t)); + real_t *c=(real_t*)malloc((size_t)M*sizeof(real_t)); + if(!a||!c){ free(a); free(c); return 1; } + + for(int i=0;i PRECISION) err++; + } + + free(a); free(c); + return err; +} +#endif + +int main(void){ + int failcode=0, failed; +#ifndef T1 + failed=0; for(int i=0;i +#include +#include +#include + +// C++ integral constant expressions: constexpr + enum +static constexpr int ICE_CONST2 = 2; +static constexpr int ICE_CONST4 = 4; +enum class E2 : int { V = 2 }; +static constexpr int ICE_LOWER = 3; + +static int check_vec_add(const real_t* a, const real_t* b, const real_t* c, int nloc){ + int err = 0; + for(int i=0;i PRECISION) err++; + } + return err; +} + +#ifndef T1 +//T1:syntax,collapse-clause,runtime,loop,V:3.4- +// collapse(2) literal ICE +int test1(){ + int err = 0; + const int M = 64, N = 16, MN = M*N; + real_t *a=(real_t*)std::malloc((size_t)MN*sizeof(real_t)); + real_t *b=(real_t*)std::malloc((size_t)MN*sizeof(real_t)); + real_t *c=(real_t*)std::malloc((size_t)MN*sizeof(real_t)); + if(!a||!b||!c){ std::free(a); std::free(b); std::free(c); return 1; } + + for(int i=0;i PRECISION) err++; + } + std::free(a); std::free(c); + return err; +} +#endif + +#ifndef T4 +//T4:syntax,tile-clause,runtime,loop,V:3.4- +// tile(ICE_CONST2, int(E2::V)) constexpr + enum-class ICE +int test4(){ + int err = 0; + const int M = 64, N = 40, MN = M*N; + real_t *a=(real_t*)std::malloc((size_t)MN*sizeof(real_t)); + real_t *b=(real_t*)std::malloc((size_t)MN*sizeof(real_t)); + real_t *c=(real_t*)std::malloc((size_t)MN*sizeof(real_t)); + if(!a||!b||!c){ std::free(a); std::free(b); std::free(c); return 1; } + + for(int i=0;i PRECISION) err++; + } + std::free(a); std::free(c); + return err; +} +#endif + +#ifndef T6 +//T6:syntax,cache-directive,runtime,loop,V:3.4- +// cache lower:length uses ICE lower + ICE length +int test6(){ + int err = 0; + const int M = 512; + real_t *a=(real_t*)std::malloc((size_t)M*sizeof(real_t)); + real_t *c=(real_t*)std::malloc((size_t)M*sizeof(real_t)); + if(!a||!c){ std::free(a); std::free(c); return 1; } + + for(int i=0;i PRECISION) err++; + } + std::free(a); std::free(c); + return err; +} +#endif + +#ifndef T7 +//T7:syntax,gang-clause,runtime,loop,V:3.4- +// gang(dim:ICE_CONST2) where dim is an integral constant expression (constexpr), must evaluate to 1..3 +// NOTE: Some compilers may not support the 'dim:' keyword form yet; keep this as spec conformance coverage. +int test7(){ + int err = 0; + const int M = 512; + real_t *a=(real_t*)std::malloc((size_t)M*sizeof(real_t)); + real_t *c=(real_t*)std::malloc((size_t)M*sizeof(real_t)); + if(!a||!c){ std::free(a); std::free(c); return 1; } + + for(int i=0;i PRECISION) err++; + } + + std::free(a); std::free(c); + return err; +} +#endif + + +int main(){ + int failcode=0, failed; +#ifndef T1 + failed=0; for(int i=0;i Date: Mon, 2 Feb 2026 20:04:00 -0500 Subject: [PATCH 02/15] Update acc_integral_constant_expression.c got rid of literal int tests and wrote descriptions. --- Tests/acc_integral_constant_expression.c | 170 ++++++++++------------- 1 file changed, 73 insertions(+), 97 deletions(-) diff --git a/Tests/acc_integral_constant_expression.c b/Tests/acc_integral_constant_expression.c index 13c841c..07da99a 100644 --- a/Tests/acc_integral_constant_expression.c +++ b/Tests/acc_integral_constant_expression.c @@ -1,10 +1,13 @@ // acc_integral_constant_expression.c +// Validates that C integral constant expressions (macros and enums) are accepted in OpenACC clause arguments where the spec requires an integral-constant-expression. +// Uses constant expressions in clauses such as collapse, tile, cache indexing/slices, and gang(dim:) to ensure the compiler parses and applies them correctly. +// Each test performs simple array computations on the device and verifies results on the host to confirm correct runtime behavior. + #include "acc_testsuite.h" #include #include #include #include - // C integer constant expressions: enums + macros enum { ICE_ENUM2 = 2, ICE_ENUM4 = 4, ICE_ENUM_LOWER = 3 }; #define ICE_MACRO2 (1 + 1) @@ -12,59 +15,23 @@ enum { ICE_ENUM2 = 2, ICE_ENUM4 = 4, ICE_ENUM_LOWER = 3 }; #define ICE_TILE2 (ICE_MACRO2) // still ICE #define ICE_LEN4 (4) -static int check_vec_add(const real_t* a, const real_t* b, const real_t* c, int nloc){ - int err = 0; - for(int i=0;i PRECISION) err++; - } - return err; -} - #ifndef T1 //T1:syntax,collapse-clause,runtime,loop,V:3.4- -// collapse(2) literal ICE (positive, non-zero) -int test1(void){ - int err = 0; - const int M = 64, N = 16; - const int MN = M*N; - real_t *a=(real_t*)malloc((size_t)MN*sizeof(real_t)); - real_t *b=(real_t*)malloc((size_t)MN*sizeof(real_t)); - real_t *c=(real_t*)malloc((size_t)MN*sizeof(real_t)); - if(!a||!b||!c){ free(a); free(b); free(c); return 1; } - - for(int i=0;i PRECISION) err++; + } - err += check_vec_add(a,b,c,MN); - free(a); free(b); free(c); + free(a); + free(b); + free(c); return err; } #endif - -#ifndef T3 -//T3:syntax,tile-clause,runtime,loop,V:3.4- -// tile(2) literal ICE -int test3(void){ +#ifndef T2 +//T2:syntax,tile-clause,runtime,loop,V:3.4- +// tile(ICE_TILE1) macro ICE +int test2(void){ int err = 0; const int M = 256; real_t *a=(real_t*)malloc((size_t)M*sizeof(real_t)); real_t *c=(real_t*)malloc((size_t)M*sizeof(real_t)); - if(!a||!c){ free(a); free(c); return 1; } - + if(!a||!c){ + free(a); + free(c); + return 1; + } for(int i=0;i PRECISION) err++; } - free(a); free(c); + free(a); + free(c); return err; } #endif - -#ifndef T4 -//T4:syntax,tile-clause,runtime,loop,V:3.4- +#ifndef T3 +//T3:syntax,tile-clause,runtime,loop,V:3.4- // tile(ICE_ENUM2, ICE_MACRO2) enum + macro ICE -int test4(void){ +int test3(void){ int err = 0; const int M = 64, N = 40; const int MN = M*N; real_t *a=(real_t*)malloc((size_t)MN*sizeof(real_t)); real_t *b=(real_t*)malloc((size_t)MN*sizeof(real_t)); real_t *c=(real_t*)malloc((size_t)MN*sizeof(real_t)); - if(!a||!b||!c){ free(a); free(b); free(c); return 1; } - + if(!a||!b||!c){ + free(a); + free(b); + free(c); + return 1; + } for(int i=0;i PRECISION) err++; + } - err += check_vec_add(a,b,c,MN); - free(a); free(b); free(c); + free(a); + free(b); + free(c); return err; } #endif - -#ifndef T5 -//T5:syntax,cache-directive,runtime,loop,V:3.4- +#ifndef T4 +//T4:syntax,cache-directive,runtime,loop,V:3.4- // cache: element index uses ICE (enum) -int test5(void){ +int test4(void){ int err = 0; const int M = 512; real_t *a=(real_t*)malloc((size_t)M*sizeof(real_t)); real_t *c=(real_t*)malloc((size_t)M*sizeof(real_t)); - if(!a||!c){ free(a); free(c); return 1; } - + if(!a||!c){ + free(a); + free(c); + return 1; + } for(int i=0;i PRECISION) err++; } - free(a); free(c); + free(a); + free(c); return err; } #endif - -#ifndef T6 -//T6:syntax,cache-directive,runtime,loop,V:3.4- +#ifndef T5 +//T5:syntax,cache-directive,runtime,loop,V:3.4- // cache: subarray lower:length uses ICE lower + ICE length -int test6(void){ +int test5(void){ int err = 0; const int M = 512; real_t *a=(real_t*)malloc((size_t)M*sizeof(real_t)); real_t *c=(real_t*)malloc((size_t)M*sizeof(real_t)); - if(!a||!c){ free(a); free(c); return 1; } - + if(!a||!c){ + free(a); + free(c); + return 1; + } for(int i=0;i PRECISION) err++; } - free(a); free(c); + free(a); + free(c); return err; } #endif - -#ifndef T7 -//T7:syntax,gang-clause,runtime,loop,V:3.4- +#ifndef T6 +//T6:syntax,gang-clause,runtime,loop,V:3.4- // gang(dim:ICE_ENUM2) where dim is an integral-constant-expression (enum), must evaluate to 1..3 // NOTE: Some compilers may not support the 'dim:' keyword form yet; keep this as spec conformance coverage. -int test7(void){ +int test6(void){ int err = 0; const int M = 512; real_t *a=(real_t*)malloc((size_t)M*sizeof(real_t)); real_t *c=(real_t*)malloc((size_t)M*sizeof(real_t)); - if(!a||!c){ free(a); free(c); return 1; } - + if(!a||!c){ + free(a); + free(c); + return 1; + } for(int i=0;i PRECISION) err++; } - - free(a); free(c); + free(a); + free(c); return err; } #endif - int main(void){ int failcode=0, failed; #ifndef T1 @@ -248,9 +227,6 @@ int main(void){ #endif #ifndef T6 failed=0; for(int i=0;i Date: Mon, 2 Feb 2026 20:06:00 -0500 Subject: [PATCH 03/15] Update acc_integral_constant_expression.cpp removed literal int tests, fixed formatting, and added descriptions --- Tests/acc_integral_constant_expression.cpp | 174 +++++++++------------ 1 file changed, 74 insertions(+), 100 deletions(-) diff --git a/Tests/acc_integral_constant_expression.cpp b/Tests/acc_integral_constant_expression.cpp index f77dacd..f9bc1b0 100644 --- a/Tests/acc_integral_constant_expression.cpp +++ b/Tests/acc_integral_constant_expression.cpp @@ -1,67 +1,35 @@ // acc_integral_constant_expression.cpp +// Validates that C++ integral constant expressions (constexpr values and enums) are accepted in OpenACC clause arguments where the spec requires an integral-constant-expression. +// Exercises constant expressions in collapse, tile, cache indexing/slices, and gang(dim:) to confirm correct parsing and conformance to the spec’s compile-time constant requirement. +// Tests check correctness by running device loops and comparing computed results against expected host values. + #include "acc_testsuite.h" #include #include #include #include - // C++ integral constant expressions: constexpr + enum static constexpr int ICE_CONST2 = 2; static constexpr int ICE_CONST4 = 4; enum class E2 : int { V = 2 }; static constexpr int ICE_LOWER = 3; -static int check_vec_add(const real_t* a, const real_t* b, const real_t* c, int nloc){ - int err = 0; - for(int i=0;i PRECISION) err++; - } - return err; -} - #ifndef T1 //T1:syntax,collapse-clause,runtime,loop,V:3.4- -// collapse(2) literal ICE -int test1(){ - int err = 0; - const int M = 64, N = 16, MN = M*N; - real_t *a=(real_t*)std::malloc((size_t)MN*sizeof(real_t)); - real_t *b=(real_t*)std::malloc((size_t)MN*sizeof(real_t)); - real_t *c=(real_t*)std::malloc((size_t)MN*sizeof(real_t)); - if(!a||!b||!c){ std::free(a); std::free(b); std::free(c); return 1; } - - for(int i=0;i PRECISION) err++; + } + std::free(a); + std::free(b); + std::free(c); return err; } #endif - -#ifndef T3 -//T3:syntax,tile-clause,runtime,loop,V:3.4- -// tile(2) literal ICE -int test3(){ +#ifndef T2 +//T2:syntax,tile-clause,runtime,loop,V:3.4- +// tile(ICE_CONST2) constexpr ICE +int test2(){ int err = 0; const int M = 256; real_t *a=(real_t*)std::malloc((size_t)M*sizeof(real_t)); real_t *c=(real_t*)std::malloc((size_t)M*sizeof(real_t)); - if(!a||!c){ std::free(a); std::free(c); return 1; } - + if(!a||!c){ + std::free(a); + std::free(c); + return 1; + } for(int i=0;i PRECISION) err++; } - std::free(a); std::free(c); + std::free(a); + std::free(c); return err; } #endif - -#ifndef T4 -//T4:syntax,tile-clause,runtime,loop,V:3.4- +#ifndef T3 +//T3:syntax,tile-clause,runtime,loop,V:3.4- // tile(ICE_CONST2, int(E2::V)) constexpr + enum-class ICE -int test4(){ +int test3(){ int err = 0; const int M = 64, N = 40, MN = M*N; real_t *a=(real_t*)std::malloc((size_t)MN*sizeof(real_t)); real_t *b=(real_t*)std::malloc((size_t)MN*sizeof(real_t)); real_t *c=(real_t*)std::malloc((size_t)MN*sizeof(real_t)); - if(!a||!b||!c){ std::free(a); std::free(b); std::free(c); return 1; } - + if(!a||!b||!c){ + std::free(a); + std::free(b); + std::free(c); + return 1; + } for(int i=0;i PRECISION) err++; + } + std::free(a); + std::free(b); + std::free(c); return err; } #endif - -#ifndef T5 -//T5:syntax,cache-directive,runtime,loop,V:3.4- +#ifndef T4 +//T4:syntax,cache-directive,runtime,loop,V:3.4- // cache element index uses constexpr ICE -int test5(){ +int test4(){ int err = 0; const int M = 512; real_t *a=(real_t*)std::malloc((size_t)M*sizeof(real_t)); real_t *c=(real_t*)std::malloc((size_t)M*sizeof(real_t)); - if(!a||!c){ std::free(a); std::free(c); return 1; } - + if(!a||!c){ + std::free(a); + std::free(c); + return 1; + } for(int i=0;i PRECISION) err++; } - std::free(a); std::free(c); + std::free(a); + std::free(c); return err; } #endif - -#ifndef T6 -//T6:syntax,cache-directive,runtime,loop,V:3.4- +#ifndef T5 +//T5:syntax,cache-directive,runtime,loop,V:3.4- // cache lower:length uses ICE lower + ICE length -int test6(){ +int test5(){ int err = 0; const int M = 512; real_t *a=(real_t*)std::malloc((size_t)M*sizeof(real_t)); real_t *c=(real_t*)std::malloc((size_t)M*sizeof(real_t)); - if(!a||!c){ std::free(a); std::free(c); return 1; } - + if(!a||!c){ + std::free(a); + std::free(c); + return 1; + } for(int i=0;i PRECISION) err++; } - std::free(a); std::free(c); + std::free(a); + std::free(c); return err; } #endif - -#ifndef T7 -//T7:syntax,gang-clause,runtime,loop,V:3.4- +#ifndef T6 +//T6:syntax,gang-clause,runtime,loop,V:3.4- // gang(dim:ICE_CONST2) where dim is an integral constant expression (constexpr), must evaluate to 1..3 // NOTE: Some compilers may not support the 'dim:' keyword form yet; keep this as spec conformance coverage. -int test7(){ +int test6(){ int err = 0; const int M = 512; real_t *a=(real_t*)std::malloc((size_t)M*sizeof(real_t)); real_t *c=(real_t*)std::malloc((size_t)M*sizeof(real_t)); - if(!a||!c){ std::free(a); std::free(c); return 1; } - + if(!a||!c){ + std::free(a); + std::free(c); + return 1; + } for(int i=0;i PRECISION) err++; } - - std::free(a); std::free(c); + std::free(a); + std::free(c); return err; } #endif - - int main(){ int failcode=0, failed; #ifndef T1 @@ -245,9 +222,6 @@ int main(){ #endif #ifndef T6 failed=0; for(int i=0;i Date: Mon, 2 Feb 2026 20:11:32 -0500 Subject: [PATCH 04/15] Update acc_integral_constant_expression.F90 removed literal int tests and added descriptions --- Tests/acc_integral_constant_expression.F90 | 134 +++++---------------- 1 file changed, 29 insertions(+), 105 deletions(-) diff --git a/Tests/acc_integral_constant_expression.F90 b/Tests/acc_integral_constant_expression.F90 index 979547e..b2b2fa3 100644 --- a/Tests/acc_integral_constant_expression.F90 +++ b/Tests/acc_integral_constant_expression.F90 @@ -1,55 +1,22 @@ +! Validates that Fortran integer constant expressions declared as PARAMETER are accepted in OpenACC clause arguments that require an integral-constant-expression. +! Uses PARAMETER constants in collapse, tile, cache bounds/lengths, and gang(dim:) to ensure spec-conformant compile-time constants are handled correctly. +! Confirms runtime correctness by executing device computations and verifying that results match expected values after returning to the host. + #ifndef T1 !T1:syntax,collapse-clause,runtime,loop,V:3.4- LOGICAL FUNCTION test1() - IMPLICIT NONE - INCLUDE "acc_testsuite.Fh" - INTEGER, PARAMETER :: M_T1 = 64, N_T1 = 16 - INTEGER :: i, j, idx, errors - REAL(8), DIMENSION(M_T1*N_T1) :: a, b, c - - errors = 0 - DO idx = 1, M_T1*N_T1 - a(idx) = DBLE(idx) - b(idx) = DBLE(2*idx) - c(idx) = 0.0D0 - END DO - - !$acc data copyin(a(1:M_T1*N_T1), b(1:M_T1*N_T1)) copy(c(1:M_T1*N_T1)) - !$acc parallel loop collapse(2) - DO i = 1, M_T1 - DO j = 1, N_T1 - idx = (i-1)*N_T1 + j - c(idx) = a(idx) + b(idx) - END DO - END DO - !$acc end parallel loop - !$acc end data - - DO idx = 1, M_T1*N_T1 - IF (ABS(c(idx)-(a(idx)+b(idx))) .GT. PRECISION) errors = errors + 1 - END DO - test1 = (errors .NE. 0) - END FUNCTION -#endif - - -#ifndef T2 -!T2:syntax,collapse-clause,runtime,loop,V:3.4- - LOGICAL FUNCTION test2() IMPLICIT NONE INCLUDE "acc_testsuite.Fh" INTEGER, PARAMETER :: COLL_T2 = 1 + 1 INTEGER, PARAMETER :: M_T2 = 48, N_T2 = 12 INTEGER :: i, j, idx, errors REAL(8), DIMENSION(M_T2*N_T2) :: a, b, c - errors = 0 DO idx = 1, M_T2*N_T2 a(idx) = DBLE(idx+2) b(idx) = DBLE(idx-1) c(idx) = 0.0D0 END DO - !$acc data copyin(a(1:M_T2*N_T2), b(1:M_T2*N_T2)) copy(c(1:M_T2*N_T2)) !$acc parallel loop collapse(COLL_T2) DO i = 1, M_T2 @@ -60,65 +27,56 @@ LOGICAL FUNCTION test2() END DO !$acc end parallel loop !$acc end data - DO idx = 1, M_T2*N_T2 IF (ABS(c(idx)-(a(idx)+b(idx))) .GT. PRECISION) errors = errors + 1 END DO - test2 = (errors .NE. 0) + test1 = (errors .NE. 0) END FUNCTION #endif - - -#ifndef T3 -!T3:syntax,tile-clause,runtime,loop,V:3.4- - LOGICAL FUNCTION test3() +#ifndef T2 +!T2:syntax,tile-clause,runtime,loop,V:3.4- + LOGICAL FUNCTION test2() IMPLICIT NONE INCLUDE "acc_testsuite.Fh" + INTEGER, PARAMETER :: TILE_T2 = 1 + 1 INTEGER, PARAMETER :: M_T3 = 256 INTEGER :: i, errors REAL(8), DIMENSION(M_T3) :: a, c - errors = 0 DO i = 1, M_T3 a(i) = DBLE(i) c(i) = 0.0D0 END DO - !$acc data copyin(a(1:M_T3)) copy(c(1:M_T3)) - !$acc parallel loop tile(2) + !$acc parallel loop tile(TILE_T2) DO i = 1, M_T3 c(i) = 2.0D0 * a(i) END DO !$acc end parallel loop !$acc end data - DO i = 1, M_T3 IF (ABS(c(i) - 2.0D0*a(i)) .GT. PRECISION) errors = errors + 1 END DO - test3 = (errors .NE. 0) + test2 = (errors .NE. 0) END FUNCTION #endif - - -#ifndef T4 -!T4:syntax,tile-clause,runtime,loop,V:3.4- - LOGICAL FUNCTION test4() +#ifndef T3 +!T3:syntax,tile-clause,runtime,loop,V:3.4- + LOGICAL FUNCTION test3() IMPLICIT NONE INCLUDE "acc_testsuite.Fh" - INTEGER, PARAMETER :: TILE2_T4 = 2 + INTEGER, PARAMETER :: TILE2_T4 = 1 + 1 INTEGER, PARAMETER :: M_T4 = 64, N_T4 = 40 INTEGER :: i, j, idx, errors REAL(8), DIMENSION(M_T4*N_T4) :: a, b, c - errors = 0 DO idx = 1, M_T4*N_T4 a(idx) = DBLE(idx+1) b(idx) = DBLE(3*idx) c(idx) = 0.0D0 END DO - !$acc data copyin(a(1:M_T4*N_T4), b(1:M_T4*N_T4)) copy(c(1:M_T4*N_T4)) - !$acc parallel loop tile(TILE2_T4, 2) + !$acc parallel loop tile(TILE2_T4, TILE2_T4) DO i = 1, M_T4 DO j = 1, N_T4 idx = (i-1)*N_T4 + j @@ -127,17 +85,15 @@ LOGICAL FUNCTION test4() END DO !$acc end parallel loop !$acc end data - DO idx = 1, M_T4*N_T4 IF (ABS(c(idx)-(a(idx)+b(idx))) .GT. PRECISION) errors = errors + 1 END DO - test4 = (errors .NE. 0) + test3 = (errors .NE. 0) END FUNCTION #endif - -#ifndef T5 -!T5:syntax,cache-directive,runtime,compute,V:3.4- - LOGICAL FUNCTION test5() +#ifndef T4 +!T4:syntax,cache-directive,runtime,compute,V:3.4- + LOGICAL FUNCTION test4() IMPLICIT NONE INCLUDE "acc_testsuite.Fh" INTEGER, PARAMETER :: M_T5 = 1024 @@ -145,15 +101,12 @@ LOGICAL FUNCTION test5() INTEGER, PARAMETER :: LO_T5 = 32 INTEGER :: i, errors REAL(8), DIMENSION(M_T5) :: p, cp - errors = 0 DO i = 1, M_T5 p(i) = DBLE(i) cp(i) = 0.0D0 END DO - !$acc data copyin(p(1:M_T5)) copy(cp(1:M_T5)) - ! One-iteration loop: satisfies gfortran "cache must be inside loop" ! and avoids Cray executing cache per-iteration in the real loop. !$acc parallel loop @@ -162,25 +115,21 @@ LOGICAL FUNCTION test5() cp(1) = cp(1) ! no-op END DO !$acc end parallel loop - !$acc parallel loop DO i = 1, M_T5 cp(i) = p(i) + 1.0D0 END DO !$acc end parallel loop - !$acc end data - DO i = 1, M_T5 IF (ABS(cp(i) - (p(i)+1.0D0)) .GT. PRECISION) errors = errors + 1 END DO - test5 = (errors .NE. 0) + test4 = (errors .NE. 0) END FUNCTION #endif - -#ifndef T6 -!T6:syntax,cache-directive,runtime,compute,V:3.4- - LOGICAL FUNCTION test6() +#ifndef T5 +!T5:syntax,cache-directive,runtime,compute,V:3.4- + LOGICAL FUNCTION test5() IMPLICIT NONE INCLUDE "acc_testsuite.Fh" INTEGER, PARAMETER :: M_T6 = 1024 @@ -189,55 +138,46 @@ LOGICAL FUNCTION test6() INTEGER, PARAMETER :: HI_T6 = LO_T6 + LEN_T6 - 1 INTEGER :: i, errors REAL(8), DIMENSION(M_T6) :: q, cq - errors = 0 DO i = 1, M_T6 q(i) = DBLE(i) cq(i) = 0.0D0 END DO - !$acc data copyin(q(1:M_T6)) copy(cq(1:M_T6)) - !$acc parallel loop DO i = 1, 1 !$acc cache(q(LO_T6:HI_T6)) cq(1) = cq(1) ! no-op END DO !$acc end parallel loop - !$acc parallel loop DO i = 1, M_T6 cq(i) = q(i) * 2.0D0 END DO !$acc end parallel loop - !$acc end data - DO i = 1, M_T6 IF (ABS(cq(i) - 2.0D0*q(i)) .GT. PRECISION) errors = errors + 1 END DO - test6 = (errors .NE. 0) + test5 = (errors .NE. 0) END FUNCTION #endif - -#ifndef T7 -!T7:syntax,gang-clause,runtime,loop,V:3.4- +#ifndef T6 +!T6:syntax,gang-clause,runtime,loop,V:3.4- ! gang(dim:DIM_T7) where dim is an integral constant expression (PARAMETER), must evaluate to 1..3 ! NOTE: Some compilers may not support the 'dim:' keyword form yet; keep this as spec conformance coverage. - LOGICAL FUNCTION test7() + LOGICAL FUNCTION test6() IMPLICIT NONE INCLUDE "acc_testsuite.Fh" INTEGER, PARAMETER :: M_T7 = 512 INTEGER, PARAMETER :: DIM_T7 = 2 INTEGER :: i, errors REAL(8), DIMENSION(M_T7) :: a, c - errors = 0 DO i = 1, M_T7 a(i) = DBLE(i) c(i) = 0.0D0 END DO - !$acc data copyin(a(1:M_T7)) copy(c(1:M_T7)) !$acc parallel loop gang(dim:DIM_T7) DO i = 1, M_T7 @@ -245,15 +185,12 @@ LOGICAL FUNCTION test7() END DO !$acc end parallel loop !$acc end data - DO i = 1, M_T7 IF (ABS(c(i) - 2.0D0*a(i)) .GT. PRECISION) errors = errors + 1 END DO - - test7 = (errors .NE. 0) + test6 = (errors .NE. 0) END FUNCTION #endif - PROGRAM main IMPLICIT NONE INCLUDE "acc_testsuite.Fh" @@ -277,12 +214,7 @@ PROGRAM main #ifndef T6 LOGICAL :: test6 #endif -#ifndef T7 - LOGICAL :: test7 -#endif - failcode = 0 - #ifndef T1 failed = .FALSE. DO testrun = 1, NUM_TEST_CALLS @@ -325,13 +257,5 @@ PROGRAM main END DO IF (failed) failcode = failcode + 2**5 #endif -#ifndef T7 - failed = .FALSE. - DO testrun = 1, NUM_TEST_CALLS - failed = failed .OR. test7() - END DO - IF (failed) failcode = failcode + 2**6 -#endif - CALL EXIT(failcode) END PROGRAM From eade29010fbb2054a2fb0fcfaaccd2974fb28252 Mon Sep 17 00:00:00 2001 From: Ryanpadrone <159075564+Ryanpadrone@users.noreply.github.com> Date: Thu, 12 Feb 2026 20:22:11 -0500 Subject: [PATCH 05/15] Update acc_integral_constant_expression.c --- Tests/acc_integral_constant_expression.c | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) diff --git a/Tests/acc_integral_constant_expression.c b/Tests/acc_integral_constant_expression.c index 07da99a..aac63af 100644 --- a/Tests/acc_integral_constant_expression.c +++ b/Tests/acc_integral_constant_expression.c @@ -1,7 +1,12 @@ // acc_integral_constant_expression.c -// Validates that C integral constant expressions (macros and enums) are accepted in OpenACC clause arguments where the spec requires an integral-constant-expression. -// Uses constant expressions in clauses such as collapse, tile, cache indexing/slices, and gang(dim:) to ensure the compiler parses and applies them correctly. -// Each test performs simple array computations on the device and verifies results on the host to confirm correct runtime behavior. +//Feature under test (OpenACC 3.4, Section 1.6, Feb 2026): +// - Clause arguments that require an integral-constant-expression accept +// C integral constant expressions (macros and enum values). +// +// Notes: +// - Uses integral constant expressions in: collapse, tile, cache (index and slice), +// and gang(dim:) to validate compile-time constant handling. + #include "acc_testsuite.h" #include From 966540ba68055439a7a323b50c1048edbef0350a Mon Sep 17 00:00:00 2001 From: Ryanpadrone <159075564+Ryanpadrone@users.noreply.github.com> Date: Thu, 12 Feb 2026 20:22:44 -0500 Subject: [PATCH 06/15] Update acc_integral_constant_expression.cpp --- Tests/acc_integral_constant_expression.cpp | 12 +++++++++--- 1 file changed, 9 insertions(+), 3 deletions(-) diff --git a/Tests/acc_integral_constant_expression.cpp b/Tests/acc_integral_constant_expression.cpp index f9bc1b0..dd5507f 100644 --- a/Tests/acc_integral_constant_expression.cpp +++ b/Tests/acc_integral_constant_expression.cpp @@ -1,7 +1,13 @@ // acc_integral_constant_expression.cpp -// Validates that C++ integral constant expressions (constexpr values and enums) are accepted in OpenACC clause arguments where the spec requires an integral-constant-expression. -// Exercises constant expressions in collapse, tile, cache indexing/slices, and gang(dim:) to confirm correct parsing and conformance to the spec’s compile-time constant requirement. -// Tests check correctness by running device loops and comparing computed results against expected host values. +// +// Feature under test (OpenACC 3.4, Section 1.6, Feb 2026): +// - Clause arguments that require an integral-constant-expression accept +// C++ integral constant expressions (constexpr values and enum values). +// +// Notes: +// - Uses integral constant expressions in: collapse, tile, cache (index and slice), +// and gang(dim:) to validate compile-time constant handling. + #include "acc_testsuite.h" #include From 941e8aa40c9ae79b6c101f7263f898d96f7fefa8 Mon Sep 17 00:00:00 2001 From: Ryanpadrone <159075564+Ryanpadrone@users.noreply.github.com> Date: Thu, 12 Feb 2026 20:23:10 -0500 Subject: [PATCH 07/15] Update acc_integral_constant_expression.F90 --- Tests/acc_integral_constant_expression.F90 | 13 ++++++++++--- 1 file changed, 10 insertions(+), 3 deletions(-) diff --git a/Tests/acc_integral_constant_expression.F90 b/Tests/acc_integral_constant_expression.F90 index b2b2fa3..22ae99f 100644 --- a/Tests/acc_integral_constant_expression.F90 +++ b/Tests/acc_integral_constant_expression.F90 @@ -1,6 +1,13 @@ -! Validates that Fortran integer constant expressions declared as PARAMETER are accepted in OpenACC clause arguments that require an integral-constant-expression. -! Uses PARAMETER constants in collapse, tile, cache bounds/lengths, and gang(dim:) to ensure spec-conformant compile-time constants are handled correctly. -! Confirms runtime correctness by executing device computations and verifying that results match expected values after returning to the host. +! acc_integral_constant_expression.F90 +! +! Feature under test (OpenACC 3.4, Section 1.6, Feb 2026): +! - Clause arguments that require an integral-constant-expression accept +! Fortran integer constant expressions declared with PARAMETER. +! +! Notes: +! - Uses PARAMETER constants in: collapse, tile, cache bounds/lengths, +! and gang(dim:) to validate compile-time constant handling. + #ifndef T1 !T1:syntax,collapse-clause,runtime,loop,V:3.4- From 0eb29ed8d04e2c8976ed080a6913720cbdb3be4c Mon Sep 17 00:00:00 2001 From: Ryanpadrone <159075564+Ryanpadrone@users.noreply.github.com> Date: Fri, 13 Feb 2026 16:03:04 -0500 Subject: [PATCH 08/15] Update acc_integral_constant_expression.F90 --- Tests/acc_integral_constant_expression.F90 | 21 +++++++-------------- 1 file changed, 7 insertions(+), 14 deletions(-) diff --git a/Tests/acc_integral_constant_expression.F90 b/Tests/acc_integral_constant_expression.F90 index 22ae99f..f24f138 100644 --- a/Tests/acc_integral_constant_expression.F90 +++ b/Tests/acc_integral_constant_expression.F90 @@ -114,19 +114,15 @@ LOGICAL FUNCTION test4() cp(i) = 0.0D0 END DO !$acc data copyin(p(1:M_T5)) copy(cp(1:M_T5)) - ! One-iteration loop: satisfies gfortran "cache must be inside loop" - ! and avoids Cray executing cache per-iteration in the real loop. - !$acc parallel loop - DO i = 1, 1 - !$acc cache(p(LO_T5:LO_T5+L_T5-1)) - cp(1) = cp(1) ! no-op - END DO - !$acc end parallel loop + !$acc parallel loop DO i = 1, M_T5 + !$acc cache(p(LO_T5:LO_T5+L_T5-1)) cp(i) = p(i) + 1.0D0 END DO !$acc end parallel loop + + !$acc end data DO i = 1, M_T5 IF (ABS(cp(i) - (p(i)+1.0D0)) .GT. PRECISION) errors = errors + 1 @@ -151,17 +147,14 @@ LOGICAL FUNCTION test5() cq(i) = 0.0D0 END DO !$acc data copyin(q(1:M_T6)) copy(cq(1:M_T6)) - !$acc parallel loop - DO i = 1, 1 - !$acc cache(q(LO_T6:HI_T6)) - cq(1) = cq(1) ! no-op - END DO - !$acc end parallel loop + !$acc parallel loop DO i = 1, M_T6 + !$acc cache(q(LO_T6:HI_T6)) cq(i) = q(i) * 2.0D0 END DO !$acc end parallel loop + !$acc end data DO i = 1, M_T6 IF (ABS(cq(i) - 2.0D0*q(i)) .GT. PRECISION) errors = errors + 1 From 7aeb8973f00d59509602ed6134f0b70d94880d71 Mon Sep 17 00:00:00 2001 From: Ryanpadrone <159075564+Ryanpadrone@users.noreply.github.com> Date: Wed, 18 Feb 2026 18:50:54 -0500 Subject: [PATCH 09/15] Update acc_integral_constant_expression.c --- Tests/acc_integral_constant_expression.c | 153 ++++++++++++++++++----- 1 file changed, 119 insertions(+), 34 deletions(-) diff --git a/Tests/acc_integral_constant_expression.c b/Tests/acc_integral_constant_expression.c index aac63af..f3198d3 100644 --- a/Tests/acc_integral_constant_expression.c +++ b/Tests/acc_integral_constant_expression.c @@ -1,12 +1,29 @@ // acc_integral_constant_expression.c +// //Feature under test (OpenACC 3.4, Section 1.6, Feb 2026): // - Clause arguments that require an integral-constant-expression accept // C integral constant expressions (macros and enum values). // // Notes: -// - Uses integral constant expressions in: collapse, tile, cache (index and slice), -// and gang(dim:) to validate compile-time constant handling. - +// T1: collapse() accepts an integral-constant-expression (ICE). +// This test uses a macro ICE in collapse() and checks runtime correctness. +// +// T2: tile() accepts an integral-constant-expression (ICE). +// This test uses a macro ICE in tile() and checks runtime correctness. +// +// T3: tile() accepts ICE values (enums/macros). +// This test mixes enum + macro ICE in tile() and checks correctness. +// +// T4: cache() indexing accepts an integral-constant-expression (ICE). +// This test uses an enum ICE as the cache element index. +// +// T5: cache() subarray slices accept ICE values. +// This test uses enum/macro ICE for lower:length in cache(). +// +// T6: gang(dim:) accepts an integral-constant-expression (ICE) (valid range 1..3). +// This test uses an enum ICE in gang(dim:) and checks runtime correctness. +// – Some compilers may not support the 'dim:' keyword form yet; keep this as spec conformance coverage. +// #include "acc_testsuite.h" #include @@ -21,8 +38,6 @@ enum { ICE_ENUM2 = 2, ICE_ENUM4 = 4, ICE_ENUM_LOWER = 3 }; #define ICE_LEN4 (4) #ifndef T1 -//T1:syntax,collapse-clause,runtime,loop,V:3.4- -// collapse(ICE_MACRO2) macro arithmetic ICE int test1(void){ int err = 0; const int M = 48, N = 12; @@ -36,7 +51,11 @@ int test1(void){ free(c); return 1; } - for(int i=0;i PRECISION) err++; + if (fabs(c[i] - (a[i] + b[i])) > PRECISION){ + err++; + } } free(a); @@ -58,8 +79,6 @@ int test1(void){ } #endif #ifndef T2 -//T2:syntax,tile-clause,runtime,loop,V:3.4- -// tile(ICE_TILE1) macro ICE int test2(void){ int err = 0; const int M = 256; @@ -70,7 +89,11 @@ int test2(void){ free(c); return 1; } - for(int i=0;i PRECISION) err++; + if (fabs(c[i] - a[i]*(real_t)2.0) > PRECISION){ + err++; + } } free(a); free(c); @@ -87,8 +112,6 @@ int test2(void){ } #endif #ifndef T3 -//T3:syntax,tile-clause,runtime,loop,V:3.4- -// tile(ICE_ENUM2, ICE_MACRO2) enum + macro ICE int test3(void){ int err = 0; const int M = 64, N = 40; @@ -102,7 +125,13 @@ int test3(void){ free(c); return 1; } - for(int i=0;i PRECISION) err++; + if (fabs(c[i] - (a[i] + b[i])) > PRECISION){ + err++; + } } free(a); @@ -124,8 +155,6 @@ int test3(void){ } #endif #ifndef T4 -//T4:syntax,cache-directive,runtime,loop,V:3.4- -// cache: element index uses ICE (enum) int test4(void){ int err = 0; const int M = 512; @@ -136,7 +165,12 @@ int test4(void){ free(c); return 1; } - for(int i=0;i PRECISION) err++; + if (fabs(c[i] - (a[i]+(real_t)1.0)) > PRECISION){ + err++; + } } + free(a); free(c); return err; } #endif #ifndef T5 -//T5:syntax,cache-directive,runtime,loop,V:3.4- -// cache: subarray lower:length uses ICE lower + ICE length int test5(void){ int err = 0; const int M = 512; @@ -166,7 +202,10 @@ int test5(void){ free(c); return 1; } - for(int i=0;i PRECISION) err++; + if (fabs(c[i] - (a[i]+(real_t)2.0)) > PRECISION){ + err++; + } } + free(a); free(c); return err; } #endif #ifndef T6 -//T6:syntax,gang-clause,runtime,loop,V:3.4- -// gang(dim:ICE_ENUM2) where dim is an integral-constant-expression (enum), must evaluate to 1..3 -// NOTE: Some compilers may not support the 'dim:' keyword form yet; keep this as spec conformance coverage. int test6(void){ int err = 0; const int M = 512; @@ -197,7 +237,12 @@ int test6(void){ free(c); return 1; } - for(int i=0;i PRECISION) err++; + if (fabs(c[i] - a[i]*(real_t)2.0) > PRECISION){ + err++; + } } + free(a); free(c); return err; @@ -216,22 +265,58 @@ int test6(void){ int main(void){ int failcode=0, failed; #ifndef T1 - failed=0; for(int i=0;i Date: Wed, 18 Feb 2026 19:11:53 -0500 Subject: [PATCH 10/15] Update acc_integral_constant_expression.cpp --- Tests/acc_integral_constant_expression.cpp | 145 ++++++++++++++++++--- 1 file changed, 124 insertions(+), 21 deletions(-) diff --git a/Tests/acc_integral_constant_expression.cpp b/Tests/acc_integral_constant_expression.cpp index dd5507f..8a390d0 100644 --- a/Tests/acc_integral_constant_expression.cpp +++ b/Tests/acc_integral_constant_expression.cpp @@ -4,9 +4,26 @@ // - Clause arguments that require an integral-constant-expression accept // C++ integral constant expressions (constexpr values and enum values). // -// Notes: -// - Uses integral constant expressions in: collapse, tile, cache (index and slice), -// and gang(dim:) to validate compile-time constant handling. +// Notes: +// T1: collapse() accepts an integral-constant-expression (ICE). +// This test uses a macro ICE in collapse() and checks runtime correctness. +// +// T2: tile() accepts an integral-constant-expression (ICE). +// This test uses a macro ICE in tile() and checks runtime correctness. +// +// T3: tile() accepts ICE values (enums/macros). +// This test mixes enum + macro ICE in tile() and checks correctness. +// +// T4: cache() indexing accepts an integral-constant-expression (ICE). +// This test uses an enum ICE as the cache element index. +// +// T5: cache() subarray slices accept ICE values. +// This test uses enum/macro ICE for lower:length in cache(). +// +// T6: gang(dim:) accepts an integral-constant-expression (ICE) (valid range 1..3). +// This test uses an enum ICE in gang(dim:) and checks runtime correctness. +// – Some compilers may not support the 'dim:' keyword form yet; keep this as spec conformance coverage. +// #include "acc_testsuite.h" @@ -35,7 +52,13 @@ int test1(){ std::free(c); return 1; } - for(int i=0;i PRECISION) err++; + if (std::fabs(c[i] - (a[i] + b[i])) > PRECISION){ + err++; + } } std::free(a); std::free(b); @@ -68,7 +93,11 @@ int test2(){ std::free(c); return 1; } - for(int i=0;i PRECISION) err++; + if (std::fabs(c[i] - a[i]*(real_t)2.0) > PRECISION){ + err++; + } } std::free(a); std::free(c); @@ -99,7 +131,13 @@ int test3(){ std::free(c); return 1; } - for(int i=0;i PRECISION) err++; + if (std::fabs(c[i] - (a[i] + b[i])) > PRECISION){ + err++; + } } std::free(a); std::free(b); @@ -132,7 +172,12 @@ int test4(){ std::free(c); return 1; } - for(int i=0;i PRECISION) err++; + if (std::fabs(c[i] - (a[i]+(real_t)1.0)) > PRECISION){ + err++; + } } + std::free(a); std::free(c); return err; @@ -162,7 +211,12 @@ int test5(){ std::free(c); return 1; } - for(int i=0;i PRECISION) err++; + if (std::fabs(c[i] - (a[i]+(real_t)2.0)) > PRECISION){ + err++; + } } + std::free(a); std::free(c); return err; @@ -193,7 +251,12 @@ int test6(){ std::free(c); return 1; } - for(int i=0;i PRECISION) err++; + if (std::fabs(c[i] - a[i]*(real_t)2.0) > PRECISION){ + err++; + } } + std::free(a); std::free(c); return err; @@ -212,22 +279,58 @@ int test6(){ int main(){ int failcode=0, failed; #ifndef T1 - failed=0; for(int i=0;i Date: Wed, 18 Feb 2026 19:22:21 -0500 Subject: [PATCH 11/15] Update acc_integral_constant_expression.F90 --- Tests/acc_integral_constant_expression.F90 | 70 +++++++++++++++++----- 1 file changed, 54 insertions(+), 16 deletions(-) diff --git a/Tests/acc_integral_constant_expression.F90 b/Tests/acc_integral_constant_expression.F90 index f24f138..136ebd4 100644 --- a/Tests/acc_integral_constant_expression.F90 +++ b/Tests/acc_integral_constant_expression.F90 @@ -4,10 +4,24 @@ ! - Clause arguments that require an integral-constant-expression accept ! Fortran integer constant expressions declared with PARAMETER. ! -! Notes: -! - Uses PARAMETER constants in: collapse, tile, cache bounds/lengths, -! and gang(dim:) to validate compile-time constant handling. - +! T1: collapse() accepts an integral-constant-expression (ICE). +! This test uses a PARAMETER constant expression in collapse(). +! +! T2: tile() accepts an integral-constant-expression (ICE). +! This test uses a PARAMETER constant expression in tile(). +! +! T3: tile() accepts ICE values. +! This test uses PARAMETER ICE values in tile( , ). +! +! T4: cache() slice bounds accept integral-constant-expressions (ICE). +! This test uses PARAMETER ICE values in cache(lower:upper). +! +! T5:cache() slice bounds accept integral-constant-expressions (ICE). +! This test uses PARAMETER ICE values in cache(lower:upper). +! +! T6: gang(dim:) accepts an integral-constant-expression (ICE) (must be 1..3). +! This test uses a PARAMETER ICE value in gang(dim:). +! #ifndef T1 !T1:syntax,collapse-clause,runtime,loop,V:3.4- @@ -35,7 +49,9 @@ LOGICAL FUNCTION test1() !$acc end parallel loop !$acc end data DO idx = 1, M_T2*N_T2 - IF (ABS(c(idx)-(a(idx)+b(idx))) .GT. PRECISION) errors = errors + 1 + IF (ABS(c(idx)-(a(idx)+b(idx))) .GT. PRECISION) THEN + errors = errors + 1 + END IF END DO test1 = (errors .NE. 0) END FUNCTION @@ -62,7 +78,9 @@ LOGICAL FUNCTION test2() !$acc end parallel loop !$acc end data DO i = 1, M_T3 - IF (ABS(c(i) - 2.0D0*a(i)) .GT. PRECISION) errors = errors + 1 + IF (ABS(c(i) - 2.0D0*a(i)) .GT. PRECISION) THEN + errors = errors + 1 + END IF END DO test2 = (errors .NE. 0) END FUNCTION @@ -93,7 +111,9 @@ LOGICAL FUNCTION test3() !$acc end parallel loop !$acc end data DO idx = 1, M_T4*N_T4 - IF (ABS(c(idx)-(a(idx)+b(idx))) .GT. PRECISION) errors = errors + 1 + IF (ABS(c(idx)-(a(idx)+b(idx))) .GT. PRECISION) THEN + errors = errors + 1 + END IF END DO test3 = (errors .NE. 0) END FUNCTION @@ -125,7 +145,9 @@ LOGICAL FUNCTION test4() !$acc end data DO i = 1, M_T5 - IF (ABS(cp(i) - (p(i)+1.0D0)) .GT. PRECISION) errors = errors + 1 + IF (ABS(cp(i) - (p(i)+1.0D0)) .GT. PRECISION) THEN + errors = errors + 1 + END IF END DO test4 = (errors .NE. 0) END FUNCTION @@ -157,7 +179,9 @@ LOGICAL FUNCTION test5() !$acc end data DO i = 1, M_T6 - IF (ABS(cq(i) - 2.0D0*q(i)) .GT. PRECISION) errors = errors + 1 + IF (ABS(cq(i) - 2.0D0*q(i)) .GT. PRECISION) THEN + errors = errors + 1 + END IF END DO test5 = (errors .NE. 0) END FUNCTION @@ -186,7 +210,9 @@ LOGICAL FUNCTION test6() !$acc end parallel loop !$acc end data DO i = 1, M_T7 - IF (ABS(c(i) - 2.0D0*a(i)) .GT. PRECISION) errors = errors + 1 + IF (ABS(c(i) - 2.0D0*a(i)) .GT. PRECISION) THEN + errors = errors + 1 + END IF END DO test6 = (errors .NE. 0) END FUNCTION @@ -220,42 +246,54 @@ PROGRAM main DO testrun = 1, NUM_TEST_CALLS failed = failed .OR. test1() END DO - IF (failed) failcode = failcode + 2**0 + IF (failed) THEN + failcode = failcode + 2**0 + END IF #endif #ifndef T2 failed = .FALSE. DO testrun = 1, NUM_TEST_CALLS failed = failed .OR. test2() END DO - IF (failed) failcode = failcode + 2**1 + IF (failed) THEN + failcode = failcode + 2**1 + END IF #endif #ifndef T3 failed = .FALSE. DO testrun = 1, NUM_TEST_CALLS failed = failed .OR. test3() END DO - IF (failed) failcode = failcode + 2**2 + IF (failed) THEN + failcode = failcode + 2**2 + END IF #endif #ifndef T4 failed = .FALSE. DO testrun = 1, NUM_TEST_CALLS failed = failed .OR. test4() END DO - IF (failed) failcode = failcode + 2**3 + IF (failed) THEN + failcode = failcode + 2**3 + END IF #endif #ifndef T5 failed = .FALSE. DO testrun = 1, NUM_TEST_CALLS failed = failed .OR. test5() END DO - IF (failed) failcode = failcode + 2**4 + IF (failed) THEN + failcode = failcode + 2**4 + END IF #endif #ifndef T6 failed = .FALSE. DO testrun = 1, NUM_TEST_CALLS failed = failed .OR. test6() END DO - IF (failed) failcode = failcode + 2**5 + IF (failed) THEN + failcode = failcode + 2**5 + END IF #endif CALL EXIT(failcode) END PROGRAM From 9ad8d2894c9a91f5cf9d3610305d65cd6770ef23 Mon Sep 17 00:00:00 2001 From: Ryanpadrone <159075564+Ryanpadrone@users.noreply.github.com> Date: Wed, 18 Feb 2026 19:25:13 -0500 Subject: [PATCH 12/15] Update acc_integral_constant_expression.cpp --- Tests/acc_integral_constant_expression.cpp | 27 +++++++--------------- 1 file changed, 8 insertions(+), 19 deletions(-) diff --git a/Tests/acc_integral_constant_expression.cpp b/Tests/acc_integral_constant_expression.cpp index 8a390d0..d08edb2 100644 --- a/Tests/acc_integral_constant_expression.cpp +++ b/Tests/acc_integral_constant_expression.cpp @@ -4,25 +4,14 @@ // - Clause arguments that require an integral-constant-expression accept // C++ integral constant expressions (constexpr values and enum values). // -// Notes: -// T1: collapse() accepts an integral-constant-expression (ICE). -// This test uses a macro ICE in collapse() and checks runtime correctness. -// -// T2: tile() accepts an integral-constant-expression (ICE). -// This test uses a macro ICE in tile() and checks runtime correctness. -// -// T3: tile() accepts ICE values (enums/macros). -// This test mixes enum + macro ICE in tile() and checks correctness. -// -// T4: cache() indexing accepts an integral-constant-expression (ICE). -// This test uses an enum ICE as the cache element index. -// -// T5: cache() subarray slices accept ICE values. -// This test uses enum/macro ICE for lower:length in cache(). -// -// T6: gang(dim:) accepts an integral-constant-expression (ICE) (valid range 1..3). -// This test uses an enum ICE in gang(dim:) and checks runtime correctness. -// – Some compilers may not support the 'dim:' keyword form yet; keep this as spec conformance coverage. +// Notes: +// - T1: collapse() uses a constexpr ICE. +// - T2: tile() uses a constexpr ICE. +// - T3: tile() mixes constexpr + enum ICE. +// - T4: cache() element index uses a constexpr ICE. +// - T5: cache() lower:length slice uses constexpr ICE values. +// - T6: gang(dim:) uses a constexpr ICE (must be 1..3). +// Some compilers may not support gang(dim:) yet; keep for spec coverage. // From 64102186a3708dafdff3acd30f28b4773f0e7c9a Mon Sep 17 00:00:00 2001 From: Ryanpadrone <159075564+Ryanpadrone@users.noreply.github.com> Date: Wed, 18 Feb 2026 19:26:12 -0500 Subject: [PATCH 13/15] Update acc_integral_constant_expression.c --- Tests/acc_integral_constant_expression.c | 28 +++++++----------------- 1 file changed, 8 insertions(+), 20 deletions(-) diff --git a/Tests/acc_integral_constant_expression.c b/Tests/acc_integral_constant_expression.c index f3198d3..3cf4d19 100644 --- a/Tests/acc_integral_constant_expression.c +++ b/Tests/acc_integral_constant_expression.c @@ -4,26 +4,14 @@ // - Clause arguments that require an integral-constant-expression accept // C integral constant expressions (macros and enum values). // -// Notes: -// T1: collapse() accepts an integral-constant-expression (ICE). -// This test uses a macro ICE in collapse() and checks runtime correctness. -// -// T2: tile() accepts an integral-constant-expression (ICE). -// This test uses a macro ICE in tile() and checks runtime correctness. -// -// T3: tile() accepts ICE values (enums/macros). -// This test mixes enum + macro ICE in tile() and checks correctness. -// -// T4: cache() indexing accepts an integral-constant-expression (ICE). -// This test uses an enum ICE as the cache element index. -// -// T5: cache() subarray slices accept ICE values. -// This test uses enum/macro ICE for lower:length in cache(). -// -// T6: gang(dim:) accepts an integral-constant-expression (ICE) (valid range 1..3). -// This test uses an enum ICE in gang(dim:) and checks runtime correctness. -// – Some compilers may not support the 'dim:' keyword form yet; keep this as spec conformance coverage. -// +// Notes: +// - T1: collapse() uses a macro ICE. +// - T2: tile() uses a macro ICE. +// - T3: tile() mixes enum + macro ICE. +// - T4: cache() element index uses an enum ICE. +// - T5: cache() lower:length slice uses ICE values. +// - T6: gang(dim:) uses an enum ICE (must be 1..3). +// Some compilers may not support gang(dim:) yet; keep for spec coverage. #include "acc_testsuite.h" #include From 3d5e2fa8bc2665cc80db773ff6ed3c1d29e41cf0 Mon Sep 17 00:00:00 2001 From: Ryanpadrone <159075564+Ryanpadrone@users.noreply.github.com> Date: Wed, 18 Feb 2026 19:26:53 -0500 Subject: [PATCH 14/15] Update acc_integral_constant_expression.F90 --- Tests/acc_integral_constant_expression.F90 | 25 +++++++--------------- 1 file changed, 8 insertions(+), 17 deletions(-) diff --git a/Tests/acc_integral_constant_expression.F90 b/Tests/acc_integral_constant_expression.F90 index 136ebd4..d9fd0b5 100644 --- a/Tests/acc_integral_constant_expression.F90 +++ b/Tests/acc_integral_constant_expression.F90 @@ -4,23 +4,14 @@ ! - Clause arguments that require an integral-constant-expression accept ! Fortran integer constant expressions declared with PARAMETER. ! -! T1: collapse() accepts an integral-constant-expression (ICE). -! This test uses a PARAMETER constant expression in collapse(). -! -! T2: tile() accepts an integral-constant-expression (ICE). -! This test uses a PARAMETER constant expression in tile(). -! -! T3: tile() accepts ICE values. -! This test uses PARAMETER ICE values in tile( , ). -! -! T4: cache() slice bounds accept integral-constant-expressions (ICE). -! This test uses PARAMETER ICE values in cache(lower:upper). -! -! T5:cache() slice bounds accept integral-constant-expressions (ICE). -! This test uses PARAMETER ICE values in cache(lower:upper). -! -! T6: gang(dim:) accepts an integral-constant-expression (ICE) (must be 1..3). -! This test uses a PARAMETER ICE value in gang(dim:). +! Notes: +! - T1: collapse() uses a PARAMETER ICE. +! - T2: tile() uses a PARAMETER ICE. +! - T3: tile() uses PARAMETER ICE values in tile( , ). +! - T4: cache() slice bounds use PARAMETER ICE values. +! - T5: cache() slice bounds use PARAMETER ICE values. +! - T6: gang(dim:) uses a PARAMETER ICE (must be 1..3). +! Some compilers may not support gang(dim:) yet; keep for spec coverage. ! #ifndef T1 From efa2648821b8a0981a7a0421e604ec7f2a896d1e Mon Sep 17 00:00:00 2001 From: Ryanpadrone <159075564+Ryanpadrone@users.noreply.github.com> Date: Wed, 18 Feb 2026 20:06:30 -0500 Subject: [PATCH 15/15] Update acc_integral_constant_expression.cpp --- Tests/acc_integral_constant_expression.cpp | 13 ------------- 1 file changed, 13 deletions(-) diff --git a/Tests/acc_integral_constant_expression.cpp b/Tests/acc_integral_constant_expression.cpp index d08edb2..5b70f59 100644 --- a/Tests/acc_integral_constant_expression.cpp +++ b/Tests/acc_integral_constant_expression.cpp @@ -27,8 +27,6 @@ enum class E2 : int { V = 2 }; static constexpr int ICE_LOWER = 3; #ifndef T1 -//T1:syntax,collapse-clause,runtime,loop,V:3.4- -// collapse(ICE_CONST2) constexpr ICE int test1(){ int err = 0; const int M = 48, N = 12, MN = M*N; @@ -70,8 +68,6 @@ int test1(){ } #endif #ifndef T2 -//T2:syntax,tile-clause,runtime,loop,V:3.4- -// tile(ICE_CONST2) constexpr ICE int test2(){ int err = 0; const int M = 256; @@ -106,8 +102,6 @@ int test2(){ } #endif #ifndef T3 -//T3:syntax,tile-clause,runtime,loop,V:3.4- -// tile(ICE_CONST2, int(E2::V)) constexpr + enum-class ICE int test3(){ int err = 0; const int M = 64, N = 40, MN = M*N; @@ -149,8 +143,6 @@ int test3(){ } #endif #ifndef T4 -//T4:syntax,cache-directive,runtime,loop,V:3.4- -// cache element index uses constexpr ICE int test4(){ int err = 0; const int M = 512; @@ -188,8 +180,6 @@ int test4(){ } #endif #ifndef T5 -//T5:syntax,cache-directive,runtime,loop,V:3.4- -// cache lower:length uses ICE lower + ICE length int test5(){ int err = 0; const int M = 512; @@ -227,9 +217,6 @@ int test5(){ } #endif #ifndef T6 -//T6:syntax,gang-clause,runtime,loop,V:3.4- -// gang(dim:ICE_CONST2) where dim is an integral constant expression (constexpr), must evaluate to 1..3 -// NOTE: Some compilers may not support the 'dim:' keyword form yet; keep this as spec conformance coverage. int test6(){ int err = 0; const int M = 512;