From 4ea683352535a607c7f355ad4aa0faa040832718 Mon Sep 17 00:00:00 2001 From: Ryan Padrone Date: Sat, 24 Jan 2026 14:25:13 -0800 Subject: [PATCH 01/14] if condition tests --- Tests/acc_if_condition.F90 | 244 +++++++++++++++++++++++++++++++++++++ Tests/acc_if_condition.c | 194 +++++++++++++++++++++++++++++ Tests/acc_if_condition.cpp | 173 ++++++++++++++++++++++++++ 3 files changed, 611 insertions(+) create mode 100644 Tests/acc_if_condition.F90 create mode 100644 Tests/acc_if_condition.c create mode 100644 Tests/acc_if_condition.cpp diff --git a/Tests/acc_if_condition.F90 b/Tests/acc_if_condition.F90 new file mode 100644 index 0000000..5972052 --- /dev/null +++ b/Tests/acc_if_condition.F90 @@ -0,0 +1,244 @@ +! acc_if_condition.F90 +! Fortran conditions must be LOGICAL. + +#ifndef T1 +!T1:syntax,if-clause,runtime,enter-data,V:3.4- + LOGICAL FUNCTION test1() + USE OPENACC + IMPLICIT NONE + INCLUDE "acc_testsuite.Fh" + INTEGER :: i, errors + REAL(8), DIMENSION(LOOPCOUNT) :: a + LOGICAL :: present + + errors = 0 + DO i=1, LOOPCOUNT + a(i) = DBLE(i) + END DO + + !$acc enter data copyin(a(1:LOOPCOUNT)) if(.FALSE.) + present = acc_is_present(a) + IF (present) errors = errors + 1 + + IF (present) THEN + !$acc exit data delete(a(1:LOOPCOUNT)) if(.TRUE.) + END IF + test1 = (errors .NE. 0) + END FUNCTION +#endif + +#ifndef T2 +!T2:syntax,if-clause,runtime,enter-data,V:3.4- + LOGICAL FUNCTION test2() + USE OPENACC + IMPLICIT NONE + INCLUDE "acc_testsuite.Fh" + INTEGER :: i, errors + REAL(8), DIMENSION(LOOPCOUNT) :: a + LOGICAL :: present + + errors = 0 + DO i=1, LOOPCOUNT + a(i) = DBLE(i) + END DO + + !$acc enter data copyin(a(1:LOOPCOUNT)) if(.TRUE.) + present = acc_is_present(a) + IF (.NOT. present) errors = errors + 1 + + !$acc exit data delete(a(1:LOOPCOUNT)) if(.TRUE.) + test2 = (errors .NE. 0) + END FUNCTION +#endif + +#ifndef T3 +!T3:syntax,if-clause,runtime,exit-data,V:3.4- + LOGICAL FUNCTION test3() + USE OPENACC + IMPLICIT NONE + INCLUDE "acc_testsuite.Fh" + INTEGER :: i, errors + REAL(8), DIMENSION(LOOPCOUNT) :: a + LOGICAL :: present + + errors = 0 + DO i=1, LOOPCOUNT + a(i) = DBLE(i) + END DO + + !$acc enter data copyin(a(1:LOOPCOUNT)) if(.TRUE.) + present = acc_is_present(a) + IF (.NOT. present) errors = errors + 1 + + !$acc exit data delete(a(1:LOOPCOUNT)) if(.FALSE.) + present = acc_is_present(a) + IF (.NOT. present) errors = errors + 1 + + !$acc exit data delete(a(1:LOOPCOUNT)) if(.TRUE.) + test3 = (errors .NE. 0) + END FUNCTION +#endif + +#ifndef T4 +!T4:syntax,if-clause,runtime,exit-data,V:3.4- + LOGICAL FUNCTION test4() + USE OPENACC + IMPLICIT NONE + INCLUDE "acc_testsuite.Fh" + INTEGER :: i, errors + REAL(8), DIMENSION(LOOPCOUNT) :: a + LOGICAL :: present + + errors = 0 + DO i=1, LOOPCOUNT + a(i) = DBLE(i) + END DO + + !$acc enter data copyin(a(1:LOOPCOUNT)) if(.TRUE.) + present = acc_is_present(a) + IF (.NOT. present) errors = errors + 1 + + !$acc exit data delete(a(1:LOOPCOUNT)) if(.TRUE.) + present = acc_is_present(a) + IF (present) errors = errors + 1 + + test4 = (errors .NE. 0) + END FUNCTION +#endif + +#ifndef T5 +!T5:syntax,if-clause,runtime,compute,V:3.4- +! logical variable condition + LOGICAL FUNCTION test5() + IMPLICIT NONE + INCLUDE "acc_testsuite.Fh" + INTEGER :: i, errors + REAL(8), DIMENSION(LOOPCOUNT) :: a, c + LOGICAL :: cond + + errors = 0 + cond = .TRUE. + + CALL RANDOM_NUMBER(a) + c = 0.0D0 + + !$acc data copyin(a(1:LOOPCOUNT)) copy(c(1:LOOPCOUNT)) + !$acc parallel loop present(a(1:LOOPCOUNT), c(1:LOOPCOUNT)) if(cond) + DO i=1, LOOPCOUNT + c(i) = 2.0D0 * a(i) + END DO + !$acc end parallel loop + !$acc end data + + DO i=1, LOOPCOUNT + IF (ABS(c(i) - 2.0D0*a(i)) .GT. PRECISION) errors = errors + 1 + END DO + + test5 = (errors .NE. 0) + END FUNCTION +#endif + +#ifndef T6 +!T6:syntax,if-clause,runtime,compute,V:3.4- +! logical expression condition + LOGICAL FUNCTION test6() + IMPLICIT NONE + INCLUDE "acc_testsuite.Fh" + INTEGER :: i, errors + REAL(8), DIMENSION(LOOPCOUNT) :: a, c + LOGICAL :: cond + + errors = 0 + cond = .TRUE. + + CALL RANDOM_NUMBER(a) + c = 0.0D0 + + !$acc data copyin(a(1:LOOPCOUNT)) copy(c(1:LOOPCOUNT)) + !$acc parallel loop present(a(1:LOOPCOUNT), c(1:LOOPCOUNT)) & + !$acc& if( (LOOPCOUNT .GT. 0) .AND. cond ) + DO i=1, LOOPCOUNT + c(i) = a(i) + 1.0D0 + END DO + !$acc end parallel loop + !$acc end data + + DO i=1, LOOPCOUNT + IF (ABS(c(i) - (a(i)+1.0D0)) .GT. PRECISION) errors = errors + 1 + END DO + + test6 = (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 + + 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 + + CALL EXIT(failcode) + END PROGRAM diff --git a/Tests/acc_if_condition.c b/Tests/acc_if_condition.c new file mode 100644 index 0000000..ca867e0 --- /dev/null +++ b/Tests/acc_if_condition.c @@ -0,0 +1,194 @@ +// acc_if_condition.c +#include "acc_testsuite.h" +#include +#include +#include +#include + +#ifndef T1 +//T1:syntax,if-clause,runtime,enter-data,V:3.4- +// enter data if(0) => must be NO-OP (not present) +int test1(void){ + int err = 0; + real_t *a = (real_t*)malloc(n * sizeof(real_t)); + if (!a) return 1; + for (int i = 0; i < n; ++i) a[i] = (real_t)i; + + #pragma acc enter data copyin(a[0:n]) if(0) + + if (acc_is_present(a, (size_t)n * sizeof(real_t))) err++; + + #pragma acc exit data delete(a[0:n]) if(1) + free(a); + return err; +} +#endif + +#ifndef T2 +//T2:syntax,if-clause,runtime,enter-data,V:3.4- +// enter data if(1) => must happen (present) +int test2(void){ + int err = 0; + real_t *a = (real_t*)malloc(n * sizeof(real_t)); + if (!a) return 1; + for (int i = 0; i < n; ++i) a[i] = (real_t)i; + + #pragma acc enter data copyin(a[0:n]) if(1) + + if (!acc_is_present(a, (size_t)n * sizeof(real_t))) err++; + + #pragma acc exit data delete(a[0:n]) if(1) + free(a); + return err; +} +#endif + +#ifndef T3 +//T3:syntax,if-clause,runtime,exit-data,V:3.4- +// exit data delete if(0) => must be NO-OP (still present) +int test3(void){ + int err = 0; + real_t *a = (real_t*)malloc(n * sizeof(real_t)); + if (!a) return 1; + for (int i = 0; i < n; ++i) a[i] = (real_t)i; + + #pragma acc enter data copyin(a[0:n]) if(1) + if (!acc_is_present(a, (size_t)n * sizeof(real_t))) err++; + + #pragma acc exit data delete(a[0:n]) if(0) + if (!acc_is_present(a, (size_t)n * sizeof(real_t))) err++; + + #pragma acc exit data delete(a[0:n]) if(1) + free(a); + return err; +} +#endif + +#ifndef T4 +//T4:syntax,if-clause,runtime,exit-data,V:3.4- +// exit data delete if(1) => must delete (not present) +int test4(void){ + int err = 0; + real_t *a = (real_t*)malloc(n * sizeof(real_t)); + if (!a) return 1; + for (int i = 0; i < n; ++i) a[i] = (real_t)i; + + #pragma acc enter data copyin(a[0:n]) if(1) + if (!acc_is_present(a, (size_t)n * sizeof(real_t))) err++; + + #pragma acc exit data delete(a[0:n]) if(1) + if (acc_is_present(a, (size_t)n * sizeof(real_t))) err++; + + free(a); + return err; +} +#endif + +// ---------- compute-side condition FORM coverage (C rules: any scalar) ---------- + +#ifndef T5 +//T5:syntax,if-clause,runtime,compute,V:3.4- +// int scalar expression as condition +int test5(void){ + int err = 0; + srand(SEED); + real_t *a = (real_t*)malloc(n*sizeof(real_t)); + real_t *b = (real_t*)malloc(n*sizeof(real_t)); + real_t *c = (real_t*)malloc(n*sizeof(real_t)); + if (!a || !b || !c){ free(a); free(b); free(c); return 1; } + + for (int i=0;i 0); // runtime scalar int condition + + #pragma acc data copyin(a[0:n],b[0:n]) copyout(c[0:n]) + { + #pragma acc parallel loop present(a[0:n],b[0:n],c[0:n]) if(cond_int) + for (int i=0;iPRECISION) err++; + free(a); free(b); free(c); + return err; +} +#endif + +#ifndef T6 +//T6:syntax,if-clause,runtime,compute,V:3.4- +// floating-point scalar as condition (C: nonzero => true) +int test6(void){ + int err = 0; + srand(SEED); + real_t *a = (real_t*)malloc(n*sizeof(real_t)); + real_t *c = (real_t*)malloc(n*sizeof(real_t)); + if (!a || !c){ free(a); free(c); return 1; } + + for (int i=0;i true in C + + #pragma acc data copyin(a[0:n]) copyout(c[0:n]) + { + #pragma acc parallel loop present(a[0:n],c[0:n]) if(cond_real) + for (int i=0;iPRECISION) err++; + free(a); free(c); + return err; +} +#endif + +#ifndef T7 +//T7:syntax,if-clause,runtime,compute,V:3.4- +// pointer scalar as condition (C: non-NULL => true) +int test7(void){ + int err = 0; + srand(SEED); + real_t *a = (real_t*)malloc(n*sizeof(real_t)); + real_t *c = (real_t*)malloc(n*sizeof(real_t)); + if (!a || !c){ free(a); free(c); return 1; } + + for (int i=0;i true in C + + #pragma acc data copyin(a[0:n]) copyout(c[0:n]) + { + #pragma acc parallel loop present(a[0:n],c[0:n]) if(cond_ptr) + for (int i=0;iPRECISION) 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 + +struct BoolLike { + int v; + explicit operator bool() const { return v != 0; } +}; + +#ifndef T1 +//T1:syntax,if-clause,runtime,enter-data,V:3.4- +int test1(){ + int err=0; + real_t* a=(real_t*)std::malloc(n*sizeof(real_t)); + if(!a) return 1; + for(int i=0;i 0); + + #pragma acc data copyin(a[0:n],b[0:n]) copyout(c[0:n]) + { + #pragma acc parallel loop present(a[0:n],b[0:n],c[0:n]) if(cond_int) + for(int i=0;iPRECISION) err++; + std::free(a); std::free(b); std::free(c); + return err; +} +#endif + +#ifndef T6 +//T6:syntax,if-clause,runtime,compute,V:3.4- +// C++ condition forms: pointer + user-defined bool-convertible type + fp comparison->bool +int test6(){ + int err=0; + std::srand(SEED); + real_t* a=(real_t*)std::malloc(n*sizeof(real_t)); + real_t* c=(real_t*)std::malloc(n*sizeof(real_t)); + if(!a||!c){ std::free(a); std::free(c); return 1; } + + for(int i=0;i true + BoolLike cond_obj{1}; // operator bool() => true + double x = 1.0; + bool cond_fp = (x != 0.0); // C++-correct “float-based” condition + + #pragma acc data copyin(a[0:n]) copyout(c[0:n]) + { + #pragma acc parallel loop present(a[0:n],c[0:n]) if(cond_obj) + for(int i=0;iPRECISION) 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:34:33 -0500 Subject: [PATCH 02/14] Update acc_if_condition.c added description --- Tests/acc_if_condition.c | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) diff --git a/Tests/acc_if_condition.c b/Tests/acc_if_condition.c index ca867e0..14781dc 100644 --- a/Tests/acc_if_condition.c +++ b/Tests/acc_if_condition.c @@ -1,4 +1,20 @@ // acc_if_condition.c +// Validates OpenACC 3.4’s clarified definition of “condition” when used as an argument to the if clause, +// and verifies that if(condition) correctly gates directive execution (OpenACC 3.4, Section 1.6). +// +// Test strategy: +// 1) Behavior-verifiable data-directive gating (T1–T4): +// Uses enter data / exit data with if(true/false) and checks device presence via acc_is_present. +// This directly proves that the runtime treats if(false) as a no-op and if(true) as executing the directive. +// +// 2) Condition-form coverage for compute constructs (T5–T7): +// Confirms the compiler accepts the full set of C-valid “condition” forms in if(...): +// - integer scalar expression (T5) +// - floating-point scalar condition (T6) (nonzero => true in C) +// - pointer scalar condition (T7) (non-NULL => true in C) +// Each compute test performs a simple device computation and verifies results on the host. +// + #include "acc_testsuite.h" #include #include From 7f7ff6848913333d41dd4271c252cbb22a3020bc Mon Sep 17 00:00:00 2001 From: Ryanpadrone <159075564+Ryanpadrone@users.noreply.github.com> Date: Mon, 2 Feb 2026 20:35:59 -0500 Subject: [PATCH 03/14] Update acc_if_condition.cpp added description --- Tests/acc_if_condition.cpp | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) diff --git a/Tests/acc_if_condition.cpp b/Tests/acc_if_condition.cpp index 6a154ca..2905e34 100644 --- a/Tests/acc_if_condition.cpp +++ b/Tests/acc_if_condition.cpp @@ -1,4 +1,21 @@ // acc_if_condition.cpp +// Validates OpenACC 3.4’s clarified definition of “condition” when used as an argument to the if clause, +// and verifies that if(condition) correctly gates directive execution (OpenACC 3.4, Section 1.6). +// +// Test strategy: +// 1) Behavior-verifiable data-directive gating (T1–T4): +// Uses enter data / exit data with if(true/false) and checks device presence via acc_is_present. +// This directly proves correct gating behavior: if(false) => no-op, if(true) => directive executes. +// +// 2) Condition-form coverage for compute constructs under C++ rules (T5–T6): +// In C++, a “condition” must be contextually convertible to bool. These tests confirm that OpenACC +// accepts C++-legal condition forms in if(...), including: +// - integer scalar expression (T5) +// - pointer condition, user-defined bool-convertible type (operator bool), and a floating-point +// comparison yielding bool (T6) +// Each compute region performs simple arithmetic and verifies results on the host. +// + #include "acc_testsuite.h" #include #include From 434cb095e8c3d98f770bb0f90dbd0dbf6f3ee25f Mon Sep 17 00:00:00 2001 From: Ryanpadrone <159075564+Ryanpadrone@users.noreply.github.com> Date: Mon, 2 Feb 2026 20:37:37 -0500 Subject: [PATCH 04/14] Update acc_if_condition.F90 added description --- Tests/acc_if_condition.F90 | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) diff --git a/Tests/acc_if_condition.F90 b/Tests/acc_if_condition.F90 index 5972052..9b20531 100644 --- a/Tests/acc_if_condition.F90 +++ b/Tests/acc_if_condition.F90 @@ -1,4 +1,20 @@ ! acc_if_condition.F90 +! Validates OpenACC 3.4’s clarified definition of “condition” when used as an argument to the if clause, +! and verifies that if(condition) correctly gates directive execution (OpenACC 3.4, Section 1.6). +! +! Test strategy: +! 1) Behavior-verifiable data-directive gating (T1–T4): +! Uses enter data / exit data with if(.TRUE./.FALSE.) and checks device presence via acc_is_present. +! This directly verifies correct gating behavior for data directives in Fortran. +! +! 2) Condition-form coverage for compute constructs under Fortran rules (T5–T6): +! Fortran conditions must be LOGICAL. These tests confirm that OpenACC accepts valid Fortran LOGICAL +! conditions in if(...), including: +! - LOGICAL variable condition (T5) +! - LOGICAL expression condition (T6) +! Each compute test performs a simple computation and verifies results on the host. +! + ! Fortran conditions must be LOGICAL. #ifndef T1 From cb46b20d2de1e0fcf36006175a03cb38f3e6fb64 Mon Sep 17 00:00:00 2001 From: Ryanpadrone <159075564+Ryanpadrone@users.noreply.github.com> Date: Thu, 12 Feb 2026 20:33:05 -0500 Subject: [PATCH 05/14] Update acc_if_condition.c --- Tests/acc_if_condition.c | 21 ++++++++------------- 1 file changed, 8 insertions(+), 13 deletions(-) diff --git a/Tests/acc_if_condition.c b/Tests/acc_if_condition.c index 14781dc..3bbb1b7 100644 --- a/Tests/acc_if_condition.c +++ b/Tests/acc_if_condition.c @@ -1,19 +1,14 @@ // acc_if_condition.c -// Validates OpenACC 3.4’s clarified definition of “condition” when used as an argument to the if clause, -// and verifies that if(condition) correctly gates directive execution (OpenACC 3.4, Section 1.6). // -// Test strategy: -// 1) Behavior-verifiable data-directive gating (T1–T4): -// Uses enter data / exit data with if(true/false) and checks device presence via acc_is_present. -// This directly proves that the runtime treats if(false) as a no-op and if(true) as executing the directive. -// -// 2) Condition-form coverage for compute constructs (T5–T7): -// Confirms the compiler accepts the full set of C-valid “condition” forms in if(...): -// - integer scalar expression (T5) -// - floating-point scalar condition (T6) (nonzero => true in C) -// - pointer scalar condition (T7) (non-NULL => true in C) -// Each compute test performs a simple device computation and verifies results on the host. +// Feature under test (OpenACC 3.4, Section 1.6, Feb 2026): +// - Clarified definition of "condition" when used as an argument to the if clause. +// - The if(condition) clause must accept any valid C scalar condition expression. +// - The if clause must correctly gate execution of data and compute directives. // +// Notes: +// - T1–T4 verify runtime gating behavior for enter data / exit data. +// - T5–T7 verify valid C condition forms (integer, floating-point, pointer). + #include "acc_testsuite.h" #include From 55120c349524624a3ddfa66c0ecfc641c4bb7813 Mon Sep 17 00:00:00 2001 From: Ryanpadrone <159075564+Ryanpadrone@users.noreply.github.com> Date: Thu, 12 Feb 2026 20:33:42 -0500 Subject: [PATCH 06/14] Update acc_if_condition.cpp --- Tests/acc_if_condition.cpp | 20 +++++++------------- 1 file changed, 7 insertions(+), 13 deletions(-) diff --git a/Tests/acc_if_condition.cpp b/Tests/acc_if_condition.cpp index 2905e34..203486c 100644 --- a/Tests/acc_if_condition.cpp +++ b/Tests/acc_if_condition.cpp @@ -1,19 +1,13 @@ // acc_if_condition.cpp -// Validates OpenACC 3.4’s clarified definition of “condition” when used as an argument to the if clause, -// and verifies that if(condition) correctly gates directive execution (OpenACC 3.4, Section 1.6). // -// Test strategy: -// 1) Behavior-verifiable data-directive gating (T1–T4): -// Uses enter data / exit data with if(true/false) and checks device presence via acc_is_present. -// This directly proves correct gating behavior: if(false) => no-op, if(true) => directive executes. +// Feature under test (OpenACC 3.4, Section 1.6, Feb 2026): +// - Clarified definition of "condition" when used as an argument to the if clause. +// - The if(condition) clause must accept any expression that is contextually convertible to bool in C++. +// - The if clause must correctly gate execution of data and compute directives. // -// 2) Condition-form coverage for compute constructs under C++ rules (T5–T6): -// In C++, a “condition” must be contextually convertible to bool. These tests confirm that OpenACC -// accepts C++-legal condition forms in if(...), including: -// - integer scalar expression (T5) -// - pointer condition, user-defined bool-convertible type (operator bool), and a floating-point -// comparison yielding bool (T6) -// Each compute region performs simple arithmetic and verifies results on the host. +// Notes: +// - T1–T4 verify runtime gating behavior for enter data / exit data. +// - T5–T6 verify valid C++ condition forms (integer, pointer, bool-convertible expressions). // #include "acc_testsuite.h" From fd1f1183c38e75669f04d7fb5463014030b7d077 Mon Sep 17 00:00:00 2001 From: Ryanpadrone <159075564+Ryanpadrone@users.noreply.github.com> Date: Thu, 12 Feb 2026 20:34:20 -0500 Subject: [PATCH 07/14] Update acc_if_condition.F90 --- Tests/acc_if_condition.F90 | 20 +++++++------------- 1 file changed, 7 insertions(+), 13 deletions(-) diff --git a/Tests/acc_if_condition.F90 b/Tests/acc_if_condition.F90 index 9b20531..ea7c272 100644 --- a/Tests/acc_if_condition.F90 +++ b/Tests/acc_if_condition.F90 @@ -1,19 +1,13 @@ ! acc_if_condition.F90 -! Validates OpenACC 3.4’s clarified definition of “condition” when used as an argument to the if clause, -! and verifies that if(condition) correctly gates directive execution (OpenACC 3.4, Section 1.6). ! -! Test strategy: -! 1) Behavior-verifiable data-directive gating (T1–T4): -! Uses enter data / exit data with if(.TRUE./.FALSE.) and checks device presence via acc_is_present. -! This directly verifies correct gating behavior for data directives in Fortran. -! -! 2) Condition-form coverage for compute constructs under Fortran rules (T5–T6): -! Fortran conditions must be LOGICAL. These tests confirm that OpenACC accepts valid Fortran LOGICAL -! conditions in if(...), including: -! - LOGICAL variable condition (T5) -! - LOGICAL expression condition (T6) -! Each compute test performs a simple computation and verifies results on the host. +! Feature under test (OpenACC 3.4, Section 1.6, Feb 2026): +! - Clarified definition of "condition" when used as an argument to the if clause. +! - In Fortran, the if clause argument must be a LOGICAL expression. +! - The if clause must correctly gate execution of data and compute directives. ! +! Notes: +! - T1–T4 verify runtime gating behavior for enter data / exit data. +! - T5–T6 verify valid Fortran LOGICAL variable and expression forms. ! Fortran conditions must be LOGICAL. From 12fa10775632a9db648417e0702496c526363809 Mon Sep 17 00:00:00 2001 From: Ryanpadrone <159075564+Ryanpadrone@users.noreply.github.com> Date: Thu, 12 Feb 2026 20:56:11 -0500 Subject: [PATCH 08/14] Update acc_if_condition.c --- Tests/acc_if_condition.c | 140 +++++++++++++++++++++++++++++++-------- 1 file changed, 111 insertions(+), 29 deletions(-) diff --git a/Tests/acc_if_condition.c b/Tests/acc_if_condition.c index 3bbb1b7..9844fc9 100644 --- a/Tests/acc_if_condition.c +++ b/Tests/acc_if_condition.c @@ -22,12 +22,20 @@ int test1(void){ int err = 0; real_t *a = (real_t*)malloc(n * sizeof(real_t)); - if (!a) return 1; - for (int i = 0; i < n; ++i) a[i] = (real_t)i; + + if (!a){ + return 1; + } + + for (int i = 0; i < n; ++i){ + a[i] = (real_t)i; + } #pragma acc enter data copyin(a[0:n]) if(0) - if (acc_is_present(a, (size_t)n * sizeof(real_t))) err++; + if (acc_is_present(a, (size_t)n * sizeof(real_t))){ + err++; + } #pragma acc exit data delete(a[0:n]) if(1) free(a); @@ -41,12 +49,20 @@ int test1(void){ int test2(void){ int err = 0; real_t *a = (real_t*)malloc(n * sizeof(real_t)); - if (!a) return 1; - for (int i = 0; i < n; ++i) a[i] = (real_t)i; + + if (!a){ + return 1; + } + + for (int i = 0; i < n; ++i){ + a[i] = (real_t)i; + } #pragma acc enter data copyin(a[0:n]) if(1) - if (!acc_is_present(a, (size_t)n * sizeof(real_t))) err++; + if (!acc_is_present(a, (size_t)n * sizeof(real_t))){ + err++; + } #pragma acc exit data delete(a[0:n]) if(1) free(a); @@ -60,14 +76,24 @@ int test2(void){ int test3(void){ int err = 0; real_t *a = (real_t*)malloc(n * sizeof(real_t)); - if (!a) return 1; - for (int i = 0; i < n; ++i) a[i] = (real_t)i; + + if (!a){ + return 1; + } + + for (int i = 0; i < n; ++i){ + a[i] = (real_t)i; + } #pragma acc enter data copyin(a[0:n]) if(1) - if (!acc_is_present(a, (size_t)n * sizeof(real_t))) err++; + if (!acc_is_present(a, (size_t)n * sizeof(real_t))){ + err++; + } #pragma acc exit data delete(a[0:n]) if(0) - if (!acc_is_present(a, (size_t)n * sizeof(real_t))) err++; + if (!acc_is_present(a, (size_t)n * sizeof(real_t))){ + err++; + } #pragma acc exit data delete(a[0:n]) if(1) free(a); @@ -81,14 +107,24 @@ int test3(void){ int test4(void){ int err = 0; real_t *a = (real_t*)malloc(n * sizeof(real_t)); - if (!a) return 1; - for (int i = 0; i < n; ++i) a[i] = (real_t)i; + + if (!a){ + return 1; + } + + for (int i = 0; i < n; ++i){ + a[i] = (real_t)i; + } #pragma acc enter data copyin(a[0:n]) if(1) - if (!acc_is_present(a, (size_t)n * sizeof(real_t))) err++; + if (!acc_is_present(a, (size_t)n * sizeof(real_t))){ + err++; + } #pragma acc exit data delete(a[0:n]) if(1) - if (acc_is_present(a, (size_t)n * sizeof(real_t))) err++; + if (acc_is_present(a, (size_t)n * sizeof(real_t))){ + err++; + } free(a); return err; @@ -106,20 +142,38 @@ int test5(void){ real_t *a = (real_t*)malloc(n*sizeof(real_t)); real_t *b = (real_t*)malloc(n*sizeof(real_t)); real_t *c = (real_t*)malloc(n*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 0); // runtime scalar int condition #pragma acc data copyin(a[0:n],b[0:n]) copyout(c[0:n]) { #pragma acc parallel loop present(a[0:n],b[0:n],c[0:n]) if(cond_int) - for (int i=0;iPRECISION) err++; - free(a); free(b); free(c); + for (int i=0;iPRECISION){ + err++; + } + } + free(a); + free(b); + free(c); return err; } #endif @@ -132,20 +186,34 @@ int test6(void){ srand(SEED); real_t *a = (real_t*)malloc(n*sizeof(real_t)); real_t *c = (real_t*)malloc(n*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 true in C #pragma acc data copyin(a[0:n]) copyout(c[0:n]) { #pragma acc parallel loop present(a[0:n],c[0:n]) if(cond_real) - for (int i=0;iPRECISION) err++; - free(a); free(c); + for (int i=0;iPRECISION){ + err++; + } + } + free(a); + free(c); return err; } #endif @@ -158,20 +226,34 @@ int test7(void){ srand(SEED); real_t *a = (real_t*)malloc(n*sizeof(real_t)); real_t *c = (real_t*)malloc(n*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 true in C #pragma acc data copyin(a[0:n]) copyout(c[0:n]) { #pragma acc parallel loop present(a[0:n],c[0:n]) if(cond_ptr) - for (int i=0;iPRECISION) err++; - free(a); free(c); + for (int i=0;iPRECISION){ + err++; + } + } + free(a); + free(c); return err; } #endif From 6c2f98a77e4a251440c1822aa88e654ad4ddc4f7 Mon Sep 17 00:00:00 2001 From: Ryanpadrone <159075564+Ryanpadrone@users.noreply.github.com> Date: Fri, 13 Feb 2026 14:38:23 -0500 Subject: [PATCH 09/14] Update acc_if_condition.cpp --- Tests/acc_if_condition.cpp | 122 +++++++++++++++++++++++++++++-------- 1 file changed, 96 insertions(+), 26 deletions(-) diff --git a/Tests/acc_if_condition.cpp b/Tests/acc_if_condition.cpp index 203486c..b79889a 100644 --- a/Tests/acc_if_condition.cpp +++ b/Tests/acc_if_condition.cpp @@ -26,11 +26,19 @@ struct BoolLike { int test1(){ int err=0; real_t* a=(real_t*)std::malloc(n*sizeof(real_t)); - if(!a) return 1; - for(int i=0;i 0); #pragma acc data copyin(a[0:n],b[0:n]) copyout(c[0:n]) { #pragma acc parallel loop present(a[0:n],b[0:n],c[0:n]) if(cond_int) - for(int i=0;iPRECISION) err++; - std::free(a); std::free(b); std::free(c); + for(int i=0;iPRECISION){ + err++; + } + } + + std::free(a); + std::free(b); + std::free(c); return err; } #endif @@ -129,9 +183,16 @@ int test6(){ std::srand(SEED); real_t* a=(real_t*)std::malloc(n*sizeof(real_t)); real_t* c=(real_t*)std::malloc(n*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 true BoolLike cond_obj{1}; // operator bool() => true @@ -141,21 +202,30 @@ int test6(){ #pragma acc data copyin(a[0:n]) copyout(c[0:n]) { #pragma acc parallel loop present(a[0:n],c[0:n]) if(cond_obj) - for(int i=0;iPRECISION) err++; + if(std::fabs(c[i]-expect)>PRECISION){ + err++; + } } - std::free(a); std::free(c); + std::free(a); + std::free(c); return err; } #endif From 23d44ad2ac479be9d6ce83422517743d53433303 Mon Sep 17 00:00:00 2001 From: Ryanpadrone <159075564+Ryanpadrone@users.noreply.github.com> Date: Fri, 13 Feb 2026 15:14:44 -0500 Subject: [PATCH 10/14] Update acc_if_condition.F90 --- Tests/acc_if_condition.F90 | 56 ++++++++++++++++++++++++++++---------- 1 file changed, 42 insertions(+), 14 deletions(-) diff --git a/Tests/acc_if_condition.F90 b/Tests/acc_if_condition.F90 index ea7c272..f7b8199 100644 --- a/Tests/acc_if_condition.F90 +++ b/Tests/acc_if_condition.F90 @@ -28,7 +28,9 @@ LOGICAL FUNCTION test1() !$acc enter data copyin(a(1:LOOPCOUNT)) if(.FALSE.) present = acc_is_present(a) - IF (present) errors = errors + 1 + IF (present) THEN + errors = errors + 1 + END IF IF (present) THEN !$acc exit data delete(a(1:LOOPCOUNT)) if(.TRUE.) @@ -54,7 +56,9 @@ LOGICAL FUNCTION test2() !$acc enter data copyin(a(1:LOOPCOUNT)) if(.TRUE.) present = acc_is_present(a) - IF (.NOT. present) errors = errors + 1 + IF (.NOT. present) THEN + errors = errors + 1 + END IF !$acc exit data delete(a(1:LOOPCOUNT)) if(.TRUE.) test2 = (errors .NE. 0) @@ -78,11 +82,15 @@ LOGICAL FUNCTION test3() !$acc enter data copyin(a(1:LOOPCOUNT)) if(.TRUE.) present = acc_is_present(a) - IF (.NOT. present) errors = errors + 1 + IF (.NOT. present) THEN + errors = errors + 1 + END IF !$acc exit data delete(a(1:LOOPCOUNT)) if(.FALSE.) present = acc_is_present(a) - IF (.NOT. present) errors = errors + 1 + IF (.NOT. present) THEN + errors = errors + 1 + END IF !$acc exit data delete(a(1:LOOPCOUNT)) if(.TRUE.) test3 = (errors .NE. 0) @@ -106,11 +114,15 @@ LOGICAL FUNCTION test4() !$acc enter data copyin(a(1:LOOPCOUNT)) if(.TRUE.) present = acc_is_present(a) - IF (.NOT. present) errors = errors + 1 + IF (.NOT. present) THEN + errors = errors + 1 + END IF !$acc exit data delete(a(1:LOOPCOUNT)) if(.TRUE.) present = acc_is_present(a) - IF (present) errors = errors + 1 + IF (present) THEN + errors = errors + 1 + END IF test4 = (errors .NE. 0) END FUNCTION @@ -141,7 +153,9 @@ LOGICAL FUNCTION test5() !$acc end data DO i=1, LOOPCOUNT - 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 test5 = (errors .NE. 0) @@ -174,7 +188,9 @@ LOGICAL FUNCTION test6() !$acc end data DO i=1, LOOPCOUNT - IF (ABS(c(i) - (a(i)+1.0D0)) .GT. PRECISION) errors = errors + 1 + IF (ABS(c(i) - (a(i)+1.0D0)) .GT. PRECISION) THEN + errors = errors + 1 + END IF END DO test6 = (errors .NE. 0) @@ -212,42 +228,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) From 838ae3c29fefd6ab9c8324761ae54c42d734435b Mon Sep 17 00:00:00 2001 From: Ryanpadrone <159075564+Ryanpadrone@users.noreply.github.com> Date: Fri, 13 Feb 2026 15:29:23 -0500 Subject: [PATCH 11/14] Update acc_if_condition.c --- Tests/acc_if_condition.c | 56 +++++++++++++++++++++++++++++++++++----- 1 file changed, 49 insertions(+), 7 deletions(-) diff --git a/Tests/acc_if_condition.c b/Tests/acc_if_condition.c index 9844fc9..eded215 100644 --- a/Tests/acc_if_condition.c +++ b/Tests/acc_if_condition.c @@ -262,25 +262,67 @@ int main(void){ int failcode = 0, failed; #ifndef T1 - failed=0; for(int i=0;i Date: Fri, 13 Feb 2026 15:34:13 -0500 Subject: [PATCH 12/14] Update acc_if_condition.cpp --- Tests/acc_if_condition.cpp | 48 +++++++++++++++++++++++++++++++++----- 1 file changed, 42 insertions(+), 6 deletions(-) diff --git a/Tests/acc_if_condition.cpp b/Tests/acc_if_condition.cpp index b79889a..e67cac7 100644 --- a/Tests/acc_if_condition.cpp +++ b/Tests/acc_if_condition.cpp @@ -233,22 +233,58 @@ int test6(){ int main(){ int failcode=0, failed; #ifndef T1 - failed=0; for(int i=0;i Date: Wed, 18 Feb 2026 20:03:08 -0500 Subject: [PATCH 13/14] Update acc_if_condition.c --- Tests/acc_if_condition.c | 21 +++------------------ 1 file changed, 3 insertions(+), 18 deletions(-) diff --git a/Tests/acc_if_condition.c b/Tests/acc_if_condition.c index eded215..09dd178 100644 --- a/Tests/acc_if_condition.c +++ b/Tests/acc_if_condition.c @@ -17,8 +17,6 @@ #include #ifndef T1 -//T1:syntax,if-clause,runtime,enter-data,V:3.4- -// enter data if(0) => must be NO-OP (not present) int test1(void){ int err = 0; real_t *a = (real_t*)malloc(n * sizeof(real_t)); @@ -44,8 +42,6 @@ int test1(void){ #endif #ifndef T2 -//T2:syntax,if-clause,runtime,enter-data,V:3.4- -// enter data if(1) => must happen (present) int test2(void){ int err = 0; real_t *a = (real_t*)malloc(n * sizeof(real_t)); @@ -71,8 +67,6 @@ int test2(void){ #endif #ifndef T3 -//T3:syntax,if-clause,runtime,exit-data,V:3.4- -// exit data delete if(0) => must be NO-OP (still present) int test3(void){ int err = 0; real_t *a = (real_t*)malloc(n * sizeof(real_t)); @@ -102,8 +96,6 @@ int test3(void){ #endif #ifndef T4 -//T4:syntax,if-clause,runtime,exit-data,V:3.4- -// exit data delete if(1) => must delete (not present) int test4(void){ int err = 0; real_t *a = (real_t*)malloc(n * sizeof(real_t)); @@ -131,11 +123,8 @@ int test4(void){ } #endif -// ---------- compute-side condition FORM coverage (C rules: any scalar) ---------- #ifndef T5 -//T5:syntax,if-clause,runtime,compute,V:3.4- -// int scalar expression as condition int test5(void){ int err = 0; srand(SEED); @@ -156,7 +145,7 @@ int test5(void){ c[i]=0; } - int cond_int = (n > 0); // runtime scalar int condition + int cond_int = (n > 0); #pragma acc data copyin(a[0:n],b[0:n]) copyout(c[0:n]) { @@ -179,8 +168,6 @@ int test5(void){ #endif #ifndef T6 -//T6:syntax,if-clause,runtime,compute,V:3.4- -// floating-point scalar as condition (C: nonzero => true) int test6(void){ int err = 0; srand(SEED); @@ -197,7 +184,7 @@ int test6(void){ c[i]=0; } - real_t cond_real = (real_t)1.0; // nonzero scalar => true in C + real_t cond_real = (real_t)1.0; #pragma acc data copyin(a[0:n]) copyout(c[0:n]) { @@ -219,8 +206,6 @@ int test6(void){ #endif #ifndef T7 -//T7:syntax,if-clause,runtime,compute,V:3.4- -// pointer scalar as condition (C: non-NULL => true) int test7(void){ int err = 0; srand(SEED); @@ -237,7 +222,7 @@ int test7(void){ c[i]=0; } - void* cond_ptr = (void*)a; // non-NULL pointer => true in C + void* cond_ptr = (void*)a; #pragma acc data copyin(a[0:n]) copyout(c[0:n]) { From 512c54f9f38941a1c42c9b37a8e1cf2e99dd9439 Mon Sep 17 00:00:00 2001 From: Ryanpadrone <159075564+Ryanpadrone@users.noreply.github.com> Date: Wed, 18 Feb 2026 20:04:17 -0500 Subject: [PATCH 14/14] Update acc_if_condition.cpp --- Tests/acc_if_condition.cpp | 14 +++----------- 1 file changed, 3 insertions(+), 11 deletions(-) diff --git a/Tests/acc_if_condition.cpp b/Tests/acc_if_condition.cpp index e67cac7..6ad1a6e 100644 --- a/Tests/acc_if_condition.cpp +++ b/Tests/acc_if_condition.cpp @@ -22,7 +22,6 @@ struct BoolLike { }; #ifndef T1 -//T1:syntax,if-clause,runtime,enter-data,V:3.4- int test1(){ int err=0; real_t* a=(real_t*)std::malloc(n*sizeof(real_t)); @@ -47,7 +46,6 @@ int test1(){ #endif #ifndef T2 -//T2:syntax,if-clause,runtime,enter-data,V:3.4- int test2(){ int err=0; real_t* a=(real_t*)std::malloc(n*sizeof(real_t)); @@ -72,7 +70,6 @@ int test2(){ #endif #ifndef T3 -//T3:syntax,if-clause,runtime,exit-data,V:3.4- int test3(){ int err=0; real_t* a=(real_t*)std::malloc(n*sizeof(real_t)); @@ -102,7 +99,6 @@ int test3(){ #endif #ifndef T4 -//T4:syntax,if-clause,runtime,exit-data,V:3.4- int test4(){ int err=0; real_t* a=(real_t*)std::malloc(n*sizeof(real_t)); @@ -131,8 +127,6 @@ int test4(){ #endif #ifndef T5 -//T5:syntax,if-clause,runtime,compute,V:3.4- -// int expression condition (valid C++) int test5(){ int err=0; std::srand(SEED); @@ -176,8 +170,6 @@ int test5(){ #endif #ifndef T6 -//T6:syntax,if-clause,runtime,compute,V:3.4- -// C++ condition forms: pointer + user-defined bool-convertible type + fp comparison->bool int test6(){ int err=0; std::srand(SEED); @@ -194,10 +186,10 @@ int test6(){ c[i]=0; } - void* cond_ptr = (void*)a; // non-null pointer => true - BoolLike cond_obj{1}; // operator bool() => true + void* cond_ptr = (void*)a; + BoolLike cond_obj{1}; double x = 1.0; - bool cond_fp = (x != 0.0); // C++-correct “float-based” condition + bool cond_fp = (x != 0.0); #pragma acc data copyin(a[0:n]) copyout(c[0:n]) {