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.
Files changed (886) hide show
  1. offload/__init__.py +10 -0
  2. offload/__main__.py +5 -0
  3. offload/_bundle.py +74 -0
  4. offload/_root/catalog/acc/claims.yaml +197 -0
  5. offload/_root/catalog/acc/clauses.yaml +391 -0
  6. offload/_root/catalog/acc/no_oracle.yaml +89 -0
  7. offload/_root/catalog/acc/out_of_scope.yaml +17 -0
  8. offload/_root/catalog/acc/rules.yaml +433 -0
  9. offload/_root/catalog/acc/semantic_atoms.yaml +27 -0
  10. offload/_root/catalog/acc/skeleton.yaml +1567 -0
  11. offload/_root/catalog/acc/spec_overrides.yaml +72 -0
  12. offload/_root/catalog/later_forms.yaml +76 -0
  13. offload/_root/catalog/machines.yaml +218 -0
  14. offload/_root/catalog/omp/claims.yaml +2047 -0
  15. offload/_root/catalog/omp/clauses.yaml +914 -0
  16. offload/_root/catalog/omp/derivations.yaml +177 -0
  17. offload/_root/catalog/omp/memory_modes.yaml +40 -0
  18. offload/_root/catalog/omp/no_oracle.yaml +373 -0
  19. offload/_root/catalog/omp/omp50_delta.yaml +377 -0
  20. offload/_root/catalog/omp/out_of_scope.yaml +64 -0
  21. offload/_root/catalog/omp/port_equivalence.yaml +352 -0
  22. offload/_root/catalog/omp/rules.yaml +3131 -0
  23. offload/_root/catalog/omp/rules_coverage.yaml +9939 -0
  24. offload/_root/catalog/omp/semantic_atoms.yaml +34 -0
  25. offload/_root/catalog/omp/skeleton.yaml +9181 -0
  26. offload/_root/catalog/omp/spec_overrides.yaml +932 -0
  27. offload/_root/catalog/toolchains.yaml +472 -0
  28. offload/_root/catalog/vendor_claims_generic.yaml +40925 -0
  29. offload/_root/data/canuse/b.json +1 -0
  30. offload/_root/data/canuse/c.json +1 -0
  31. offload/_root/data/canuse/columns.json +1 -0
  32. offload/_root/data/canuse/d.json +1 -0
  33. offload/_root/data/canuse/f.json +1 -0
  34. offload/_root/data/canuse/index.json +1 -0
  35. offload/_root/data/canuse/p.json +1 -0
  36. offload/_root/data/compilers/afar.json +1 -0
  37. offload/_root/data/compilers/cce19.json +1 -0
  38. offload/_root/data/compilers/cce20.json +1 -0
  39. offload/_root/data/compilers/cce21.json +1 -0
  40. offload/_root/data/compilers/cce21_4.json +1 -0
  41. offload/_root/data/compilers/gcc.json +1 -0
  42. offload/_root/data/compilers/gcc_sm80.json +1 -0
  43. offload/_root/data/compilers/nvhpc.json +1 -0
  44. offload/_root/data/compilers/nvhpc269.json +1 -0
  45. offload/_root/data/findings/AUTHORING.md +107 -0
  46. offload/_root/data/findings/README.md +33 -0
  47. offload/_root/data/findings/afar-c-error-directive-in-target-link.c +37 -0
  48. offload/_root/data/findings/afar-c-lastprivate-distribute-parallel-for-small-type.c +56 -0
  49. offload/_root/data/findings/afar-c-teams-distribute-reduction-first-team.c +59 -0
  50. offload/_root/data/findings/afar-c-update-iterator-copy-mode.c +45 -0
  51. offload/_root/data/findings/afar-c-xnack1-target-is-present.c +31 -0
  52. offload/_root/data/findings/afar-cce19-character-defaultmap.f90 +27 -0
  53. offload/_root/data/findings/afar-cce19-task-in-target-ice.f90 +23 -0
  54. offload/_root/data/findings/afar-clang-requires-device-safesync-hang.c +24 -0
  55. offload/_root/data/findings/afar-flang-firstprivate-map-two-targets.f90 +34 -0
  56. offload/_root/data/findings/afar-flang-loop-bind-teams-reduction.f90 +27 -0
  57. offload/_root/data/findings/afar-flang-task-reduction-max.f90 +31 -0
  58. offload/_root/data/findings/afar-flang-thread-limit-target-parallel-do.f90 +22 -0
  59. offload/_root/data/findings/afar-linear-ref-omp50.f90 +29 -0
  60. offload/_root/data/findings/afar-loop-bind-thread-in-teams.f90 +44 -0
  61. offload/_root/data/findings/afar-nontemporal-assumed-shape-ice.f90 +38 -0
  62. offload/_root/data/findings/afar-udr-derived-type-link.f90 +41 -0
  63. offload/_root/data/findings/afar-xnack1-atomic-min-nested-parallel.f90 +53 -0
  64. offload/_root/data/findings/afar-xnack1-present-not-enforced.f90 +36 -0
  65. offload/_root/data/findings/afar-xnack1-target-is-present.f90 +47 -0
  66. offload/_root/data/findings/apps/afar-cce-teams-private-array-nested-parallel-wrong.f90 +100 -0
  67. offload/_root/data/findings/apps/cce20-device-link-infer-address-spaces-crash.f90 +159 -0
  68. offload/_root/data/findings/apps/cce21-device-link-agpr-copy-mfma-assert.f90 +343 -0
  69. offload/_root/data/findings/apps/cce21-private-array-loaded-subscript-wrong.f90 +113 -0
  70. offload/_root/data/findings/apps/controls/bubble-simple-rddot.f90 +284 -0
  71. offload/_root/data/findings/apps/controls/bubble-two-substeps.f90 +287 -0
  72. offload/_root/data/findings/apps/controls/cbc-inline.f90 +97 -0
  73. offload/_root/data/findings/apps/controls/cbc-integers.f90 +91 -0
  74. offload/_root/data/findings/apps/controls/cbc-only-density.f90 +97 -0
  75. offload/_root/data/findings/apps/controls/cbc-only-velocity.f90 +97 -0
  76. offload/_root/data/findings/apps/controls/gcc-acc-c-tile-control.c +26 -0
  77. offload/_root/data/findings/apps/controls/gcc-acc-tile-control.f90 +29 -0
  78. offload/_root/data/findings/apps/controls/private-array-subscript-probes.f90 +45 -0
  79. offload/_root/data/findings/apps/controls/teams-private-array-read-par.f90 +31 -0
  80. offload/_root/data/findings/apps/controls/teams-private-array-seq.f90 +30 -0
  81. offload/_root/data/findings/apps/controls/teams-private-array-shared.f90 +34 -0
  82. offload/_root/data/findings/apps/controls/teams-private-array-split.f90 +36 -0
  83. offload/_root/data/findings/apps/controls/teams-private-array-write-par.f90 +31 -0
  84. offload/_root/data/findings/apps/gcc-acc-c-tile-partial-tiles-wrong.c +60 -0
  85. offload/_root/data/findings/apps/gcc-acc-tile-partial-tiles-wrong.f90 +64 -0
  86. offload/_root/data/findings/catalog/afar-c-complex-reduction-link.c +66 -0
  87. offload/_root/data/findings/catalog/afar-c-critical-hint-link.c +68 -0
  88. offload/_root/data/findings/catalog/afar-c-ordered-doacross-link.c +62 -0
  89. offload/_root/data/findings/catalog/afar-c-reduction-task-link.c +81 -0
  90. offload/_root/data/findings/catalog/afar-flang-absent-optional-target-crash.f90 +76 -0
  91. offload/_root/data/findings/catalog/afar-flang-critical-target-parallel-wrong.f90 +74 -0
  92. offload/_root/data/findings/catalog/afar-flang-dist-schedule-chunk.f90 +80 -0
  93. offload/_root/data/findings/catalog/afar-flang-linear-parallel-ice.f90 +68 -0
  94. offload/_root/data/findings/catalog/afar-flang-named-critical-link.f90 +67 -0
  95. offload/_root/data/findings/catalog/afar-flang-ordered-wrong.f90 +78 -0
  96. offload/_root/data/findings/catalog/afar-flang-reduction-minus-rejected.f90 +77 -0
  97. offload/_root/data/findings/catalog/afar-flang-reduction-task-ice.f90 +68 -0
  98. offload/_root/data/findings/catalog/afar-flang-sections-in-target-ice.f90 +67 -0
  99. offload/_root/data/findings/catalog/afar-flang-workdistribute-ice.f90 +71 -0
  100. offload/_root/data/findings/catalog/c-allocate-const-mem-firstprivate-wrong.c +79 -0
  101. offload/_root/data/findings/catalog/cce-acc-allocate-in-compute-crash.f90 +65 -0
  102. offload/_root/data/findings/catalog/cce-acc-character-dummy-routine-ice.f90 +81 -0
  103. offload/_root/data/findings/catalog/cce-acc-loop-seq-in-routine-wrong.f90 +81 -0
  104. offload/_root/data/findings/catalog/cce-acc-stop-in-compute-crash.f90 +62 -0
  105. offload/_root/data/findings/catalog/cce-allocators-stack-ice.f90 +81 -0
  106. offload/_root/data/findings/catalog/cce-atomic-default-mem-order-acquire-release-rejected.f90 +61 -0
  107. offload/_root/data/findings/catalog/cce-c-allocate-align-link.c +83 -0
  108. offload/_root/data/findings/catalog/cce-c-allocate-allocator-modifier-rejected.c +77 -0
  109. offload/_root/data/findings/catalog/cce-c-device-type-directive-name-ice.c +70 -0
  110. offload/_root/data/findings/catalog/cce-c-dist-schedule-chunk.c +81 -0
  111. offload/_root/data/findings/catalog/cce-c-f-pointer-device-link.f90 +70 -0
  112. offload/_root/data/findings/catalog/cce-c-lastprivate-parallel-in-seq-loop-wrong.c +64 -0
  113. offload/_root/data/findings/catalog/cce-c-long-double-ice.c +61 -0
  114. offload/_root/data/findings/catalog/cce-c-map-iterator-ice.c +92 -0
  115. offload/_root/data/findings/catalog/cce-c-motion-iterator-rejected.c +68 -0
  116. offload/_root/data/findings/catalog/cce-c-ordered-doacross-link.c +64 -0
  117. offload/_root/data/findings/catalog/cce-c-ordered-link.c +77 -0
  118. offload/_root/data/findings/catalog/cce-c-recursive-function-ice.c +62 -0
  119. offload/_root/data/findings/catalog/cce-c-reduction-inscan-ice.c +67 -0
  120. offload/_root/data/findings/catalog/cce-c-reduction-task-link.c +73 -0
  121. offload/_root/data/findings/catalog/cce-c-sections-in-target-wrong.c +70 -0
  122. offload/_root/data/findings/catalog/cce-c-single-masked-task-link.c +66 -0
  123. offload/_root/data/findings/catalog/cce-c-task-in-target-link.c +75 -0
  124. offload/_root/data/findings/catalog/cce-c-uses-allocators-traits-rejected.c +71 -0
  125. offload/_root/data/findings/catalog/cce-flang-allocate-const-mem-ice.f90 +67 -0
  126. offload/_root/data/findings/catalog/cce-flang-allocate-in-target-crash.f90 +68 -0
  127. offload/_root/data/findings/catalog/cce-flang-lastprivate-parallel-in-seq-loop-wrong.f90 +83 -0
  128. offload/_root/data/findings/catalog/cce-flang-stop-in-target-crash.f90 +64 -0
  129. offload/_root/data/findings/catalog/cce-iterator-link.f90 +67 -0
  130. offload/_root/data/findings/catalog/cce-linear-lastprivate-ice.f90 +69 -0
  131. offload/_root/data/findings/catalog/cce-nohost-link.f90 +90 -0
  132. offload/_root/data/findings/catalog/cce-reduction-inscan-ice.f90 +66 -0
  133. offload/_root/data/findings/catalog/cce-reduction-task-link.f90 +76 -0
  134. offload/_root/data/findings/catalog/cce19-reduction-task-addrspacecast-ice.f90 +77 -0
  135. offload/_root/data/findings/catalog/cce20-c-defaultmap-private-storage-rejected.c +85 -0
  136. offload/_root/data/findings/catalog/cce20-map-self-rejected.f90 +64 -0
  137. offload/_root/data/findings/catalog/cce21-c-declare-target-local-rejected.c +73 -0
  138. offload/_root/data/findings/catalog/cce21-c-target-loop-ice.c +77 -0
  139. offload/_root/data/findings/catalog/defaultmap-present-private-array-abort.f90 +73 -0
  140. offload/_root/data/findings/catalog/nvhpc-acc-associate-illegal-address.f90 +66 -0
  141. offload/_root/data/findings/catalog/nvhpc-c-function-pointer-kernel-missing.c +68 -0
  142. offload/_root/data/findings/catalog/nvhpc-c-long-double-kernel-missing.c +64 -0
  143. offload/_root/data/findings/catalog/nvhpc-c-static-local-kernel-missing.c +73 -0
  144. offload/_root/data/findings/catalog/nvhpc-c-vla-kernel-missing.c +63 -0
  145. offload/_root/data/findings/catalog/nvhpc-flang-type-bound-kernel-missing.f90 +86 -0
  146. offload/_root/data/findings/cce-acc-init-set-runtime-assert.f90 +35 -0
  147. offload/_root/data/findings/cce-acc-reduction-200-int8-scalars-wrong.f90 +1278 -0
  148. offload/_root/data/findings/cce-acc-routine-bind-module-ice.f90 +35 -0
  149. offload/_root/data/findings/cce-acc-self-condition-ignored.f90 +17 -0
  150. offload/_root/data/findings/cce-c-dist-schedule-segv.c +34 -0
  151. offload/_root/data/findings/cce-c-map-delete-refcount.c +47 -0
  152. offload/_root/data/findings/cce-c-map-present-assert.c +45 -0
  153. offload/_root/data/findings/cce-c-openmp45-device-link.c +34 -0
  154. offload/_root/data/findings/cce-c-parallel-for-in-target.c +73 -0
  155. offload/_root/data/findings/cce-defaultmap-tofrom-explicit-map.f90 +92 -0
  156. offload/_root/data/findings/cce-mapper-next-map-copy-back.f90 +48 -0
  157. offload/_root/data/findings/cce-trim-merge-output-one-character.f90 +40 -0
  158. offload/_root/data/findings/cce-uses-allocators-traits-omp50.f90 +28 -0
  159. offload/_root/data/findings/cce19-acc-if-false-link.f90 +17 -0
  160. offload/_root/data/findings/cce19-c-reduction-63-scalars-one-wrong.c +235 -0
  161. offload/_root/data/findings/cce19-target-parallel-guarded-loop.f90 +35 -0
  162. offload/_root/data/findings/cce19-target-parallel-single-ice.f90 +38 -0
  163. offload/_root/data/findings/cce21-alloc-2e32-sum-wrong.f90 +68 -0
  164. offload/_root/data/findings/cce21-defaultmap-aggregate-flag.f90 +52 -0
  165. offload/_root/data/findings/cce21-in-reduction-assumed-shape-write-lost.f90 +61 -0
  166. offload/_root/data/findings/cce21-in-reduction-taskwait-link.f90 +59 -0
  167. offload/_root/data/findings/cce21-linear-modifier-default-none.f90 +59 -0
  168. offload/_root/data/findings/clang-c-declare-target-to-omp52.c +50 -0
  169. offload/_root/data/findings/clang-c-linear-directive-name-hang.c +30 -0
  170. offload/_root/data/findings/clang-c-map-iterator-omp51.c +51 -0
  171. offload/_root/data/findings/clang-c-shared-declare-target-combined.c +58 -0
  172. offload/_root/data/findings/dataenv/cce-value-dummy-target-write-visible.f90 +74 -0
  173. offload/_root/data/findings/defaultmap-none-loop-variable.f90 +69 -0
  174. offload/_root/data/findings/fortran-loop-bind-thread-in-parallel.f90 +53 -0
  175. offload/_root/data/findings/fortran-schedule-static-in-target.f90 +55 -0
  176. offload/_root/data/findings/fresh/cce-common-block-name-in-map-rejected.f90 +47 -0
  177. offload/_root/data/findings/fresh/cce-if-stop-in-target-ice-one-condition.f90 +38 -0
  178. offload/_root/data/findings/fresh/cce-if-stop-in-target-ice.f90 +43 -0
  179. offload/_root/data/findings/fresh/cce-list-directed-print-in-target-copy-crash.f90 +40 -0
  180. offload/_root/data/findings/fresh/cce19-acc-automatic-array-copyout-copy-crash.f90 +56 -0
  181. offload/_root/data/findings/fresh/cce21-combined-if-runtime-expr-loop-skipped.f90 +57 -0
  182. offload/_root/data/findings/fresh/nvhpc-acc-gang-worker-collapse-nested-vector-reduction-lost.f90 +67 -0
  183. offload/_root/data/findings/fresh/nvhpc-teams-loop-module-allocatable-assign-fort2-crash.f90 +73 -0
  184. offload/_root/data/findings/fuzz/1131-afar.f90 +48 -0
  185. offload/_root/data/findings/fuzz/1391-cce20.f90 +40 -0
  186. offload/_root/data/findings/fuzz/14-cce20.f90 +36 -0
  187. offload/_root/data/findings/fuzz/1505-cce20.f90 +88 -0
  188. offload/_root/data/findings/fuzz/1540-afar.f90 +44 -0
  189. offload/_root/data/findings/fuzz/158-afar.f90 +63 -0
  190. offload/_root/data/findings/fuzz/16-cce20.f90 +39 -0
  191. offload/_root/data/findings/fuzz/1644-cce21.f90 +31 -0
  192. offload/_root/data/findings/fuzz/165-cce19.f90 +52 -0
  193. offload/_root/data/findings/fuzz/1749-cce20.f90 +34 -0
  194. offload/_root/data/findings/fuzz/1936-afar.f90 +61 -0
  195. offload/_root/data/findings/fuzz/1978-cce19.f90 +41 -0
  196. offload/_root/data/findings/fuzz/2014-cce19.f90 +46 -0
  197. offload/_root/data/findings/fuzz/2224-cce19.f90 +30 -0
  198. offload/_root/data/findings/fuzz/2334-cce19.f90 +57 -0
  199. offload/_root/data/findings/fuzz/536-cce19.f90 +38 -0
  200. offload/_root/data/findings/fuzz/591-cce19.f90 +54 -0
  201. offload/_root/data/findings/fuzz/650-afar.f90 +58 -0
  202. offload/_root/data/findings/fuzz/698-afar.f90 +68 -0
  203. offload/_root/data/findings/fuzz/700-afar.f90 +46 -0
  204. offload/_root/data/findings/fuzz/775-cce21.f90 +33 -0
  205. offload/_root/data/findings/fuzz/87-afar.f90 +47 -0
  206. offload/_root/data/findings/fuzz/916-afar.f90 +67 -0
  207. offload/_root/data/findings/fuzz/958-cce20.f90 +44 -0
  208. offload/_root/data/findings/fuzz/98-cce19.f90 +40 -0
  209. offload/_root/data/findings/fuzz/README.md +236 -0
  210. offload/_root/data/findings/fuzz/b1-121-afar.f90 +47 -0
  211. offload/_root/data/findings/fuzz/b1-183-afar.f90 +55 -0
  212. offload/_root/data/findings/fuzz/b1-22-cce20.f90 +38 -0
  213. offload/_root/data/findings/fuzz/b1-231-afar.f90 +56 -0
  214. offload/_root/data/findings/fuzz/b1-268-afar.f90 +46 -0
  215. offload/_root/data/findings/fuzz/b2-183-afar.f90 +57 -0
  216. offload/_root/data/findings/fuzz/b2-209-cce19.f90 +51 -0
  217. offload/_root/data/findings/fuzz/b2-213-afar.f90 +63 -0
  218. offload/_root/data/findings/fuzz/b2-52-afar.f90 +56 -0
  219. offload/_root/data/findings/fuzz/b2-68-afar.f90 +54 -0
  220. offload/_root/data/findings/fuzz/b2-85-cce20.f90 +55 -0
  221. offload/_root/data/findings/fuzz/b3-188-cce19.f90 +90 -0
  222. offload/_root/data/findings/fuzz/b3-190-cce21.f90 +88 -0
  223. offload/_root/data/findings/fuzz/b3-197-cce19.f90 +77 -0
  224. offload/_root/data/findings/fuzz/b3-250-cce20.f90 +89 -0
  225. offload/_root/data/findings/fuzz/b3-278-cce19.f90 +70 -0
  226. offload/_root/data/findings/fuzz/b3-45-cce21.f90 +83 -0
  227. offload/_root/data/findings/fuzz/b3-54-afar.f90 +67 -0
  228. offload/_root/data/findings/fuzz/b3-61-cce20.f90 +100 -0
  229. offload/_root/data/findings/fuzz/b3-9-afar.f90 +100 -0
  230. offload/_root/data/findings/fuzz/b3-9-cce21.f90 +103 -0
  231. offload/_root/data/findings/fuzz/b3-94-afar.f90 +80 -0
  232. offload/_root/data/findings/fuzz/b4-39-afar.f90 +141 -0
  233. offload/_root/data/findings/fuzz/b4-86-cce19.f90 +71 -0
  234. offload/_root/data/findings/fuzz/controls/gcc-complex-pointer-store-control.f90 +28 -0
  235. offload/_root/data/findings/fuzz/controls/gcc-declare-reduction-module-control.f90 +29 -0
  236. offload/_root/data/findings/fuzz/controls/gcc-target-simd-map-nontemporal-control.f90 +21 -0
  237. offload/_root/data/findings/fuzz/controls/nvhpc-allocatable-component-mapped-control.f90 +22 -0
  238. offload/_root/data/findings/fuzz/controls/nvhpc-allocatable-component-unreferenced-control.f90 +22 -0
  239. offload/_root/data/findings/fuzz/controls/nvhpc-default-none-removed-control.f90 +18 -0
  240. offload/_root/data/findings/fuzz/controls/nvhpc-default-shared-control.f90 +18 -0
  241. offload/_root/data/findings/fuzz/controls/nvhpc-defaultmap-firstprivate-removed-control.f90 +15 -0
  242. offload/_root/data/findings/fuzz/controls/nvhpc-defaultmap-to-scalar-reduction-mapped-control.f90 +17 -0
  243. offload/_root/data/findings/fuzz/controls/nvhpc-defaultmap-to-scalar-removed-control.f90 +17 -0
  244. offload/_root/data/findings/fuzz/controls/nvhpc-defaultmap-tofrom-lastprivate-control.f90 +15 -0
  245. offload/_root/data/findings/fuzz/controls/nvhpc-depend-explicit-map-control.f90 +22 -0
  246. offload/_root/data/findings/fuzz/controls/nvhpc-depend-removed-control.f90 +22 -0
  247. offload/_root/data/findings/fuzz/controls/nvhpc-distribute-end-distribute-control.f90 +16 -0
  248. offload/_root/data/findings/fuzz/controls/nvhpc-distribute-parallel-num-threads-removed-control.f90 +26 -0
  249. offload/_root/data/findings/fuzz/controls/nvhpc-distribute-parallel-removed-control.f90 +22 -0
  250. offload/_root/data/findings/fuzz/controls/nvhpc-distribute-simd-no-end-directive-control.f90 +15 -0
  251. offload/_root/data/findings/fuzz/controls/nvhpc-explicit-length-character-dummy-control.f90 +18 -0
  252. offload/_root/data/findings/fuzz/controls/nvhpc-loop-character-array-value-control.f90 +23 -0
  253. offload/_root/data/findings/fuzz/controls/nvhpc-loop-character-distribute-control.f90 +20 -0
  254. offload/_root/data/findings/fuzz/controls/nvhpc-map-always-first-control.f90 +15 -0
  255. offload/_root/data/findings/fuzz/controls/nvhpc-map-always-removed-control.f90 +15 -0
  256. offload/_root/data/findings/fuzz/controls/nvhpc-num-threads-removed-control.f90 +12 -0
  257. offload/_root/data/findings/fuzz/controls/nvhpc-target-parallel-firstprivate-dropped-control.f90 +15 -0
  258. offload/_root/data/findings/fuzz/controls/nvhpc-target-parallel-single-nowait-control.f90 +13 -0
  259. offload/_root/data/findings/fuzz/controls/nvhpc-target-parallel-split-control.f90 +15 -0
  260. offload/_root/data/findings/fuzz/controls/nvhpc-target-simd-collapse-split-control.f90 +21 -0
  261. offload/_root/data/findings/fuzz/controls/nvhpc-target-simd-end-directive-control.f90 +14 -0
  262. offload/_root/data/findings/fuzz/controls/nvhpc-target-simd-no-collapse-control.f90 +19 -0
  263. offload/_root/data/findings/fuzz/controls/nvhpc-target-simd-split-no-end-directive-control.f90 +15 -0
  264. offload/_root/data/findings/fuzz/gcc-declare-reduction-module-not-found.f90 +66 -0
  265. offload/_root/data/findings/fuzz/gcc-strided-target-update-rejected.f90 +58 -0
  266. offload/_root/data/findings/fuzz/gcc-target-simd-map-nontemporal-rejected.f90 +54 -0
  267. offload/_root/data/findings/fuzz/nvhpc-allocatable-component-implicit-map-illegal-address.f90 +84 -0
  268. offload/_root/data/findings/fuzz/nvhpc-assumed-length-character-dummy-map-ice.f90 +69 -0
  269. offload/_root/data/findings/fuzz/nvhpc-default-none-reduction-lastprivate-fort1-crash.f90 +70 -0
  270. offload/_root/data/findings/fuzz/nvhpc-defaultmap-firstprivate-lastprivate-ice.f90 +71 -0
  271. offload/_root/data/findings/fuzz/nvhpc-defaultmap-to-scalar-reduction-lost.f90 +82 -0
  272. offload/_root/data/findings/fuzz/nvhpc-depend-implicit-map-illegal-address.f90 +81 -0
  273. offload/_root/data/findings/fuzz/nvhpc-distribute-parallel-num-threads-writes-lost.f90 +79 -0
  274. offload/_root/data/findings/fuzz/nvhpc-end-distribute-simd-rejected.f90 +70 -0
  275. offload/_root/data/findings/fuzz/nvhpc-loop-character-achar-unsupported.f90 +75 -0
  276. offload/_root/data/findings/fuzz/nvhpc-map-always-after-map-to-not-copied-back.f90 +70 -0
  277. offload/_root/data/findings/fuzz/nvhpc-num-threads-reduction-identity-lost.f90 +54 -0
  278. offload/_root/data/findings/fuzz/nvhpc-target-parallel-firstprivate-translate-failure.f90 +66 -0
  279. offload/_root/data/findings/fuzz/nvhpc-target-parallel-single-hang.f90 +68 -0
  280. offload/_root/data/findings/fuzz/nvhpc-target-simd-collapse-translate-failure.f90 +73 -0
  281. offload/_root/data/findings/fuzz/nvhpc-target-simd-no-end-directive-rejected.f90 +68 -0
  282. offload/_root/data/findings/fuzz/par-s1-2082-gcc_g90.f90 +71 -0
  283. offload/_root/data/findings/fuzz/s1-2370-cce21.f90 +67 -0
  284. offload/_root/data/findings/fuzz/s1-2592-cce21.f90 +56 -0
  285. offload/_root/data/findings/fuzz/s1-3463-cce21.f90 +92 -0
  286. offload/_root/data/findings/fuzz/s1-4339-afar.f90 +79 -0
  287. offload/_root/data/findings/fuzz/s1-6085-cce21.f90 +96 -0
  288. offload/_root/data/findings/fuzz/s1-6760-cce20.f90 +65 -0
  289. offload/_root/data/findings/fuzz/s1-6888-cce21.f90 +76 -0
  290. offload/_root/data/findings/fuzz/s1-7882-cce20.f90 +63 -0
  291. offload/_root/data/findings/fuzz/s1-8634-cce21.f90 +45 -0
  292. offload/_root/data/findings/fuzz/s1-91-cce21.f90 +92 -0
  293. offload/_root/data/findings/fuzz/s1-9443-afar.f90 +59 -0
  294. offload/_root/data/findings/fuzz/s1-9914-cce19.f90 +78 -0
  295. offload/_root/data/findings/gcc/controls/gcc-acc-c-detach-control.c +34 -0
  296. offload/_root/data/findings/gcc/controls/gcc-acc-detach-control.f90 +26 -0
  297. offload/_root/data/findings/gcc/controls/gcc-defaultmap-to-pointer-control.f90 +31 -0
  298. offload/_root/data/findings/gcc/controls/gcc-target-in-task-control.c +26 -0
  299. offload/_root/data/findings/gcc/controls/gcc-target-in-task-control.f90 +21 -0
  300. offload/_root/data/findings/gcc/gcc-acc-bind-device-type-rejected.f90 +71 -0
  301. offload/_root/data/findings/gcc/gcc-acc-c-bind-device-type-rejected.c +76 -0
  302. offload/_root/data/findings/gcc/gcc-acc-c-detach-delete-attach-underflow.c +74 -0
  303. offload/_root/data/findings/gcc/gcc-acc-c-gang-dim-rejected.c +79 -0
  304. offload/_root/data/findings/gcc/gcc-acc-c-link-in-routine-rejected.c +82 -0
  305. offload/_root/data/findings/gcc/gcc-acc-detach-delete-attach-underflow.f90 +66 -0
  306. offload/_root/data/findings/gcc/gcc-acc-gang-dim-collapse-force-rejected.f90 +69 -0
  307. offload/_root/data/findings/gcc/gcc-acc-init-set-shutdown-rejected.f90 +70 -0
  308. offload/_root/data/findings/gcc/gcc-acc-link-in-routine-rejected.f90 +82 -0
  309. offload/_root/data/findings/gcc/gcc-acc-use-device-allocatable-rejected.f90 +88 -0
  310. offload/_root/data/findings/gcc/gcc-c-motion-mapper-rejected.c +110 -0
  311. offload/_root/data/findings/gcc/gcc-c-omp60-undocumented-rejected.c +76 -0
  312. offload/_root/data/findings/gcc/gcc-c-omp60-unimplemented-rejected.c +119 -0
  313. offload/_root/data/findings/gcc/gcc-c-target-in-task-mandatory-device-not-found.c +87 -0
  314. offload/_root/data/findings/gcc/gcc-c-uses-allocators-traits-unimplemented.c +85 -0
  315. offload/_root/data/findings/gcc/gcc-declare-mapper-rejected.f90 +85 -0
  316. offload/_root/data/findings/gcc/gcc-defaultmap-to-pointer-copy-back.f90 +66 -0
  317. offload/_root/data/findings/gcc/gcc-loop-bind-default-none-rejected.f90 +93 -0
  318. offload/_root/data/findings/gcc/gcc-omp60-undocumented-rejected.f90 +72 -0
  319. offload/_root/data/findings/gcc/gcc-omp60-unimplemented-rejected.f90 +112 -0
  320. offload/_root/data/findings/gcc/gcc-target-in-task-mandatory-device-not-found.f90 +83 -0
  321. offload/_root/data/findings/gcc/gcc-uses-allocators-traits-unimplemented.f90 +78 -0
  322. offload/_root/data/findings/harvest/afar-flang-strided-target-update.f90 +96 -0
  323. offload/_root/data/findings/harvest/cce-acc-declare-create-module-allocatable-xnack1-fault.f90 +58 -0
  324. offload/_root/data/findings/harvest/cce-c-implicit-struct-map-partly-present.c +100 -0
  325. offload/_root/data/findings/harvest/cce-c-strided-target-update.c +74 -0
  326. offload/_root/data/findings/harvest/cce-ftn-target-parallel-thread-query-ice.f90 +67 -0
  327. offload/_root/data/findings/harvest/cce-named-constant-array-declare-target-routine-rejected.f90 +69 -0
  328. offload/_root/data/findings/harvest/cce-use-device-ptr-c-ptr-not-converted.f90 +64 -0
  329. offload/_root/data/findings/harvest/cce21-declare-target-link-module-variable-write-lost.f90 +63 -0
  330. offload/_root/data/findings/harvest/cce21-internal-procedure-calls-internal-in-target-fault.f90 +71 -0
  331. offload/_root/data/findings/harvest/controls/cce-c-implicit-struct-map-partly-present-target-only-control.c +22 -0
  332. offload/_root/data/findings/harvest/controls/cce-c-implicit-struct-map-partly-present-whole-control.c +23 -0
  333. offload/_root/data/findings/harvest/controls/gcc-acc-declare-create-allocatable-control.f90 +34 -0
  334. offload/_root/data/findings/harvest/controls/gcc-c-same-item-two-maps-control.c +17 -0
  335. offload/_root/data/findings/harvest/controls/gcc-c-target-data-struct-pointer-section-control.c +27 -0
  336. offload/_root/data/findings/harvest/controls/gcc-c-target-data-two-maps-control.c +20 -0
  337. offload/_root/data/findings/harvest/controls/gcc-same-item-two-maps-control.f90 +16 -0
  338. offload/_root/data/findings/harvest/controls/gcc-teams-simd-matmul-allocatable-control.f90 +27 -0
  339. offload/_root/data/findings/harvest/gcc-acc-declare-create-allocatable-not-mapped.f90 +66 -0
  340. offload/_root/data/findings/harvest/gcc-c-same-item-two-maps-rejected.c +45 -0
  341. offload/_root/data/findings/harvest/gcc-c-strided-section-rejected.c +70 -0
  342. offload/_root/data/findings/harvest/gcc-c-target-data-struct-pointer-section-ice.c +78 -0
  343. offload/_root/data/findings/harvest/gcc-c-target-data-two-maps-ice.c +49 -0
  344. offload/_root/data/findings/harvest/gcc-same-item-two-maps-rejected.f90 +46 -0
  345. offload/_root/data/findings/harvest/gcc-teams-simd-matmul-allocatable-ice.f90 +53 -0
  346. offload/_root/data/findings/harvest/nvhpc-c-target-data-if-false-use-device-ptr-garbage.c +49 -0
  347. offload/_root/data/findings/harvest/nvhpc-named-constant-array-declare-target-routine-rejected.f90 +65 -0
  348. offload/_root/data/findings/harvest/nvhpc-use-device-ptr-c-ptr-not-found.f90 +60 -0
  349. offload/_root/data/findings/harvest/nvhpc2511-target-nowait-in-parallel-for-ice.c +59 -0
  350. offload/_root/data/findings/hecbench/controls/f16-ctl-float-array.c +28 -0
  351. offload/_root/data/findings/hecbench/controls/pc-ctl-builtin-popcount.c +37 -0
  352. offload/_root/data/findings/hecbench/controls/pc-ctl-shift-sum.c +43 -0
  353. offload/_root/data/findings/hecbench/gcc-c-float16-array-in-target-lto-ice.c +65 -0
  354. offload/_root/data/findings/hecbench/gcc-c-swar-popcount-assembler-error.c +80 -0
  355. offload/_root/data/findings/index.yaml +2453 -0
  356. offload/_root/data/findings/malloc/afar-device-malloc-in-kernel-corrupts-records.c +371 -0
  357. offload/_root/data/findings/malloc/controls/afar-first-use-malloc-direct.c +52 -0
  358. offload/_root/data/findings/malloc/controls/afar-first-use-malloc-fence.c +57 -0
  359. offload/_root/data/findings/malloc/controls/afar-first-use-malloc-flush.c +57 -0
  360. offload/_root/data/findings/malloc/controls/afar-first-use-malloc-stack.c +52 -0
  361. offload/_root/data/findings/multithread-allocatable-section-maps.f90 +91 -0
  362. offload/_root/data/findings/nested/afar-cce-c-call-result-member-in-target-rejected.c +69 -0
  363. offload/_root/data/findings/nested/afar-cce-c-update-struct-and-member-rejected.c +92 -0
  364. offload/_root/data/findings/nested/afar-flang-pointer-root-allocatable-component-enter-data-fault.f90 +121 -0
  365. offload/_root/data/findings/nested/cce-c-struct-and-nested-pointee-sections-ice.c +79 -0
  366. offload/_root/data/findings/nested/cce-fortran-nested-allocatable-component-copy-fault.f90 +64 -0
  367. offload/_root/data/findings/nested/cce-fortran-pointer-to-type-with-allocatable-scalar-component-typed-transfer.f90 +93 -0
  368. offload/_root/data/findings/nested/cce-fortran-update-to-pointer-root-allocatable-scalar-component-no-accelerator-object.f90 +80 -0
  369. offload/_root/data/findings/nested/controls/c3-ctl-nested-data.c +27 -0
  370. offload/_root/data/findings/nested/controls/c5-acc-serial-struct-and-array.c +26 -0
  371. offload/_root/data/findings/nested/controls/e2-ctl-two-directives.c +42 -0
  372. offload/_root/data/findings/nested/controls/e3-ctl-attach-clause.c +42 -0
  373. offload/_root/data/findings/nested/controls/f3-pointer-array-only.c +33 -0
  374. offload/_root/data/findings/nested/controls/f5-ctl-copyout-exit.c +33 -0
  375. offload/_root/data/findings/nested/controls/f6-ctl-pointer-to-struct-array.c +28 -0
  376. offload/_root/data/findings/nested/controls/g2-ctl-allocatable.f90 +34 -0
  377. offload/_root/data/findings/nested/controls/g2-ctl-entered-to.f90 +34 -0
  378. offload/_root/data/findings/nested/controls/g3-ctl-from-struct-no-element.c +27 -0
  379. offload/_root/data/findings/nested/controls/g3-ptrs-two-elements-to.c +27 -0
  380. offload/_root/data/findings/nested/controls/g3-ptrs-two-elements-tofrom.c +27 -0
  381. offload/_root/data/findings/nested/controls/g5-ctl-element-pointers-only.f90 +36 -0
  382. offload/_root/data/findings/nested/controls/g5-ctl-root-pointer-only.f90 +36 -0
  383. offload/_root/data/findings/nested/controls/gp2-ctl-no-mapper-explicit-maps.c +24 -0
  384. offload/_root/data/findings/nested/controls/gt2-ctl-no-always.c +26 -0
  385. offload/_root/data/findings/nested/controls/gt3-ctl-always-on-structure-only.c +26 -0
  386. offload/_root/data/findings/nested/controls/j1-embedded-struct-pointer-to-struct.c +24 -0
  387. offload/_root/data/findings/nested/controls/j2-ctl-pointer-instead-of-embedded.c +24 -0
  388. offload/_root/data/findings/nested/controls/j6-ctl-struct-and-one-pointee-level.c +23 -0
  389. offload/_root/data/findings/nested/controls/j7-ctl-struct-and-embedded-pointee.c +24 -0
  390. offload/_root/data/findings/nested/controls/m2-ctl-variable-root.f90 +32 -0
  391. offload/_root/data/findings/nested/controls/m3-ctl-fixed-array-component.f90 +32 -0
  392. offload/_root/data/findings/nested/controls/m5-ctl-no-enter-data.f90 +33 -0
  393. offload/_root/data/findings/nested/controls/n8-ctl-fixed-array-in-component.f90 +33 -0
  394. offload/_root/data/findings/nested/controls/n9-ctl-allocatable-in-the-variable.f90 +33 -0
  395. offload/_root/data/findings/nested/controls/ns4-ctl-two-directives-struct-then-pointee.c +27 -0
  396. offload/_root/data/findings/nested/controls/ns8-ctl-enter-together-exit-split.c +26 -0
  397. offload/_root/data/findings/nested/controls/nu3-ctl-update-pointee-only.c +28 -0
  398. offload/_root/data/findings/nested/controls/p2-ctl-pointer-variable.c +27 -0
  399. offload/_root/data/findings/nested/controls/p3-ctl-direct-member.c +26 -0
  400. offload/_root/data/findings/nested/controls/q2-ctl-fixed-array.f90 +37 -0
  401. offload/_root/data/findings/nested/controls/q3-ctl-allocatable-component-of-the-variable.f90 +38 -0
  402. offload/_root/data/findings/nested/controls/ta2-ctl-no-allocatable-component.f90 +42 -0
  403. offload/_root/data/findings/nested/controls/ta3-ctl-allocatable-scalar-in-the-variable.f90 +38 -0
  404. offload/_root/data/findings/nested/controls/ta4-ctl-pointer-component-only.f90 +42 -0
  405. offload/_root/data/findings/nested/controls/u3-ctl-update-member-only.c +24 -0
  406. offload/_root/data/findings/nested/controls/u4-ctl-two-updates.c +25 -0
  407. offload/_root/data/findings/nested/controls/u5-ctl-same-list-in-map.c +25 -0
  408. offload/_root/data/findings/nested/controls/ua2-ctl-variable-root.f90 +37 -0
  409. offload/_root/data/findings/nested/controls/ua4-ctl-to-in-place-of-alloc-and-update.f90 +37 -0
  410. offload/_root/data/findings/nested/controls/v2-ctl-parent-first.c +25 -0
  411. offload/_root/data/findings/nested/controls/v4-ctl-embedded-member.c +24 -0
  412. offload/_root/data/findings/nested/gcc-acc-c-exit-data-of-a-pointer-array-element-target-hangs.c +83 -0
  413. offload/_root/data/findings/nested/gcc-acc-c-parent-and-shared-pointee-one-directive.c +88 -0
  414. offload/_root/data/findings/nested/gcc-acc-c-struct-and-member-array-one-directive.c +84 -0
  415. offload/_root/data/findings/nested/gcc-c-always-on-pointer-member-section-ice.c +75 -0
  416. offload/_root/data/findings/nested/gcc-c-declare-mapper-pointer-member-section-gpu-fault.c +93 -0
  417. offload/_root/data/findings/nested/gcc-c-from-struct-and-pointee-section-rejected.c +83 -0
  418. offload/_root/data/findings/nested/gcc-fortran-pointer-component-alloc-bounds-lost.f90 +62 -0
  419. offload/_root/data/findings/nested/gcc-fortran-root-and-element-pointer-components-ice.f90 +77 -0
  420. offload/_root/data/findings/nested/nvhpc-c-pointee-before-parent-in-one-map-list-copy-fault.c +55 -0
  421. offload/_root/data/findings/nested/nvhpc-c-update-from-structure-overwrites-attached-pointer-segv.c +86 -0
  422. offload/_root/data/findings/nvhpc-acc-atomic-update-sum-fort2-crash.f90 +53 -0
  423. offload/_root/data/findings/nvhpc-c-acc-atomic-update-sum-ice.c +43 -0
  424. offload/_root/data/findings/nvhpc-c-dist-schedule-chunk-compile-hang.c +41 -0
  425. offload/_root/data/findings/nvhpc-c-map-present-ignored.c +42 -0
  426. offload/_root/data/findings/nvhpc-c-ordered-in-target-nvcpfe-crash.c +92 -0
  427. offload/_root/data/findings/nvhpc-c-parallel-for-firstprivate-in-target.c +62 -0
  428. offload/_root/data/findings/nvhpc-c-parallel-if-in-target-nvvm-ice.c +56 -0
  429. offload/_root/data/findings/nvhpc-defaultmap-firstprivate-explicit-map.f90 +45 -0
  430. offload/_root/data/findings/nvhpc-defaultmap-from-allocatable-indexing.f90 +60 -0
  431. offload/_root/data/findings/nvhpc-depend-inoutset-ignored.f90 +64 -0
  432. offload/_root/data/findings/nvhpc-dist-schedule-chunk-illegal-address.f90 +52 -0
  433. offload/_root/data/findings/nvhpc-managed-acc-shutdown-host-access.f90 +42 -0
  434. offload/_root/data/findings/nvhpc-parallel-if-in-target-nvvm-ice.f90 +60 -0
  435. offload/_root/data/findings/oop/afar-final-dealloc-device-link.f90 +85 -0
  436. offload/_root/data/findings/oop/afar-pdt-length-parameter-not-implemented.f90 +65 -0
  437. offload/_root/data/findings/oop/cce-class-is-device-link.f90 +86 -0
  438. offload/_root/data/findings/oop/cce-copy-alloc-component-section-fault.f90 +73 -0
  439. offload/_root/data/findings/oop/cce-copy-parent-to-component-tofrom-lost.f90 +65 -0
  440. offload/_root/data/findings/oop/cce-copy-second-member-section-lost.f90 +65 -0
  441. offload/_root/data/findings/oop/cce-element-component-map-lost.f90 +64 -0
  442. offload/_root/data/findings/oop/cce-final-dealloc-device-abort.f90 +85 -0
  443. offload/_root/data/findings/oop/cce-pdt-default-mapper-rejected.f90 +71 -0
  444. offload/_root/data/findings/oop/cce-polymorphic-dispatch-device-link.f90 +100 -0
  445. offload/_root/data/findings/oop/cce-section-of-element-component-overlap.f90 +76 -0
  446. offload/_root/data/findings/oop/cce-select-type-guard-not-taken.f90 +91 -0
  447. offload/_root/data/findings/oop/cce-udr-derived-type-unsupported.f90 +69 -0
  448. offload/_root/data/findings/oop/cce21-element-component-map-lost.f90 +62 -0
  449. offload/_root/data/findings/oop/controls/alloccomp-comp-only.f90 +44 -0
  450. offload/_root/data/findings/oop/controls/alloccomp-whole-explicit-component.f90 +50 -0
  451. offload/_root/data/findings/oop/controls/alloccomp-whole.f90 +49 -0
  452. offload/_root/data/findings/oop/controls/elemsec-element.f90 +47 -0
  453. offload/_root/data/findings/oop/controls/final-local.f90 +64 -0
  454. offload/_root/data/findings/oop/controls/host-class-star-select-type.f90 +58 -0
  455. offload/_root/data/findings/oop/controls/host-firstprivate-defined-assignment.f90 +54 -0
  456. offload/_root/data/findings/oop/controls/host-lastprivate-defined-assignment.f90 +58 -0
  457. offload/_root/data/findings/oop/controls/host-private-finalization.f90 +51 -0
  458. offload/_root/data/findings/oop/controls/host-select-type.f90 +65 -0
  459. offload/_root/data/findings/oop/controls/parent-and-comp-component-only.f90 +45 -0
  460. offload/_root/data/findings/oop/controls/pdt-kind.f90 +46 -0
  461. offload/_root/data/findings/oop/controls/pdt-len-host.f90 +43 -0
  462. offload/_root/data/findings/oop/controls/pdt-len-unparameterized.f90 +46 -0
  463. offload/_root/data/findings/oop/controls/poly-dispatch-static.f90 +75 -0
  464. offload/_root/data/findings/oop/controls/section-alloc-whole-component.f90 +49 -0
  465. offload/_root/data/findings/oop/controls/section-element-whole-array.f90 +50 -0
  466. offload/_root/data/findings/oop/controls/section-element-whole-component.f90 +50 -0
  467. offload/_root/data/findings/oop/controls/section-fixed.f90 +43 -0
  468. offload/_root/data/findings/oop/controls/tbp-override.f90 +64 -0
  469. offload/_root/data/findings/oop/gcc-acc-parent-and-member-data-rejected.f90 +63 -0
  470. offload/_root/data/findings/oop/gcc-pdt-length-parameter-abort.f90 +68 -0
  471. offload/_root/data/findings/oop/gcc-polymorphic-dispatch-abort.f90 +97 -0
  472. offload/_root/data/findings/oop/gcc-vtab-not-marked-for-offload.f90 +94 -0
  473. offload/_root/data/findings/oop/nvhpc-copy-alloc-component-illegal-address.f90 +76 -0
  474. offload/_root/data/findings/oop/nvhpc-copy-pdt-length-parameter-illegal-address.f90 +69 -0
  475. offload/_root/data/findings/oop/nvhpc-named-mapper-rejected.f90 +65 -0
  476. offload/_root/data/findings/oop/nvhpc-polymorphic-dispatch-translate-failure.f90 +90 -0
  477. offload/_root/data/findings/oop/nvhpc-polymorphism-runtime-unsupported.f90 +94 -0
  478. offload/_root/data/findings/oop/nvhpc-type-bound-call-rejected.f90 +89 -0
  479. offload/_root/data/findings/oop/nvhpc-udr-derived-type-rejected.f90 +67 -0
  480. offload/_root/data/findings/reviews/afar-c-error-directive-in-target-link.json +217 -0
  481. offload/_root/data/findings/reviews/afar-c-lastprivate-distribute-parallel-for-small-type.json +113 -0
  482. offload/_root/data/findings/reviews/afar-c-teams-distribute-reduction-first-team.json +130 -0
  483. offload/_root/data/findings/reviews/afar-c-update-iterator-copy-mode.json +113 -0
  484. offload/_root/data/findings/reviews/afar-cce19-character-defaultmap.json +292 -0
  485. offload/_root/data/findings/reviews/afar-clang-requires-device-safesync-hang.json +191 -0
  486. offload/_root/data/findings/reviews/afar-flang-firstprivate-map-two-targets.json +130 -0
  487. offload/_root/data/findings/reviews/afar-flang-loop-bind-teams-reduction.json +126 -0
  488. offload/_root/data/findings/reviews/afar-flang-task-reduction-max.json +113 -0
  489. offload/_root/data/findings/reviews/afar-flang-thread-limit-target-parallel-do.json +113 -0
  490. offload/_root/data/findings/reviews/afar-loop-bind-thread-in-teams.json +191 -0
  491. offload/_root/data/findings/reviews/afar-nontemporal-assumed-shape-ice.json +113 -0
  492. offload/_root/data/findings/reviews/afar-udr-derived-type-link.json +113 -0
  493. offload/_root/data/findings/reviews/afar-xnack1-atomic-min-nested-parallel.json +113 -0
  494. offload/_root/data/findings/reviews/afar-xnack1-target-is-present.json +113 -0
  495. offload/_root/data/findings/reviews/apps--afar-cce-teams-private-array-nested-parallel-wrong.json +113 -0
  496. offload/_root/data/findings/reviews/apps--cce20-device-link-infer-address-spaces-crash.json +113 -0
  497. offload/_root/data/findings/reviews/apps--cce21-device-link-agpr-copy-mfma-assert.json +113 -0
  498. offload/_root/data/findings/reviews/apps--cce21-private-array-loaded-subscript-wrong.json +113 -0
  499. offload/_root/data/findings/reviews/apps--gcc-acc-c-tile-partial-tiles-wrong.json +113 -0
  500. offload/_root/data/findings/reviews/catalog--afar-c-ordered-doacross-link.json +113 -0
  501. offload/_root/data/findings/reviews/catalog--afar-c-reduction-task-link.json +113 -0
  502. offload/_root/data/findings/reviews/catalog--afar-flang-absent-optional-target-crash.json +113 -0
  503. offload/_root/data/findings/reviews/catalog--afar-flang-critical-target-parallel-wrong.json +113 -0
  504. offload/_root/data/findings/reviews/catalog--afar-flang-dist-schedule-chunk.json +113 -0
  505. offload/_root/data/findings/reviews/catalog--afar-flang-linear-parallel-ice.json +113 -0
  506. offload/_root/data/findings/reviews/catalog--afar-flang-named-critical-link.json +126 -0
  507. offload/_root/data/findings/reviews/catalog--afar-flang-ordered-wrong.json +113 -0
  508. offload/_root/data/findings/reviews/catalog--afar-flang-reduction-minus-rejected.json +113 -0
  509. offload/_root/data/findings/reviews/catalog--afar-flang-sections-in-target-ice.json +113 -0
  510. offload/_root/data/findings/reviews/catalog--afar-flang-workdistribute-ice.json +113 -0
  511. offload/_root/data/findings/reviews/catalog--c-allocate-const-mem-firstprivate-wrong.json +113 -0
  512. offload/_root/data/findings/reviews/catalog--cce-acc-character-dummy-routine-ice.json +113 -0
  513. offload/_root/data/findings/reviews/catalog--cce-acc-loop-seq-in-routine-wrong.json +113 -0
  514. offload/_root/data/findings/reviews/catalog--cce-allocators-stack-ice.json +113 -0
  515. offload/_root/data/findings/reviews/catalog--cce-c-allocate-align-link.json +113 -0
  516. offload/_root/data/findings/reviews/catalog--cce-c-allocate-allocator-modifier-rejected.json +113 -0
  517. offload/_root/data/findings/reviews/catalog--cce-c-dist-schedule-chunk.json +113 -0
  518. offload/_root/data/findings/reviews/catalog--cce-c-f-pointer-device-link.json +130 -0
  519. offload/_root/data/findings/reviews/catalog--cce-c-long-double-ice.json +217 -0
  520. offload/_root/data/findings/reviews/catalog--cce-c-map-iterator-ice.json +217 -0
  521. offload/_root/data/findings/reviews/catalog--cce-c-recursive-function-ice.json +113 -0
  522. offload/_root/data/findings/reviews/catalog--cce-c-sections-in-target-wrong.json +113 -0
  523. offload/_root/data/findings/reviews/catalog--cce-flang-allocate-in-target-crash.json +113 -0
  524. offload/_root/data/findings/reviews/catalog--cce-flang-lastprivate-parallel-in-seq-loop-wrong.json +113 -0
  525. offload/_root/data/findings/reviews/catalog--cce-flang-stop-in-target-crash.json +113 -0
  526. offload/_root/data/findings/reviews/catalog--cce-iterator-link.json +113 -0
  527. offload/_root/data/findings/reviews/catalog--cce-linear-lastprivate-ice.json +113 -0
  528. offload/_root/data/findings/reviews/catalog--cce-reduction-inscan-ice.json +113 -0
  529. offload/_root/data/findings/reviews/catalog--cce-reduction-task-link.json +113 -0
  530. offload/_root/data/findings/reviews/catalog--cce19-reduction-task-addrspacecast-ice.json +113 -0
  531. offload/_root/data/findings/reviews/catalog--cce20-c-defaultmap-private-storage-rejected.json +217 -0
  532. offload/_root/data/findings/reviews/catalog--cce20-map-self-rejected.json +204 -0
  533. offload/_root/data/findings/reviews/catalog--cce21-c-target-loop-ice.json +126 -0
  534. offload/_root/data/findings/reviews/catalog--defaultmap-present-private-array-abort.json +236 -0
  535. offload/_root/data/findings/reviews/catalog--nvhpc-acc-associate-illegal-address.json +113 -0
  536. offload/_root/data/findings/reviews/catalog--nvhpc-c-function-pointer-kernel-missing.json +268 -0
  537. offload/_root/data/findings/reviews/cce-acc-init-set-runtime-assert.json +113 -0
  538. offload/_root/data/findings/reviews/cce-acc-reduction-200-int8-scalars-wrong.json +113 -0
  539. offload/_root/data/findings/reviews/cce-acc-routine-bind-module-ice.json +113 -0
  540. offload/_root/data/findings/reviews/cce-c-dist-schedule-segv.json +113 -0
  541. offload/_root/data/findings/reviews/cce-c-map-delete-refcount.json +149 -0
  542. offload/_root/data/findings/reviews/cce-c-map-present-assert.json +126 -0
  543. offload/_root/data/findings/reviews/cce-c-openmp45-device-link.json +113 -0
  544. offload/_root/data/findings/reviews/cce-c-parallel-for-in-target.json +141 -0
  545. offload/_root/data/findings/reviews/cce-mapper-next-map-copy-back.json +208 -0
  546. offload/_root/data/findings/reviews/cce-uses-allocators-traits-omp50.json +191 -0
  547. offload/_root/data/findings/reviews/cce19-c-reduction-63-scalars-one-wrong.json +113 -0
  548. offload/_root/data/findings/reviews/cce19-target-parallel-guarded-loop.json +113 -0
  549. offload/_root/data/findings/reviews/cce19-target-parallel-single-ice.json +113 -0
  550. offload/_root/data/findings/reviews/cce21-alloc-2e32-sum-wrong.json +113 -0
  551. offload/_root/data/findings/reviews/cce21-defaultmap-aggregate-flag.json +210 -0
  552. offload/_root/data/findings/reviews/cce21-in-reduction-assumed-shape-write-lost.json +113 -0
  553. offload/_root/data/findings/reviews/cce21-in-reduction-taskwait-link.json +113 -0
  554. offload/_root/data/findings/reviews/clang-c-declare-target-to-omp52.json +113 -0
  555. offload/_root/data/findings/reviews/clang-c-linear-directive-name-hang.json +113 -0
  556. offload/_root/data/findings/reviews/clang-c-shared-declare-target-combined.json +132 -0
  557. offload/_root/data/findings/reviews/dataenv--cce-value-dummy-target-write-visible.json +113 -0
  558. offload/_root/data/findings/reviews/defaultmap-none-loop-variable.json +113 -0
  559. offload/_root/data/findings/reviews/fortran-schedule-static-in-target.json +113 -0
  560. offload/_root/data/findings/reviews/fresh--cce-common-block-name-in-map-rejected.json +113 -0
  561. offload/_root/data/findings/reviews/fresh--cce-list-directed-print-in-target-copy-crash.json +217 -0
  562. offload/_root/data/findings/reviews/fresh--cce19-acc-automatic-array-copyout-copy-crash.json +113 -0
  563. offload/_root/data/findings/reviews/fresh--cce21-combined-if-runtime-expr-loop-skipped.json +113 -0
  564. offload/_root/data/findings/reviews/fresh--nvhpc-acc-gang-worker-collapse-nested-vector-reduction-lost.json +113 -0
  565. offload/_root/data/findings/reviews/fresh--nvhpc-teams-loop-module-allocatable-assign-fort2-crash.json +113 -0
  566. offload/_root/data/findings/reviews/fuzz--1505-cce20.json +113 -0
  567. offload/_root/data/findings/reviews/fuzz--1540-afar.json +113 -0
  568. offload/_root/data/findings/reviews/fuzz--1978-cce19.json +130 -0
  569. offload/_root/data/findings/reviews/fuzz--2334-cce19.json +113 -0
  570. offload/_root/data/findings/reviews/fuzz--591-cce19.json +147 -0
  571. offload/_root/data/findings/reviews/fuzz--650-afar.json +113 -0
  572. offload/_root/data/findings/reviews/fuzz--916-afar.json +130 -0
  573. offload/_root/data/findings/reviews/fuzz--98-cce19.json +113 -0
  574. offload/_root/data/findings/reviews/fuzz--b1-121-afar.json +160 -0
  575. offload/_root/data/findings/reviews/fuzz--b2-209-cce19.json +141 -0
  576. offload/_root/data/findings/reviews/fuzz--b2-68-afar.json +113 -0
  577. offload/_root/data/findings/reviews/fuzz--b2-85-cce20.json +217 -0
  578. offload/_root/data/findings/reviews/fuzz--b3-188-cce19.json +113 -0
  579. offload/_root/data/findings/reviews/fuzz--b3-278-cce19.json +212 -0
  580. offload/_root/data/findings/reviews/fuzz--b3-54-afar.json +113 -0
  581. offload/_root/data/findings/reviews/fuzz--b3-61-cce20.json +191 -0
  582. offload/_root/data/findings/reviews/fuzz--b4-86-cce19.json +113 -0
  583. offload/_root/data/findings/reviews/fuzz--gcc-declare-reduction-module-not-found.json +113 -0
  584. offload/_root/data/findings/reviews/fuzz--gcc-target-simd-map-nontemporal-rejected.json +113 -0
  585. offload/_root/data/findings/reviews/fuzz--nvhpc-allocatable-component-implicit-map-illegal-address.json +141 -0
  586. offload/_root/data/findings/reviews/fuzz--nvhpc-assumed-length-character-dummy-map-ice.json +113 -0
  587. offload/_root/data/findings/reviews/fuzz--nvhpc-default-none-reduction-lastprivate-fort1-crash.json +113 -0
  588. offload/_root/data/findings/reviews/fuzz--nvhpc-defaultmap-firstprivate-lastprivate-ice.json +113 -0
  589. offload/_root/data/findings/reviews/fuzz--nvhpc-defaultmap-to-scalar-reduction-lost.json +113 -0
  590. offload/_root/data/findings/reviews/fuzz--nvhpc-depend-implicit-map-illegal-address.json +113 -0
  591. offload/_root/data/findings/reviews/fuzz--nvhpc-distribute-parallel-num-threads-writes-lost.json +113 -0
  592. offload/_root/data/findings/reviews/fuzz--nvhpc-end-distribute-simd-rejected.json +113 -0
  593. offload/_root/data/findings/reviews/fuzz--nvhpc-loop-character-achar-unsupported.json +113 -0
  594. offload/_root/data/findings/reviews/fuzz--nvhpc-map-always-after-map-to-not-copied-back.json +113 -0
  595. offload/_root/data/findings/reviews/fuzz--nvhpc-num-threads-reduction-identity-lost.json +113 -0
  596. offload/_root/data/findings/reviews/fuzz--nvhpc-target-parallel-firstprivate-translate-failure.json +191 -0
  597. offload/_root/data/findings/reviews/fuzz--nvhpc-target-parallel-single-hang.json +113 -0
  598. offload/_root/data/findings/reviews/fuzz--nvhpc-target-simd-collapse-translate-failure.json +113 -0
  599. offload/_root/data/findings/reviews/fuzz--nvhpc-target-simd-no-end-directive-rejected.json +113 -0
  600. offload/_root/data/findings/reviews/fuzz--par-s1-2082-gcc_g90.json +126 -0
  601. offload/_root/data/findings/reviews/fuzz--s1-2370-cce21.json +113 -0
  602. offload/_root/data/findings/reviews/fuzz--s1-2592-cce21.json +113 -0
  603. offload/_root/data/findings/reviews/fuzz--s1-3463-cce21.json +113 -0
  604. offload/_root/data/findings/reviews/fuzz--s1-6760-cce20.json +130 -0
  605. offload/_root/data/findings/reviews/fuzz--s1-6888-cce21.json +113 -0
  606. offload/_root/data/findings/reviews/fuzz--s1-7882-cce20.json +113 -0
  607. offload/_root/data/findings/reviews/fuzz--s1-8634-cce21.json +113 -0
  608. offload/_root/data/findings/reviews/fuzz--s1-91-cce21.json +113 -0
  609. offload/_root/data/findings/reviews/fuzz--s1-9443-afar.json +113 -0
  610. offload/_root/data/findings/reviews/fuzz--s1-9914-cce19.json +141 -0
  611. offload/_root/data/findings/reviews/gcc--gcc-acc-bind-device-type-rejected.json +113 -0
  612. offload/_root/data/findings/reviews/gcc--gcc-acc-detach-delete-attach-underflow.json +314 -0
  613. offload/_root/data/findings/reviews/gcc--gcc-acc-gang-dim-collapse-force-rejected.json +113 -0
  614. offload/_root/data/findings/reviews/gcc--gcc-acc-init-set-shutdown-rejected.json +113 -0
  615. offload/_root/data/findings/reviews/gcc--gcc-acc-link-in-routine-rejected.json +113 -0
  616. offload/_root/data/findings/reviews/gcc--gcc-acc-use-device-allocatable-rejected.json +113 -0
  617. offload/_root/data/findings/reviews/gcc--gcc-c-motion-mapper-rejected.json +113 -0
  618. offload/_root/data/findings/reviews/gcc--gcc-c-omp60-undocumented-rejected.json +217 -0
  619. offload/_root/data/findings/reviews/gcc--gcc-c-omp60-unimplemented-rejected.json +236 -0
  620. offload/_root/data/findings/reviews/gcc--gcc-c-target-in-task-mandatory-device-not-found.json +236 -0
  621. offload/_root/data/findings/reviews/gcc--gcc-c-uses-allocators-traits-unimplemented.json +113 -0
  622. offload/_root/data/findings/reviews/gcc--gcc-declare-mapper-rejected.json +113 -0
  623. offload/_root/data/findings/reviews/gcc--gcc-defaultmap-to-pointer-copy-back.json +217 -0
  624. offload/_root/data/findings/reviews/gcc--gcc-loop-bind-default-none-rejected.json +113 -0
  625. offload/_root/data/findings/reviews/harvest--afar-flang-strided-target-update.json +141 -0
  626. offload/_root/data/findings/reviews/harvest--cce-acc-declare-create-module-allocatable-xnack1-fault.json +113 -0
  627. offload/_root/data/findings/reviews/harvest--cce-c-implicit-struct-map-partly-present.json +217 -0
  628. offload/_root/data/findings/reviews/harvest--cce-c-strided-target-update.json +141 -0
  629. offload/_root/data/findings/reviews/harvest--cce-ftn-target-parallel-thread-query-ice.json +130 -0
  630. offload/_root/data/findings/reviews/harvest--cce-named-constant-array-declare-target-routine-rejected.json +113 -0
  631. offload/_root/data/findings/reviews/harvest--cce-use-device-ptr-c-ptr-not-converted.json +113 -0
  632. offload/_root/data/findings/reviews/harvest--cce21-declare-target-link-module-variable-write-lost.json +113 -0
  633. offload/_root/data/findings/reviews/harvest--cce21-internal-procedure-calls-internal-in-target-fault.json +158 -0
  634. offload/_root/data/findings/reviews/harvest--gcc-acc-declare-create-allocatable-not-mapped.json +204 -0
  635. offload/_root/data/findings/reviews/harvest--gcc-c-same-item-two-maps-rejected.json +143 -0
  636. offload/_root/data/findings/reviews/harvest--gcc-c-strided-section-rejected.json +164 -0
  637. offload/_root/data/findings/reviews/harvest--gcc-c-target-data-struct-pointer-section-ice.json +113 -0
  638. offload/_root/data/findings/reviews/harvest--gcc-c-target-data-two-maps-ice.json +113 -0
  639. offload/_root/data/findings/reviews/harvest--gcc-teams-simd-matmul-allocatable-ice.json +113 -0
  640. offload/_root/data/findings/reviews/harvest--nvhpc-c-target-data-if-false-use-device-ptr-garbage.json +113 -0
  641. offload/_root/data/findings/reviews/harvest--nvhpc-named-constant-array-declare-target-routine-rejected.json +126 -0
  642. offload/_root/data/findings/reviews/harvest--nvhpc-use-device-ptr-c-ptr-not-found.json +113 -0
  643. offload/_root/data/findings/reviews/harvest--nvhpc2511-target-nowait-in-parallel-for-ice.json +130 -0
  644. offload/_root/data/findings/reviews/hecbench--gcc-c-float16-array-in-target-lto-ice.json +217 -0
  645. offload/_root/data/findings/reviews/hecbench--gcc-c-swar-popcount-assembler-error.json +126 -0
  646. offload/_root/data/findings/reviews/malloc--afar-device-malloc-in-kernel-corrupts-records.json +270 -0
  647. offload/_root/data/findings/reviews/multithread-allocatable-section-maps.json +191 -0
  648. offload/_root/data/findings/reviews/nested--afar-cce-c-call-result-member-in-target-rejected.json +113 -0
  649. offload/_root/data/findings/reviews/nested--afar-cce-c-update-struct-and-member-rejected.json +126 -0
  650. offload/_root/data/findings/reviews/nested--afar-flang-pointer-root-allocatable-component-enter-data-fault.json +191 -0
  651. offload/_root/data/findings/reviews/nested--cce-c-struct-and-nested-pointee-sections-ice.json +113 -0
  652. offload/_root/data/findings/reviews/nested--cce-fortran-nested-allocatable-component-copy-fault.json +214 -0
  653. offload/_root/data/findings/reviews/nested--cce-fortran-pointer-to-type-with-allocatable-scalar-component-typed-transfer.json +191 -0
  654. offload/_root/data/findings/reviews/nested--cce-fortran-update-to-pointer-root-allocatable-scalar-component-no-accelerator-object.json +297 -0
  655. offload/_root/data/findings/reviews/nested--gcc-acc-c-exit-data-of-a-pointer-array-element-target-hangs.json +204 -0
  656. offload/_root/data/findings/reviews/nested--gcc-acc-c-parent-and-shared-pointee-one-directive.json +130 -0
  657. offload/_root/data/findings/reviews/nested--gcc-acc-c-struct-and-member-array-one-directive.json +141 -0
  658. offload/_root/data/findings/reviews/nested--gcc-c-always-on-pointer-member-section-ice.json +113 -0
  659. offload/_root/data/findings/reviews/nested--gcc-c-declare-mapper-pointer-member-section-gpu-fault.json +113 -0
  660. offload/_root/data/findings/reviews/nested--gcc-c-from-struct-and-pointee-section-rejected.json +113 -0
  661. offload/_root/data/findings/reviews/nested--gcc-fortran-pointer-component-alloc-bounds-lost.json +217 -0
  662. offload/_root/data/findings/reviews/nested--gcc-fortran-root-and-element-pointer-components-ice.json +217 -0
  663. offload/_root/data/findings/reviews/nested--nvhpc-c-pointee-before-parent-in-one-map-list-copy-fault.json +204 -0
  664. offload/_root/data/findings/reviews/nested--nvhpc-c-update-from-structure-overwrites-attached-pointer-segv.json +191 -0
  665. offload/_root/data/findings/reviews/nvhpc-c-acc-atomic-update-sum-ice.json +277 -0
  666. offload/_root/data/findings/reviews/nvhpc-c-dist-schedule-chunk-compile-hang.json +113 -0
  667. offload/_root/data/findings/reviews/nvhpc-c-map-present-ignored.json +113 -0
  668. offload/_root/data/findings/reviews/nvhpc-c-ordered-in-target-nvcpfe-crash.json +113 -0
  669. offload/_root/data/findings/reviews/nvhpc-c-parallel-for-firstprivate-in-target.json +113 -0
  670. offload/_root/data/findings/reviews/nvhpc-defaultmap-firstprivate-explicit-map.json +113 -0
  671. offload/_root/data/findings/reviews/nvhpc-defaultmap-from-allocatable-indexing.json +132 -0
  672. offload/_root/data/findings/reviews/nvhpc-depend-inoutset-ignored.json +113 -0
  673. offload/_root/data/findings/reviews/nvhpc-dist-schedule-chunk-illegal-address.json +113 -0
  674. offload/_root/data/findings/reviews/nvhpc-managed-acc-shutdown-host-access.json +113 -0
  675. offload/_root/data/findings/reviews/nvhpc-parallel-if-in-target-nvvm-ice.json +113 -0
  676. offload/_root/data/findings/reviews/oop--afar-final-dealloc-device-link.json +132 -0
  677. offload/_root/data/findings/reviews/oop--afar-pdt-length-parameter-not-implemented.json +113 -0
  678. offload/_root/data/findings/reviews/oop--cce-class-is-device-link.json +130 -0
  679. offload/_root/data/findings/reviews/oop--cce-copy-alloc-component-section-fault.json +217 -0
  680. offload/_root/data/findings/reviews/oop--cce-copy-parent-to-component-tofrom-lost.json +217 -0
  681. offload/_root/data/findings/reviews/oop--cce-copy-second-member-section-lost.json +113 -0
  682. offload/_root/data/findings/reviews/oop--cce-element-component-map-lost.json +113 -0
  683. offload/_root/data/findings/reviews/oop--cce-final-dealloc-device-abort.json +208 -0
  684. offload/_root/data/findings/reviews/oop--cce-pdt-default-mapper-rejected.json +191 -0
  685. offload/_root/data/findings/reviews/oop--cce-polymorphic-dispatch-device-link.json +247 -0
  686. offload/_root/data/findings/reviews/oop--cce-section-of-element-component-overlap.json +113 -0
  687. offload/_root/data/findings/reviews/oop--cce-select-type-guard-not-taken.json +191 -0
  688. offload/_root/data/findings/reviews/oop--cce-udr-derived-type-unsupported.json +132 -0
  689. offload/_root/data/findings/reviews/oop--gcc-acc-parent-and-member-data-rejected.json +141 -0
  690. offload/_root/data/findings/reviews/oop--gcc-pdt-length-parameter-abort.json +141 -0
  691. offload/_root/data/findings/reviews/oop--gcc-polymorphic-dispatch-abort.json +217 -0
  692. offload/_root/data/findings/reviews/oop--gcc-vtab-not-marked-for-offload.json +113 -0
  693. offload/_root/data/findings/reviews/oop--nvhpc-copy-alloc-component-illegal-address.json +113 -0
  694. offload/_root/data/findings/reviews/oop--nvhpc-copy-pdt-length-parameter-illegal-address.json +236 -0
  695. offload/_root/data/findings/reviews/oop--nvhpc-named-mapper-rejected.json +113 -0
  696. offload/_root/data/findings/reviews/oop--nvhpc-polymorphic-dispatch-translate-failure.json +223 -0
  697. offload/_root/data/findings/reviews/oop--nvhpc-polymorphism-runtime-unsupported.json +126 -0
  698. offload/_root/data/findings/reviews/oop--nvhpc-type-bound-call-rejected.json +113 -0
  699. offload/_root/data/findings/reviews/oop--nvhpc-udr-derived-type-rejected.json +113 -0
  700. offload/_root/data/findings/reviews/stress--afar-c-lastprivate-combined-target-not-mapped.json +113 -0
  701. offload/_root/data/findings/reviews/stress--afar-target-scalar-implicit-firstprivate.json +175 -0
  702. offload/_root/data/findings/reviews/stress--cce-acc-declare-create-scalar-serial-firstprivate.json +113 -0
  703. offload/_root/data/findings/reviews/stress--cce-c-distribute-lastprivate-lost.json +113 -0
  704. offload/_root/data/findings/reviews/stress--cce-c-flto-offload-dropped.json +204 -0
  705. offload/_root/data/findings/reviews/stress--cce-ftn-cif-record-split-abort.json +113 -0
  706. offload/_root/data/findings/reviews/stress--cce-lastprivate-num-threads-collapse-simd.json +113 -0
  707. offload/_root/data/findings/reviews/stress--cce-teams-reduction-many-teams-wrap.json +113 -0
  708. offload/_root/data/findings/reviews/stress--cce21-declare-target-scalar-map-write-lost.json +113 -0
  709. offload/_root/data/findings/reviews/stress--gcc-declare-target-allocatable-component-ice.json +191 -0
  710. offload/_root/data/findings/reviews/stress--nvhpc-acc-derived-type-component-not-copied.json +126 -0
  711. offload/_root/data/findings/reviews/stress--nvhpc-c-lastprivate-teams-distribute-parallel-for-lost.json +113 -0
  712. offload/_root/data/findings/reviews/stress--nvhpc-declare-target-scalar-write-lost.json +113 -0
  713. offload/_root/data/findings/reviews/stress--nvhpc-lastprivate-combined-target-not-mapped.json +113 -0
  714. offload/_root/data/findings/reviews/stress--nvhpc-target-scalar-implicit-firstprivate.json +130 -0
  715. offload/_root/data/findings/reviews/target-update-sections-in-parallel.json +113 -0
  716. offload/_root/data/findings/stress/afar-c-lastprivate-combined-target-not-mapped.c +72 -0
  717. offload/_root/data/findings/stress/afar-target-scalar-implicit-firstprivate.f90 +47 -0
  718. offload/_root/data/findings/stress/cce-acc-declare-create-scalar-serial-firstprivate.f90 +43 -0
  719. offload/_root/data/findings/stress/cce-c-distribute-lastprivate-lost.c +52 -0
  720. offload/_root/data/findings/stress/cce-c-flto-offload-dropped.c +73 -0
  721. offload/_root/data/findings/stress/cce-ftn-cif-record-split-abort.f90 +109 -0
  722. offload/_root/data/findings/stress/cce-lastprivate-num-threads-collapse-simd.f90 +66 -0
  723. offload/_root/data/findings/stress/cce-teams-reduction-many-teams-wrap.f90 +55 -0
  724. offload/_root/data/findings/stress/cce21-declare-target-scalar-map-write-lost.f90 +58 -0
  725. offload/_root/data/findings/stress/controls/gcc-declare-target-allocatable-component-control.f90 +29 -0
  726. offload/_root/data/findings/stress/gcc-declare-target-allocatable-component-ice.f90 +61 -0
  727. offload/_root/data/findings/stress/nvhpc-acc-derived-type-component-not-copied.f90 +33 -0
  728. offload/_root/data/findings/stress/nvhpc-c-lastprivate-teams-distribute-parallel-for-lost.c +62 -0
  729. offload/_root/data/findings/stress/nvhpc-declare-target-scalar-write-lost.f90 +43 -0
  730. offload/_root/data/findings/stress/nvhpc-lastprivate-combined-target-not-mapped.f90 +60 -0
  731. offload/_root/data/findings/stress/nvhpc-target-scalar-implicit-firstprivate.f90 +41 -0
  732. offload/_root/data/findings/target-update-sections-in-parallel.f90 +53 -0
  733. offload/_root/data/issues.json +1 -0
  734. offload/_root/data/search.json +1 -0
  735. offload/_root/data/vendor/checks/build.py +288 -0
  736. offload/_version.py +24 -0
  737. offload/canuse.py +88 -0
  738. offload/cli.py +52 -0
  739. offload/data.py +85 -0
  740. offload/engine/__init__.py +0 -0
  741. offload/engine/acc_c_gen.py +415 -0
  742. offload/engine/acc_gen.py +1104 -0
  743. offload/engine/acc_rules.py +656 -0
  744. offload/engine/apps.py +804 -0
  745. offload/engine/baseline.py +324 -0
  746. offload/engine/c_gen.py +883 -0
  747. offload/engine/c_program.py +913 -0
  748. offload/engine/c_rules.py +503 -0
  749. offload/engine/campaign.py +1180 -0
  750. offload/engine/campaigns/__init__.py +2 -0
  751. offload/engine/campaigns/hecbench.py +153 -0
  752. offload/engine/campaigns/nested.py +76 -0
  753. offload/engine/campaigns/oop.py +61 -0
  754. offload/engine/canary.py +275 -0
  755. offload/engine/catalog.py +860 -0
  756. offload/engine/citations.py +532 -0
  757. offload/engine/clang_oracle.py +208 -0
  758. offload/engine/combos.py +234 -0
  759. offload/engine/confirm/__init__.py +2 -0
  760. offload/engine/confirm/backlog.py +159 -0
  761. offload/engine/confirm/claims.py +423 -0
  762. offload/engine/confirm/collectors.py +665 -0
  763. offload/engine/confirm/decisions.py +202 -0
  764. offload/engine/confirm/draft.py +195 -0
  765. offload/engine/confirm/engine.py +157 -0
  766. offload/engine/confirm/execute.py +382 -0
  767. offload/engine/confirm/facts.py +467 -0
  768. offload/engine/confirm/findings.py +617 -0
  769. offload/engine/confirm/forms.py +145 -0
  770. offload/engine/confirm/ingest.py +372 -0
  771. offload/engine/confirm/jobs.py +215 -0
  772. offload/engine/confirm/legality.py +323 -0
  773. offload/engine/confirm/machines.py +254 -0
  774. offload/engine/confirm/minimize.py +268 -0
  775. offload/engine/confirm/model.py +249 -0
  776. offload/engine/confirm/ports.py +107 -0
  777. offload/engine/confirm/programs.py +222 -0
  778. offload/engine/confirm/registry.py +151 -0
  779. offload/engine/confirm/regress.py +278 -0
  780. offload/engine/confirm/rules.py +565 -0
  781. offload/engine/confirm/store.py +63 -0
  782. offload/engine/confirm/triage.py +838 -0
  783. offload/engine/confirm/validate.py +607 -0
  784. offload/engine/confirm/witness.py +355 -0
  785. offload/engine/corpus_check.py +388 -0
  786. offload/engine/coverage.py +318 -0
  787. offload/engine/dataenv_gen.py +1318 -0
  788. offload/engine/dataenv_rules.py +278 -0
  789. offload/engine/devtemps.py +146 -0
  790. offload/engine/expected.py +2559 -0
  791. offload/engine/f2c.py +1783 -0
  792. offload/engine/finding_claims.py +330 -0
  793. offload/engine/finding_header.py +229 -0
  794. offload/engine/finding_rows.py +382 -0
  795. offload/engine/flang_oracle.py +299 -0
  796. offload/engine/fsource.py +620 -0
  797. offload/engine/fuzz.py +2455 -0
  798. offload/engine/fuzz_base.py +2016 -0
  799. offload/engine/fuzz_campaign.py +592 -0
  800. offload/engine/fuzz_exec.py +798 -0
  801. offload/engine/fuzz_min.py +1049 -0
  802. offload/engine/fuzz_profile.py +340 -0
  803. offload/engine/fuzz_report.py +1270 -0
  804. offload/engine/fuzz_steer.py +181 -0
  805. offload/engine/gate.py +1013 -0
  806. offload/engine/gate_report.py +711 -0
  807. offload/engine/gate_run.py +118 -0
  808. offload/engine/gate_stored.py +466 -0
  809. offload/engine/gen.py +1114 -0
  810. offload/engine/gen_templates.py +2583 -0
  811. offload/engine/grammar.py +695 -0
  812. offload/engine/harness.py +1472 -0
  813. offload/engine/harvest/__init__.py +3 -0
  814. offload/engine/harvest/c_runtime.py +465 -0
  815. offload/engine/harvest/checks.py +534 -0
  816. offload/engine/harvest/convert.py +784 -0
  817. offload/engine/harvest/f_runtime.py +668 -0
  818. offload/engine/harvest/filters.py +338 -0
  819. offload/engine/harvest/history.py +122 -0
  820. offload/engine/harvest/inventory.py +399 -0
  821. offload/engine/harvest2/__init__.py +5 -0
  822. offload/engine/harvest2/aomp.py +119 -0
  823. offload/engine/harvest2/examples.py +116 -0
  824. offload/engine/harvest2/gomp.py +679 -0
  825. offload/engine/harvest2/hand.py +150 -0
  826. offload/engine/harvest2/split.py +78 -0
  827. offload/engine/harvest_known/__init__.py +2 -0
  828. offload/engine/harvest_known/apps.py +65 -0
  829. offload/engine/harvest_known/cases.py +128 -0
  830. offload/engine/harvest_known/centres.py +184 -0
  831. offload/engine/harvest_known/forum.py +180 -0
  832. offload/engine/harvest_known/relnotes.py +42 -0
  833. offload/engine/harvest_known/textscan.py +107 -0
  834. offload/engine/hdrwrap.py +42 -0
  835. offload/engine/hecbench.py +568 -0
  836. offload/engine/hecbench_report.py +265 -0
  837. offload/engine/hecbench_run.py +483 -0
  838. offload/engine/idioms.py +1427 -0
  839. offload/engine/kbody_cites.py +81 -0
  840. offload/engine/kbody_emit.py +949 -0
  841. offload/engine/kbody_gen.py +795 -0
  842. offload/engine/legality_review.py +236 -0
  843. offload/engine/localcfg.py +58 -0
  844. offload/engine/malloc_dd.py +267 -0
  845. offload/engine/mutate.py +1933 -0
  846. offload/engine/nested_cites.py +196 -0
  847. offload/engine/nested_emit.py +789 -0
  848. offload/engine/nested_gen.py +1721 -0
  849. offload/engine/offload_scope.py +197 -0
  850. offload/engine/ompvv.py +624 -0
  851. offload/engine/oop_gen.py +2249 -0
  852. offload/engine/prerun.py +1435 -0
  853. offload/engine/program_source.py +739 -0
  854. offload/engine/provenance.py +103 -0
  855. offload/engine/reduce.py +2098 -0
  856. offload/engine/report.py +3374 -0
  857. offload/engine/root.py +33 -0
  858. offload/engine/rules.py +4256 -0
  859. offload/engine/run_matrix.py +325 -0
  860. offload/engine/site/__init__.py +1 -0
  861. offload/engine/site/columns.py +53 -0
  862. offload/engine/site/data.py +648 -0
  863. offload/engine/site/header.py +228 -0
  864. offload/engine/site/inputs.py +115 -0
  865. offload/engine/site/matrix.py +434 -0
  866. offload/engine/site/scrub.py +294 -0
  867. offload/engine/skeleton.py +121 -0
  868. offload/engine/spec_text.py +242 -0
  869. offload/engine/stress.py +4122 -0
  870. offload/engine/stress_c.py +1000 -0
  871. offload/engine/stress_exec.py +805 -0
  872. offload/engine/stress_min.py +248 -0
  873. offload/engine/stress_report.py +552 -0
  874. offload/engine/textclean.py +97 -0
  875. offload/engine/toolchains.py +1070 -0
  876. offload/engine/transforms.py +511 -0
  877. offload/engine/usage.py +1252 -0
  878. offload/engine/widen.py +673 -0
  879. offload/engine/widen_progs.py +2396 -0
  880. offload/issues.py +146 -0
  881. offtarget-0.1.0.dist-info/METADATA +86 -0
  882. offtarget-0.1.0.dist-info/RECORD +886 -0
  883. offtarget-0.1.0.dist-info/WHEEL +4 -0
  884. offtarget-0.1.0.dist-info/entry_points.txt +2 -0
  885. offtarget-0.1.0.dist-info/licenses/LICENSE +21 -0
  886. offtarget-0.1.0.dist-info/licenses/THIRD_PARTY_NOTICES.md +20 -0
@@ -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"