offtarget 0.1.0__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- offload/__init__.py +10 -0
- offload/__main__.py +5 -0
- offload/_bundle.py +74 -0
- offload/_root/catalog/acc/claims.yaml +197 -0
- offload/_root/catalog/acc/clauses.yaml +391 -0
- offload/_root/catalog/acc/no_oracle.yaml +89 -0
- offload/_root/catalog/acc/out_of_scope.yaml +17 -0
- offload/_root/catalog/acc/rules.yaml +433 -0
- offload/_root/catalog/acc/semantic_atoms.yaml +27 -0
- offload/_root/catalog/acc/skeleton.yaml +1567 -0
- offload/_root/catalog/acc/spec_overrides.yaml +72 -0
- offload/_root/catalog/later_forms.yaml +76 -0
- offload/_root/catalog/machines.yaml +218 -0
- offload/_root/catalog/omp/claims.yaml +2047 -0
- offload/_root/catalog/omp/clauses.yaml +914 -0
- offload/_root/catalog/omp/derivations.yaml +177 -0
- offload/_root/catalog/omp/memory_modes.yaml +40 -0
- offload/_root/catalog/omp/no_oracle.yaml +373 -0
- offload/_root/catalog/omp/omp50_delta.yaml +377 -0
- offload/_root/catalog/omp/out_of_scope.yaml +64 -0
- offload/_root/catalog/omp/port_equivalence.yaml +352 -0
- offload/_root/catalog/omp/rules.yaml +3131 -0
- offload/_root/catalog/omp/rules_coverage.yaml +9939 -0
- offload/_root/catalog/omp/semantic_atoms.yaml +34 -0
- offload/_root/catalog/omp/skeleton.yaml +9181 -0
- offload/_root/catalog/omp/spec_overrides.yaml +932 -0
- offload/_root/catalog/toolchains.yaml +472 -0
- offload/_root/catalog/vendor_claims_generic.yaml +40925 -0
- offload/_root/data/canuse/b.json +1 -0
- offload/_root/data/canuse/c.json +1 -0
- offload/_root/data/canuse/columns.json +1 -0
- offload/_root/data/canuse/d.json +1 -0
- offload/_root/data/canuse/f.json +1 -0
- offload/_root/data/canuse/index.json +1 -0
- offload/_root/data/canuse/p.json +1 -0
- offload/_root/data/compilers/afar.json +1 -0
- offload/_root/data/compilers/cce19.json +1 -0
- offload/_root/data/compilers/cce20.json +1 -0
- offload/_root/data/compilers/cce21.json +1 -0
- offload/_root/data/compilers/cce21_4.json +1 -0
- offload/_root/data/compilers/gcc.json +1 -0
- offload/_root/data/compilers/gcc_sm80.json +1 -0
- offload/_root/data/compilers/nvhpc.json +1 -0
- offload/_root/data/compilers/nvhpc269.json +1 -0
- offload/_root/data/findings/AUTHORING.md +107 -0
- offload/_root/data/findings/README.md +33 -0
- offload/_root/data/findings/afar-c-error-directive-in-target-link.c +37 -0
- offload/_root/data/findings/afar-c-lastprivate-distribute-parallel-for-small-type.c +56 -0
- offload/_root/data/findings/afar-c-teams-distribute-reduction-first-team.c +59 -0
- offload/_root/data/findings/afar-c-update-iterator-copy-mode.c +45 -0
- offload/_root/data/findings/afar-c-xnack1-target-is-present.c +31 -0
- offload/_root/data/findings/afar-cce19-character-defaultmap.f90 +27 -0
- offload/_root/data/findings/afar-cce19-task-in-target-ice.f90 +23 -0
- offload/_root/data/findings/afar-clang-requires-device-safesync-hang.c +24 -0
- offload/_root/data/findings/afar-flang-firstprivate-map-two-targets.f90 +34 -0
- offload/_root/data/findings/afar-flang-loop-bind-teams-reduction.f90 +27 -0
- offload/_root/data/findings/afar-flang-task-reduction-max.f90 +31 -0
- offload/_root/data/findings/afar-flang-thread-limit-target-parallel-do.f90 +22 -0
- offload/_root/data/findings/afar-linear-ref-omp50.f90 +29 -0
- offload/_root/data/findings/afar-loop-bind-thread-in-teams.f90 +44 -0
- offload/_root/data/findings/afar-nontemporal-assumed-shape-ice.f90 +38 -0
- offload/_root/data/findings/afar-udr-derived-type-link.f90 +41 -0
- offload/_root/data/findings/afar-xnack1-atomic-min-nested-parallel.f90 +53 -0
- offload/_root/data/findings/afar-xnack1-present-not-enforced.f90 +36 -0
- offload/_root/data/findings/afar-xnack1-target-is-present.f90 +47 -0
- offload/_root/data/findings/apps/afar-cce-teams-private-array-nested-parallel-wrong.f90 +100 -0
- offload/_root/data/findings/apps/cce20-device-link-infer-address-spaces-crash.f90 +159 -0
- offload/_root/data/findings/apps/cce21-device-link-agpr-copy-mfma-assert.f90 +343 -0
- offload/_root/data/findings/apps/cce21-private-array-loaded-subscript-wrong.f90 +113 -0
- offload/_root/data/findings/apps/controls/bubble-simple-rddot.f90 +284 -0
- offload/_root/data/findings/apps/controls/bubble-two-substeps.f90 +287 -0
- offload/_root/data/findings/apps/controls/cbc-inline.f90 +97 -0
- offload/_root/data/findings/apps/controls/cbc-integers.f90 +91 -0
- offload/_root/data/findings/apps/controls/cbc-only-density.f90 +97 -0
- offload/_root/data/findings/apps/controls/cbc-only-velocity.f90 +97 -0
- offload/_root/data/findings/apps/controls/gcc-acc-c-tile-control.c +26 -0
- offload/_root/data/findings/apps/controls/gcc-acc-tile-control.f90 +29 -0
- offload/_root/data/findings/apps/controls/private-array-subscript-probes.f90 +45 -0
- offload/_root/data/findings/apps/controls/teams-private-array-read-par.f90 +31 -0
- offload/_root/data/findings/apps/controls/teams-private-array-seq.f90 +30 -0
- offload/_root/data/findings/apps/controls/teams-private-array-shared.f90 +34 -0
- offload/_root/data/findings/apps/controls/teams-private-array-split.f90 +36 -0
- offload/_root/data/findings/apps/controls/teams-private-array-write-par.f90 +31 -0
- offload/_root/data/findings/apps/gcc-acc-c-tile-partial-tiles-wrong.c +60 -0
- offload/_root/data/findings/apps/gcc-acc-tile-partial-tiles-wrong.f90 +64 -0
- offload/_root/data/findings/catalog/afar-c-complex-reduction-link.c +66 -0
- offload/_root/data/findings/catalog/afar-c-critical-hint-link.c +68 -0
- offload/_root/data/findings/catalog/afar-c-ordered-doacross-link.c +62 -0
- offload/_root/data/findings/catalog/afar-c-reduction-task-link.c +81 -0
- offload/_root/data/findings/catalog/afar-flang-absent-optional-target-crash.f90 +76 -0
- offload/_root/data/findings/catalog/afar-flang-critical-target-parallel-wrong.f90 +74 -0
- offload/_root/data/findings/catalog/afar-flang-dist-schedule-chunk.f90 +80 -0
- offload/_root/data/findings/catalog/afar-flang-linear-parallel-ice.f90 +68 -0
- offload/_root/data/findings/catalog/afar-flang-named-critical-link.f90 +67 -0
- offload/_root/data/findings/catalog/afar-flang-ordered-wrong.f90 +78 -0
- offload/_root/data/findings/catalog/afar-flang-reduction-minus-rejected.f90 +77 -0
- offload/_root/data/findings/catalog/afar-flang-reduction-task-ice.f90 +68 -0
- offload/_root/data/findings/catalog/afar-flang-sections-in-target-ice.f90 +67 -0
- offload/_root/data/findings/catalog/afar-flang-workdistribute-ice.f90 +71 -0
- offload/_root/data/findings/catalog/c-allocate-const-mem-firstprivate-wrong.c +79 -0
- offload/_root/data/findings/catalog/cce-acc-allocate-in-compute-crash.f90 +65 -0
- offload/_root/data/findings/catalog/cce-acc-character-dummy-routine-ice.f90 +81 -0
- offload/_root/data/findings/catalog/cce-acc-loop-seq-in-routine-wrong.f90 +81 -0
- offload/_root/data/findings/catalog/cce-acc-stop-in-compute-crash.f90 +62 -0
- offload/_root/data/findings/catalog/cce-allocators-stack-ice.f90 +81 -0
- offload/_root/data/findings/catalog/cce-atomic-default-mem-order-acquire-release-rejected.f90 +61 -0
- offload/_root/data/findings/catalog/cce-c-allocate-align-link.c +83 -0
- offload/_root/data/findings/catalog/cce-c-allocate-allocator-modifier-rejected.c +77 -0
- offload/_root/data/findings/catalog/cce-c-device-type-directive-name-ice.c +70 -0
- offload/_root/data/findings/catalog/cce-c-dist-schedule-chunk.c +81 -0
- offload/_root/data/findings/catalog/cce-c-f-pointer-device-link.f90 +70 -0
- offload/_root/data/findings/catalog/cce-c-lastprivate-parallel-in-seq-loop-wrong.c +64 -0
- offload/_root/data/findings/catalog/cce-c-long-double-ice.c +61 -0
- offload/_root/data/findings/catalog/cce-c-map-iterator-ice.c +92 -0
- offload/_root/data/findings/catalog/cce-c-motion-iterator-rejected.c +68 -0
- offload/_root/data/findings/catalog/cce-c-ordered-doacross-link.c +64 -0
- offload/_root/data/findings/catalog/cce-c-ordered-link.c +77 -0
- offload/_root/data/findings/catalog/cce-c-recursive-function-ice.c +62 -0
- offload/_root/data/findings/catalog/cce-c-reduction-inscan-ice.c +67 -0
- offload/_root/data/findings/catalog/cce-c-reduction-task-link.c +73 -0
- offload/_root/data/findings/catalog/cce-c-sections-in-target-wrong.c +70 -0
- offload/_root/data/findings/catalog/cce-c-single-masked-task-link.c +66 -0
- offload/_root/data/findings/catalog/cce-c-task-in-target-link.c +75 -0
- offload/_root/data/findings/catalog/cce-c-uses-allocators-traits-rejected.c +71 -0
- offload/_root/data/findings/catalog/cce-flang-allocate-const-mem-ice.f90 +67 -0
- offload/_root/data/findings/catalog/cce-flang-allocate-in-target-crash.f90 +68 -0
- offload/_root/data/findings/catalog/cce-flang-lastprivate-parallel-in-seq-loop-wrong.f90 +83 -0
- offload/_root/data/findings/catalog/cce-flang-stop-in-target-crash.f90 +64 -0
- offload/_root/data/findings/catalog/cce-iterator-link.f90 +67 -0
- offload/_root/data/findings/catalog/cce-linear-lastprivate-ice.f90 +69 -0
- offload/_root/data/findings/catalog/cce-nohost-link.f90 +90 -0
- offload/_root/data/findings/catalog/cce-reduction-inscan-ice.f90 +66 -0
- offload/_root/data/findings/catalog/cce-reduction-task-link.f90 +76 -0
- offload/_root/data/findings/catalog/cce19-reduction-task-addrspacecast-ice.f90 +77 -0
- offload/_root/data/findings/catalog/cce20-c-defaultmap-private-storage-rejected.c +85 -0
- offload/_root/data/findings/catalog/cce20-map-self-rejected.f90 +64 -0
- offload/_root/data/findings/catalog/cce21-c-declare-target-local-rejected.c +73 -0
- offload/_root/data/findings/catalog/cce21-c-target-loop-ice.c +77 -0
- offload/_root/data/findings/catalog/defaultmap-present-private-array-abort.f90 +73 -0
- offload/_root/data/findings/catalog/nvhpc-acc-associate-illegal-address.f90 +66 -0
- offload/_root/data/findings/catalog/nvhpc-c-function-pointer-kernel-missing.c +68 -0
- offload/_root/data/findings/catalog/nvhpc-c-long-double-kernel-missing.c +64 -0
- offload/_root/data/findings/catalog/nvhpc-c-static-local-kernel-missing.c +73 -0
- offload/_root/data/findings/catalog/nvhpc-c-vla-kernel-missing.c +63 -0
- offload/_root/data/findings/catalog/nvhpc-flang-type-bound-kernel-missing.f90 +86 -0
- offload/_root/data/findings/cce-acc-init-set-runtime-assert.f90 +35 -0
- offload/_root/data/findings/cce-acc-reduction-200-int8-scalars-wrong.f90 +1278 -0
- offload/_root/data/findings/cce-acc-routine-bind-module-ice.f90 +35 -0
- offload/_root/data/findings/cce-acc-self-condition-ignored.f90 +17 -0
- offload/_root/data/findings/cce-c-dist-schedule-segv.c +34 -0
- offload/_root/data/findings/cce-c-map-delete-refcount.c +47 -0
- offload/_root/data/findings/cce-c-map-present-assert.c +45 -0
- offload/_root/data/findings/cce-c-openmp45-device-link.c +34 -0
- offload/_root/data/findings/cce-c-parallel-for-in-target.c +73 -0
- offload/_root/data/findings/cce-defaultmap-tofrom-explicit-map.f90 +92 -0
- offload/_root/data/findings/cce-mapper-next-map-copy-back.f90 +48 -0
- offload/_root/data/findings/cce-trim-merge-output-one-character.f90 +40 -0
- offload/_root/data/findings/cce-uses-allocators-traits-omp50.f90 +28 -0
- offload/_root/data/findings/cce19-acc-if-false-link.f90 +17 -0
- offload/_root/data/findings/cce19-c-reduction-63-scalars-one-wrong.c +235 -0
- offload/_root/data/findings/cce19-target-parallel-guarded-loop.f90 +35 -0
- offload/_root/data/findings/cce19-target-parallel-single-ice.f90 +38 -0
- offload/_root/data/findings/cce21-alloc-2e32-sum-wrong.f90 +68 -0
- offload/_root/data/findings/cce21-defaultmap-aggregate-flag.f90 +52 -0
- offload/_root/data/findings/cce21-in-reduction-assumed-shape-write-lost.f90 +61 -0
- offload/_root/data/findings/cce21-in-reduction-taskwait-link.f90 +59 -0
- offload/_root/data/findings/cce21-linear-modifier-default-none.f90 +59 -0
- offload/_root/data/findings/clang-c-declare-target-to-omp52.c +50 -0
- offload/_root/data/findings/clang-c-linear-directive-name-hang.c +30 -0
- offload/_root/data/findings/clang-c-map-iterator-omp51.c +51 -0
- offload/_root/data/findings/clang-c-shared-declare-target-combined.c +58 -0
- offload/_root/data/findings/dataenv/cce-value-dummy-target-write-visible.f90 +74 -0
- offload/_root/data/findings/defaultmap-none-loop-variable.f90 +69 -0
- offload/_root/data/findings/fortran-loop-bind-thread-in-parallel.f90 +53 -0
- offload/_root/data/findings/fortran-schedule-static-in-target.f90 +55 -0
- offload/_root/data/findings/fresh/cce-common-block-name-in-map-rejected.f90 +47 -0
- offload/_root/data/findings/fresh/cce-if-stop-in-target-ice-one-condition.f90 +38 -0
- offload/_root/data/findings/fresh/cce-if-stop-in-target-ice.f90 +43 -0
- offload/_root/data/findings/fresh/cce-list-directed-print-in-target-copy-crash.f90 +40 -0
- offload/_root/data/findings/fresh/cce19-acc-automatic-array-copyout-copy-crash.f90 +56 -0
- offload/_root/data/findings/fresh/cce21-combined-if-runtime-expr-loop-skipped.f90 +57 -0
- offload/_root/data/findings/fresh/nvhpc-acc-gang-worker-collapse-nested-vector-reduction-lost.f90 +67 -0
- offload/_root/data/findings/fresh/nvhpc-teams-loop-module-allocatable-assign-fort2-crash.f90 +73 -0
- offload/_root/data/findings/fuzz/1131-afar.f90 +48 -0
- offload/_root/data/findings/fuzz/1391-cce20.f90 +40 -0
- offload/_root/data/findings/fuzz/14-cce20.f90 +36 -0
- offload/_root/data/findings/fuzz/1505-cce20.f90 +88 -0
- offload/_root/data/findings/fuzz/1540-afar.f90 +44 -0
- offload/_root/data/findings/fuzz/158-afar.f90 +63 -0
- offload/_root/data/findings/fuzz/16-cce20.f90 +39 -0
- offload/_root/data/findings/fuzz/1644-cce21.f90 +31 -0
- offload/_root/data/findings/fuzz/165-cce19.f90 +52 -0
- offload/_root/data/findings/fuzz/1749-cce20.f90 +34 -0
- offload/_root/data/findings/fuzz/1936-afar.f90 +61 -0
- offload/_root/data/findings/fuzz/1978-cce19.f90 +41 -0
- offload/_root/data/findings/fuzz/2014-cce19.f90 +46 -0
- offload/_root/data/findings/fuzz/2224-cce19.f90 +30 -0
- offload/_root/data/findings/fuzz/2334-cce19.f90 +57 -0
- offload/_root/data/findings/fuzz/536-cce19.f90 +38 -0
- offload/_root/data/findings/fuzz/591-cce19.f90 +54 -0
- offload/_root/data/findings/fuzz/650-afar.f90 +58 -0
- offload/_root/data/findings/fuzz/698-afar.f90 +68 -0
- offload/_root/data/findings/fuzz/700-afar.f90 +46 -0
- offload/_root/data/findings/fuzz/775-cce21.f90 +33 -0
- offload/_root/data/findings/fuzz/87-afar.f90 +47 -0
- offload/_root/data/findings/fuzz/916-afar.f90 +67 -0
- offload/_root/data/findings/fuzz/958-cce20.f90 +44 -0
- offload/_root/data/findings/fuzz/98-cce19.f90 +40 -0
- offload/_root/data/findings/fuzz/README.md +236 -0
- offload/_root/data/findings/fuzz/b1-121-afar.f90 +47 -0
- offload/_root/data/findings/fuzz/b1-183-afar.f90 +55 -0
- offload/_root/data/findings/fuzz/b1-22-cce20.f90 +38 -0
- offload/_root/data/findings/fuzz/b1-231-afar.f90 +56 -0
- offload/_root/data/findings/fuzz/b1-268-afar.f90 +46 -0
- offload/_root/data/findings/fuzz/b2-183-afar.f90 +57 -0
- offload/_root/data/findings/fuzz/b2-209-cce19.f90 +51 -0
- offload/_root/data/findings/fuzz/b2-213-afar.f90 +63 -0
- offload/_root/data/findings/fuzz/b2-52-afar.f90 +56 -0
- offload/_root/data/findings/fuzz/b2-68-afar.f90 +54 -0
- offload/_root/data/findings/fuzz/b2-85-cce20.f90 +55 -0
- offload/_root/data/findings/fuzz/b3-188-cce19.f90 +90 -0
- offload/_root/data/findings/fuzz/b3-190-cce21.f90 +88 -0
- offload/_root/data/findings/fuzz/b3-197-cce19.f90 +77 -0
- offload/_root/data/findings/fuzz/b3-250-cce20.f90 +89 -0
- offload/_root/data/findings/fuzz/b3-278-cce19.f90 +70 -0
- offload/_root/data/findings/fuzz/b3-45-cce21.f90 +83 -0
- offload/_root/data/findings/fuzz/b3-54-afar.f90 +67 -0
- offload/_root/data/findings/fuzz/b3-61-cce20.f90 +100 -0
- offload/_root/data/findings/fuzz/b3-9-afar.f90 +100 -0
- offload/_root/data/findings/fuzz/b3-9-cce21.f90 +103 -0
- offload/_root/data/findings/fuzz/b3-94-afar.f90 +80 -0
- offload/_root/data/findings/fuzz/b4-39-afar.f90 +141 -0
- offload/_root/data/findings/fuzz/b4-86-cce19.f90 +71 -0
- offload/_root/data/findings/fuzz/controls/gcc-complex-pointer-store-control.f90 +28 -0
- offload/_root/data/findings/fuzz/controls/gcc-declare-reduction-module-control.f90 +29 -0
- offload/_root/data/findings/fuzz/controls/gcc-target-simd-map-nontemporal-control.f90 +21 -0
- offload/_root/data/findings/fuzz/controls/nvhpc-allocatable-component-mapped-control.f90 +22 -0
- offload/_root/data/findings/fuzz/controls/nvhpc-allocatable-component-unreferenced-control.f90 +22 -0
- offload/_root/data/findings/fuzz/controls/nvhpc-default-none-removed-control.f90 +18 -0
- offload/_root/data/findings/fuzz/controls/nvhpc-default-shared-control.f90 +18 -0
- offload/_root/data/findings/fuzz/controls/nvhpc-defaultmap-firstprivate-removed-control.f90 +15 -0
- offload/_root/data/findings/fuzz/controls/nvhpc-defaultmap-to-scalar-reduction-mapped-control.f90 +17 -0
- offload/_root/data/findings/fuzz/controls/nvhpc-defaultmap-to-scalar-removed-control.f90 +17 -0
- offload/_root/data/findings/fuzz/controls/nvhpc-defaultmap-tofrom-lastprivate-control.f90 +15 -0
- offload/_root/data/findings/fuzz/controls/nvhpc-depend-explicit-map-control.f90 +22 -0
- offload/_root/data/findings/fuzz/controls/nvhpc-depend-removed-control.f90 +22 -0
- offload/_root/data/findings/fuzz/controls/nvhpc-distribute-end-distribute-control.f90 +16 -0
- offload/_root/data/findings/fuzz/controls/nvhpc-distribute-parallel-num-threads-removed-control.f90 +26 -0
- offload/_root/data/findings/fuzz/controls/nvhpc-distribute-parallel-removed-control.f90 +22 -0
- offload/_root/data/findings/fuzz/controls/nvhpc-distribute-simd-no-end-directive-control.f90 +15 -0
- offload/_root/data/findings/fuzz/controls/nvhpc-explicit-length-character-dummy-control.f90 +18 -0
- offload/_root/data/findings/fuzz/controls/nvhpc-loop-character-array-value-control.f90 +23 -0
- offload/_root/data/findings/fuzz/controls/nvhpc-loop-character-distribute-control.f90 +20 -0
- offload/_root/data/findings/fuzz/controls/nvhpc-map-always-first-control.f90 +15 -0
- offload/_root/data/findings/fuzz/controls/nvhpc-map-always-removed-control.f90 +15 -0
- offload/_root/data/findings/fuzz/controls/nvhpc-num-threads-removed-control.f90 +12 -0
- offload/_root/data/findings/fuzz/controls/nvhpc-target-parallel-firstprivate-dropped-control.f90 +15 -0
- offload/_root/data/findings/fuzz/controls/nvhpc-target-parallel-single-nowait-control.f90 +13 -0
- offload/_root/data/findings/fuzz/controls/nvhpc-target-parallel-split-control.f90 +15 -0
- offload/_root/data/findings/fuzz/controls/nvhpc-target-simd-collapse-split-control.f90 +21 -0
- offload/_root/data/findings/fuzz/controls/nvhpc-target-simd-end-directive-control.f90 +14 -0
- offload/_root/data/findings/fuzz/controls/nvhpc-target-simd-no-collapse-control.f90 +19 -0
- offload/_root/data/findings/fuzz/controls/nvhpc-target-simd-split-no-end-directive-control.f90 +15 -0
- offload/_root/data/findings/fuzz/gcc-declare-reduction-module-not-found.f90 +66 -0
- offload/_root/data/findings/fuzz/gcc-strided-target-update-rejected.f90 +58 -0
- offload/_root/data/findings/fuzz/gcc-target-simd-map-nontemporal-rejected.f90 +54 -0
- offload/_root/data/findings/fuzz/nvhpc-allocatable-component-implicit-map-illegal-address.f90 +84 -0
- offload/_root/data/findings/fuzz/nvhpc-assumed-length-character-dummy-map-ice.f90 +69 -0
- offload/_root/data/findings/fuzz/nvhpc-default-none-reduction-lastprivate-fort1-crash.f90 +70 -0
- offload/_root/data/findings/fuzz/nvhpc-defaultmap-firstprivate-lastprivate-ice.f90 +71 -0
- offload/_root/data/findings/fuzz/nvhpc-defaultmap-to-scalar-reduction-lost.f90 +82 -0
- offload/_root/data/findings/fuzz/nvhpc-depend-implicit-map-illegal-address.f90 +81 -0
- offload/_root/data/findings/fuzz/nvhpc-distribute-parallel-num-threads-writes-lost.f90 +79 -0
- offload/_root/data/findings/fuzz/nvhpc-end-distribute-simd-rejected.f90 +70 -0
- offload/_root/data/findings/fuzz/nvhpc-loop-character-achar-unsupported.f90 +75 -0
- offload/_root/data/findings/fuzz/nvhpc-map-always-after-map-to-not-copied-back.f90 +70 -0
- offload/_root/data/findings/fuzz/nvhpc-num-threads-reduction-identity-lost.f90 +54 -0
- offload/_root/data/findings/fuzz/nvhpc-target-parallel-firstprivate-translate-failure.f90 +66 -0
- offload/_root/data/findings/fuzz/nvhpc-target-parallel-single-hang.f90 +68 -0
- offload/_root/data/findings/fuzz/nvhpc-target-simd-collapse-translate-failure.f90 +73 -0
- offload/_root/data/findings/fuzz/nvhpc-target-simd-no-end-directive-rejected.f90 +68 -0
- offload/_root/data/findings/fuzz/par-s1-2082-gcc_g90.f90 +71 -0
- offload/_root/data/findings/fuzz/s1-2370-cce21.f90 +67 -0
- offload/_root/data/findings/fuzz/s1-2592-cce21.f90 +56 -0
- offload/_root/data/findings/fuzz/s1-3463-cce21.f90 +92 -0
- offload/_root/data/findings/fuzz/s1-4339-afar.f90 +79 -0
- offload/_root/data/findings/fuzz/s1-6085-cce21.f90 +96 -0
- offload/_root/data/findings/fuzz/s1-6760-cce20.f90 +65 -0
- offload/_root/data/findings/fuzz/s1-6888-cce21.f90 +76 -0
- offload/_root/data/findings/fuzz/s1-7882-cce20.f90 +63 -0
- offload/_root/data/findings/fuzz/s1-8634-cce21.f90 +45 -0
- offload/_root/data/findings/fuzz/s1-91-cce21.f90 +92 -0
- offload/_root/data/findings/fuzz/s1-9443-afar.f90 +59 -0
- offload/_root/data/findings/fuzz/s1-9914-cce19.f90 +78 -0
- offload/_root/data/findings/gcc/controls/gcc-acc-c-detach-control.c +34 -0
- offload/_root/data/findings/gcc/controls/gcc-acc-detach-control.f90 +26 -0
- offload/_root/data/findings/gcc/controls/gcc-defaultmap-to-pointer-control.f90 +31 -0
- offload/_root/data/findings/gcc/controls/gcc-target-in-task-control.c +26 -0
- offload/_root/data/findings/gcc/controls/gcc-target-in-task-control.f90 +21 -0
- offload/_root/data/findings/gcc/gcc-acc-bind-device-type-rejected.f90 +71 -0
- offload/_root/data/findings/gcc/gcc-acc-c-bind-device-type-rejected.c +76 -0
- offload/_root/data/findings/gcc/gcc-acc-c-detach-delete-attach-underflow.c +74 -0
- offload/_root/data/findings/gcc/gcc-acc-c-gang-dim-rejected.c +79 -0
- offload/_root/data/findings/gcc/gcc-acc-c-link-in-routine-rejected.c +82 -0
- offload/_root/data/findings/gcc/gcc-acc-detach-delete-attach-underflow.f90 +66 -0
- offload/_root/data/findings/gcc/gcc-acc-gang-dim-collapse-force-rejected.f90 +69 -0
- offload/_root/data/findings/gcc/gcc-acc-init-set-shutdown-rejected.f90 +70 -0
- offload/_root/data/findings/gcc/gcc-acc-link-in-routine-rejected.f90 +82 -0
- offload/_root/data/findings/gcc/gcc-acc-use-device-allocatable-rejected.f90 +88 -0
- offload/_root/data/findings/gcc/gcc-c-motion-mapper-rejected.c +110 -0
- offload/_root/data/findings/gcc/gcc-c-omp60-undocumented-rejected.c +76 -0
- offload/_root/data/findings/gcc/gcc-c-omp60-unimplemented-rejected.c +119 -0
- offload/_root/data/findings/gcc/gcc-c-target-in-task-mandatory-device-not-found.c +87 -0
- offload/_root/data/findings/gcc/gcc-c-uses-allocators-traits-unimplemented.c +85 -0
- offload/_root/data/findings/gcc/gcc-declare-mapper-rejected.f90 +85 -0
- offload/_root/data/findings/gcc/gcc-defaultmap-to-pointer-copy-back.f90 +66 -0
- offload/_root/data/findings/gcc/gcc-loop-bind-default-none-rejected.f90 +93 -0
- offload/_root/data/findings/gcc/gcc-omp60-undocumented-rejected.f90 +72 -0
- offload/_root/data/findings/gcc/gcc-omp60-unimplemented-rejected.f90 +112 -0
- offload/_root/data/findings/gcc/gcc-target-in-task-mandatory-device-not-found.f90 +83 -0
- offload/_root/data/findings/gcc/gcc-uses-allocators-traits-unimplemented.f90 +78 -0
- offload/_root/data/findings/harvest/afar-flang-strided-target-update.f90 +96 -0
- offload/_root/data/findings/harvest/cce-acc-declare-create-module-allocatable-xnack1-fault.f90 +58 -0
- offload/_root/data/findings/harvest/cce-c-implicit-struct-map-partly-present.c +100 -0
- offload/_root/data/findings/harvest/cce-c-strided-target-update.c +74 -0
- offload/_root/data/findings/harvest/cce-ftn-target-parallel-thread-query-ice.f90 +67 -0
- offload/_root/data/findings/harvest/cce-named-constant-array-declare-target-routine-rejected.f90 +69 -0
- offload/_root/data/findings/harvest/cce-use-device-ptr-c-ptr-not-converted.f90 +64 -0
- offload/_root/data/findings/harvest/cce21-declare-target-link-module-variable-write-lost.f90 +63 -0
- offload/_root/data/findings/harvest/cce21-internal-procedure-calls-internal-in-target-fault.f90 +71 -0
- offload/_root/data/findings/harvest/controls/cce-c-implicit-struct-map-partly-present-target-only-control.c +22 -0
- offload/_root/data/findings/harvest/controls/cce-c-implicit-struct-map-partly-present-whole-control.c +23 -0
- offload/_root/data/findings/harvest/controls/gcc-acc-declare-create-allocatable-control.f90 +34 -0
- offload/_root/data/findings/harvest/controls/gcc-c-same-item-two-maps-control.c +17 -0
- offload/_root/data/findings/harvest/controls/gcc-c-target-data-struct-pointer-section-control.c +27 -0
- offload/_root/data/findings/harvest/controls/gcc-c-target-data-two-maps-control.c +20 -0
- offload/_root/data/findings/harvest/controls/gcc-same-item-two-maps-control.f90 +16 -0
- offload/_root/data/findings/harvest/controls/gcc-teams-simd-matmul-allocatable-control.f90 +27 -0
- offload/_root/data/findings/harvest/gcc-acc-declare-create-allocatable-not-mapped.f90 +66 -0
- offload/_root/data/findings/harvest/gcc-c-same-item-two-maps-rejected.c +45 -0
- offload/_root/data/findings/harvest/gcc-c-strided-section-rejected.c +70 -0
- offload/_root/data/findings/harvest/gcc-c-target-data-struct-pointer-section-ice.c +78 -0
- offload/_root/data/findings/harvest/gcc-c-target-data-two-maps-ice.c +49 -0
- offload/_root/data/findings/harvest/gcc-same-item-two-maps-rejected.f90 +46 -0
- offload/_root/data/findings/harvest/gcc-teams-simd-matmul-allocatable-ice.f90 +53 -0
- offload/_root/data/findings/harvest/nvhpc-c-target-data-if-false-use-device-ptr-garbage.c +49 -0
- offload/_root/data/findings/harvest/nvhpc-named-constant-array-declare-target-routine-rejected.f90 +65 -0
- offload/_root/data/findings/harvest/nvhpc-use-device-ptr-c-ptr-not-found.f90 +60 -0
- offload/_root/data/findings/harvest/nvhpc2511-target-nowait-in-parallel-for-ice.c +59 -0
- offload/_root/data/findings/hecbench/controls/f16-ctl-float-array.c +28 -0
- offload/_root/data/findings/hecbench/controls/pc-ctl-builtin-popcount.c +37 -0
- offload/_root/data/findings/hecbench/controls/pc-ctl-shift-sum.c +43 -0
- offload/_root/data/findings/hecbench/gcc-c-float16-array-in-target-lto-ice.c +65 -0
- offload/_root/data/findings/hecbench/gcc-c-swar-popcount-assembler-error.c +80 -0
- offload/_root/data/findings/index.yaml +2453 -0
- offload/_root/data/findings/malloc/afar-device-malloc-in-kernel-corrupts-records.c +371 -0
- offload/_root/data/findings/malloc/controls/afar-first-use-malloc-direct.c +52 -0
- offload/_root/data/findings/malloc/controls/afar-first-use-malloc-fence.c +57 -0
- offload/_root/data/findings/malloc/controls/afar-first-use-malloc-flush.c +57 -0
- offload/_root/data/findings/malloc/controls/afar-first-use-malloc-stack.c +52 -0
- offload/_root/data/findings/multithread-allocatable-section-maps.f90 +91 -0
- offload/_root/data/findings/nested/afar-cce-c-call-result-member-in-target-rejected.c +69 -0
- offload/_root/data/findings/nested/afar-cce-c-update-struct-and-member-rejected.c +92 -0
- offload/_root/data/findings/nested/afar-flang-pointer-root-allocatable-component-enter-data-fault.f90 +121 -0
- offload/_root/data/findings/nested/cce-c-struct-and-nested-pointee-sections-ice.c +79 -0
- offload/_root/data/findings/nested/cce-fortran-nested-allocatable-component-copy-fault.f90 +64 -0
- offload/_root/data/findings/nested/cce-fortran-pointer-to-type-with-allocatable-scalar-component-typed-transfer.f90 +93 -0
- offload/_root/data/findings/nested/cce-fortran-update-to-pointer-root-allocatable-scalar-component-no-accelerator-object.f90 +80 -0
- offload/_root/data/findings/nested/controls/c3-ctl-nested-data.c +27 -0
- offload/_root/data/findings/nested/controls/c5-acc-serial-struct-and-array.c +26 -0
- offload/_root/data/findings/nested/controls/e2-ctl-two-directives.c +42 -0
- offload/_root/data/findings/nested/controls/e3-ctl-attach-clause.c +42 -0
- offload/_root/data/findings/nested/controls/f3-pointer-array-only.c +33 -0
- offload/_root/data/findings/nested/controls/f5-ctl-copyout-exit.c +33 -0
- offload/_root/data/findings/nested/controls/f6-ctl-pointer-to-struct-array.c +28 -0
- offload/_root/data/findings/nested/controls/g2-ctl-allocatable.f90 +34 -0
- offload/_root/data/findings/nested/controls/g2-ctl-entered-to.f90 +34 -0
- offload/_root/data/findings/nested/controls/g3-ctl-from-struct-no-element.c +27 -0
- offload/_root/data/findings/nested/controls/g3-ptrs-two-elements-to.c +27 -0
- offload/_root/data/findings/nested/controls/g3-ptrs-two-elements-tofrom.c +27 -0
- offload/_root/data/findings/nested/controls/g5-ctl-element-pointers-only.f90 +36 -0
- offload/_root/data/findings/nested/controls/g5-ctl-root-pointer-only.f90 +36 -0
- offload/_root/data/findings/nested/controls/gp2-ctl-no-mapper-explicit-maps.c +24 -0
- offload/_root/data/findings/nested/controls/gt2-ctl-no-always.c +26 -0
- offload/_root/data/findings/nested/controls/gt3-ctl-always-on-structure-only.c +26 -0
- offload/_root/data/findings/nested/controls/j1-embedded-struct-pointer-to-struct.c +24 -0
- offload/_root/data/findings/nested/controls/j2-ctl-pointer-instead-of-embedded.c +24 -0
- offload/_root/data/findings/nested/controls/j6-ctl-struct-and-one-pointee-level.c +23 -0
- offload/_root/data/findings/nested/controls/j7-ctl-struct-and-embedded-pointee.c +24 -0
- offload/_root/data/findings/nested/controls/m2-ctl-variable-root.f90 +32 -0
- offload/_root/data/findings/nested/controls/m3-ctl-fixed-array-component.f90 +32 -0
- offload/_root/data/findings/nested/controls/m5-ctl-no-enter-data.f90 +33 -0
- offload/_root/data/findings/nested/controls/n8-ctl-fixed-array-in-component.f90 +33 -0
- offload/_root/data/findings/nested/controls/n9-ctl-allocatable-in-the-variable.f90 +33 -0
- offload/_root/data/findings/nested/controls/ns4-ctl-two-directives-struct-then-pointee.c +27 -0
- offload/_root/data/findings/nested/controls/ns8-ctl-enter-together-exit-split.c +26 -0
- offload/_root/data/findings/nested/controls/nu3-ctl-update-pointee-only.c +28 -0
- offload/_root/data/findings/nested/controls/p2-ctl-pointer-variable.c +27 -0
- offload/_root/data/findings/nested/controls/p3-ctl-direct-member.c +26 -0
- offload/_root/data/findings/nested/controls/q2-ctl-fixed-array.f90 +37 -0
- offload/_root/data/findings/nested/controls/q3-ctl-allocatable-component-of-the-variable.f90 +38 -0
- offload/_root/data/findings/nested/controls/ta2-ctl-no-allocatable-component.f90 +42 -0
- offload/_root/data/findings/nested/controls/ta3-ctl-allocatable-scalar-in-the-variable.f90 +38 -0
- offload/_root/data/findings/nested/controls/ta4-ctl-pointer-component-only.f90 +42 -0
- offload/_root/data/findings/nested/controls/u3-ctl-update-member-only.c +24 -0
- offload/_root/data/findings/nested/controls/u4-ctl-two-updates.c +25 -0
- offload/_root/data/findings/nested/controls/u5-ctl-same-list-in-map.c +25 -0
- offload/_root/data/findings/nested/controls/ua2-ctl-variable-root.f90 +37 -0
- offload/_root/data/findings/nested/controls/ua4-ctl-to-in-place-of-alloc-and-update.f90 +37 -0
- offload/_root/data/findings/nested/controls/v2-ctl-parent-first.c +25 -0
- offload/_root/data/findings/nested/controls/v4-ctl-embedded-member.c +24 -0
- offload/_root/data/findings/nested/gcc-acc-c-exit-data-of-a-pointer-array-element-target-hangs.c +83 -0
- offload/_root/data/findings/nested/gcc-acc-c-parent-and-shared-pointee-one-directive.c +88 -0
- offload/_root/data/findings/nested/gcc-acc-c-struct-and-member-array-one-directive.c +84 -0
- offload/_root/data/findings/nested/gcc-c-always-on-pointer-member-section-ice.c +75 -0
- offload/_root/data/findings/nested/gcc-c-declare-mapper-pointer-member-section-gpu-fault.c +93 -0
- offload/_root/data/findings/nested/gcc-c-from-struct-and-pointee-section-rejected.c +83 -0
- offload/_root/data/findings/nested/gcc-fortran-pointer-component-alloc-bounds-lost.f90 +62 -0
- offload/_root/data/findings/nested/gcc-fortran-root-and-element-pointer-components-ice.f90 +77 -0
- offload/_root/data/findings/nested/nvhpc-c-pointee-before-parent-in-one-map-list-copy-fault.c +55 -0
- offload/_root/data/findings/nested/nvhpc-c-update-from-structure-overwrites-attached-pointer-segv.c +86 -0
- offload/_root/data/findings/nvhpc-acc-atomic-update-sum-fort2-crash.f90 +53 -0
- offload/_root/data/findings/nvhpc-c-acc-atomic-update-sum-ice.c +43 -0
- offload/_root/data/findings/nvhpc-c-dist-schedule-chunk-compile-hang.c +41 -0
- offload/_root/data/findings/nvhpc-c-map-present-ignored.c +42 -0
- offload/_root/data/findings/nvhpc-c-ordered-in-target-nvcpfe-crash.c +92 -0
- offload/_root/data/findings/nvhpc-c-parallel-for-firstprivate-in-target.c +62 -0
- offload/_root/data/findings/nvhpc-c-parallel-if-in-target-nvvm-ice.c +56 -0
- offload/_root/data/findings/nvhpc-defaultmap-firstprivate-explicit-map.f90 +45 -0
- offload/_root/data/findings/nvhpc-defaultmap-from-allocatable-indexing.f90 +60 -0
- offload/_root/data/findings/nvhpc-depend-inoutset-ignored.f90 +64 -0
- offload/_root/data/findings/nvhpc-dist-schedule-chunk-illegal-address.f90 +52 -0
- offload/_root/data/findings/nvhpc-managed-acc-shutdown-host-access.f90 +42 -0
- offload/_root/data/findings/nvhpc-parallel-if-in-target-nvvm-ice.f90 +60 -0
- offload/_root/data/findings/oop/afar-final-dealloc-device-link.f90 +85 -0
- offload/_root/data/findings/oop/afar-pdt-length-parameter-not-implemented.f90 +65 -0
- offload/_root/data/findings/oop/cce-class-is-device-link.f90 +86 -0
- offload/_root/data/findings/oop/cce-copy-alloc-component-section-fault.f90 +73 -0
- offload/_root/data/findings/oop/cce-copy-parent-to-component-tofrom-lost.f90 +65 -0
- offload/_root/data/findings/oop/cce-copy-second-member-section-lost.f90 +65 -0
- offload/_root/data/findings/oop/cce-element-component-map-lost.f90 +64 -0
- offload/_root/data/findings/oop/cce-final-dealloc-device-abort.f90 +85 -0
- offload/_root/data/findings/oop/cce-pdt-default-mapper-rejected.f90 +71 -0
- offload/_root/data/findings/oop/cce-polymorphic-dispatch-device-link.f90 +100 -0
- offload/_root/data/findings/oop/cce-section-of-element-component-overlap.f90 +76 -0
- offload/_root/data/findings/oop/cce-select-type-guard-not-taken.f90 +91 -0
- offload/_root/data/findings/oop/cce-udr-derived-type-unsupported.f90 +69 -0
- offload/_root/data/findings/oop/cce21-element-component-map-lost.f90 +62 -0
- offload/_root/data/findings/oop/controls/alloccomp-comp-only.f90 +44 -0
- offload/_root/data/findings/oop/controls/alloccomp-whole-explicit-component.f90 +50 -0
- offload/_root/data/findings/oop/controls/alloccomp-whole.f90 +49 -0
- offload/_root/data/findings/oop/controls/elemsec-element.f90 +47 -0
- offload/_root/data/findings/oop/controls/final-local.f90 +64 -0
- offload/_root/data/findings/oop/controls/host-class-star-select-type.f90 +58 -0
- offload/_root/data/findings/oop/controls/host-firstprivate-defined-assignment.f90 +54 -0
- offload/_root/data/findings/oop/controls/host-lastprivate-defined-assignment.f90 +58 -0
- offload/_root/data/findings/oop/controls/host-private-finalization.f90 +51 -0
- offload/_root/data/findings/oop/controls/host-select-type.f90 +65 -0
- offload/_root/data/findings/oop/controls/parent-and-comp-component-only.f90 +45 -0
- offload/_root/data/findings/oop/controls/pdt-kind.f90 +46 -0
- offload/_root/data/findings/oop/controls/pdt-len-host.f90 +43 -0
- offload/_root/data/findings/oop/controls/pdt-len-unparameterized.f90 +46 -0
- offload/_root/data/findings/oop/controls/poly-dispatch-static.f90 +75 -0
- offload/_root/data/findings/oop/controls/section-alloc-whole-component.f90 +49 -0
- offload/_root/data/findings/oop/controls/section-element-whole-array.f90 +50 -0
- offload/_root/data/findings/oop/controls/section-element-whole-component.f90 +50 -0
- offload/_root/data/findings/oop/controls/section-fixed.f90 +43 -0
- offload/_root/data/findings/oop/controls/tbp-override.f90 +64 -0
- offload/_root/data/findings/oop/gcc-acc-parent-and-member-data-rejected.f90 +63 -0
- offload/_root/data/findings/oop/gcc-pdt-length-parameter-abort.f90 +68 -0
- offload/_root/data/findings/oop/gcc-polymorphic-dispatch-abort.f90 +97 -0
- offload/_root/data/findings/oop/gcc-vtab-not-marked-for-offload.f90 +94 -0
- offload/_root/data/findings/oop/nvhpc-copy-alloc-component-illegal-address.f90 +76 -0
- offload/_root/data/findings/oop/nvhpc-copy-pdt-length-parameter-illegal-address.f90 +69 -0
- offload/_root/data/findings/oop/nvhpc-named-mapper-rejected.f90 +65 -0
- offload/_root/data/findings/oop/nvhpc-polymorphic-dispatch-translate-failure.f90 +90 -0
- offload/_root/data/findings/oop/nvhpc-polymorphism-runtime-unsupported.f90 +94 -0
- offload/_root/data/findings/oop/nvhpc-type-bound-call-rejected.f90 +89 -0
- offload/_root/data/findings/oop/nvhpc-udr-derived-type-rejected.f90 +67 -0
- offload/_root/data/findings/reviews/afar-c-error-directive-in-target-link.json +217 -0
- offload/_root/data/findings/reviews/afar-c-lastprivate-distribute-parallel-for-small-type.json +113 -0
- offload/_root/data/findings/reviews/afar-c-teams-distribute-reduction-first-team.json +130 -0
- offload/_root/data/findings/reviews/afar-c-update-iterator-copy-mode.json +113 -0
- offload/_root/data/findings/reviews/afar-cce19-character-defaultmap.json +292 -0
- offload/_root/data/findings/reviews/afar-clang-requires-device-safesync-hang.json +191 -0
- offload/_root/data/findings/reviews/afar-flang-firstprivate-map-two-targets.json +130 -0
- offload/_root/data/findings/reviews/afar-flang-loop-bind-teams-reduction.json +126 -0
- offload/_root/data/findings/reviews/afar-flang-task-reduction-max.json +113 -0
- offload/_root/data/findings/reviews/afar-flang-thread-limit-target-parallel-do.json +113 -0
- offload/_root/data/findings/reviews/afar-loop-bind-thread-in-teams.json +191 -0
- offload/_root/data/findings/reviews/afar-nontemporal-assumed-shape-ice.json +113 -0
- offload/_root/data/findings/reviews/afar-udr-derived-type-link.json +113 -0
- offload/_root/data/findings/reviews/afar-xnack1-atomic-min-nested-parallel.json +113 -0
- offload/_root/data/findings/reviews/afar-xnack1-target-is-present.json +113 -0
- offload/_root/data/findings/reviews/apps--afar-cce-teams-private-array-nested-parallel-wrong.json +113 -0
- offload/_root/data/findings/reviews/apps--cce20-device-link-infer-address-spaces-crash.json +113 -0
- offload/_root/data/findings/reviews/apps--cce21-device-link-agpr-copy-mfma-assert.json +113 -0
- offload/_root/data/findings/reviews/apps--cce21-private-array-loaded-subscript-wrong.json +113 -0
- offload/_root/data/findings/reviews/apps--gcc-acc-c-tile-partial-tiles-wrong.json +113 -0
- offload/_root/data/findings/reviews/catalog--afar-c-ordered-doacross-link.json +113 -0
- offload/_root/data/findings/reviews/catalog--afar-c-reduction-task-link.json +113 -0
- offload/_root/data/findings/reviews/catalog--afar-flang-absent-optional-target-crash.json +113 -0
- offload/_root/data/findings/reviews/catalog--afar-flang-critical-target-parallel-wrong.json +113 -0
- offload/_root/data/findings/reviews/catalog--afar-flang-dist-schedule-chunk.json +113 -0
- offload/_root/data/findings/reviews/catalog--afar-flang-linear-parallel-ice.json +113 -0
- offload/_root/data/findings/reviews/catalog--afar-flang-named-critical-link.json +126 -0
- offload/_root/data/findings/reviews/catalog--afar-flang-ordered-wrong.json +113 -0
- offload/_root/data/findings/reviews/catalog--afar-flang-reduction-minus-rejected.json +113 -0
- offload/_root/data/findings/reviews/catalog--afar-flang-sections-in-target-ice.json +113 -0
- offload/_root/data/findings/reviews/catalog--afar-flang-workdistribute-ice.json +113 -0
- offload/_root/data/findings/reviews/catalog--c-allocate-const-mem-firstprivate-wrong.json +113 -0
- offload/_root/data/findings/reviews/catalog--cce-acc-character-dummy-routine-ice.json +113 -0
- offload/_root/data/findings/reviews/catalog--cce-acc-loop-seq-in-routine-wrong.json +113 -0
- offload/_root/data/findings/reviews/catalog--cce-allocators-stack-ice.json +113 -0
- offload/_root/data/findings/reviews/catalog--cce-c-allocate-align-link.json +113 -0
- offload/_root/data/findings/reviews/catalog--cce-c-allocate-allocator-modifier-rejected.json +113 -0
- offload/_root/data/findings/reviews/catalog--cce-c-dist-schedule-chunk.json +113 -0
- offload/_root/data/findings/reviews/catalog--cce-c-f-pointer-device-link.json +130 -0
- offload/_root/data/findings/reviews/catalog--cce-c-long-double-ice.json +217 -0
- offload/_root/data/findings/reviews/catalog--cce-c-map-iterator-ice.json +217 -0
- offload/_root/data/findings/reviews/catalog--cce-c-recursive-function-ice.json +113 -0
- offload/_root/data/findings/reviews/catalog--cce-c-sections-in-target-wrong.json +113 -0
- offload/_root/data/findings/reviews/catalog--cce-flang-allocate-in-target-crash.json +113 -0
- offload/_root/data/findings/reviews/catalog--cce-flang-lastprivate-parallel-in-seq-loop-wrong.json +113 -0
- offload/_root/data/findings/reviews/catalog--cce-flang-stop-in-target-crash.json +113 -0
- offload/_root/data/findings/reviews/catalog--cce-iterator-link.json +113 -0
- offload/_root/data/findings/reviews/catalog--cce-linear-lastprivate-ice.json +113 -0
- offload/_root/data/findings/reviews/catalog--cce-reduction-inscan-ice.json +113 -0
- offload/_root/data/findings/reviews/catalog--cce-reduction-task-link.json +113 -0
- offload/_root/data/findings/reviews/catalog--cce19-reduction-task-addrspacecast-ice.json +113 -0
- offload/_root/data/findings/reviews/catalog--cce20-c-defaultmap-private-storage-rejected.json +217 -0
- offload/_root/data/findings/reviews/catalog--cce20-map-self-rejected.json +204 -0
- offload/_root/data/findings/reviews/catalog--cce21-c-target-loop-ice.json +126 -0
- offload/_root/data/findings/reviews/catalog--defaultmap-present-private-array-abort.json +236 -0
- offload/_root/data/findings/reviews/catalog--nvhpc-acc-associate-illegal-address.json +113 -0
- offload/_root/data/findings/reviews/catalog--nvhpc-c-function-pointer-kernel-missing.json +268 -0
- offload/_root/data/findings/reviews/cce-acc-init-set-runtime-assert.json +113 -0
- offload/_root/data/findings/reviews/cce-acc-reduction-200-int8-scalars-wrong.json +113 -0
- offload/_root/data/findings/reviews/cce-acc-routine-bind-module-ice.json +113 -0
- offload/_root/data/findings/reviews/cce-c-dist-schedule-segv.json +113 -0
- offload/_root/data/findings/reviews/cce-c-map-delete-refcount.json +149 -0
- offload/_root/data/findings/reviews/cce-c-map-present-assert.json +126 -0
- offload/_root/data/findings/reviews/cce-c-openmp45-device-link.json +113 -0
- offload/_root/data/findings/reviews/cce-c-parallel-for-in-target.json +141 -0
- offload/_root/data/findings/reviews/cce-mapper-next-map-copy-back.json +208 -0
- offload/_root/data/findings/reviews/cce-uses-allocators-traits-omp50.json +191 -0
- offload/_root/data/findings/reviews/cce19-c-reduction-63-scalars-one-wrong.json +113 -0
- offload/_root/data/findings/reviews/cce19-target-parallel-guarded-loop.json +113 -0
- offload/_root/data/findings/reviews/cce19-target-parallel-single-ice.json +113 -0
- offload/_root/data/findings/reviews/cce21-alloc-2e32-sum-wrong.json +113 -0
- offload/_root/data/findings/reviews/cce21-defaultmap-aggregate-flag.json +210 -0
- offload/_root/data/findings/reviews/cce21-in-reduction-assumed-shape-write-lost.json +113 -0
- offload/_root/data/findings/reviews/cce21-in-reduction-taskwait-link.json +113 -0
- offload/_root/data/findings/reviews/clang-c-declare-target-to-omp52.json +113 -0
- offload/_root/data/findings/reviews/clang-c-linear-directive-name-hang.json +113 -0
- offload/_root/data/findings/reviews/clang-c-shared-declare-target-combined.json +132 -0
- offload/_root/data/findings/reviews/dataenv--cce-value-dummy-target-write-visible.json +113 -0
- offload/_root/data/findings/reviews/defaultmap-none-loop-variable.json +113 -0
- offload/_root/data/findings/reviews/fortran-schedule-static-in-target.json +113 -0
- offload/_root/data/findings/reviews/fresh--cce-common-block-name-in-map-rejected.json +113 -0
- offload/_root/data/findings/reviews/fresh--cce-list-directed-print-in-target-copy-crash.json +217 -0
- offload/_root/data/findings/reviews/fresh--cce19-acc-automatic-array-copyout-copy-crash.json +113 -0
- offload/_root/data/findings/reviews/fresh--cce21-combined-if-runtime-expr-loop-skipped.json +113 -0
- offload/_root/data/findings/reviews/fresh--nvhpc-acc-gang-worker-collapse-nested-vector-reduction-lost.json +113 -0
- offload/_root/data/findings/reviews/fresh--nvhpc-teams-loop-module-allocatable-assign-fort2-crash.json +113 -0
- offload/_root/data/findings/reviews/fuzz--1505-cce20.json +113 -0
- offload/_root/data/findings/reviews/fuzz--1540-afar.json +113 -0
- offload/_root/data/findings/reviews/fuzz--1978-cce19.json +130 -0
- offload/_root/data/findings/reviews/fuzz--2334-cce19.json +113 -0
- offload/_root/data/findings/reviews/fuzz--591-cce19.json +147 -0
- offload/_root/data/findings/reviews/fuzz--650-afar.json +113 -0
- offload/_root/data/findings/reviews/fuzz--916-afar.json +130 -0
- offload/_root/data/findings/reviews/fuzz--98-cce19.json +113 -0
- offload/_root/data/findings/reviews/fuzz--b1-121-afar.json +160 -0
- offload/_root/data/findings/reviews/fuzz--b2-209-cce19.json +141 -0
- offload/_root/data/findings/reviews/fuzz--b2-68-afar.json +113 -0
- offload/_root/data/findings/reviews/fuzz--b2-85-cce20.json +217 -0
- offload/_root/data/findings/reviews/fuzz--b3-188-cce19.json +113 -0
- offload/_root/data/findings/reviews/fuzz--b3-278-cce19.json +212 -0
- offload/_root/data/findings/reviews/fuzz--b3-54-afar.json +113 -0
- offload/_root/data/findings/reviews/fuzz--b3-61-cce20.json +191 -0
- offload/_root/data/findings/reviews/fuzz--b4-86-cce19.json +113 -0
- offload/_root/data/findings/reviews/fuzz--gcc-declare-reduction-module-not-found.json +113 -0
- offload/_root/data/findings/reviews/fuzz--gcc-target-simd-map-nontemporal-rejected.json +113 -0
- offload/_root/data/findings/reviews/fuzz--nvhpc-allocatable-component-implicit-map-illegal-address.json +141 -0
- offload/_root/data/findings/reviews/fuzz--nvhpc-assumed-length-character-dummy-map-ice.json +113 -0
- offload/_root/data/findings/reviews/fuzz--nvhpc-default-none-reduction-lastprivate-fort1-crash.json +113 -0
- offload/_root/data/findings/reviews/fuzz--nvhpc-defaultmap-firstprivate-lastprivate-ice.json +113 -0
- offload/_root/data/findings/reviews/fuzz--nvhpc-defaultmap-to-scalar-reduction-lost.json +113 -0
- offload/_root/data/findings/reviews/fuzz--nvhpc-depend-implicit-map-illegal-address.json +113 -0
- offload/_root/data/findings/reviews/fuzz--nvhpc-distribute-parallel-num-threads-writes-lost.json +113 -0
- offload/_root/data/findings/reviews/fuzz--nvhpc-end-distribute-simd-rejected.json +113 -0
- offload/_root/data/findings/reviews/fuzz--nvhpc-loop-character-achar-unsupported.json +113 -0
- offload/_root/data/findings/reviews/fuzz--nvhpc-map-always-after-map-to-not-copied-back.json +113 -0
- offload/_root/data/findings/reviews/fuzz--nvhpc-num-threads-reduction-identity-lost.json +113 -0
- offload/_root/data/findings/reviews/fuzz--nvhpc-target-parallel-firstprivate-translate-failure.json +191 -0
- offload/_root/data/findings/reviews/fuzz--nvhpc-target-parallel-single-hang.json +113 -0
- offload/_root/data/findings/reviews/fuzz--nvhpc-target-simd-collapse-translate-failure.json +113 -0
- offload/_root/data/findings/reviews/fuzz--nvhpc-target-simd-no-end-directive-rejected.json +113 -0
- offload/_root/data/findings/reviews/fuzz--par-s1-2082-gcc_g90.json +126 -0
- offload/_root/data/findings/reviews/fuzz--s1-2370-cce21.json +113 -0
- offload/_root/data/findings/reviews/fuzz--s1-2592-cce21.json +113 -0
- offload/_root/data/findings/reviews/fuzz--s1-3463-cce21.json +113 -0
- offload/_root/data/findings/reviews/fuzz--s1-6760-cce20.json +130 -0
- offload/_root/data/findings/reviews/fuzz--s1-6888-cce21.json +113 -0
- offload/_root/data/findings/reviews/fuzz--s1-7882-cce20.json +113 -0
- offload/_root/data/findings/reviews/fuzz--s1-8634-cce21.json +113 -0
- offload/_root/data/findings/reviews/fuzz--s1-91-cce21.json +113 -0
- offload/_root/data/findings/reviews/fuzz--s1-9443-afar.json +113 -0
- offload/_root/data/findings/reviews/fuzz--s1-9914-cce19.json +141 -0
- offload/_root/data/findings/reviews/gcc--gcc-acc-bind-device-type-rejected.json +113 -0
- offload/_root/data/findings/reviews/gcc--gcc-acc-detach-delete-attach-underflow.json +314 -0
- offload/_root/data/findings/reviews/gcc--gcc-acc-gang-dim-collapse-force-rejected.json +113 -0
- offload/_root/data/findings/reviews/gcc--gcc-acc-init-set-shutdown-rejected.json +113 -0
- offload/_root/data/findings/reviews/gcc--gcc-acc-link-in-routine-rejected.json +113 -0
- offload/_root/data/findings/reviews/gcc--gcc-acc-use-device-allocatable-rejected.json +113 -0
- offload/_root/data/findings/reviews/gcc--gcc-c-motion-mapper-rejected.json +113 -0
- offload/_root/data/findings/reviews/gcc--gcc-c-omp60-undocumented-rejected.json +217 -0
- offload/_root/data/findings/reviews/gcc--gcc-c-omp60-unimplemented-rejected.json +236 -0
- offload/_root/data/findings/reviews/gcc--gcc-c-target-in-task-mandatory-device-not-found.json +236 -0
- offload/_root/data/findings/reviews/gcc--gcc-c-uses-allocators-traits-unimplemented.json +113 -0
- offload/_root/data/findings/reviews/gcc--gcc-declare-mapper-rejected.json +113 -0
- offload/_root/data/findings/reviews/gcc--gcc-defaultmap-to-pointer-copy-back.json +217 -0
- offload/_root/data/findings/reviews/gcc--gcc-loop-bind-default-none-rejected.json +113 -0
- offload/_root/data/findings/reviews/harvest--afar-flang-strided-target-update.json +141 -0
- offload/_root/data/findings/reviews/harvest--cce-acc-declare-create-module-allocatable-xnack1-fault.json +113 -0
- offload/_root/data/findings/reviews/harvest--cce-c-implicit-struct-map-partly-present.json +217 -0
- offload/_root/data/findings/reviews/harvest--cce-c-strided-target-update.json +141 -0
- offload/_root/data/findings/reviews/harvest--cce-ftn-target-parallel-thread-query-ice.json +130 -0
- offload/_root/data/findings/reviews/harvest--cce-named-constant-array-declare-target-routine-rejected.json +113 -0
- offload/_root/data/findings/reviews/harvest--cce-use-device-ptr-c-ptr-not-converted.json +113 -0
- offload/_root/data/findings/reviews/harvest--cce21-declare-target-link-module-variable-write-lost.json +113 -0
- offload/_root/data/findings/reviews/harvest--cce21-internal-procedure-calls-internal-in-target-fault.json +158 -0
- offload/_root/data/findings/reviews/harvest--gcc-acc-declare-create-allocatable-not-mapped.json +204 -0
- offload/_root/data/findings/reviews/harvest--gcc-c-same-item-two-maps-rejected.json +143 -0
- offload/_root/data/findings/reviews/harvest--gcc-c-strided-section-rejected.json +164 -0
- offload/_root/data/findings/reviews/harvest--gcc-c-target-data-struct-pointer-section-ice.json +113 -0
- offload/_root/data/findings/reviews/harvest--gcc-c-target-data-two-maps-ice.json +113 -0
- offload/_root/data/findings/reviews/harvest--gcc-teams-simd-matmul-allocatable-ice.json +113 -0
- offload/_root/data/findings/reviews/harvest--nvhpc-c-target-data-if-false-use-device-ptr-garbage.json +113 -0
- offload/_root/data/findings/reviews/harvest--nvhpc-named-constant-array-declare-target-routine-rejected.json +126 -0
- offload/_root/data/findings/reviews/harvest--nvhpc-use-device-ptr-c-ptr-not-found.json +113 -0
- offload/_root/data/findings/reviews/harvest--nvhpc2511-target-nowait-in-parallel-for-ice.json +130 -0
- offload/_root/data/findings/reviews/hecbench--gcc-c-float16-array-in-target-lto-ice.json +217 -0
- offload/_root/data/findings/reviews/hecbench--gcc-c-swar-popcount-assembler-error.json +126 -0
- offload/_root/data/findings/reviews/malloc--afar-device-malloc-in-kernel-corrupts-records.json +270 -0
- offload/_root/data/findings/reviews/multithread-allocatable-section-maps.json +191 -0
- offload/_root/data/findings/reviews/nested--afar-cce-c-call-result-member-in-target-rejected.json +113 -0
- offload/_root/data/findings/reviews/nested--afar-cce-c-update-struct-and-member-rejected.json +126 -0
- offload/_root/data/findings/reviews/nested--afar-flang-pointer-root-allocatable-component-enter-data-fault.json +191 -0
- offload/_root/data/findings/reviews/nested--cce-c-struct-and-nested-pointee-sections-ice.json +113 -0
- offload/_root/data/findings/reviews/nested--cce-fortran-nested-allocatable-component-copy-fault.json +214 -0
- offload/_root/data/findings/reviews/nested--cce-fortran-pointer-to-type-with-allocatable-scalar-component-typed-transfer.json +191 -0
- offload/_root/data/findings/reviews/nested--cce-fortran-update-to-pointer-root-allocatable-scalar-component-no-accelerator-object.json +297 -0
- offload/_root/data/findings/reviews/nested--gcc-acc-c-exit-data-of-a-pointer-array-element-target-hangs.json +204 -0
- offload/_root/data/findings/reviews/nested--gcc-acc-c-parent-and-shared-pointee-one-directive.json +130 -0
- offload/_root/data/findings/reviews/nested--gcc-acc-c-struct-and-member-array-one-directive.json +141 -0
- offload/_root/data/findings/reviews/nested--gcc-c-always-on-pointer-member-section-ice.json +113 -0
- offload/_root/data/findings/reviews/nested--gcc-c-declare-mapper-pointer-member-section-gpu-fault.json +113 -0
- offload/_root/data/findings/reviews/nested--gcc-c-from-struct-and-pointee-section-rejected.json +113 -0
- offload/_root/data/findings/reviews/nested--gcc-fortran-pointer-component-alloc-bounds-lost.json +217 -0
- offload/_root/data/findings/reviews/nested--gcc-fortran-root-and-element-pointer-components-ice.json +217 -0
- offload/_root/data/findings/reviews/nested--nvhpc-c-pointee-before-parent-in-one-map-list-copy-fault.json +204 -0
- offload/_root/data/findings/reviews/nested--nvhpc-c-update-from-structure-overwrites-attached-pointer-segv.json +191 -0
- offload/_root/data/findings/reviews/nvhpc-c-acc-atomic-update-sum-ice.json +277 -0
- offload/_root/data/findings/reviews/nvhpc-c-dist-schedule-chunk-compile-hang.json +113 -0
- offload/_root/data/findings/reviews/nvhpc-c-map-present-ignored.json +113 -0
- offload/_root/data/findings/reviews/nvhpc-c-ordered-in-target-nvcpfe-crash.json +113 -0
- offload/_root/data/findings/reviews/nvhpc-c-parallel-for-firstprivate-in-target.json +113 -0
- offload/_root/data/findings/reviews/nvhpc-defaultmap-firstprivate-explicit-map.json +113 -0
- offload/_root/data/findings/reviews/nvhpc-defaultmap-from-allocatable-indexing.json +132 -0
- offload/_root/data/findings/reviews/nvhpc-depend-inoutset-ignored.json +113 -0
- offload/_root/data/findings/reviews/nvhpc-dist-schedule-chunk-illegal-address.json +113 -0
- offload/_root/data/findings/reviews/nvhpc-managed-acc-shutdown-host-access.json +113 -0
- offload/_root/data/findings/reviews/nvhpc-parallel-if-in-target-nvvm-ice.json +113 -0
- offload/_root/data/findings/reviews/oop--afar-final-dealloc-device-link.json +132 -0
- offload/_root/data/findings/reviews/oop--afar-pdt-length-parameter-not-implemented.json +113 -0
- offload/_root/data/findings/reviews/oop--cce-class-is-device-link.json +130 -0
- offload/_root/data/findings/reviews/oop--cce-copy-alloc-component-section-fault.json +217 -0
- offload/_root/data/findings/reviews/oop--cce-copy-parent-to-component-tofrom-lost.json +217 -0
- offload/_root/data/findings/reviews/oop--cce-copy-second-member-section-lost.json +113 -0
- offload/_root/data/findings/reviews/oop--cce-element-component-map-lost.json +113 -0
- offload/_root/data/findings/reviews/oop--cce-final-dealloc-device-abort.json +208 -0
- offload/_root/data/findings/reviews/oop--cce-pdt-default-mapper-rejected.json +191 -0
- offload/_root/data/findings/reviews/oop--cce-polymorphic-dispatch-device-link.json +247 -0
- offload/_root/data/findings/reviews/oop--cce-section-of-element-component-overlap.json +113 -0
- offload/_root/data/findings/reviews/oop--cce-select-type-guard-not-taken.json +191 -0
- offload/_root/data/findings/reviews/oop--cce-udr-derived-type-unsupported.json +132 -0
- offload/_root/data/findings/reviews/oop--gcc-acc-parent-and-member-data-rejected.json +141 -0
- offload/_root/data/findings/reviews/oop--gcc-pdt-length-parameter-abort.json +141 -0
- offload/_root/data/findings/reviews/oop--gcc-polymorphic-dispatch-abort.json +217 -0
- offload/_root/data/findings/reviews/oop--gcc-vtab-not-marked-for-offload.json +113 -0
- offload/_root/data/findings/reviews/oop--nvhpc-copy-alloc-component-illegal-address.json +113 -0
- offload/_root/data/findings/reviews/oop--nvhpc-copy-pdt-length-parameter-illegal-address.json +236 -0
- offload/_root/data/findings/reviews/oop--nvhpc-named-mapper-rejected.json +113 -0
- offload/_root/data/findings/reviews/oop--nvhpc-polymorphic-dispatch-translate-failure.json +223 -0
- offload/_root/data/findings/reviews/oop--nvhpc-polymorphism-runtime-unsupported.json +126 -0
- offload/_root/data/findings/reviews/oop--nvhpc-type-bound-call-rejected.json +113 -0
- offload/_root/data/findings/reviews/oop--nvhpc-udr-derived-type-rejected.json +113 -0
- offload/_root/data/findings/reviews/stress--afar-c-lastprivate-combined-target-not-mapped.json +113 -0
- offload/_root/data/findings/reviews/stress--afar-target-scalar-implicit-firstprivate.json +175 -0
- offload/_root/data/findings/reviews/stress--cce-acc-declare-create-scalar-serial-firstprivate.json +113 -0
- offload/_root/data/findings/reviews/stress--cce-c-distribute-lastprivate-lost.json +113 -0
- offload/_root/data/findings/reviews/stress--cce-c-flto-offload-dropped.json +204 -0
- offload/_root/data/findings/reviews/stress--cce-ftn-cif-record-split-abort.json +113 -0
- offload/_root/data/findings/reviews/stress--cce-lastprivate-num-threads-collapse-simd.json +113 -0
- offload/_root/data/findings/reviews/stress--cce-teams-reduction-many-teams-wrap.json +113 -0
- offload/_root/data/findings/reviews/stress--cce21-declare-target-scalar-map-write-lost.json +113 -0
- offload/_root/data/findings/reviews/stress--gcc-declare-target-allocatable-component-ice.json +191 -0
- offload/_root/data/findings/reviews/stress--nvhpc-acc-derived-type-component-not-copied.json +126 -0
- offload/_root/data/findings/reviews/stress--nvhpc-c-lastprivate-teams-distribute-parallel-for-lost.json +113 -0
- offload/_root/data/findings/reviews/stress--nvhpc-declare-target-scalar-write-lost.json +113 -0
- offload/_root/data/findings/reviews/stress--nvhpc-lastprivate-combined-target-not-mapped.json +113 -0
- offload/_root/data/findings/reviews/stress--nvhpc-target-scalar-implicit-firstprivate.json +130 -0
- offload/_root/data/findings/reviews/target-update-sections-in-parallel.json +113 -0
- offload/_root/data/findings/stress/afar-c-lastprivate-combined-target-not-mapped.c +72 -0
- offload/_root/data/findings/stress/afar-target-scalar-implicit-firstprivate.f90 +47 -0
- offload/_root/data/findings/stress/cce-acc-declare-create-scalar-serial-firstprivate.f90 +43 -0
- offload/_root/data/findings/stress/cce-c-distribute-lastprivate-lost.c +52 -0
- offload/_root/data/findings/stress/cce-c-flto-offload-dropped.c +73 -0
- offload/_root/data/findings/stress/cce-ftn-cif-record-split-abort.f90 +109 -0
- offload/_root/data/findings/stress/cce-lastprivate-num-threads-collapse-simd.f90 +66 -0
- offload/_root/data/findings/stress/cce-teams-reduction-many-teams-wrap.f90 +55 -0
- offload/_root/data/findings/stress/cce21-declare-target-scalar-map-write-lost.f90 +58 -0
- offload/_root/data/findings/stress/controls/gcc-declare-target-allocatable-component-control.f90 +29 -0
- offload/_root/data/findings/stress/gcc-declare-target-allocatable-component-ice.f90 +61 -0
- offload/_root/data/findings/stress/nvhpc-acc-derived-type-component-not-copied.f90 +33 -0
- offload/_root/data/findings/stress/nvhpc-c-lastprivate-teams-distribute-parallel-for-lost.c +62 -0
- offload/_root/data/findings/stress/nvhpc-declare-target-scalar-write-lost.f90 +43 -0
- offload/_root/data/findings/stress/nvhpc-lastprivate-combined-target-not-mapped.f90 +60 -0
- offload/_root/data/findings/stress/nvhpc-target-scalar-implicit-firstprivate.f90 +41 -0
- offload/_root/data/findings/target-update-sections-in-parallel.f90 +53 -0
- offload/_root/data/issues.json +1 -0
- offload/_root/data/search.json +1 -0
- offload/_root/data/vendor/checks/build.py +288 -0
- offload/_version.py +24 -0
- offload/canuse.py +88 -0
- offload/cli.py +52 -0
- offload/data.py +85 -0
- offload/engine/__init__.py +0 -0
- offload/engine/acc_c_gen.py +415 -0
- offload/engine/acc_gen.py +1104 -0
- offload/engine/acc_rules.py +656 -0
- offload/engine/apps.py +804 -0
- offload/engine/baseline.py +324 -0
- offload/engine/c_gen.py +883 -0
- offload/engine/c_program.py +913 -0
- offload/engine/c_rules.py +503 -0
- offload/engine/campaign.py +1180 -0
- offload/engine/campaigns/__init__.py +2 -0
- offload/engine/campaigns/hecbench.py +153 -0
- offload/engine/campaigns/nested.py +76 -0
- offload/engine/campaigns/oop.py +61 -0
- offload/engine/canary.py +275 -0
- offload/engine/catalog.py +860 -0
- offload/engine/citations.py +532 -0
- offload/engine/clang_oracle.py +208 -0
- offload/engine/combos.py +234 -0
- offload/engine/confirm/__init__.py +2 -0
- offload/engine/confirm/backlog.py +159 -0
- offload/engine/confirm/claims.py +423 -0
- offload/engine/confirm/collectors.py +665 -0
- offload/engine/confirm/decisions.py +202 -0
- offload/engine/confirm/draft.py +195 -0
- offload/engine/confirm/engine.py +157 -0
- offload/engine/confirm/execute.py +382 -0
- offload/engine/confirm/facts.py +467 -0
- offload/engine/confirm/findings.py +617 -0
- offload/engine/confirm/forms.py +145 -0
- offload/engine/confirm/ingest.py +372 -0
- offload/engine/confirm/jobs.py +215 -0
- offload/engine/confirm/legality.py +323 -0
- offload/engine/confirm/machines.py +254 -0
- offload/engine/confirm/minimize.py +268 -0
- offload/engine/confirm/model.py +249 -0
- offload/engine/confirm/ports.py +107 -0
- offload/engine/confirm/programs.py +222 -0
- offload/engine/confirm/registry.py +151 -0
- offload/engine/confirm/regress.py +278 -0
- offload/engine/confirm/rules.py +565 -0
- offload/engine/confirm/store.py +63 -0
- offload/engine/confirm/triage.py +838 -0
- offload/engine/confirm/validate.py +607 -0
- offload/engine/confirm/witness.py +355 -0
- offload/engine/corpus_check.py +388 -0
- offload/engine/coverage.py +318 -0
- offload/engine/dataenv_gen.py +1318 -0
- offload/engine/dataenv_rules.py +278 -0
- offload/engine/devtemps.py +146 -0
- offload/engine/expected.py +2559 -0
- offload/engine/f2c.py +1783 -0
- offload/engine/finding_claims.py +330 -0
- offload/engine/finding_header.py +229 -0
- offload/engine/finding_rows.py +382 -0
- offload/engine/flang_oracle.py +299 -0
- offload/engine/fsource.py +620 -0
- offload/engine/fuzz.py +2455 -0
- offload/engine/fuzz_base.py +2016 -0
- offload/engine/fuzz_campaign.py +592 -0
- offload/engine/fuzz_exec.py +798 -0
- offload/engine/fuzz_min.py +1049 -0
- offload/engine/fuzz_profile.py +340 -0
- offload/engine/fuzz_report.py +1270 -0
- offload/engine/fuzz_steer.py +181 -0
- offload/engine/gate.py +1013 -0
- offload/engine/gate_report.py +711 -0
- offload/engine/gate_run.py +118 -0
- offload/engine/gate_stored.py +466 -0
- offload/engine/gen.py +1114 -0
- offload/engine/gen_templates.py +2583 -0
- offload/engine/grammar.py +695 -0
- offload/engine/harness.py +1472 -0
- offload/engine/harvest/__init__.py +3 -0
- offload/engine/harvest/c_runtime.py +465 -0
- offload/engine/harvest/checks.py +534 -0
- offload/engine/harvest/convert.py +784 -0
- offload/engine/harvest/f_runtime.py +668 -0
- offload/engine/harvest/filters.py +338 -0
- offload/engine/harvest/history.py +122 -0
- offload/engine/harvest/inventory.py +399 -0
- offload/engine/harvest2/__init__.py +5 -0
- offload/engine/harvest2/aomp.py +119 -0
- offload/engine/harvest2/examples.py +116 -0
- offload/engine/harvest2/gomp.py +679 -0
- offload/engine/harvest2/hand.py +150 -0
- offload/engine/harvest2/split.py +78 -0
- offload/engine/harvest_known/__init__.py +2 -0
- offload/engine/harvest_known/apps.py +65 -0
- offload/engine/harvest_known/cases.py +128 -0
- offload/engine/harvest_known/centres.py +184 -0
- offload/engine/harvest_known/forum.py +180 -0
- offload/engine/harvest_known/relnotes.py +42 -0
- offload/engine/harvest_known/textscan.py +107 -0
- offload/engine/hdrwrap.py +42 -0
- offload/engine/hecbench.py +568 -0
- offload/engine/hecbench_report.py +265 -0
- offload/engine/hecbench_run.py +483 -0
- offload/engine/idioms.py +1427 -0
- offload/engine/kbody_cites.py +81 -0
- offload/engine/kbody_emit.py +949 -0
- offload/engine/kbody_gen.py +795 -0
- offload/engine/legality_review.py +236 -0
- offload/engine/localcfg.py +58 -0
- offload/engine/malloc_dd.py +267 -0
- offload/engine/mutate.py +1933 -0
- offload/engine/nested_cites.py +196 -0
- offload/engine/nested_emit.py +789 -0
- offload/engine/nested_gen.py +1721 -0
- offload/engine/offload_scope.py +197 -0
- offload/engine/ompvv.py +624 -0
- offload/engine/oop_gen.py +2249 -0
- offload/engine/prerun.py +1435 -0
- offload/engine/program_source.py +739 -0
- offload/engine/provenance.py +103 -0
- offload/engine/reduce.py +2098 -0
- offload/engine/report.py +3374 -0
- offload/engine/root.py +33 -0
- offload/engine/rules.py +4256 -0
- offload/engine/run_matrix.py +325 -0
- offload/engine/site/__init__.py +1 -0
- offload/engine/site/columns.py +53 -0
- offload/engine/site/data.py +648 -0
- offload/engine/site/header.py +228 -0
- offload/engine/site/inputs.py +115 -0
- offload/engine/site/matrix.py +434 -0
- offload/engine/site/scrub.py +294 -0
- offload/engine/skeleton.py +121 -0
- offload/engine/spec_text.py +242 -0
- offload/engine/stress.py +4122 -0
- offload/engine/stress_c.py +1000 -0
- offload/engine/stress_exec.py +805 -0
- offload/engine/stress_min.py +248 -0
- offload/engine/stress_report.py +552 -0
- offload/engine/textclean.py +97 -0
- offload/engine/toolchains.py +1070 -0
- offload/engine/transforms.py +511 -0
- offload/engine/usage.py +1252 -0
- offload/engine/widen.py +673 -0
- offload/engine/widen_progs.py +2396 -0
- offload/issues.py +146 -0
- offtarget-0.1.0.dist-info/METADATA +86 -0
- offtarget-0.1.0.dist-info/RECORD +886 -0
- offtarget-0.1.0.dist-info/WHEEL +4 -0
- offtarget-0.1.0.dist-info/entry_points.txt +2 -0
- offtarget-0.1.0.dist-info/licenses/LICENSE +21 -0
- offtarget-0.1.0.dist-info/licenses/THIRD_PARTY_NOTICES.md +20 -0
offload/engine/prerun.py
ADDED
|
@@ -0,0 +1,1435 @@
|
|
|
1
|
+
"""The pre-run legality and race check of a generated program.
|
|
2
|
+
|
|
3
|
+
``check(program) -> (ok, reasons)``: a fuzz, stress or reproducer program is
|
|
4
|
+
compiled and run only when ``ok``. Legality needs two witnesses that are not
|
|
5
|
+
the compiler under test, and both must accept: ``rules`` (the rules of
|
|
6
|
+
``offload.engine.rules``, the checks in ``EXTRA`` and the race rule) and
|
|
7
|
+
``frontend`` (``amdflang`` or ``amdclang`` with ``-fsyntax-only``). A
|
|
8
|
+
program is refused when no front end is available (``witness unavailable``),
|
|
9
|
+
when the witnesses disagree (``witnesses disagree``) or when the rules
|
|
10
|
+
cannot read it (``unreadable``). A refusal by the front end alone carries
|
|
11
|
+
``FRONTEND_ONLY`` and is listed in the reports (``refusal_kind``).
|
|
12
|
+
The race rule (``races``) reports a scalar written in a loop shared by
|
|
13
|
+
threads, teams or gangs that no clause privatizes or reduces. ``EXTRA``
|
|
14
|
+
holds restrictions ``offload.engine.rules`` does not check, one rule id each."""
|
|
15
|
+
from __future__ import annotations
|
|
16
|
+
|
|
17
|
+
import re
|
|
18
|
+
import tempfile
|
|
19
|
+
from pathlib import Path
|
|
20
|
+
|
|
21
|
+
RACE_CITE = ("OpenMP 5.2 §1.4.1 p.27 (a data race: the result is "
|
|
22
|
+
"unspecified), §5.1.1, §5.8.1")
|
|
23
|
+
ACC_RACE_CITE = "OpenACC 3.4 §2.9.15 (independent loop iterations)"
|
|
24
|
+
|
|
25
|
+
|
|
26
|
+
# --- the program ------------------------------------------------------------------
|
|
27
|
+
|
|
28
|
+
# AFAR's amdclang has no openacc.h: the C OpenACC witness reads the
|
|
29
|
+
# declarations the programs use (fix, item 10; the program compiled
|
|
30
|
+
# and run is unchanged)
|
|
31
|
+
# Guarded (a converted program includes openacc.h twice: its own
|
|
32
|
+
# include and its self-check's) and the whole OpenACC 3.4 C API (§3.2),
|
|
33
|
+
# so a program calling acc_copyin is not refused for an implicit
|
|
34
|
+
# declaration of the stub's making
|
|
35
|
+
_ACC_PROTOS = """
|
|
36
|
+
typedef enum { acc_device_none = 0, acc_device_default = 1,
|
|
37
|
+
acc_device_host = 2, acc_device_not_host = 3 } acc_device_t;
|
|
38
|
+
typedef enum { acc_property_memory = 1, acc_property_free_memory = 2,
|
|
39
|
+
acc_property_shared_memory_support = 3, acc_property_name = 4,
|
|
40
|
+
acc_property_vendor = 5, acc_property_driver = 6 } acc_device_property_t;
|
|
41
|
+
enum { acc_async_noval = -1, acc_async_sync = -2, acc_async_default = -3 };
|
|
42
|
+
int acc_get_num_devices(acc_device_t);
|
|
43
|
+
void acc_set_device_type(acc_device_t);
|
|
44
|
+
acc_device_t acc_get_device_type(void);
|
|
45
|
+
void acc_set_device_num(int, acc_device_t);
|
|
46
|
+
int acc_get_device_num(acc_device_t);
|
|
47
|
+
size_t acc_get_property(int, acc_device_t, acc_device_property_t);
|
|
48
|
+
const char *acc_get_property_string(int, acc_device_t, acc_device_property_t);
|
|
49
|
+
void acc_init(acc_device_t); void acc_init_device(int, acc_device_t);
|
|
50
|
+
void acc_shutdown(acc_device_t); void acc_shutdown_device(int, acc_device_t);
|
|
51
|
+
int acc_async_test(int); int acc_async_test_device(int, int);
|
|
52
|
+
int acc_async_test_all(void); int acc_async_test_all_device(int);
|
|
53
|
+
void acc_wait(int); void acc_wait_device(int, int);
|
|
54
|
+
void acc_wait_async(int, int); void acc_wait_device_async(int, int, int);
|
|
55
|
+
void acc_wait_all(void); void acc_wait_all_device(int);
|
|
56
|
+
void acc_wait_all_async(int); void acc_wait_all_device_async(int, int);
|
|
57
|
+
void acc_async_wait(int); void acc_async_wait_all(void);
|
|
58
|
+
int acc_get_default_async(void); void acc_set_default_async(int);
|
|
59
|
+
int acc_on_device(acc_device_t);
|
|
60
|
+
void *acc_malloc(size_t); void acc_free(void *);
|
|
61
|
+
void *acc_copyin(void *, size_t); void acc_copyin_async(void *, size_t, int);
|
|
62
|
+
void *acc_create(void *, size_t); void acc_create_async(void *, size_t, int);
|
|
63
|
+
void *acc_present_or_copyin(void *, size_t); void *acc_pcopyin(void *, size_t);
|
|
64
|
+
void *acc_present_or_create(void *, size_t); void *acc_pcreate(void *, size_t);
|
|
65
|
+
void acc_copyout(void *, size_t); void acc_copyout_async(void *, size_t, int);
|
|
66
|
+
void acc_copyout_finalize(void *, size_t);
|
|
67
|
+
void acc_copyout_finalize_async(void *, size_t, int);
|
|
68
|
+
void acc_delete(void *, size_t); void acc_delete_async(void *, size_t, int);
|
|
69
|
+
void acc_delete_finalize(void *, size_t);
|
|
70
|
+
void acc_delete_finalize_async(void *, size_t, int);
|
|
71
|
+
void acc_update_device(void *, size_t);
|
|
72
|
+
void acc_update_device_async(void *, size_t, int);
|
|
73
|
+
void acc_update_self(void *, size_t); void acc_update_self_async(void *, size_t, int);
|
|
74
|
+
void acc_map_data(void *, void *, size_t); void acc_unmap_data(void *);
|
|
75
|
+
void *acc_deviceptr(void *); void *acc_hostptr(void *);
|
|
76
|
+
int acc_is_present(void *, size_t);
|
|
77
|
+
void acc_memcpy_to_device(void *, void *, size_t);
|
|
78
|
+
void acc_memcpy_to_device_async(void *, void *, size_t, int);
|
|
79
|
+
void acc_memcpy_from_device(void *, void *, size_t);
|
|
80
|
+
void acc_memcpy_from_device_async(void *, void *, size_t, int);
|
|
81
|
+
void acc_memcpy_device(void *, void *, size_t);
|
|
82
|
+
void acc_memcpy_device_async(void *, void *, size_t, int);
|
|
83
|
+
void acc_memcpy_d2d(void *, void *, size_t, int, int);
|
|
84
|
+
void acc_memcpy_d2d_async(void *, void *, size_t, int, int, int);
|
|
85
|
+
void acc_attach(void **); void acc_attach_async(void **, int);
|
|
86
|
+
void acc_detach(void **); void acc_detach_async(void **, int);
|
|
87
|
+
void acc_detach_finalize(void **); void acc_detach_finalize_async(void **, int);
|
|
88
|
+
"""
|
|
89
|
+
ACC_H_STUB = ("#ifndef HV_OPENACC_STUB\n#define HV_OPENACC_STUB\n"
|
|
90
|
+
"#include <stddef.h>\n" + _ACC_PROTOS.strip() + "\n#endif")
|
|
91
|
+
|
|
92
|
+
|
|
93
|
+
def _acc_c_stub(files, lang, model):
|
|
94
|
+
if lang != "c" or model != "acc":
|
|
95
|
+
return files
|
|
96
|
+
return [(n, re.sub(r"^\s*#\s*include\s*<openacc\.h>",
|
|
97
|
+
lambda m: ACC_H_STUB, t, flags=re.M))
|
|
98
|
+
for n, t in files]
|
|
99
|
+
|
|
100
|
+
|
|
101
|
+
def _files_of(program) -> tuple[list, str, str, int]:
|
|
102
|
+
files, lang, model, version = _files_of_raw(program)
|
|
103
|
+
return _acc_c_stub(files, lang, model), lang, model, version
|
|
104
|
+
|
|
105
|
+
|
|
106
|
+
def _files_of_raw(program) -> tuple[list, str, str, int]:
|
|
107
|
+
"""(files [(name, text)], lang, model, version) of a stress program
|
|
108
|
+
(``files``), a fuzz program (``source``), a confirmer ProgramRef
|
|
109
|
+
(``text``, file marks) or a (text, lang) pair."""
|
|
110
|
+
if isinstance(program, tuple):
|
|
111
|
+
# (text, lang[, model[, version]])
|
|
112
|
+
text, lang = program[0], program[1]
|
|
113
|
+
model = program[2] if len(program) > 2 and program[2] else \
|
|
114
|
+
_model_of(text)
|
|
115
|
+
files = _split(text) or [("prog.c" if lang == "c" else "prog.f90",
|
|
116
|
+
text)]
|
|
117
|
+
v = program[3] if len(program) > 3 and program[3] else 52
|
|
118
|
+
return files, lang, model, 34 if model == "acc" else v
|
|
119
|
+
if hasattr(program, "files") and program.files:
|
|
120
|
+
lang = getattr(program, "lang", "f90")
|
|
121
|
+
model = getattr(program, "model", "omp")
|
|
122
|
+
return list(program.files), lang, model, \
|
|
123
|
+
34 if model == "acc" else 52
|
|
124
|
+
text = getattr(program, "text", None) or getattr(program, "source", "")
|
|
125
|
+
lang = getattr(program, "lang", "f90")
|
|
126
|
+
lang = "c" if lang == "c" else "f90"
|
|
127
|
+
model = getattr(program, "model", None) or _model_of(text)
|
|
128
|
+
files = _split(text) or [("prog.c" if lang == "c" else "prog.f90",
|
|
129
|
+
text)]
|
|
130
|
+
v = getattr(program, "version", 0) or 52
|
|
131
|
+
return files, lang, model, 34 if model == "acc" else v
|
|
132
|
+
|
|
133
|
+
|
|
134
|
+
def _split(text: str):
|
|
135
|
+
from offload.engine.confirm.programs import split_files
|
|
136
|
+
return split_files(text)
|
|
137
|
+
|
|
138
|
+
|
|
139
|
+
def _model_of(text: str) -> str:
|
|
140
|
+
acc = re.search(r"^\s*(?:!\$acc|#\s*pragma\s+acc)\b", text, re.M | re.I)
|
|
141
|
+
omp = re.search(r"^\s*(?:!\$omp|#\s*pragma\s+omp)\b", text, re.M | re.I)
|
|
142
|
+
return "acc" if acc and not omp else "omp"
|
|
143
|
+
|
|
144
|
+
|
|
145
|
+
def _sources(files, lang) -> list[str]:
|
|
146
|
+
"""The texts the rules read: Fortran files joined in compile order;
|
|
147
|
+
each C file with its local headers inlined."""
|
|
148
|
+
if lang == "c":
|
|
149
|
+
heads = {n: t for n, t in files if n.endswith(".h")}
|
|
150
|
+
out = []
|
|
151
|
+
for n, t in files:
|
|
152
|
+
if n.endswith(".c"):
|
|
153
|
+
for h, ht in heads.items():
|
|
154
|
+
t = t.replace(f'#include "{h}"', ht)
|
|
155
|
+
out.append(t)
|
|
156
|
+
return out
|
|
157
|
+
return ["\n".join(t for n, t in files if not n.endswith(".h"))]
|
|
158
|
+
|
|
159
|
+
|
|
160
|
+
# --- witness 1: offload.engine.rules, EXTRA and the race rule ---------------------------
|
|
161
|
+
|
|
162
|
+
def rules_witness(program) -> tuple[bool | None, list[str]]:
|
|
163
|
+
"""(accepted, reasons): None when the rules cannot read the program
|
|
164
|
+
(a grammar or scanner limit: no verdict)."""
|
|
165
|
+
from offload.engine.grammar import GrammarError
|
|
166
|
+
from offload.engine.rules import ProgramError, parse_program, violations
|
|
167
|
+
files, lang, model, version = _files_of(program)
|
|
168
|
+
reasons: list[str] = []
|
|
169
|
+
for text in _sources(files, lang):
|
|
170
|
+
try:
|
|
171
|
+
tree = parse_program(text, version, "c" if lang == "c" else
|
|
172
|
+
None)
|
|
173
|
+
except (GrammarError, ProgramError) as e:
|
|
174
|
+
return None, [f"rules: cannot read it: {type(e).__name__}: "
|
|
175
|
+
f"{str(e).splitlines()[0][:200]}"]
|
|
176
|
+
except Exception as e: # a scanner limit is no verdict either
|
|
177
|
+
return None, [f"rules: cannot read it: {type(e).__name__}: "
|
|
178
|
+
f"{str(e)[:200]}"]
|
|
179
|
+
found = violations(tree, version)
|
|
180
|
+
reasons += [f"rules: violates {r}" for r in found]
|
|
181
|
+
reasons += [f"race: {r}" for r in races(tree, text, lang)]
|
|
182
|
+
reasons += [f"restriction: {r}" for r in extra(text, lang, tree)]
|
|
183
|
+
return not reasons, reasons
|
|
184
|
+
|
|
185
|
+
|
|
186
|
+
# --- the race rule --------------------------------------------------------------------
|
|
187
|
+
|
|
188
|
+
_OMP_THREADED = {"parallel", "do", "for", "loop", "distribute", "taskloop"}
|
|
189
|
+
_PROTECT = ("atomic", "critical", "single", "masked", "master", "ordered")
|
|
190
|
+
_DSA = ("private", "firstprivate", "lastprivate", "reduction", "linear",
|
|
191
|
+
"in_reduction", "task_reduction", "copyprivate", "induction")
|
|
192
|
+
_F_ASSIGN = re.compile(r"^\s*(?:\d+\s+)?([a-z_]\w*)\s*=(?!=)(.*)$", re.I)
|
|
193
|
+
_F_DO = re.compile(r"^\s*(?:\w+\s*:\s*)?do\s+(?:concurrent\s*\(\s*)?"
|
|
194
|
+
r"([a-z_]\w*)\s*=", re.I)
|
|
195
|
+
_C_ASSIGN = re.compile(r"(?<![\w.\]>])([A-Za-z_]\w*)\s*([-+*/%&|^]|<<|>>)?="
|
|
196
|
+
r"(?!=)")
|
|
197
|
+
_C_INCR = re.compile(r"(?:(?<![\w.\]>])([A-Za-z_]\w*)\s*(?:\+\+|--))|"
|
|
198
|
+
r"(?:(?:\+\+|--)\s*([A-Za-z_]\w*))")
|
|
199
|
+
_C_FOR = re.compile(r"\bfor\s*\(\s*(?:[A-Za-z_][\w\s\*]*\s)?([A-Za-z_]\w*)"
|
|
200
|
+
r"\s*=")
|
|
201
|
+
_C_DECL = re.compile(r"\b(?:int|long|double|float|char|short|bool|_Bool|"
|
|
202
|
+
r"unsigned|signed|size_t|int64_t|int32_t|uint64_t|"
|
|
203
|
+
r"uint32_t|const|struct\s+\w+)\b[\w\s\*]*?\b"
|
|
204
|
+
r"([A-Za-z_]\w*)\s*(?:=|;|\[|,)")
|
|
205
|
+
|
|
206
|
+
|
|
207
|
+
def _children(tree) -> dict:
|
|
208
|
+
kids: dict[int, list] = {}
|
|
209
|
+
for p, c in tree.nesting:
|
|
210
|
+
kids.setdefault(p, []).append(c)
|
|
211
|
+
return kids
|
|
212
|
+
|
|
213
|
+
|
|
214
|
+
def _parents(tree) -> dict:
|
|
215
|
+
return {c: p for p, c in tree.nesting}
|
|
216
|
+
|
|
217
|
+
|
|
218
|
+
def _descendants(kids, i) -> list:
|
|
219
|
+
out, todo = [], list(kids.get(i, ()))
|
|
220
|
+
while todo:
|
|
221
|
+
k = todo.pop()
|
|
222
|
+
out.append(k)
|
|
223
|
+
todo += kids.get(k, ())
|
|
224
|
+
return out
|
|
225
|
+
|
|
226
|
+
|
|
227
|
+
class _AllBut(set):
|
|
228
|
+
"""Every name but the ones a shared clause lists (a default(private) or
|
|
229
|
+
default(firstprivate) clause privatizes the rest)."""
|
|
230
|
+
|
|
231
|
+
def __init__(self, shared):
|
|
232
|
+
super().__init__()
|
|
233
|
+
self.shared = set(shared)
|
|
234
|
+
|
|
235
|
+
def __contains__(self, name) -> bool:
|
|
236
|
+
return name not in self.shared
|
|
237
|
+
|
|
238
|
+
def __ior__(self, other):
|
|
239
|
+
return self
|
|
240
|
+
|
|
241
|
+
|
|
242
|
+
def _dsa_names(d) -> set:
|
|
243
|
+
out = set()
|
|
244
|
+
for c in d.clauses:
|
|
245
|
+
if c.name == "default" and any(a.strip().lower() in (
|
|
246
|
+
"private", "firstprivate") for a in c.args):
|
|
247
|
+
shared = set()
|
|
248
|
+
for c2 in d.clauses:
|
|
249
|
+
if c2.name == "shared":
|
|
250
|
+
shared |= {a.strip().lower() for a in c2.args}
|
|
251
|
+
return _AllBut(shared)
|
|
252
|
+
for c in d.clauses:
|
|
253
|
+
if c.name in _DSA:
|
|
254
|
+
for a in c.args:
|
|
255
|
+
m = re.match(r"\s*(?:[\w+*\-.]+\s*:\s*)*([A-Za-z_]\w*)",
|
|
256
|
+
a.strip())
|
|
257
|
+
if m:
|
|
258
|
+
out.add(m.group(1).lower())
|
|
259
|
+
return out
|
|
260
|
+
|
|
261
|
+
|
|
262
|
+
def _threaded(tree, i, model: str) -> bool:
|
|
263
|
+
d = tree.directives[i]
|
|
264
|
+
leaves = d.name.split()
|
|
265
|
+
if model == "acc":
|
|
266
|
+
if "loop" not in leaves or any(c.name == "seq" for c in d.clauses):
|
|
267
|
+
return False
|
|
268
|
+
if leaves[0] in ("kernels", "serial"):
|
|
269
|
+
return False # kernels: the compiler decides
|
|
270
|
+
# a loop inside a kernels or serial construct: not a race
|
|
271
|
+
par = _parents(tree)
|
|
272
|
+
k = i
|
|
273
|
+
while k in par:
|
|
274
|
+
k = par[k]
|
|
275
|
+
name = tree.directives[k].name.split()[0]
|
|
276
|
+
if name in ("kernels", "serial"):
|
|
277
|
+
return False
|
|
278
|
+
if name == "parallel":
|
|
279
|
+
return True
|
|
280
|
+
return leaves[0] == "parallel"
|
|
281
|
+
return bool(_OMP_THREADED & set(leaves))
|
|
282
|
+
|
|
283
|
+
|
|
284
|
+
def _scalar(tree, name: str) -> bool:
|
|
285
|
+
"""Not declared anywhere as an array, pointer, allocatable or derived
|
|
286
|
+
type (an undeclared name is taken as a scalar)."""
|
|
287
|
+
for (s, n), attr in tree.decls.items():
|
|
288
|
+
if n == name and attr in ("pointer", "allocatable"):
|
|
289
|
+
return False
|
|
290
|
+
if any(n == name for (_, n) in tree.arrays):
|
|
291
|
+
return False
|
|
292
|
+
if any(n == name for (_, n) in tree.vartypes):
|
|
293
|
+
return False
|
|
294
|
+
return True
|
|
295
|
+
|
|
296
|
+
|
|
297
|
+
def races(tree, text: str, lang: str) -> list[str]:
|
|
298
|
+
"""The race rule (module docstring) on one parsed source."""
|
|
299
|
+
lines = text.splitlines()
|
|
300
|
+
model = "acc" if tree.directives and tree.directives[0].atoms and \
|
|
301
|
+
next(iter(tree.directives[0].atoms)).startswith("acc.") else None
|
|
302
|
+
if model is None:
|
|
303
|
+
model = "acc" if re.search(r"^\s*(?:!\$acc|#\s*pragma\s+acc)\b",
|
|
304
|
+
text, re.M | re.I) else "omp"
|
|
305
|
+
kids = _children(tree)
|
|
306
|
+
par = _parents(tree)
|
|
307
|
+
out = []
|
|
308
|
+
for i, d in enumerate(tree.directives):
|
|
309
|
+
a = tree.assoc[i]
|
|
310
|
+
if a.kind != "loop" or not a.end_line or not _threaded(tree, i,
|
|
311
|
+
model):
|
|
312
|
+
continue
|
|
313
|
+
priv = _dsa_names(d)
|
|
314
|
+
nested = _descendants(kids, i)
|
|
315
|
+
for k in nested:
|
|
316
|
+
more = _dsa_names(tree.directives[k])
|
|
317
|
+
priv = more if isinstance(more, _AllBut) else priv | more
|
|
318
|
+
leaves = d.name.split()
|
|
319
|
+
if model == "omp" and not (set(leaves) & {"parallel", "do", "for",
|
|
320
|
+
"loop", "taskloop"}):
|
|
321
|
+
# a distribute loop: one thread per team runs it; the
|
|
322
|
+
# enclosing teams construct may privatize
|
|
323
|
+
k = i
|
|
324
|
+
while k in par:
|
|
325
|
+
k = par[k]
|
|
326
|
+
if "teams" in tree.directives[k].name.split():
|
|
327
|
+
priv |= _dsa_names(tree.directives[k])
|
|
328
|
+
break
|
|
329
|
+
if model == "acc":
|
|
330
|
+
k = i
|
|
331
|
+
while k in par:
|
|
332
|
+
k = par[k]
|
|
333
|
+
priv |= _dsa_names(tree.directives[k])
|
|
334
|
+
if tree.directives[k].name.split()[0] == "parallel":
|
|
335
|
+
break
|
|
336
|
+
protected = []
|
|
337
|
+
for k in nested:
|
|
338
|
+
if tree.directives[k].name.split()[0] in _PROTECT:
|
|
339
|
+
b = tree.assoc[k]
|
|
340
|
+
# an atomic without an end directive protects the next
|
|
341
|
+
# statement
|
|
342
|
+
protected.append((b.line, (b.end_line or b.line + 1) +
|
|
343
|
+
(1 if lang == "c" else 0)))
|
|
344
|
+
first = a.line
|
|
345
|
+
# Fortran: up to the END DO; C: the loop's last line included
|
|
346
|
+
body = range(first + 1, a.end_line + (1 if lang == "c" else 0))
|
|
347
|
+
found = _writes(lines, body, lang, protected)
|
|
348
|
+
loopvars = {v.lower() for v in a.loop_vars}
|
|
349
|
+
for name, (ln, update) in sorted(found.items()):
|
|
350
|
+
low = name.lower()
|
|
351
|
+
if low in priv or low in loopvars or not _scalar(tree, low):
|
|
352
|
+
continue
|
|
353
|
+
if model == "acc" and not update:
|
|
354
|
+
continue # OpenACC privatizes scalars by analysis
|
|
355
|
+
kind = "updated (x = x op ...)" if update else "written"
|
|
356
|
+
cite = ACC_RACE_CITE if model == "acc" else RACE_CITE
|
|
357
|
+
out.append(f"line {ln}: {name} is {kind} in every iteration of "
|
|
358
|
+
f"'{d.name}' (line {first}) and no clause makes it "
|
|
359
|
+
f"private or a reduction: {cite}")
|
|
360
|
+
if model == "omp":
|
|
361
|
+
out += array_races(tree, text, lang, lines, body, d, a, priv,
|
|
362
|
+
protected)
|
|
363
|
+
return out
|
|
364
|
+
|
|
365
|
+
|
|
366
|
+
# --- array and aliasing races ----------------------------------
|
|
367
|
+
|
|
368
|
+
_F_ARR_W = re.compile(r"^\s*([a-z_]\w*)\s*\(([^=]*)\)\s*=(?!=)(.*)$", re.I)
|
|
369
|
+
_C_ARR_W = re.compile(r"(?<![\w.>])([A-Za-z_]\w*)\s*\[([^\]]*)\]\s*"
|
|
370
|
+
r"([-+*/%&|^]?)=(?!=)")
|
|
371
|
+
_C_LOCAL_ARRAY = re.compile(
|
|
372
|
+
# no static or extern: a variable with static storage duration declared
|
|
373
|
+
# inside the construct is shared (5.2 §5.1.1 p.98 l.1)
|
|
374
|
+
r"^(?:(?:const|volatile|register|unsigned|signed|long|short)\s+)*"
|
|
375
|
+
r"(?:int|long|double|float|char|short|bool|_Bool|size_t|"
|
|
376
|
+
r"u?int(?:8|16|32|64)_t|struct\s+\w+|[A-Za-z_]\w*_t)\s*\**\s*"
|
|
377
|
+
r"([A-Za-z_]\w*)\s*\[")
|
|
378
|
+
_OFFSET = re.compile(r"^([A-Za-z_]\w*)\s*(?:([+-])\s*(\d+))?$")
|
|
379
|
+
|
|
380
|
+
|
|
381
|
+
def _statements(lines, body, lang, protected) -> list[tuple[int, str, bool]]:
|
|
382
|
+
"""(line, statement, guarded) of the loop body, outside protected
|
|
383
|
+
regions; Fortran continuations joined, C split at ';'."""
|
|
384
|
+
out, stmt, start, in_if = [], "", 0, 0
|
|
385
|
+
for ln in body:
|
|
386
|
+
if ln - 1 >= len(lines):
|
|
387
|
+
break
|
|
388
|
+
if any(a < ln <= b for a, b in protected):
|
|
389
|
+
continue
|
|
390
|
+
raw = lines[ln - 1]
|
|
391
|
+
if lang == "c":
|
|
392
|
+
code = re.sub(r"//.*$", "", raw)
|
|
393
|
+
if code.strip().startswith("#"):
|
|
394
|
+
continue
|
|
395
|
+
guarded = re.search(r"\bif\b", code) is not None
|
|
396
|
+
for part in re.split(r"[;{}]", code):
|
|
397
|
+
if part.strip():
|
|
398
|
+
out.append((ln, part.strip(), guarded))
|
|
399
|
+
continue
|
|
400
|
+
if raw.lstrip().lower().startswith(("!$omp", "!$acc")):
|
|
401
|
+
continue
|
|
402
|
+
code = raw.split("!")[0]
|
|
403
|
+
if not code.strip():
|
|
404
|
+
continue
|
|
405
|
+
if not stmt:
|
|
406
|
+
start = ln
|
|
407
|
+
stmt = (stmt + " " + code.rstrip().rstrip("&")) if stmt else \
|
|
408
|
+
code.rstrip().rstrip("&")
|
|
409
|
+
if code.rstrip().endswith("&"):
|
|
410
|
+
continue
|
|
411
|
+
st, stmt = stmt.strip(), ""
|
|
412
|
+
low = st.lower()
|
|
413
|
+
if re.match(r"^(\w+\s*:\s*)?if\s*\(.*\)\s*then\b", low):
|
|
414
|
+
in_if += 1
|
|
415
|
+
continue
|
|
416
|
+
if re.match(r"^end\s*if\b", low):
|
|
417
|
+
in_if = max(0, in_if - 1)
|
|
418
|
+
continue
|
|
419
|
+
guarded = in_if > 0
|
|
420
|
+
mi = re.match(r"^if\s*\((.*)\)\s*(?!then\b)(\w.*)$", st, re.I)
|
|
421
|
+
if mi and "=" in mi.group(2):
|
|
422
|
+
st, guarded = mi.group(2), True
|
|
423
|
+
out.append((start, st, guarded))
|
|
424
|
+
return out
|
|
425
|
+
|
|
426
|
+
|
|
427
|
+
def _ids(text: str) -> set:
|
|
428
|
+
return {x.lower() for x in re.findall(r"[A-Za-z_]\w*", text or "")}
|
|
429
|
+
|
|
430
|
+
|
|
431
|
+
def _array_name(tree, name: str) -> bool:
|
|
432
|
+
low = name.lower()
|
|
433
|
+
if any(n == low for (_, n) in tree.arrays):
|
|
434
|
+
return True
|
|
435
|
+
return any(n == low and attr in ("allocatable", "pointer")
|
|
436
|
+
for (_, n), attr in tree.decls.items())
|
|
437
|
+
|
|
438
|
+
|
|
439
|
+
def _components(sub: str) -> list | None:
|
|
440
|
+
"""[(var, offset)] of a subscript of plain `v`, `v+c`, `v-c` forms."""
|
|
441
|
+
parts = _split_top(sub)
|
|
442
|
+
out = []
|
|
443
|
+
for p in parts:
|
|
444
|
+
m = _OFFSET.match(p.strip())
|
|
445
|
+
if not m:
|
|
446
|
+
return None
|
|
447
|
+
off = int(m.group(3) or 0) * (-1 if m.group(2) == "-" else 1)
|
|
448
|
+
out.append((m.group(1).lower(), off))
|
|
449
|
+
return out
|
|
450
|
+
|
|
451
|
+
|
|
452
|
+
_C_COUNTER = r"[\w\[\].>-]+"
|
|
453
|
+
_C_LOCAL_DECL = r"^\s*(?:const\s+|static\s+|volatile\s+)*(?:unsigned\s+|signed\s+)?" \
|
|
454
|
+
r"(?:long\s+long|int|long|short|char|size_t|u?int\d+_t)\s+\**%s\b"
|
|
455
|
+
|
|
456
|
+
|
|
457
|
+
def _step(*groups) -> int:
|
|
458
|
+
"""The constant step of a counter update, 0 when there is none (a step of 0 hands every
|
|
459
|
+
iteration the same value)."""
|
|
460
|
+
for g in groups:
|
|
461
|
+
if g:
|
|
462
|
+
return int(g)
|
|
463
|
+
return 0
|
|
464
|
+
|
|
465
|
+
|
|
466
|
+
def _c_atomic_blocks(lines, rows):
|
|
467
|
+
"""[(kind, counter, variable, step, rows)] of the C `atomic capture` blocks (kind
|
|
468
|
+
"capture") and plain `atomic` / `atomic update` statements (kind "update") of the region
|
|
469
|
+
that change a counter by a constant."""
|
|
470
|
+
out = []
|
|
471
|
+
x = _C_COUNTER
|
|
472
|
+
for k, ln in enumerate(rows):
|
|
473
|
+
if ln - 1 >= len(lines):
|
|
474
|
+
break
|
|
475
|
+
raw = lines[ln - 1].strip()
|
|
476
|
+
cap = re.match(r"#\s*pragma\s+omp\s+atomic\b.*\bcapture\b", raw)
|
|
477
|
+
upd = re.match(r"#\s*pragma\s+omp\s+atomic(?:\s+update)?\s*$", raw)
|
|
478
|
+
if not (cap or upd):
|
|
479
|
+
continue
|
|
480
|
+
for n in range(1, 6):
|
|
481
|
+
used = rows[k + 1:k + 1 + n]
|
|
482
|
+
if len(used) < n:
|
|
483
|
+
break
|
|
484
|
+
blk = " ".join(lines[r - 1].strip() for r in used if r - 1 < len(lines))
|
|
485
|
+
if cap:
|
|
486
|
+
pats = ((rf"\{{\s*(\w+)\s*=\s*({x})\s*;\s*\2\s*(?:\+=\s*(\d+)|=\s*\2\s*\+\s*(\d+))\s*;\s*\}}",
|
|
487
|
+
lambda m: (m.group(1), m.group(2), _step(m.group(3), m.group(4)))),
|
|
488
|
+
(rf"\{{\s*({x})\s*(?:\+=\s*(\d+)|=\s*\1\s*\+\s*(\d+))\s*;\s*(\w+)\s*=\s*\1\s*;\s*\}}",
|
|
489
|
+
lambda m: (m.group(4), m.group(1), _step(m.group(2), m.group(3)))),
|
|
490
|
+
(rf"(\w+)\s*=\s*({x})\+\+\s*;", lambda m: (m.group(1), m.group(2), 1)),
|
|
491
|
+
(rf"(\w+)\s*=\s*\+\+({x})\s*;", lambda m: (m.group(1), m.group(2), 1)))
|
|
492
|
+
for pat, get in pats:
|
|
493
|
+
m = re.fullmatch(pat, blk)
|
|
494
|
+
if m:
|
|
495
|
+
v, cx, st = get(m)
|
|
496
|
+
out.append(("capture", cx.replace(" ", "").lower(), v.lower(), st, [ln, *used]))
|
|
497
|
+
break
|
|
498
|
+
else:
|
|
499
|
+
continue
|
|
500
|
+
break
|
|
501
|
+
for pat, get in ((rf"({x})\s*\+=\s*(\d+)\s*;", lambda m: (m.group(1), _step(m.group(2)))),
|
|
502
|
+
(rf"({x})\s*=\s*\1\s*\+\s*(\d+)\s*;", lambda m: (m.group(1), _step(m.group(2)))),
|
|
503
|
+
(rf"({x})\+\+\s*;", lambda m: (m.group(1), 1)),
|
|
504
|
+
(rf"\+\+({x})\s*;", lambda m: (m.group(1), 1))):
|
|
505
|
+
m = re.fullmatch(pat, blk)
|
|
506
|
+
if m:
|
|
507
|
+
cx, st = get(m)
|
|
508
|
+
out.append(("update", cx.replace(" ", "").lower(), None, st, [ln, *used]))
|
|
509
|
+
break
|
|
510
|
+
else:
|
|
511
|
+
continue
|
|
512
|
+
break
|
|
513
|
+
return out
|
|
514
|
+
|
|
515
|
+
|
|
516
|
+
def _f_atomic_blocks(lines, rows):
|
|
517
|
+
"""The same for Fortran: `!$omp atomic capture` ... `!$omp end atomic` and a plain
|
|
518
|
+
`!$omp atomic` / `atomic update` statement."""
|
|
519
|
+
out = []
|
|
520
|
+
for k, ln in enumerate(rows):
|
|
521
|
+
if ln - 1 >= len(lines):
|
|
522
|
+
break
|
|
523
|
+
raw = lines[ln - 1].strip()
|
|
524
|
+
cap = re.match(r"!\$omp\s+atomic\s+capture\b", raw, re.I)
|
|
525
|
+
upd = re.match(r"!\$omp\s+atomic(?:\s+update)?\s*$", raw, re.I)
|
|
526
|
+
if not (cap or upd):
|
|
527
|
+
continue
|
|
528
|
+
blk, used = [], [ln]
|
|
529
|
+
for r in rows[k + 1:k + 4]:
|
|
530
|
+
t = lines[r - 1].strip()
|
|
531
|
+
if re.match(r"!\$omp\s+end\s+atomic", t, re.I):
|
|
532
|
+
used.append(r)
|
|
533
|
+
break
|
|
534
|
+
if t and not t.startswith("!"):
|
|
535
|
+
blk.append(t.split("!")[0].strip())
|
|
536
|
+
used.append(r)
|
|
537
|
+
if upd and blk:
|
|
538
|
+
break
|
|
539
|
+
parts = [tuple(x.strip().lower() for x in b.split("=", 1)) for b in blk if "=" in b]
|
|
540
|
+
|
|
541
|
+
def step(lhs, rhs):
|
|
542
|
+
m = re.fullmatch(rf"{re.escape(lhs)}\s*\+\s*(\d+)|(\d+)\s*\+\s*{re.escape(lhs)}", rhs)
|
|
543
|
+
return _step(*m.groups()) if m else None
|
|
544
|
+
if upd and len(parts) == 1:
|
|
545
|
+
st = step(*parts[0])
|
|
546
|
+
if st is not None:
|
|
547
|
+
out.append(("update", parts[0][0].replace(" ", ""), None, st, used))
|
|
548
|
+
elif cap and len(parts) == 2:
|
|
549
|
+
(l1, r1), (l2, r2) = parts
|
|
550
|
+
if step(l1, r1) is not None and r2 == l1 and re.fullmatch(r"\w+", l2):
|
|
551
|
+
out.append(("capture", l1.replace(" ", ""), l2, step(l1, r1), used)) # x = x + c; v = x
|
|
552
|
+
elif step(l2, r2) is not None and r1 == l2 and re.fullmatch(r"\w+", l1):
|
|
553
|
+
out.append(("capture", l2.replace(" ", ""), l1, step(l2, r2), used)) # v = x; x = x + c
|
|
554
|
+
return out
|
|
555
|
+
|
|
556
|
+
|
|
557
|
+
def _claimed_slots(lines, body, lang, priv=()) -> set:
|
|
558
|
+
"""Names that hold a value an atomic capture of a counter handed out: the
|
|
559
|
+
variable `v` of `atomic capture` blocks `x = x + c; v = x` or `v = x;
|
|
560
|
+
x = x + c` (C: `{ v = x; x += c; }`, `v = x++;`). The atomic regions on
|
|
561
|
+
`x` exclude each other (OpenMP 5.2 15.8.4 p.311: 'atomic regions enforce
|
|
562
|
+
exclusive access ... among all threads in the binding thread set without
|
|
563
|
+
regard to the teams'), so no two executions capture the same value of a
|
|
564
|
+
counter that only moves up: an element indexed by `v` is written by one
|
|
565
|
+
iteration. That holds only when
|
|
566
|
+
|
|
567
|
+
* the step `c` is a constant above 0 (with 0 every capture returns the
|
|
568
|
+
same value);
|
|
569
|
+
* the counter is shared: not in a private, firstprivate, lastprivate,
|
|
570
|
+
linear or reduction clause (`priv`), and not declared in the region
|
|
571
|
+
(each thread would count on its own copy);
|
|
572
|
+
* every other access to the counter in the region is an atomic update or
|
|
573
|
+
capture with a positive constant step (a plain or atomic write, or a
|
|
574
|
+
read, could move it back or make the captured values repeat)."""
|
|
575
|
+
rows = list(body)
|
|
576
|
+
blocks = (_c_atomic_blocks if lang == "c" else _f_atomic_blocks)(lines, rows)
|
|
577
|
+
out = set()
|
|
578
|
+
for x in {b[1] for b in blocks if b[0] == "capture"}:
|
|
579
|
+
base = re.match(r"[A-Za-z_]\w*", x)
|
|
580
|
+
if not base:
|
|
581
|
+
continue
|
|
582
|
+
base = base.group(0)
|
|
583
|
+
if base in priv:
|
|
584
|
+
continue
|
|
585
|
+
if lang == "c" and any(re.match(_C_LOCAL_DECL % re.escape(base), lines[r - 1])
|
|
586
|
+
for r in rows if r - 1 < len(lines)):
|
|
587
|
+
continue
|
|
588
|
+
good = set()
|
|
589
|
+
for kind, cx, v, st, used in blocks:
|
|
590
|
+
if cx == x and st > 0:
|
|
591
|
+
good.update(used)
|
|
592
|
+
word = re.compile(rf"\b{re.escape(base)}\b", 0 if lang == "c" else re.I)
|
|
593
|
+
stray = False
|
|
594
|
+
for r in rows:
|
|
595
|
+
if r - 1 >= len(lines) or r in good:
|
|
596
|
+
continue
|
|
597
|
+
raw = lines[r - 1]
|
|
598
|
+
if lang == "c" and r >= 2 and lines[r - 2].rstrip().endswith("\\"):
|
|
599
|
+
continue # the construct's own continued pragma line: its clauses are `priv`
|
|
600
|
+
if lang != "c" and re.match(r"\s*!\$omp\s*&", raw, re.I):
|
|
601
|
+
continue
|
|
602
|
+
code = raw.split("//")[0] if lang == "c" else (raw if raw.lstrip().startswith("!$") else raw.split("!")[0])
|
|
603
|
+
if word.search(code):
|
|
604
|
+
stray = True
|
|
605
|
+
break
|
|
606
|
+
if stray:
|
|
607
|
+
continue
|
|
608
|
+
out |= {b[2] for b in blocks if b[0] == "capture" and b[1] == x and b[3] > 0}
|
|
609
|
+
return out
|
|
610
|
+
|
|
611
|
+
|
|
612
|
+
def array_races(tree, text, lang, lines, body, d, a, priv,
|
|
613
|
+
protected) -> list[str]:
|
|
614
|
+
"""Array elements that the iterations of a threaded loop share:
|
|
615
|
+
(1) an element written at a subscript that depends on no loop
|
|
616
|
+
variable of the loop (every iteration writes it); (2) a loop-carried
|
|
617
|
+
dependence: an element written at `a(i+c)` and read at `a(i+c')` in
|
|
618
|
+
another iteration; (3) aliasing: an array written through a pointer
|
|
619
|
+
that names it (Fortran `p => a`, C `p = a` / `p = &a[k]`) and read
|
|
620
|
+
or written under its own name at another subscript. Privatized and
|
|
621
|
+
reduction arrays, protected regions and one-iteration writes under an
|
|
622
|
+
IF are skipped."""
|
|
623
|
+
stmts = _statements(lines, body, lang, protected)
|
|
624
|
+
# the loop variables the construct associates (collapse, ordered);
|
|
625
|
+
# the parser lists every variable of the nest
|
|
626
|
+
n = 1
|
|
627
|
+
for c in d.clauses:
|
|
628
|
+
if c.name in ("collapse", "ordered") and c.args:
|
|
629
|
+
try:
|
|
630
|
+
n = max(n, int(str(c.args[0]).strip()))
|
|
631
|
+
except ValueError:
|
|
632
|
+
pass
|
|
633
|
+
loopvars = {v.lower() for v in list(a.loop_vars)[:n]}
|
|
634
|
+
# names that carry the loop's iteration: loop variables and scalars
|
|
635
|
+
# computed from them in the body (out(lin) with lin = (i-1)*n + j)
|
|
636
|
+
dep = set(loopvars) | _claimed_slots(lines, body, lang, priv)
|
|
637
|
+
changed = True
|
|
638
|
+
while changed:
|
|
639
|
+
changed = False
|
|
640
|
+
for _, st, _ in stmts:
|
|
641
|
+
# an inner loop whose bounds carry the iteration carries it too
|
|
642
|
+
# (do i = lo, hi with lo from the parallel loop's c); one with
|
|
643
|
+
# constant bounds does not: every iteration writes its range
|
|
644
|
+
m = re.match(r"^\s*(?:do\s+|for\s*\(\s*(?:[A-Za-z_][\w ]*\s)?)"
|
|
645
|
+
r"([A-Za-z_]\w*)\s*=(?!=)(.*)$", st, re.I) or \
|
|
646
|
+
re.match(r"^\s*([A-Za-z_]\w*)\s*=(?!=)(.*)$", st)
|
|
647
|
+
if m and m.group(1).lower() not in dep and \
|
|
648
|
+
_ids(m.group(2)) & dep:
|
|
649
|
+
dep.add(m.group(1).lower())
|
|
650
|
+
changed = True
|
|
651
|
+
writes, reads = [], []
|
|
652
|
+
for ln, st, guarded in stmts:
|
|
653
|
+
if lang == "c":
|
|
654
|
+
for m in _C_ARR_W.finditer(st):
|
|
655
|
+
writes.append((ln, m.group(1), m.group(2), guarded,
|
|
656
|
+
bool(m.group(3))))
|
|
657
|
+
rhs = st.split("=", 1)[-1] if "=" in st else st
|
|
658
|
+
for m in re.finditer(r"([A-Za-z_]\w*)\s*\[([^\]]*)\]", rhs):
|
|
659
|
+
reads.append((ln, m.group(1), m.group(2)))
|
|
660
|
+
else:
|
|
661
|
+
m = _F_ARR_W.match(st)
|
|
662
|
+
if m and _array_name(tree, m.group(1)):
|
|
663
|
+
writes.append((ln, m.group(1), m.group(2), guarded,
|
|
664
|
+
re.search(rf"\b{m.group(1)}\s*\(",
|
|
665
|
+
m.group(3), re.I) is not None))
|
|
666
|
+
rhs = m.group(3)
|
|
667
|
+
else:
|
|
668
|
+
rhs = st.split("=", 1)[-1] if "=" in st else st
|
|
669
|
+
for r in re.finditer(r"([A-Za-z_]\w*)\s*\(([^()]*)\)", rhs):
|
|
670
|
+
if _array_name(tree, r.group(1)):
|
|
671
|
+
reads.append((ln, r.group(1), r.group(2)))
|
|
672
|
+
alias = _aliases(text, lang)
|
|
673
|
+
cite = RACE_CITE
|
|
674
|
+
out, seen = [], set()
|
|
675
|
+
# An array declared in the loop body is private to each
|
|
676
|
+
# iteration (5.2 §5.1.1: a variable declared in a scope inside the
|
|
677
|
+
# construct); its initializer writes no shared element
|
|
678
|
+
local = set()
|
|
679
|
+
if lang == "c":
|
|
680
|
+
for _, st, _ in stmts:
|
|
681
|
+
m = _C_LOCAL_ARRAY.match(st)
|
|
682
|
+
if m:
|
|
683
|
+
local.add(m.group(1).lower())
|
|
684
|
+
for ln, name, sub, guarded, update in writes:
|
|
685
|
+
low = name.lower()
|
|
686
|
+
if low in priv or low in local:
|
|
687
|
+
continue
|
|
688
|
+
if not (_ids(sub) & dep):
|
|
689
|
+
if guarded and not update:
|
|
690
|
+
continue
|
|
691
|
+
key = ("same", low)
|
|
692
|
+
if key not in seen:
|
|
693
|
+
seen.add(key)
|
|
694
|
+
out.append(f"line {ln}: {name}({sub.strip()}) is written in "
|
|
695
|
+
f"every iteration of '{d.name}' (line {a.line}): "
|
|
696
|
+
f"the subscript depends on no loop variable: "
|
|
697
|
+
f"{cite}")
|
|
698
|
+
continue
|
|
699
|
+
wc = _components(sub)
|
|
700
|
+
for rl, rname, rsub in reads:
|
|
701
|
+
rlow = rname.lower()
|
|
702
|
+
other = rlow != low and (alias.get(low) == rlow or
|
|
703
|
+
alias.get(rlow) == low)
|
|
704
|
+
if rlow != low and not other:
|
|
705
|
+
continue
|
|
706
|
+
if rlow in priv or " ".join(rsub.split()) == \
|
|
707
|
+
" ".join(sub.split()):
|
|
708
|
+
continue
|
|
709
|
+
rc = _components(rsub)
|
|
710
|
+
if wc is None or rc is None or len(wc) != len(rc):
|
|
711
|
+
continue
|
|
712
|
+
if all(w[0] == r[0] for w, r in zip(wc, rc)) and any(
|
|
713
|
+
w[0] in loopvars and w[1] != r[1]
|
|
714
|
+
for w, r in zip(wc, rc)):
|
|
715
|
+
key = ("carried", low, rlow)
|
|
716
|
+
if key in seen:
|
|
717
|
+
continue
|
|
718
|
+
seen.add(key)
|
|
719
|
+
how = (f"through the alias {name} of {rname}" if other else
|
|
720
|
+
"a loop-carried dependence")
|
|
721
|
+
out.append(f"line {ln}: {name}({sub.strip()}) is written and "
|
|
722
|
+
f"{rname}({rsub.strip()}) read in other "
|
|
723
|
+
f"iterations of '{d.name}' (line {a.line}): "
|
|
724
|
+
f"{how}: {cite}")
|
|
725
|
+
return out
|
|
726
|
+
|
|
727
|
+
|
|
728
|
+
def _aliases(text: str, lang: str) -> dict:
|
|
729
|
+
"""pointer name -> the array it is pointed at (lower case)."""
|
|
730
|
+
out = {}
|
|
731
|
+
if lang == "c":
|
|
732
|
+
for m in re.finditer(r"\*\s*([A-Za-z_]\w*)\s*=\s*&?\s*([A-Za-z_]\w*)"
|
|
733
|
+
r"\s*(?:\[[^\]]*\])?\s*;", text):
|
|
734
|
+
out[m.group(1).lower()] = m.group(2).lower()
|
|
735
|
+
for m in re.finditer(r"(?<![\w*])([A-Za-z_]\w*)\s*=\s*&\s*"
|
|
736
|
+
r"([A-Za-z_]\w*)\s*\[", text):
|
|
737
|
+
out[m.group(1).lower()] = m.group(2).lower()
|
|
738
|
+
else:
|
|
739
|
+
for m in re.finditer(r"\b([A-Za-z_]\w*)\s*=>\s*([A-Za-z_]\w*)",
|
|
740
|
+
text):
|
|
741
|
+
out[m.group(1).lower()] = m.group(2).lower()
|
|
742
|
+
return out
|
|
743
|
+
|
|
744
|
+
|
|
745
|
+
def _writes(lines: list[str], body, lang: str, protected) -> dict:
|
|
746
|
+
"""name -> (first line, is an update) of the scalars assigned in the
|
|
747
|
+
body lines, outside protected ranges, Fortran BLOCKs and inner DO
|
|
748
|
+
variables / C declarations of the body. A plain write under an IF
|
|
749
|
+
(``if (i == 1) x = ...``: possibly one iteration) is not counted; an
|
|
750
|
+
update under an IF is (several iterations may take it)."""
|
|
751
|
+
found: dict[str, tuple] = {}
|
|
752
|
+
local, loopv = set(), set()
|
|
753
|
+
in_block = 0
|
|
754
|
+
in_if = 0
|
|
755
|
+
cstack: list[bool] = [] # C: is each open brace an if/else block
|
|
756
|
+
stmt = ""
|
|
757
|
+
for ln in body:
|
|
758
|
+
if ln - 1 >= len(lines):
|
|
759
|
+
break
|
|
760
|
+
raw = lines[ln - 1]
|
|
761
|
+
if any(a < ln <= b for a, b in protected):
|
|
762
|
+
continue
|
|
763
|
+
if lang == "c":
|
|
764
|
+
code = re.sub(r"//.*$", "", raw)
|
|
765
|
+
if code.strip().startswith("#"):
|
|
766
|
+
continue
|
|
767
|
+
for m in _C_FOR.finditer(code):
|
|
768
|
+
loopv.add(m.group(1))
|
|
769
|
+
for m in _C_DECL.finditer(code):
|
|
770
|
+
local.add(m.group(1))
|
|
771
|
+
guarded = any(cstack) or re.search(r"\b(?:if|else)\b",
|
|
772
|
+
code) is not None
|
|
773
|
+
for m in _C_ASSIGN.finditer(code):
|
|
774
|
+
name, op = m.group(1), m.group(2)
|
|
775
|
+
if name in ("if", "for", "while", "return"):
|
|
776
|
+
continue
|
|
777
|
+
rhs = code[m.end():]
|
|
778
|
+
upd = bool(op) or re.search(rf"\b{re.escape(name)}\b",
|
|
779
|
+
rhs) is not None
|
|
780
|
+
if upd or not guarded:
|
|
781
|
+
_add(found, name, ln, upd)
|
|
782
|
+
for m in _C_INCR.finditer(code):
|
|
783
|
+
_add(found, m.group(1) or m.group(2), ln, True)
|
|
784
|
+
for ch_i, ch in enumerate(code):
|
|
785
|
+
if ch == "{":
|
|
786
|
+
cstack.append(re.search(r"\b(?:if|else)\b",
|
|
787
|
+
code[:ch_i]) is not None
|
|
788
|
+
or bool(cstack and cstack[-1]))
|
|
789
|
+
elif ch == "}" and cstack:
|
|
790
|
+
cstack.pop()
|
|
791
|
+
continue
|
|
792
|
+
code = raw.split("!")[0] if not raw.lstrip().lower().startswith(
|
|
793
|
+
("!$omp", "!$acc")) else ""
|
|
794
|
+
if not code.strip():
|
|
795
|
+
continue
|
|
796
|
+
stmt = (stmt + " " + code.rstrip().rstrip("&")) if stmt else \
|
|
797
|
+
code.rstrip().rstrip("&")
|
|
798
|
+
if code.rstrip().endswith("&"):
|
|
799
|
+
continue
|
|
800
|
+
s, stmt = stmt.strip(), ""
|
|
801
|
+
low = s.lower()
|
|
802
|
+
if re.match(r"^(\w+\s*:\s*)?block\b", low):
|
|
803
|
+
in_block += 1
|
|
804
|
+
continue
|
|
805
|
+
if re.match(r"^end\s*block\b", low):
|
|
806
|
+
in_block -= 1
|
|
807
|
+
continue
|
|
808
|
+
m = _F_DO.match(s)
|
|
809
|
+
if m:
|
|
810
|
+
loopv.add(m.group(1).lower())
|
|
811
|
+
continue
|
|
812
|
+
if in_block:
|
|
813
|
+
continue
|
|
814
|
+
if re.match(r"^(\w+\s*:\s*)?if\s*\(.*\)\s*then\b", low) or \
|
|
815
|
+
re.match(r"^(\w+\s*:\s*)?select\s*(case|type)\b", low):
|
|
816
|
+
in_if += 1
|
|
817
|
+
continue
|
|
818
|
+
if re.match(r"^end\s*(if|select)\b", low):
|
|
819
|
+
in_if = max(0, in_if - 1)
|
|
820
|
+
continue
|
|
821
|
+
guarded = in_if > 0
|
|
822
|
+
# a one-line IF: its action statement
|
|
823
|
+
mi = re.match(r"^if\s*\((.*)\)\s*(?!then\b)(\w.*)$", s, re.I)
|
|
824
|
+
if mi and "=" in mi.group(2) and not re.match(
|
|
825
|
+
r"^then\b", mi.group(2), re.I):
|
|
826
|
+
s = mi.group(2)
|
|
827
|
+
guarded = True
|
|
828
|
+
m = _F_ASSIGN.match(s)
|
|
829
|
+
if m:
|
|
830
|
+
name = m.group(1)
|
|
831
|
+
upd = re.search(rf"\b{re.escape(name)}\b", m.group(2),
|
|
832
|
+
re.I) is not None
|
|
833
|
+
if upd or not guarded:
|
|
834
|
+
_add(found, name, ln, upd)
|
|
835
|
+
for n in list(found):
|
|
836
|
+
if n in local or n in loopv or n.lower() in loopv:
|
|
837
|
+
del found[n]
|
|
838
|
+
return found
|
|
839
|
+
|
|
840
|
+
|
|
841
|
+
def _add(found, name, ln, upd):
|
|
842
|
+
if name in found:
|
|
843
|
+
old = found[name]
|
|
844
|
+
found[name] = (old[0], old[1] or upd)
|
|
845
|
+
else:
|
|
846
|
+
found[name] = (ln, upd)
|
|
847
|
+
|
|
848
|
+
|
|
849
|
+
# --- the restriction checks offload.engine.rules lacks -------------------------------------
|
|
850
|
+
|
|
851
|
+
EXTRA_CITES = {
|
|
852
|
+
"uses-allocators-traits-constant":
|
|
853
|
+
"OpenMP 5.2 §6.8 p.181 l.16-17 (\"With this syntax, traits must be "
|
|
854
|
+
"a constant array with constant values\"), p.182 l.18-19",
|
|
855
|
+
"alloc-in-target-predefined":
|
|
856
|
+
"OpenMP 5.2 §18.13.6 p.429 l.21-26 (\"Unless dynamic_allocators "
|
|
857
|
+
"appears on a requires directive in the same compilation unit, "
|
|
858
|
+
"omp_alloc and omp_aligned_alloc invocations that appear in target "
|
|
859
|
+
"regions must not pass omp_null_allocator as the allocator "
|
|
860
|
+
"argument, which must be a constant expression that evaluates to "
|
|
861
|
+
"one of the predefined memory allocator values. The alignment "
|
|
862
|
+
"argument to omp_aligned_alloc must be a power of two and the size "
|
|
863
|
+
"argument must be a multiple of alignment.\")",
|
|
864
|
+
"declare-target-module-variable":
|
|
865
|
+
"OpenMP 5.2 §13.8 p.286 l.31-32 (\"A variable referenced in a "
|
|
866
|
+
"target region but not the target construct that is not declared "
|
|
867
|
+
"in the target region must appear in a declare target directive.\")",
|
|
868
|
+
"acc-loop-reduction-data-clause":
|
|
869
|
+
"OpenACC 3.4 §2.6.2 p.42 l.1403-1409 (\"If a scalar variable "
|
|
870
|
+
"appears in a reduction clause on a loop construct that has a "
|
|
871
|
+
"parent parallel or serial construct, and if the reduction's access "
|
|
872
|
+
"to the original variable is exposed to the parent compute "
|
|
873
|
+
"construct, the variable must appear either in an explicit data "
|
|
874
|
+
"clause visible at the compute construct or in a firstprivate, "
|
|
875
|
+
"private, or reduction clause on the compute construct.\")",
|
|
876
|
+
}
|
|
877
|
+
|
|
878
|
+
_PREDEFINED_ALLOC = re.compile(r"^omp_(?:default|large_cap|const|high_bw|"
|
|
879
|
+
r"low_lat|cgroup|pteam|thread)_mem_alloc$")
|
|
880
|
+
|
|
881
|
+
|
|
882
|
+
def _directives(text: str, lang: str, model: str) -> list[tuple]:
|
|
883
|
+
"""(first line, last line, lower-cased directive text) of every
|
|
884
|
+
directive of `model` (continuations joined)."""
|
|
885
|
+
out = []
|
|
886
|
+
lines = text.splitlines()
|
|
887
|
+
k = 0
|
|
888
|
+
pre = (rf"^\s*#\s*pragma\s+{model}\b" if lang == "c" else
|
|
889
|
+
rf"^\s*!\${model}\b")
|
|
890
|
+
while k < len(lines):
|
|
891
|
+
if re.match(pre, lines[k], re.I):
|
|
892
|
+
start, body = k, lines[k]
|
|
893
|
+
if lang == "c":
|
|
894
|
+
while body.rstrip().endswith("\\") and k + 1 < len(lines):
|
|
895
|
+
k += 1
|
|
896
|
+
body = body.rstrip()[:-1] + " " + lines[k]
|
|
897
|
+
body = re.sub(rf"^\s*#\s*pragma\s+{model}\s*", "", body,
|
|
898
|
+
flags=re.I)
|
|
899
|
+
else:
|
|
900
|
+
body = re.sub(rf"^\s*!\${model}&?\s*", "", body, flags=re.I)
|
|
901
|
+
while body.rstrip().endswith("&") and k + 1 < len(lines):
|
|
902
|
+
k += 1
|
|
903
|
+
nxt = re.sub(rf"^\s*!\${model}&?\s*", "", lines[k],
|
|
904
|
+
flags=re.I)
|
|
905
|
+
body = body.rstrip()[:-1] + " " + nxt.lstrip("&")
|
|
906
|
+
body = body.split("!")[0]
|
|
907
|
+
out.append((start + 1, k + 1, " ".join(body.lower().split())))
|
|
908
|
+
k += 1
|
|
909
|
+
return out
|
|
910
|
+
|
|
911
|
+
|
|
912
|
+
def _clause_args(d: str, name: str) -> list[str]:
|
|
913
|
+
out = []
|
|
914
|
+
for m in re.finditer(rf"\b{name}\s*\(", d):
|
|
915
|
+
depth, j = 1, m.end()
|
|
916
|
+
while j < len(d) and depth:
|
|
917
|
+
depth += {"(": 1, ")": -1}.get(d[j], 0)
|
|
918
|
+
j += 1
|
|
919
|
+
out.append(d[m.end():j - 1])
|
|
920
|
+
return out
|
|
921
|
+
|
|
922
|
+
|
|
923
|
+
def _split_top(s: str) -> list[str]:
|
|
924
|
+
out, depth, cur = [], 0, ""
|
|
925
|
+
for ch in s:
|
|
926
|
+
if ch == "," and depth == 0:
|
|
927
|
+
out.append(cur)
|
|
928
|
+
cur = ""
|
|
929
|
+
continue
|
|
930
|
+
depth += {"(": 1, ")": -1, "[": 1, "]": -1}.get(ch, 0)
|
|
931
|
+
cur += ch
|
|
932
|
+
out.append(cur)
|
|
933
|
+
return [x.strip() for x in out if x.strip()]
|
|
934
|
+
|
|
935
|
+
|
|
936
|
+
def _regions(text: str, lang: str, dirs: list, opener: str) -> list[tuple]:
|
|
937
|
+
"""(first, last) line ranges of the constructs whose directive starts
|
|
938
|
+
with `opener` (Fortran: up to the end directive or, for a loop
|
|
939
|
+
construct, the END DO of its loop; C: the following statement or
|
|
940
|
+
brace block)."""
|
|
941
|
+
lines = text.splitlines()
|
|
942
|
+
out = []
|
|
943
|
+
for first, last, d in dirs:
|
|
944
|
+
if not re.match(rf"^{opener}\b", d):
|
|
945
|
+
continue
|
|
946
|
+
if opener == "target" and re.match(
|
|
947
|
+
r"^target\s*(?:data|enter|exit|update)\b", d):
|
|
948
|
+
continue # a data construct or standalone: no region
|
|
949
|
+
if lang == "c":
|
|
950
|
+
out.append((first, _c_extent(lines, last)))
|
|
951
|
+
else:
|
|
952
|
+
out.append((first, _f_extent(lines, last, d)))
|
|
953
|
+
return out
|
|
954
|
+
|
|
955
|
+
|
|
956
|
+
def _c_extent(lines, last) -> int:
|
|
957
|
+
k = last # 0-based index of the line after the pragma
|
|
958
|
+
depth, seen = 0, False
|
|
959
|
+
while k < len(lines):
|
|
960
|
+
code = re.sub(r"//.*$", "", lines[k])
|
|
961
|
+
for ch in code:
|
|
962
|
+
if ch == "{":
|
|
963
|
+
depth += 1
|
|
964
|
+
seen = True
|
|
965
|
+
elif ch == "}":
|
|
966
|
+
depth -= 1
|
|
967
|
+
if seen and depth <= 0:
|
|
968
|
+
return k + 1
|
|
969
|
+
if not seen and code.strip().endswith(";") and depth == 0 and \
|
|
970
|
+
not code.strip().startswith(("for", "while", "if")):
|
|
971
|
+
return k + 1
|
|
972
|
+
k += 1
|
|
973
|
+
return len(lines)
|
|
974
|
+
|
|
975
|
+
|
|
976
|
+
# the words of a construct's name (a clause ends it: ``target map(...)`` is
|
|
977
|
+
# a target construct; the extent had run to the end of the file)
|
|
978
|
+
_CONSTRUCT_WORDS = {
|
|
979
|
+
"target", "teams", "distribute", "parallel", "do", "for", "simd", "loop",
|
|
980
|
+
"data", "task", "taskloop", "sections", "section", "single", "masked",
|
|
981
|
+
"master", "critical", "ordered", "atomic", "workshare", "scope",
|
|
982
|
+
"taskgroup", "kernels", "serial", "host_data", "workdistribute",
|
|
983
|
+
"enter", "exit", "update"}
|
|
984
|
+
|
|
985
|
+
|
|
986
|
+
def _construct_name(d: str) -> list[str]:
|
|
987
|
+
"""The leading words of a directive that name its construct."""
|
|
988
|
+
out = []
|
|
989
|
+
for w in re.split(r"[\s,(]+", d.strip()):
|
|
990
|
+
if w.lower() not in _CONSTRUCT_WORDS:
|
|
991
|
+
break
|
|
992
|
+
out.append(w.lower())
|
|
993
|
+
return out
|
|
994
|
+
|
|
995
|
+
|
|
996
|
+
def _f_extent(lines, last, d) -> int:
|
|
997
|
+
name = _construct_name(d) or d.split("(")[0].split()[:1]
|
|
998
|
+
head = " ".join(w for w in name[:4])
|
|
999
|
+
k = last
|
|
1000
|
+
if re.search(r"\b(?:do|loop|distribute|simd|taskloop)\b", head) and \
|
|
1001
|
+
not re.search(r"\b(?:data|update|enter|exit)\b", head):
|
|
1002
|
+
depth = 0
|
|
1003
|
+
while k < len(lines):
|
|
1004
|
+
s = lines[k].split("!")[0].strip().lower()
|
|
1005
|
+
if re.match(r"^(\w+\s*:\s*)?do\b", s):
|
|
1006
|
+
depth += 1
|
|
1007
|
+
elif re.match(r"^end\s*do\b", s) or re.match(r"^\d+\s+continue",
|
|
1008
|
+
s):
|
|
1009
|
+
depth -= 1
|
|
1010
|
+
if depth <= 0:
|
|
1011
|
+
return k + 1
|
|
1012
|
+
k += 1
|
|
1013
|
+
return len(lines)
|
|
1014
|
+
words = head.split()
|
|
1015
|
+
pat = re.compile(r"^\s*!\$(?:omp|acc)\s+end\s*" + r"\s*".join(
|
|
1016
|
+
re.escape(w) for w in words[:2]) + r"\b", re.I)
|
|
1017
|
+
while k < len(lines):
|
|
1018
|
+
if pat.match(lines[k]):
|
|
1019
|
+
return k + 1
|
|
1020
|
+
k += 1
|
|
1021
|
+
return len(lines)
|
|
1022
|
+
|
|
1023
|
+
|
|
1024
|
+
def extra(text: str, lang: str, tree=None) -> list[str]:
|
|
1025
|
+
"""The EXTRA restriction checks on one source: '<id>: <what> (<cite>)'
|
|
1026
|
+
for each violation."""
|
|
1027
|
+
out = []
|
|
1028
|
+
model = _model_of(text)
|
|
1029
|
+
if model == "omp":
|
|
1030
|
+
dirs = _directives(text, lang, "omp")
|
|
1031
|
+
out += _traits_constant(text, lang, dirs)
|
|
1032
|
+
out += _alloc_in_target(text, lang, dirs)
|
|
1033
|
+
if lang != "c":
|
|
1034
|
+
out += _module_variables(text, dirs)
|
|
1035
|
+
else:
|
|
1036
|
+
out += _acc_reduction(text, lang)
|
|
1037
|
+
return out
|
|
1038
|
+
|
|
1039
|
+
|
|
1040
|
+
def _cite(rid: str) -> str:
|
|
1041
|
+
return f"{rid}: " + "{} (" + EXTRA_CITES[rid] + ")"
|
|
1042
|
+
|
|
1043
|
+
|
|
1044
|
+
def _traits_constant(text, lang, dirs) -> list[str]:
|
|
1045
|
+
out = []
|
|
1046
|
+
for first, _, d in dirs:
|
|
1047
|
+
for arg in _clause_args(d, "uses_allocators"):
|
|
1048
|
+
if ":" in arg.split("(")[0]:
|
|
1049
|
+
continue # the 5.2 modifier form: offload.engine.rules
|
|
1050
|
+
for item in _split_top(arg):
|
|
1051
|
+
m = re.fullmatch(r"([a-z_]\w*)\s*\(\s*([a-z_]\w*)\s*\)", item)
|
|
1052
|
+
if not m:
|
|
1053
|
+
continue
|
|
1054
|
+
t = m.group(2)
|
|
1055
|
+
if lang == "c":
|
|
1056
|
+
const = re.search(rf"\bconst\b[^;]*\b{t}\s*\[", text,
|
|
1057
|
+
re.I)
|
|
1058
|
+
else:
|
|
1059
|
+
const = re.search(rf"\bparameter\b[^\n]*::[^\n]*\b{t}\b",
|
|
1060
|
+
text, re.I)
|
|
1061
|
+
if not const:
|
|
1062
|
+
out.append(_cite("uses-allocators-traits-constant")
|
|
1063
|
+
.format(f"line {first}: traits array {t} of "
|
|
1064
|
+
f"uses_allocators({item}) is not a "
|
|
1065
|
+
"constant array"))
|
|
1066
|
+
return out
|
|
1067
|
+
|
|
1068
|
+
|
|
1069
|
+
def _alloc_in_target(text, lang, dirs) -> list[str]:
|
|
1070
|
+
if any(re.match(r"^requires\b.*\bdynamic_allocators\b", d)
|
|
1071
|
+
for _, _, d in dirs):
|
|
1072
|
+
return []
|
|
1073
|
+
lines = text.splitlines()
|
|
1074
|
+
regions = _regions(text, lang, dirs, "target")
|
|
1075
|
+
out = []
|
|
1076
|
+
call = re.compile(r"\bomp_(aligned_alloc|alloc)\s*\(", re.I)
|
|
1077
|
+
for a, b in regions:
|
|
1078
|
+
body = "\n".join(lines[a:b])
|
|
1079
|
+
for m in call.finditer(body):
|
|
1080
|
+
depth, j = 1, m.end()
|
|
1081
|
+
while j < len(body) and depth:
|
|
1082
|
+
depth += {"(": 1, ")": -1}.get(body[j], 0)
|
|
1083
|
+
j += 1
|
|
1084
|
+
args = _split_top(body[m.end():j - 1].replace("\n", " ")
|
|
1085
|
+
.replace("&", " "))
|
|
1086
|
+
ln = a + body[:m.start()].count("\n") + 1
|
|
1087
|
+
if not args:
|
|
1088
|
+
continue
|
|
1089
|
+
alloc = args[-1].strip()
|
|
1090
|
+
why = []
|
|
1091
|
+
if not _PREDEFINED_ALLOC.match(alloc.lower()):
|
|
1092
|
+
why.append(f"allocator {alloc} is not a predefined "
|
|
1093
|
+
"allocator")
|
|
1094
|
+
if m.group(1).lower() == "aligned_alloc" and len(args) >= 3:
|
|
1095
|
+
al, size = args[0].strip(), args[1].strip()
|
|
1096
|
+
if al.isdigit() and (int(al) & (int(al) - 1)):
|
|
1097
|
+
why.append(f"alignment {al} is not a power of two")
|
|
1098
|
+
sz = re.fullmatch(r"(\d+)", size)
|
|
1099
|
+
if al.isdigit() and int(al) and (
|
|
1100
|
+
(sz and int(sz.group(1)) % int(al)) or
|
|
1101
|
+
(not sz and re.fullmatch(r"sizeof\s*\(\s*(int|float|"
|
|
1102
|
+
r"double|long|char)\s*\)",
|
|
1103
|
+
size) and int(al) > 8)):
|
|
1104
|
+
why.append(f"size {size} is not a multiple of the "
|
|
1105
|
+
f"alignment {al}")
|
|
1106
|
+
if why:
|
|
1107
|
+
out.append(_cite("alloc-in-target-predefined").format(
|
|
1108
|
+
f"line {ln}: omp_{m.group(1)} in a target region without"
|
|
1109
|
+
" requires dynamic_allocators: " + "; ".join(why)))
|
|
1110
|
+
return out
|
|
1111
|
+
|
|
1112
|
+
|
|
1113
|
+
def _module_variables(text, dirs) -> list[str]:
|
|
1114
|
+
"""Fortran: module variables referenced in a module procedure that is
|
|
1115
|
+
called in a target region (or declared target) without being in a
|
|
1116
|
+
declare target directive."""
|
|
1117
|
+
if any(re.match(r"^requires\b.*\bunified_shared_memory\b", d)
|
|
1118
|
+
for _, _, d in dirs):
|
|
1119
|
+
return []
|
|
1120
|
+
lines = text.splitlines()
|
|
1121
|
+
low = [ln.split("!")[0].lower() if not re.match(
|
|
1122
|
+
r"^\s*!\$omp", ln, re.I) else "" for ln in lines]
|
|
1123
|
+
# declare target lists (every form) and the procedures declared target
|
|
1124
|
+
declared, dt_procs = set(), set()
|
|
1125
|
+
for first, _, d in dirs:
|
|
1126
|
+
if not d.startswith("declare target"):
|
|
1127
|
+
continue
|
|
1128
|
+
rest = d[len("declare target"):]
|
|
1129
|
+
names = re.findall(r"[a-z_]\w*", re.sub(r"\b(?:to|enter|link|"
|
|
1130
|
+
r"device_type|indirect|"
|
|
1131
|
+
r"any|host|nohost)\b", " ",
|
|
1132
|
+
rest))
|
|
1133
|
+
declared |= set(names)
|
|
1134
|
+
if not names:
|
|
1135
|
+
dt_procs.add(first) # in a procedure's specification part
|
|
1136
|
+
out = []
|
|
1137
|
+
mods = list(re.finditer(r"^\s*module\s+(?!procedure\b)([a-z_]\w*)\s*$",
|
|
1138
|
+
"\n".join(low), re.M))
|
|
1139
|
+
for mm in mods:
|
|
1140
|
+
start = "\n".join(low)[:mm.start()].count("\n")
|
|
1141
|
+
end, contains = len(low), None
|
|
1142
|
+
for k in range(start + 1, len(low)):
|
|
1143
|
+
if re.match(r"^\s*end\s*module\b", low[k]):
|
|
1144
|
+
end = k
|
|
1145
|
+
break
|
|
1146
|
+
if contains is None and re.match(r"^\s*contains\s*$", low[k]):
|
|
1147
|
+
contains = k
|
|
1148
|
+
if contains is None:
|
|
1149
|
+
continue
|
|
1150
|
+
mvars = set()
|
|
1151
|
+
stmt = ""
|
|
1152
|
+
skip = 0 # inside a derived type definition or interface
|
|
1153
|
+
for k in range(start + 1, contains):
|
|
1154
|
+
s = low[k].strip()
|
|
1155
|
+
if not s:
|
|
1156
|
+
continue
|
|
1157
|
+
if re.match(r"^(?:abstract\s+)?interface\b", s) or re.match(
|
|
1158
|
+
r"^type\s*(?:,[^:]*)?(?:::)?\s*[a-z_]\w*\s*$", s) or \
|
|
1159
|
+
re.match(r"^type\s*,", s) and "::" in s and "(" not in \
|
|
1160
|
+
s.split("::")[0].replace("extends(", "").replace(
|
|
1161
|
+
"bind(", ""):
|
|
1162
|
+
skip += 1
|
|
1163
|
+
continue
|
|
1164
|
+
if re.match(r"^end\s*(?:type|interface)\b", s):
|
|
1165
|
+
skip = max(0, skip - 1)
|
|
1166
|
+
continue
|
|
1167
|
+
if skip:
|
|
1168
|
+
continue
|
|
1169
|
+
stmt = (stmt + " " + s.rstrip("&")) if stmt else s.rstrip("&")
|
|
1170
|
+
if s.endswith("&"):
|
|
1171
|
+
continue
|
|
1172
|
+
s, stmt = stmt, ""
|
|
1173
|
+
m = re.match(r"^(integer|real|double\s*precision|logical|"
|
|
1174
|
+
r"complex|character|type\s*\(|class\s*\()", s)
|
|
1175
|
+
if not m or "parameter" in s.split("::")[0]:
|
|
1176
|
+
continue
|
|
1177
|
+
ents = s.split("::", 1)[1] if "::" in s else s[m.end():]
|
|
1178
|
+
ents = re.sub(r"\([^()]*(?:\([^()]*\)[^()]*)*\)", "", ents)
|
|
1179
|
+
ents = re.sub(r"=[^,]*", "", ents)
|
|
1180
|
+
mvars |= {e.strip() for e in ents.split(",")
|
|
1181
|
+
if re.fullmatch(r"[a-z_]\w*", e.strip())}
|
|
1182
|
+
mvars -= declared
|
|
1183
|
+
if not mvars:
|
|
1184
|
+
continue
|
|
1185
|
+
# module procedures
|
|
1186
|
+
procs = []
|
|
1187
|
+
k = contains + 1
|
|
1188
|
+
while k < end:
|
|
1189
|
+
m = re.match(r"^\s*(?:(?:pure|elemental|recursive|impure|"
|
|
1190
|
+
r"module)\s+)*(?:[a-z0-9_*()]+\s+)*?(subroutine|"
|
|
1191
|
+
r"function)\s+([a-z_]\w*)\s*(\(([^)]*)\))?",
|
|
1192
|
+
low[k])
|
|
1193
|
+
if m:
|
|
1194
|
+
kind, name = m.group(1), m.group(2)
|
|
1195
|
+
args = {a.strip() for a in (m.group(4) or "").split(",")}
|
|
1196
|
+
j = k + 1
|
|
1197
|
+
while j < end and not re.match(
|
|
1198
|
+
rf"^\s*end\s*{kind}\b", low[j]) and not (
|
|
1199
|
+
re.match(r"^\s*end\s*$", low[j])):
|
|
1200
|
+
j += 1
|
|
1201
|
+
procs.append((name, k, j, args))
|
|
1202
|
+
k = j
|
|
1203
|
+
k += 1
|
|
1204
|
+
target_lines = [ab for ab in _regions(text, "f90", dirs, "target")]
|
|
1205
|
+
for name, a, b, args in procs:
|
|
1206
|
+
called = any(re.search(rf"\b(?:call\s+)?{name}\s*\(",
|
|
1207
|
+
"\n".join(low[x:y])) for x, y in
|
|
1208
|
+
target_lines)
|
|
1209
|
+
marked = any(a < ln - 1 < b for ln in dt_procs)
|
|
1210
|
+
if not (called or marked):
|
|
1211
|
+
continue
|
|
1212
|
+
body = "\n".join(low[a + 1:b])
|
|
1213
|
+
local = set()
|
|
1214
|
+
for s in body.splitlines():
|
|
1215
|
+
if "::" in s and re.match(r"^\s*(integer|real|double|"
|
|
1216
|
+
r"logical|complex|character|"
|
|
1217
|
+
r"type|class)", s):
|
|
1218
|
+
ents = re.sub(r"\([^()]*(?:\([^()]*\)[^()]*)*\)", "",
|
|
1219
|
+
s.split("::", 1)[1])
|
|
1220
|
+
local |= {e.strip().split("=")[0].strip()
|
|
1221
|
+
for e in ents.split(",")}
|
|
1222
|
+
# names, not components (s%c)
|
|
1223
|
+
ident = r"(?<![%\w])([a-z_]\w*)\b"
|
|
1224
|
+
used = set(re.findall(ident, body)) | (
|
|
1225
|
+
set(re.findall(ident, low[a])) - {name} - args)
|
|
1226
|
+
bad = sorted((used & mvars) - local - args)
|
|
1227
|
+
if bad:
|
|
1228
|
+
out.append(_cite("declare-target-module-variable").format(
|
|
1229
|
+
f"line {a + 1}: {name} ({'called in a target region' if called else 'declare target'}) "
|
|
1230
|
+
f"references the module variables {', '.join(bad)}, "
|
|
1231
|
+
"which no declare target directive names"))
|
|
1232
|
+
return out
|
|
1233
|
+
|
|
1234
|
+
|
|
1235
|
+
_ACC_DATA = ("copy", "copyin", "copyout", "create", "present", "no_create",
|
|
1236
|
+
"deviceptr", "attach", "pcopy", "pcopyin", "pcopyout",
|
|
1237
|
+
"pcreate", "present_or_copy", "present_or_copyin",
|
|
1238
|
+
"present_or_copyout", "present_or_create")
|
|
1239
|
+
|
|
1240
|
+
|
|
1241
|
+
def _names_in(d: str, clauses) -> set:
|
|
1242
|
+
out = set()
|
|
1243
|
+
for c in clauses:
|
|
1244
|
+
for arg in _clause_args(d, c):
|
|
1245
|
+
arg = re.sub(r"^\s*(?:readonly|zero)\s*:", "", arg)
|
|
1246
|
+
arg = re.sub(r"^[^:()]*:", "", arg) if c in (
|
|
1247
|
+
"reduction",) else arg
|
|
1248
|
+
for item in _split_top(arg):
|
|
1249
|
+
m = re.match(r"([a-z_]\w*)", item.strip())
|
|
1250
|
+
if m:
|
|
1251
|
+
out.add(m.group(1))
|
|
1252
|
+
return out
|
|
1253
|
+
|
|
1254
|
+
|
|
1255
|
+
def _acc_reduction(text, lang) -> list[str]:
|
|
1256
|
+
dirs = _directives(text, lang, "acc")
|
|
1257
|
+
lines = text.splitlines()
|
|
1258
|
+
computes = [] # (first, last, directive)
|
|
1259
|
+
for first, last, d in dirs:
|
|
1260
|
+
if re.match(r"^(parallel|serial)\b(?!\s+loop)", d):
|
|
1261
|
+
ext = _c_extent(lines, last) if lang == "c" else \
|
|
1262
|
+
_f_extent(lines, last, d)
|
|
1263
|
+
computes.append((first, ext, d))
|
|
1264
|
+
datas = []
|
|
1265
|
+
for first, last, d in dirs:
|
|
1266
|
+
if re.match(r"^(data|declare|enter data)\b", d):
|
|
1267
|
+
ext = (_c_extent(lines, last) if lang == "c" else
|
|
1268
|
+
_f_extent(lines, last, d)) if d.startswith("data") \
|
|
1269
|
+
else len(lines)
|
|
1270
|
+
datas.append((first, ext, d))
|
|
1271
|
+
out = []
|
|
1272
|
+
for first, _, d in dirs:
|
|
1273
|
+
if not re.match(r"^loop\b", d) or "reduction" not in d:
|
|
1274
|
+
continue
|
|
1275
|
+
parent = [c for c in computes if c[0] < first <= c[1]]
|
|
1276
|
+
if not parent:
|
|
1277
|
+
continue
|
|
1278
|
+
cf, cl, cd = max(parent, key=lambda c: c[0])
|
|
1279
|
+
visible = _names_in(cd, _ACC_DATA + ("firstprivate", "private",
|
|
1280
|
+
"reduction"))
|
|
1281
|
+
for a, b, dd in datas:
|
|
1282
|
+
if a <= cf <= b:
|
|
1283
|
+
visible |= _names_in(dd, _ACC_DATA)
|
|
1284
|
+
for v in sorted(_names_in(d, ("reduction",)) - visible):
|
|
1285
|
+
if _is_array(text, v, lang):
|
|
1286
|
+
continue
|
|
1287
|
+
out.append(_cite("acc-loop-reduction-data-clause").format(
|
|
1288
|
+
f"line {first}: {v} is in a loop reduction inside the "
|
|
1289
|
+
f"compute construct of line {cf} with no data clause for it"
|
|
1290
|
+
" there"))
|
|
1291
|
+
return out
|
|
1292
|
+
|
|
1293
|
+
|
|
1294
|
+
def _is_array(text, v, lang) -> bool:
|
|
1295
|
+
if lang == "c":
|
|
1296
|
+
return re.search(rf"\b{v}\s*\[", text) is not None
|
|
1297
|
+
for s in text.lower().splitlines():
|
|
1298
|
+
if "::" in s and re.search(rf"\b{v}\b", s.split("::", 1)[1]):
|
|
1299
|
+
if "dimension" in s.split("::")[0] or re.search(
|
|
1300
|
+
rf"\b{v}\s*\(", s.split("::", 1)[1]):
|
|
1301
|
+
return True
|
|
1302
|
+
return False
|
|
1303
|
+
|
|
1304
|
+
|
|
1305
|
+
# --- witness 2: the front end -----------------------------------------------------------
|
|
1306
|
+
|
|
1307
|
+
def openacc_stub(texts) -> str:
|
|
1308
|
+
"""A declarations-only Fortran ``openacc`` module for the front end
|
|
1309
|
+
(AFAR flang has no openacc.mod: "OpenACC is NOT supported for
|
|
1310
|
+
AMDGPU"), with the names of the OpenACC API the program uses: device
|
|
1311
|
+
kinds as named constants, acc_on_device / acc_is_present as logical
|
|
1312
|
+
functions, acc_get_* as integer functions, the other routines as
|
|
1313
|
+
external procedures. Base-language declarations only; the directives
|
|
1314
|
+
are what the front end checks."""
|
|
1315
|
+
names = set()
|
|
1316
|
+
for t in texts:
|
|
1317
|
+
names |= {n.lower() for n in re.findall(r"\b(acc_\w+)", t, re.I)}
|
|
1318
|
+
lines = ["module openacc", " implicit none",
|
|
1319
|
+
" integer, parameter :: acc_device_kind = 4",
|
|
1320
|
+
" integer, parameter :: acc_handle_kind = 4"]
|
|
1321
|
+
k = 0
|
|
1322
|
+
for n in sorted(names):
|
|
1323
|
+
if n in ("acc_device_kind", "acc_handle_kind"):
|
|
1324
|
+
continue
|
|
1325
|
+
if n in ("acc_on_device", "acc_is_present", "acc_async_test",
|
|
1326
|
+
"acc_async_test_all", "acc_async_test_device",
|
|
1327
|
+
"acc_async_test_all_device"):
|
|
1328
|
+
lines.append(f" logical, external :: {n}")
|
|
1329
|
+
elif n.startswith(("acc_device_", "acc_async_", "acc_property_")):
|
|
1330
|
+
lines.append(f" integer(acc_device_kind), parameter :: {n} "
|
|
1331
|
+
f"= {k}")
|
|
1332
|
+
k += 1
|
|
1333
|
+
elif n in ("acc_on_device", "acc_is_present", "acc_async_test",
|
|
1334
|
+
"acc_async_test_all"):
|
|
1335
|
+
lines.append(f" logical, external :: {n}")
|
|
1336
|
+
elif n.startswith(("acc_get_", "acc_deviceptr", "acc_hostptr")):
|
|
1337
|
+
lines.append(f" integer, external :: {n}")
|
|
1338
|
+
else:
|
|
1339
|
+
lines.append(f" external :: {n}")
|
|
1340
|
+
return "\n".join(lines + ["end module openacc", ""])
|
|
1341
|
+
|
|
1342
|
+
def frontend_witness(program, timeout_s: int = 600
|
|
1343
|
+
) -> tuple[bool | None, list[str]]:
|
|
1344
|
+
"""(accepted, reasons) of the flang or clang front end; None when it
|
|
1345
|
+
cannot run here (no AFAR install, or a checker failure)."""
|
|
1346
|
+
from offload.engine import harness
|
|
1347
|
+
from offload.engine.toolchains import AFAR_BIN
|
|
1348
|
+
files, lang, model, version = _files_of(program)
|
|
1349
|
+
tool = f"{AFAR_BIN}/amdclang" if lang == "c" else f"{AFAR_BIN}/amdflang"
|
|
1350
|
+
if not Path(tool).exists():
|
|
1351
|
+
return None, [f"frontend: {Path(tool).name} not installed here"]
|
|
1352
|
+
flag = "-fopenacc" if model == "acc" else \
|
|
1353
|
+
f"-fopenmp -fopenmp-version={version if version != 34 else 52}"
|
|
1354
|
+
std = "-std=c11 " if lang == "c" else ""
|
|
1355
|
+
with tempfile.TemporaryDirectory(prefix="prerun_") as d:
|
|
1356
|
+
for name, text in files:
|
|
1357
|
+
(Path(d) / name).write_text(text)
|
|
1358
|
+
order = [n for n, _ in files]
|
|
1359
|
+
if model == "acc" and lang != "c" and not any(
|
|
1360
|
+
re.search(r"^\s*module\s+openacc\b", t, re.I | re.M)
|
|
1361
|
+
for _, t in files):
|
|
1362
|
+
(Path(d) / "openacc_stub.f90").write_text(
|
|
1363
|
+
openacc_stub([t for _, t in files]))
|
|
1364
|
+
order.insert(0, "openacc_stub.f90")
|
|
1365
|
+
for name in order:
|
|
1366
|
+
if not name.endswith((".c", ".f90", ".F90")):
|
|
1367
|
+
continue
|
|
1368
|
+
ex = harness._execute(f"ulimit -c 0\n{tool} {std}{flag} "
|
|
1369
|
+
f"-fsyntax-only {name}\n", Path(d),
|
|
1370
|
+
timeout_s, merge=True)
|
|
1371
|
+
if ex.timed_out:
|
|
1372
|
+
return None, [f"frontend: {name}: timed out"]
|
|
1373
|
+
if ex.rc != 0:
|
|
1374
|
+
errs = [ln for ln in ex.stdout.splitlines()
|
|
1375
|
+
if re.search(r":\d+:\d+: error:", ln)] or \
|
|
1376
|
+
[ln for ln in ex.stdout.splitlines()
|
|
1377
|
+
if re.search(r"\berror:", ln)]
|
|
1378
|
+
return False, [f"frontend: {name}: " + (
|
|
1379
|
+
errs[0] if errs else ex.stdout.strip()[:300]).strip()]
|
|
1380
|
+
return True, []
|
|
1381
|
+
|
|
1382
|
+
|
|
1383
|
+
# --- the check ---------------------------------------------------------------------------
|
|
1384
|
+
|
|
1385
|
+
def check(program, frontend: bool = True,
|
|
1386
|
+
timeout_s: int = 600) -> tuple[bool, list[str]]:
|
|
1387
|
+
"""(ok, reasons): ok only when both witnesses accept and the race rule
|
|
1388
|
+
finds nothing (see the module docstring). `frontend` False skips the
|
|
1389
|
+
second witness (then ok is always False: one witness is not
|
|
1390
|
+
enough), for callers that only want the rules' reasons."""
|
|
1391
|
+
r_ok, r_why = rules_witness(program)
|
|
1392
|
+
if frontend:
|
|
1393
|
+
f_ok, f_why = frontend_witness(program, timeout_s)
|
|
1394
|
+
else:
|
|
1395
|
+
f_ok, f_why = None, ["frontend: not run"]
|
|
1396
|
+
reasons = list(r_why) + [w for w in f_why if f_ok is False]
|
|
1397
|
+
if r_ok is None or f_ok is None:
|
|
1398
|
+
reasons += [w for w in (r_why if r_ok is None else []) +
|
|
1399
|
+
(f_why if f_ok is None else []) if w not in reasons]
|
|
1400
|
+
reasons.append("witness unavailable: legality needs two witnesses")
|
|
1401
|
+
return False, reasons
|
|
1402
|
+
if r_ok != f_ok:
|
|
1403
|
+
reasons.append("witnesses disagree (rules "
|
|
1404
|
+
f"{'accept' if r_ok else 'reject'}, front end "
|
|
1405
|
+
f"{'accepts' if f_ok else 'rejects'}): legality "
|
|
1406
|
+
"review")
|
|
1407
|
+
if r_ok and not f_ok:
|
|
1408
|
+
reasons.append(FRONTEND_ONLY)
|
|
1409
|
+
return bool(r_ok and f_ok), reasons
|
|
1410
|
+
|
|
1411
|
+
|
|
1412
|
+
FRONTEND_ONLY = ("front end alone refuses: a candidate AFAR front-end "
|
|
1413
|
+
"defect (the rules accept)")
|
|
1414
|
+
|
|
1415
|
+
|
|
1416
|
+
def refusal_kind(reasons) -> str:
|
|
1417
|
+
"""The kind of a pre-run refusal from its reasons: ``frontend_only``
|
|
1418
|
+
(a candidate AFAR front-end defect), ``unreadable`` (the rules cannot
|
|
1419
|
+
read the program), ``witness_unavailable``, ``rules`` (a restriction
|
|
1420
|
+
rule), ``race``, ``restriction`` (EXTRA), ``frontend`` (both refuse),
|
|
1421
|
+
``other``."""
|
|
1422
|
+
text = reasons if isinstance(reasons, str) else "; ".join(reasons)
|
|
1423
|
+
if FRONTEND_ONLY in text:
|
|
1424
|
+
return "frontend_only"
|
|
1425
|
+
if "rules: cannot read it" in text:
|
|
1426
|
+
return "unreadable"
|
|
1427
|
+
if "witness unavailable" in text:
|
|
1428
|
+
return "witness_unavailable"
|
|
1429
|
+
for k in ("rules: violates", "race:", "restriction:"):
|
|
1430
|
+
if k in text:
|
|
1431
|
+
return {"rules: violates": "rules", "race:": "race",
|
|
1432
|
+
"restriction:": "restriction"}[k]
|
|
1433
|
+
if "frontend" in text or "front end" in text:
|
|
1434
|
+
return "frontend"
|
|
1435
|
+
return "other"
|