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
offload/engine/f2c.py ADDED
@@ -0,0 +1,1783 @@
1
+ """Translate a generated free-form Fortran program into C11.
2
+
3
+ The C programs of the slice are the Fortran programs of ``offload.engine.gen``
4
+ ported statement by statement, with the same data, oracle and output line
5
+ (``RESULT ran_on_host=<0|1> check=<pass|fail>``). ``translate`` reads the
6
+ rendered Fortran source (header, optional module ``gen_mod``, ``program
7
+ gen_prog``) and writes C: derived types as structs, module variables and
8
+ procedures at file scope, and ``int main(void)``.
9
+ Arrays keep their Fortran extents and 1-based values (``a(i)`` is
10
+ ``a[i - 1]``). Allocatable arrays become fixed-size arrays, pointer arrays
11
+ ``int *``. Directives map ``!$omp`` to
12
+ ``#pragma omp``, ``do`` to ``for``, and Fortran reduction identifiers to C
13
+ operators; end directives go away and their ``nowait`` moves up.
14
+ ``TranslateError`` is raised for anything outside this subset (``character``
15
+ variables, assumed-shape dummies, ``workdistribute``)."""
16
+ from __future__ import annotations
17
+
18
+ import dataclasses
19
+ import re
20
+ from dataclasses import dataclass, field
21
+
22
+ from offload.engine.grammar import GrammarError, parse_directive
23
+
24
+
25
+ def _top_ops(t: str) -> set[str]:
26
+ """The binary operators of a rendered C expression outside
27
+ parentheses and brackets (they are rendered with blanks around)."""
28
+ ops, depth = set(), 0
29
+ for k, ch in enumerate(t):
30
+ if ch in "([":
31
+ depth += 1
32
+ elif ch in ")]":
33
+ depth -= 1
34
+ elif depth == 0 and ch == " ":
35
+ m = re.match(r" (\S+) ", t[k:])
36
+ if m and re.fullmatch(r"[-+*/%<>=!&|^?:]+", m.group(1)):
37
+ ops.add(m.group(1))
38
+ return ops
39
+
40
+
41
+ def _paren(t: str, right: bool = False) -> str:
42
+ """Operand `t` of % in parentheses where C precedence needs them
43
+ (mod(7*s + j, m) is (7*s + j) % m, not 7*s + j % m): the left
44
+ operand when it has an operator of lower precedence than %, the right
45
+ one when it has any operator."""
46
+ ops = _top_ops(t)
47
+ if right:
48
+ return f"({t})" if ops else t
49
+ return f"({t})" if ops - {"*", "/", "%"} else t
50
+
51
+
52
+ class TranslateError(Exception):
53
+ """The Fortran program uses something the translator does not port."""
54
+
55
+
56
+ # --- the Fortran source ---------------------------------------------------------
57
+
58
+ def _strip_comment(text: str) -> str:
59
+ q = None
60
+ for i, ch in enumerate(text):
61
+ if q:
62
+ if ch == q:
63
+ q = None
64
+ elif ch in "'\"":
65
+ q = ch
66
+ elif ch == "!":
67
+ return text[:i]
68
+ return text
69
+
70
+
71
+ def logical_lines(source: str) -> list[tuple[str, str]]:
72
+ """(kind, text) per logical line: "head" (a leading ``! `` header
73
+ line), "omp" (a directive, continuations joined, sentinel kept) or
74
+ "stmt"."""
75
+ out = []
76
+ lines = source.splitlines()
77
+ k = 0
78
+ header = True
79
+ while k < len(lines):
80
+ raw = lines[k]
81
+ s = raw.strip()
82
+ k += 1
83
+ if header and s.startswith("! "):
84
+ out.append(("head", s[2:]))
85
+ continue
86
+ header = False
87
+ if not s:
88
+ continue
89
+ if s.lower().startswith(("!$omp", "!$acc")):
90
+ # OpenACC programs (!$acc) too
91
+ sent = s[:5].lower()
92
+ text = s
93
+ while _strip_comment(text[5:]).rstrip().endswith("&"):
94
+ body = _strip_comment(text[5:]).rstrip()[:-1].rstrip()
95
+ nxt = lines[k].strip()
96
+ k += 1
97
+ if not nxt.lower().startswith(sent):
98
+ raise TranslateError(f"bad continuation {nxt!r}")
99
+ nxt = nxt[5:].lstrip()
100
+ if nxt.startswith("&"):
101
+ nxt = nxt[1:].lstrip()
102
+ text = sent + " " + body.lstrip() + " " + nxt
103
+ out.append(("omp", text))
104
+ continue
105
+ if s.startswith("!"):
106
+ continue
107
+ text = _strip_comment(s).rstrip()
108
+ while text.endswith("&"):
109
+ nxt = lines[k].strip()
110
+ k += 1
111
+ if nxt.startswith("&"):
112
+ nxt = nxt[1:]
113
+ text = text[:-1].rstrip() + " " + nxt.strip()
114
+ out.append(("stmt", text))
115
+ return out
116
+
117
+
118
+ # --- expressions ----------------------------------------------------------------
119
+
120
+ @dataclass
121
+ class E:
122
+ kind: str # num, real, logical, str, name, call, member, arrayc,
123
+ # binop, unop, section, kwarg, paren
124
+ value: str = ""
125
+ args: list = field(default_factory=list)
126
+
127
+
128
+ _ETOK = re.compile(r"""\s*(?:
129
+ (?P<real>\d+\.\d*(?:[dDeE][+-]?\d+)?|\d+[dDeE][+-]?\d+)
130
+ | (?P<num>\d+(?:_\w+)?)
131
+ | (?P<dotop>\.(?:and|or|not|eqv|neqv|eq|ne|lt|le|gt|ge|true|false)\.)
132
+ | (?P<str>'(?:[^']|'')*'|"(?:[^"]|"")*")
133
+ | (?P<name>[A-Za-z_]\w*)
134
+ | (?P<op>==|/=|<=|>=|=>|\*\*|//|\(/|/\)|[-+*/<>=(),:%\[\]])
135
+ )""", re.X | re.I)
136
+
137
+
138
+ def _etoks(text: str) -> list[tuple[str, str]]:
139
+ out, pos = [], 0
140
+ text = text.rstrip()
141
+ while pos < len(text):
142
+ m = _ETOK.match(text, pos)
143
+ if not m or m.end() == pos:
144
+ raise TranslateError(f"cannot read expression {text!r} at "
145
+ f"{text[pos:]!r}")
146
+ out.append((m.lastgroup, m.group(m.lastgroup)))
147
+ pos = m.end()
148
+ return out
149
+
150
+
151
+ _BIN = {".or.": 1, ".and.": 2, ".eqv.": 0, ".neqv.": 0,
152
+ "==": 4, "/=": 4, "<": 4, "<=": 4, ">": 4, ">=": 4,
153
+ ".eq.": 4, ".ne.": 4, ".lt.": 4, ".le.": 4, ".gt.": 4, ".ge.": 4,
154
+ "+": 6, "-": 6, "*": 7, "/": 7, "**": 9}
155
+ _REL = {".eq.": "==", ".ne.": "/=", ".lt.": "<", ".le.": "<=", ".gt.": ">",
156
+ ".ge.": ">="}
157
+
158
+
159
+ class _EParser:
160
+ def __init__(self, text: str):
161
+ self.toks = _etoks(text)
162
+ self.i = 0
163
+ self.text = text
164
+
165
+ def peek(self):
166
+ return self.toks[self.i] if self.i < len(self.toks) else (None, None)
167
+
168
+ def take(self, value=None):
169
+ t = self.peek()
170
+ if value is not None and (t[1] or "").lower() != value:
171
+ raise TranslateError(f"expected {value!r} in {self.text!r}")
172
+ self.i += 1
173
+ return t
174
+
175
+ def parse(self):
176
+ e = self.expr(0)
177
+ if self.i != len(self.toks):
178
+ raise TranslateError(f"trailing tokens in {self.text!r}")
179
+ return e
180
+
181
+ def expr(self, prec):
182
+ kind, v = self.peek()
183
+ low = (v or "").lower()
184
+ if low == ".not.":
185
+ self.take()
186
+ left = E("unop", ".not.", [self.expr(3)])
187
+ elif low in ("-", "+"):
188
+ self.take()
189
+ left = E("unop", low, [self.expr(6)])
190
+ else:
191
+ left = self.primary()
192
+ while True:
193
+ kind, v = self.peek()
194
+ low = (v or "").lower()
195
+ p = _BIN.get(low)
196
+ if p is None or p < prec:
197
+ return left
198
+ self.take()
199
+ low = _REL.get(low, low)
200
+ right = self.expr(p + 1 if low != "**" else p)
201
+ left = E("binop", low, [left, right])
202
+
203
+ def primary(self):
204
+ kind, v = self.take()
205
+ if kind is None:
206
+ raise TranslateError(f"expression ends early: {self.text!r}")
207
+ low = v.lower()
208
+ if kind == "real":
209
+ return E("real", v)
210
+ if kind == "num":
211
+ return E("num", v.split("_")[0])
212
+ if kind == "dotop" and low in (".true.", ".false."):
213
+ return E("logical", low)
214
+ if kind == "str":
215
+ return E("str", v)
216
+ if v == "(":
217
+ e = self.expr(0)
218
+ self.take(")")
219
+ return E("paren", "", [e])
220
+ if v == "[" or v == "(/":
221
+ items = []
222
+ close = "]" if v == "[" else "/)"
223
+ while self.peek()[1] != close:
224
+ items.append(self.expr(0))
225
+ if self.peek()[1] == ",":
226
+ self.take()
227
+ self.take(close)
228
+ return E("arrayc", "", items)
229
+ if kind == "name":
230
+ node = E("name", v)
231
+ while True:
232
+ if self.peek()[1] == "(":
233
+ self.take()
234
+ args = []
235
+ while self.peek()[1] != ")":
236
+ args.append(self.arg())
237
+ if self.peek()[1] == ",":
238
+ self.take()
239
+ self.take(")")
240
+ node = E("call", "", [node] + args)
241
+ elif self.peek()[1] == "%":
242
+ self.take()
243
+ _, comp = self.take()
244
+ node = E("member", comp, [node])
245
+ else:
246
+ return node
247
+ raise TranslateError(f"unexpected {v!r} in {self.text!r}")
248
+
249
+ def arg(self):
250
+ """An argument: an expression, a section l:u[:s], or name=value."""
251
+ kind, v = self.peek()
252
+ if kind == "name" and self.i + 1 < len(self.toks) and \
253
+ self.toks[self.i + 1][1] == "=":
254
+ self.take()
255
+ self.take()
256
+ return E("kwarg", v.lower(), [self.expr(0)])
257
+ parts: list = []
258
+ cur = None if self.peek()[1] == ":" else self.expr(0)
259
+ if self.peek()[1] != ":":
260
+ return cur
261
+ parts.append(cur)
262
+ while self.peek()[1] == ":":
263
+ self.take()
264
+ parts.append(None if self.peek()[1] in (":", ",", ")")
265
+ else self.expr(0))
266
+ return E("section", "", parts)
267
+
268
+
269
+ def parse_expr(text: str) -> E:
270
+ return _EParser(text).parse()
271
+
272
+
273
+ # --- symbols --------------------------------------------------------------------
274
+
275
+ @dataclass
276
+ class Var:
277
+ name: str
278
+ ftype: str # integer, logical, double, c_ptr, depend, alloc,
279
+ # alloctrait, struct:<t>, character
280
+ dims: list = field(default_factory=list) # Fortran extents (texts)
281
+ attrs: set = field(default_factory=set)
282
+ init: str | None = None
283
+ intent: str | None = None
284
+ deferred: bool = False # (:) shape
285
+
286
+
287
+ _TYPE = re.compile(r"^(integer|logical|double\s*precision|real|character"
288
+ r"|type|class)\b\s*(\([^)]*\))?\s*(.*)$", re.I)
289
+
290
+
291
+ def _split_top(text: str, sep: str = ",") -> list[str]:
292
+ out, cur, depth, q = [], "", 0, None
293
+ for ch in text:
294
+ if q:
295
+ q = None if ch == q else q
296
+ elif ch in "'\"":
297
+ q = ch
298
+ elif ch in "([":
299
+ depth += 1
300
+ elif ch in ")]":
301
+ depth -= 1
302
+ elif ch == sep and depth == 0:
303
+ out.append(cur.strip())
304
+ cur = ""
305
+ continue
306
+ cur += ch
307
+ out.append(cur.strip())
308
+ return [x for x in out if x]
309
+
310
+
311
+ def parse_declaration(stmt: str) -> list[Var] | None:
312
+ m = _TYPE.match(stmt.strip())
313
+ if not m or "::" not in stmt or re.match(r"^type\s*::", stmt.strip(),
314
+ re.I):
315
+ return None
316
+ base, kind_sel, _ = m.groups()
317
+ spec, ents = stmt.split("::", 1)
318
+ attrs_text = _split_top(spec)[1:]
319
+ b = base.lower().replace(" ", "")
320
+ ks = (kind_sel or "").strip("() ").lower()
321
+ if b == "integer":
322
+ ftype = {"": "integer", "omp_depend_kind": "depend",
323
+ "omp_allocator_handle_kind": "alloc"}.get(ks)
324
+ if ftype is None:
325
+ raise TranslateError(f"integer kind {ks!r}")
326
+ elif b == "logical":
327
+ ftype = "logical"
328
+ elif b in ("doubleprecision",):
329
+ ftype = "double"
330
+ elif b == "character":
331
+ raise TranslateError("character variables are Fortran-only here")
332
+ elif b == "type":
333
+ t = ks
334
+ ftype = {"c_ptr": "c_ptr", "omp_alloctrait": "alloctrait"}.get(
335
+ t, f"struct:{t}")
336
+ else:
337
+ raise TranslateError(f"type {b!r} is not ported")
338
+ attrs, dims, intent = set(), [], None
339
+ for a in attrs_text:
340
+ al = a.lower()
341
+ if al.startswith("intent"):
342
+ intent = re.search(r"\((\w+)\)", al).group(1)
343
+ elif al.startswith("dimension"):
344
+ dims = _split_top(re.search(r"\((.*)\)", a).group(1))
345
+ else:
346
+ attrs.add(al)
347
+ out = []
348
+ for ent in _split_top(ents):
349
+ mm = re.match(r"^([A-Za-z_]\w*)\s*(\((.*?)\))?\s*(?:=\s*(.*))?$",
350
+ ent.strip(), re.S)
351
+ if not mm:
352
+ raise TranslateError(f"entity {ent!r}")
353
+ d = _split_top(mm.group(3)) if mm.group(2) else list(dims)
354
+ deferred = bool(d) and all(x == ":" for x in d)
355
+ out.append(Var(mm.group(1), ftype, [] if deferred else d,
356
+ set(attrs), mm.group(4), intent, deferred))
357
+ return out
358
+
359
+
360
+ # --- C expression emission ------------------------------------------------------
361
+
362
+ _INTRINSIC_BIN = {"iand": "&", "ior": "|", "ieor": "^"}
363
+ _OMP_FUNCS = re.compile(r"^(omp|acc)_\w+$") # The OpenACC API
364
+ _REDOP = {".and.": "&&", ".or.": "||", "iand": "&", "ior": "|", "ieor": "^"}
365
+
366
+
367
+ def _simplify_minus_one(text: str) -> str:
368
+ """text - 1, folding an integer literal or a trailing + k."""
369
+ t = text.strip()
370
+ if re.fullmatch(r"-?\d+", t):
371
+ return str(int(t) - 1)
372
+ m = re.fullmatch(r"(.*\S)\s*\+\s*(\d+)", t)
373
+ if m and _balanced(m.group(1)):
374
+ k = int(m.group(2)) - 1
375
+ return m.group(1) if k == 0 else f"{m.group(1)} + {k}"
376
+ m = re.fullmatch(r"(.*\S)\s*-\s*(\d+)", t)
377
+ if m and _balanced(m.group(1)):
378
+ return f"{m.group(1)} - {int(m.group(2)) + 1}"
379
+ return f"{t} - 1"
380
+
381
+
382
+ def _balanced(t: str) -> bool:
383
+ d = 0
384
+ for ch in t:
385
+ d += ch in "(["
386
+ d -= ch in ")]"
387
+ if d < 0:
388
+ return False
389
+ return d == 0
390
+
391
+
392
+ class Ctx:
393
+ """The symbols visible to a statement: name -> Var (innermost wins),
394
+ and the derived types' components."""
395
+
396
+ def __init__(self, scopes: list[dict], functions: dict, tr):
397
+ self.scopes = scopes
398
+ self.functions = functions
399
+ self.tr = tr
400
+
401
+ def var(self, name: str) -> Var | None:
402
+ low = name.lower()
403
+ for s in reversed(self.scopes):
404
+ if low in s:
405
+ return s[low]
406
+ return None
407
+
408
+ def of(self, e: "E") -> Var | None:
409
+ """The Var of a name or component designator (no subscripts)."""
410
+ if e.kind == "name":
411
+ return self.var(e.value)
412
+ if e.kind == "member":
413
+ base = self.of(e.args[0])
414
+ if base is None or not base.ftype.startswith("struct:"):
415
+ return None
416
+ comps = self.tr.types.get(base.ftype[7:], {})
417
+ return comps.get(e.value.lower())
418
+ return None
419
+
420
+
421
+ class Emitter:
422
+ def __init__(self, ctx: Ctx):
423
+ self.ctx = ctx
424
+
425
+ # shapes ------------------------------------------------------------------
426
+ def shape(self, e: E) -> list[str]:
427
+ """Extents (C texts) of an array-valued expression, [] if scalar."""
428
+ k = e.kind
429
+ if k == "name":
430
+ v = self.ctx.var(e.value)
431
+ return list(self.extents(v)) if v and (v.dims or v.deferred) \
432
+ else []
433
+ if k == "paren":
434
+ return self.shape(e.args[0])
435
+ if k == "unop":
436
+ return self.shape(e.args[0])
437
+ if k == "binop":
438
+ return self.shape(e.args[0]) or self.shape(e.args[1])
439
+ if k == "member":
440
+ v = self.ctx.of(e)
441
+ return [self.c(parse_expr(d)) for d in v.dims] if v and v.dims \
442
+ else []
443
+ if k == "call":
444
+ head = e.args[0]
445
+ if head.kind in ("name", "member"):
446
+ v = self.ctx.of(head)
447
+ if v is not None and (v.dims or v.deferred):
448
+ out = []
449
+ for a in e.args[1:]:
450
+ if a.kind == "section":
451
+ lo, hi = a.args[0], a.args[1] if len(a.args) > 1 \
452
+ else None
453
+ lo_t = self.c(lo) if lo else "1"
454
+ hi_t = self.c(hi) if hi else "?"
455
+ out.append(_extent(lo_t, hi_t))
456
+ return out
457
+ fn = head.value.lower()
458
+ if fn == "sum" and any(a.kind == "kwarg" for a in e.args[1:]):
459
+ full = self.shape(e.args[1])
460
+ dim = int(next(a for a in e.args[1:]
461
+ if a.kind == "kwarg").args[0].value)
462
+ return [x for j, x in enumerate(full) if j != dim - 1]
463
+ if fn in ("merge", "max", "min", "mod", "abs"):
464
+ for a in e.args[1:]:
465
+ s = self.shape(a)
466
+ if s:
467
+ return s
468
+ return []
469
+ return []
470
+
471
+ def extents(self, v: Var) -> list[str]:
472
+ if v.deferred:
473
+ ext = self.ctx.tr.allocated.get(v.name.lower())
474
+ if ext is None:
475
+ raise TranslateError(f"extent of {v.name} unknown")
476
+ return ext
477
+ return [self.c(parse_expr(d)) for d in v.dims]
478
+
479
+ # scalar emission ----------------------------------------------------------
480
+ def c(self, e: E, idx: list[str] | None = None) -> str:
481
+ """C text of `e`; for an array-valued expression, its element at
482
+ the 0-based index texts `idx`."""
483
+ k = e.kind
484
+ if k == "num":
485
+ return e.value
486
+ if k == "real":
487
+ return re.sub(r"[dD]", "e", e.value).replace("e0", "") \
488
+ if not re.search(r"[dD][+-]?[1-9]", e.value) else \
489
+ re.sub(r"[dD]", "e", e.value)
490
+ if k == "logical":
491
+ return "true" if e.value == ".true." else "false"
492
+ if k == "str":
493
+ body = e.value[1:-1].replace("''", "'")
494
+ return '"' + body.replace('"', '\\"') + '"'
495
+ if k == "paren":
496
+ return f"({self.c(e.args[0], idx)})"
497
+ if k == "name":
498
+ v = self.ctx.var(e.value)
499
+ name = e.value
500
+ if v is not None and (v.dims or v.deferred) and idx is not None:
501
+ return name + "".join(f"[{i}]" for i in idx)
502
+ if v is not None and v.intent in ("inout", "out") and \
503
+ not v.dims and not v.deferred:
504
+ return f"(*{name})"
505
+ return name
506
+ if k == "member":
507
+ v = self.ctx.of(e)
508
+ text = f"{self.c(e.args[0])}.{e.value}"
509
+ if v is not None and v.dims and idx is not None:
510
+ return text + "".join(f"[{i}]" for i in idx)
511
+ return text
512
+ if k == "unop":
513
+ op = {".not.": "!", "-": "-", "+": "+"}[e.value]
514
+ inner = e.args[0]
515
+ t = self.c(inner, idx)
516
+ if inner.kind == "binop":
517
+ t = f"({t})"
518
+ return f"{op}{t}"
519
+ if k == "binop":
520
+ return self.binop(e, idx)
521
+ if k == "call":
522
+ return self.call(e, idx)
523
+ if k == "arrayc":
524
+ return "{" + ", ".join(self.c(a) for a in e.args) + "}"
525
+ raise TranslateError(f"cannot emit {e.kind}")
526
+
527
+ _PREC = {"||": 1, "&&": 2, "==": 4, "!=": 4, "<": 5, "<=": 5, ">": 5,
528
+ ">=": 5, "+": 6, "-": 6, "*": 7, "/": 7}
529
+
530
+ def binop(self, e: E, idx) -> str:
531
+ op = e.value
532
+ if op == "**":
533
+ raise TranslateError("** is not ported")
534
+ cop = {".and.": "&&", ".or.": "||", ".eqv.": "==", ".neqv.": "!=",
535
+ "/=": "!="}.get(op, op)
536
+ p = self._PREC[cop]
537
+ parts = []
538
+ for side, a in enumerate(e.args):
539
+ t = self.c(a, idx)
540
+ if a.kind == "binop":
541
+ ap = self._PREC.get({".and.": "&&", ".or.": "||",
542
+ ".eqv.": "==", ".neqv.": "!=",
543
+ "/=": "!="}.get(a.value, a.value), 9)
544
+ if ap < p or (ap == p and side == 1 and cop in "-/") or (
545
+ cop in ("&&", "||", "==", "!=") and ap != p
546
+ and ap <= 5):
547
+ t = f"({t})"
548
+ parts.append(t)
549
+ return f"{parts[0]} {cop} {parts[1]}"
550
+
551
+ def call(self, e: E, idx) -> str:
552
+ head, args = e.args[0], e.args[1:]
553
+ if head.kind == "member":
554
+ v = self.ctx.of(head)
555
+ if v is not None and v.dims:
556
+ return self.element(e, idx)
557
+ if head.kind != "name":
558
+ raise TranslateError("call of a non-name")
559
+ name = head.value
560
+ low = name.lower()
561
+ v = self.ctx.var(name)
562
+ if v is not None and (v.dims or v.deferred):
563
+ return self.element(e, idx)
564
+ if low == "merge":
565
+ a, b, c = args
566
+ return f"({self.c(c, idx)} ? {self.c(a, idx)} : {self.c(b, idx)})"
567
+ if low == "mod":
568
+ # An operand with an operator keeps its own parentheses
569
+ # (mod(7*s + j, m) is (7*s + j) % m, not 7*s + j % m)
570
+ x = _paren(self.c(args[0], idx))
571
+ y = _paren(self.c(args[1], idx), right=True)
572
+ return f"({x} % {y})"
573
+ if low in ("max", "min"):
574
+ x, y = (self.c(a, idx) for a in args)
575
+ op = ">" if low == "max" else "<"
576
+ return f"({x} {op} {y} ? {x} : {y})"
577
+ if low in _INTRINSIC_BIN:
578
+ x, y = (self.c(a, idx) for a in args)
579
+ return f"({x} {_INTRINSIC_BIN[low]} {y})"
580
+ if low == "abs":
581
+ x = self.c(args[0], idx)
582
+ return f"({x} < 0 ? -({x}) : {x})"
583
+ if low == "c_loc":
584
+ a = args[0]
585
+ if a.kind == "name":
586
+ av = self.ctx.var(a.value)
587
+ if av is not None and (av.dims or av.deferred):
588
+ return a.value
589
+ return f"&{a.value}"
590
+ return f"&{self.c(a)}"
591
+ if low == "c_associated":
592
+ return f"({self.c(args[0])} == {self.c(args[1])})"
593
+ if low == "omp_alloctrait":
594
+ return "{" + ", ".join(self.c(a) for a in args) + "}"
595
+ if low in ("all", "any", "count", "sum"):
596
+ return self.ctx.tr.lift(e, self)
597
+ if low == "acc_is_present" and len(args) == 1 and \
598
+ args[0].kind == "name":
599
+ # The Fortran form takes the variable (3.4 §3.2.30);
600
+ # the C form its address and size in bytes
601
+ a = args[0].value
602
+ av = self.ctx.var(a)
603
+ if av is not None and "pointer" in av.attrs and \
604
+ (av.dims or av.deferred):
605
+ ext = self.ctx.tr.allocated.get(a.lower())
606
+ if ext is None:
607
+ raise TranslateError(f"extent of pointer {a}")
608
+ return f"acc_is_present({a}, ({ext[0]}) * sizeof(*{a}))"
609
+ if av is not None and (av.dims or av.deferred):
610
+ return f"acc_is_present({a}, sizeof({a}))"
611
+ return f"acc_is_present(&{a}, sizeof({a}))"
612
+ if _OMP_FUNCS.match(low) or low in self.ctx.functions:
613
+ fn = self.ctx.functions.get(low)
614
+ out = []
615
+ for k, a in enumerate(args):
616
+ t = self.c(a, idx)
617
+ if fn is not None and k < len(fn) and fn[k] in ("inout",
618
+ "out"):
619
+ t = "&" + t if not t.startswith("(*") else t[2:-1]
620
+ out.append(t)
621
+ return f"{name}({', '.join(out)})"
622
+ raise TranslateError(f"unknown function {name!r}")
623
+
624
+ def element(self, e: E, idx) -> str:
625
+ """An array reference a(...) (element, or element `idx` of a
626
+ section)."""
627
+ head, args = e.args[0], e.args[1:]
628
+ v = self.ctx.of(head)
629
+ subs = []
630
+ k = 0
631
+ for a in args:
632
+ if a.kind == "section":
633
+ lo = self.c(a.args[0]) if a.args[0] is not None else "1"
634
+ if idx is None:
635
+ raise TranslateError("section in a scalar context")
636
+ base = _simplify_minus_one(lo)
637
+ subs.append(idx[k] if base == "0" else f"{base} + {idx[k]}")
638
+ k += 1
639
+ else:
640
+ subs.append(_simplify_minus_one(self.c(a, None if not
641
+ self.shape(a)
642
+ else idx)))
643
+ name = self.c(head) if head.kind == "member" else head.value
644
+ if v is not None and v.intent in ("inout", "out") and not v.dims:
645
+ name = f"(*{name})"
646
+ return name + "".join(f"[{s}]" for s in subs)
647
+
648
+ # clause items ---------------------------------------------------------------
649
+ def item(self, text: str, mapping: bool = False) -> str:
650
+ """A list item of a clause: x, x(i), x(l:u), s%c."""
651
+ e = parse_expr(text)
652
+ if e.kind == "name":
653
+ v = self.ctx.var(e.value)
654
+ if mapping and v is not None and "pointer" in v.attrs and \
655
+ (v.dims or v.deferred):
656
+ ext = self.ctx.tr.allocated.get(v.name.lower())
657
+ if ext is None:
658
+ raise TranslateError(f"extent of pointer {v.name}")
659
+ return f"{v.name}[0:{ext[0]}]"
660
+ if mapping and v is not None and v.intent in ("inout", "out") \
661
+ and not v.dims and not v.deferred:
662
+ # A scalar dummy passed by reference is a pointer
663
+ # in C: map its pointee (the Fortran dummy's storage)
664
+ return f"{e.value}[0:1]"
665
+ return e.value
666
+ if e.kind == "member":
667
+ return self.c(e)
668
+ if e.kind == "call" and e.args[0].kind in ("name", "member"):
669
+ v = self.ctx.of(e.args[0])
670
+ if v is None or not (v.dims or v.deferred):
671
+ raise TranslateError(f"list item {text!r}")
672
+ subs = []
673
+ for a in e.args[1:]:
674
+ if a.kind == "section":
675
+ lo = self.c(a.args[0]) if a.args[0] is not None else "1"
676
+ hi = self.c(a.args[1]) if len(a.args) > 1 and \
677
+ a.args[1] is not None else None
678
+ if hi is None:
679
+ hi = self.extents(v)[len(subs)]
680
+ start = _simplify_minus_one(lo)
681
+ length = _extent(lo, hi)
682
+ st = f":{self.c(a.args[2])}" if len(a.args) > 2 and \
683
+ a.args[2] is not None else ""
684
+ subs.append(f"{start}:{length}{st}")
685
+ else:
686
+ subs.append(_simplify_minus_one(self.c(a)))
687
+ return self.c(e.args[0]) + "".join(f"[{s}]" for s in subs)
688
+ raise TranslateError(f"list item {text!r}")
689
+
690
+
691
+ def _extent(lo: str, hi: str) -> str:
692
+ """hi - lo + 1, folded where both are literals or lo is 1."""
693
+ if re.fullmatch(r"-?\d+", lo) and re.fullmatch(r"-?\d+", hi):
694
+ return str(int(hi) - int(lo) + 1)
695
+ if lo.strip() == "1":
696
+ return hi
697
+ if lo.strip() == hi.strip():
698
+ return "1" # A one-element section a(i:i)
699
+ m = re.fullmatch(r"(.+?)\s*-\s*(\d+)", hi)
700
+ if re.fullmatch(r"\d+", lo) and m:
701
+ return f"{m.group(1)} - {int(m.group(2)) + int(lo) - 1}"
702
+ return f"{hi} - ({lo}) + 1" if not re.fullmatch(r"\w+", lo) \
703
+ else f"{hi} - {lo} + 1"
704
+
705
+
706
+ # --- program structure ------------------------------------------------------------
707
+
708
+ @dataclass
709
+ class Node:
710
+ kind: str # stmt, do, while, if, dir, ifone
711
+ text: str = ""
712
+ body: list = field(default_factory=list)
713
+ orelse: list = field(default_factory=list)
714
+ end_clauses: str = "" # clauses of a paired end directive
715
+ directive: object = None # grammar.Directive of a dir node
716
+ line: str = "" # the directive's full text
717
+
718
+
719
+ @dataclass
720
+ class Unit:
721
+ kind: str # module, program, function, subroutine
722
+ name: str
723
+ params: list = field(default_factory=list)
724
+ spec: list = field(default_factory=list) # (kind, text)
725
+ body: list = field(default_factory=list) # (kind, text)
726
+ procs: list = field(default_factory=list) # module procedures
727
+ result_type: str = ""
728
+
729
+
730
+ _PROC_HEAD = re.compile(r"^(?:(integer|logical)\s+)?(function|subroutine)\s+"
731
+ r"([a-z_]\w*)\s*\(([^)]*)\)\s*$", re.I)
732
+ _END_UNIT = re.compile(r"^end\s*(module|program|function|subroutine)\b", re.I)
733
+ _SPEC_STMT = re.compile(r"^(use\b|implicit\b|integer\b|logical\b|double\s*"
734
+ r"precision\b|type\b|character\b|real\b)", re.I)
735
+
736
+
737
+ def _is_spec(kind: str, text: str, in_type: bool) -> bool:
738
+ """A line of a specification part: USE, IMPLICIT, a type declaration,
739
+ a derived-type definition line, or a declarative directive."""
740
+ low = text.lower().strip()
741
+ if in_type:
742
+ return True
743
+ if kind == "omp":
744
+ try:
745
+ d = parse_directive(text, "fortran", _VERSION[0])
746
+ except GrammarError as err:
747
+ raise TranslateError(f"directive {text!r}: {err}") from err
748
+ return d.name in ("declare target", "requires", "threadprivate",
749
+ "declare mapper", "declare reduction",
750
+ "declare simd", "error", "declare", "routine")
751
+ return bool(re.match(r"^(use\b|implicit\b|type\s*::|type\s*\(|"
752
+ r"(integer|logical|double\s*precision|real|"
753
+ r"character)\b)", low))
754
+
755
+
756
+ def _units(lines) -> list[Unit]:
757
+ units: list[Unit] = []
758
+ stack: list[Unit] = []
759
+ in_exec: dict[int, bool] = {}
760
+ in_type: dict[int, bool] = {}
761
+ for kind, text in lines:
762
+ if kind == "head":
763
+ continue
764
+ low = text.lower().strip()
765
+ if kind == "stmt":
766
+ m = re.match(r"^(module|program)\s+(\w+)$", low)
767
+ if m and not stack:
768
+ u = Unit(m.group(1), m.group(2))
769
+ units.append(u)
770
+ stack.append(u)
771
+ continue
772
+ m = _PROC_HEAD.match(text.strip())
773
+ if m and not stack:
774
+ # An external procedure (the OpenACC programs'
775
+ # routine and bind recipes), a function at file scope
776
+ u = Unit(m.group(2).lower(), m.group(3).lower(),
777
+ [p.strip().lower() for p in m.group(4).split(",")
778
+ if p.strip()],
779
+ result_type=(m.group(1) or "").lower())
780
+ units.append(u)
781
+ stack.append(u)
782
+ continue
783
+ if m and stack:
784
+ u = Unit(m.group(2).lower(), m.group(3).lower(),
785
+ [p.strip().lower() for p in m.group(4).split(",")
786
+ if p.strip()],
787
+ result_type=(m.group(1) or "").lower())
788
+ stack[-1].procs.append(u)
789
+ stack.append(u)
790
+ continue
791
+ if low == "contains":
792
+ in_exec[id(stack[-1])] = True
793
+ continue
794
+ if _END_UNIT.match(low):
795
+ stack.pop()
796
+ continue
797
+ if not stack:
798
+ raise TranslateError(f"statement outside a unit: {text!r}")
799
+ u = stack[-1]
800
+ if not in_exec.get(id(u)) and _is_spec(kind, text,
801
+ in_type.get(id(u), False)):
802
+ if kind == "stmt" and re.match(r"^type\s*::", low):
803
+ in_type[id(u)] = True
804
+ elif kind == "stmt" and re.match(r"^end\s*type\b", low):
805
+ in_type[id(u)] = False
806
+ u.spec.append((kind, text))
807
+ continue
808
+ in_exec[id(u)] = True
809
+ u.body.append((kind, text))
810
+ return units
811
+
812
+
813
+ _VERSION = [52]
814
+ # The model of the program being translated (omp, or acc for an
815
+ # OpenACC 3.4 program: !$acc -> #pragma acc)
816
+ _MODEL = ["omp"]
817
+
818
+
819
+ def _tree(lines, version) -> list[Node]:
820
+ """Nodes of an executable part."""
821
+ from offload.engine.rules import association
822
+ root: list[Node] = []
823
+ stack: list[tuple[Node, list]] = [] # (node, the list it fills)
824
+
825
+ def cur() -> list:
826
+ return stack[-1][1] if stack else root
827
+
828
+ pending_loop: list[Node] = [] # loop/statement directives awaiting body
829
+ k = 0
830
+ lines = list(lines)
831
+ while k < len(lines):
832
+ kind, text = lines[k]
833
+ k += 1
834
+ low = text.lower().strip()
835
+ if kind == "omp":
836
+ try:
837
+ d = parse_directive(text, "fortran", version)
838
+ except GrammarError as err:
839
+ raise TranslateError(f"directive {text!r}: {err}") from err
840
+ if d.end:
841
+ # the end of the innermost open block directive, or of the
842
+ # loop/statement directive that just closed
843
+ last = cur()[-1] if cur() else None
844
+ if stack and stack[-1][0].kind == "dir" and \
845
+ stack[-1][0].directive.name == d.name:
846
+ node = stack.pop()[0]
847
+ node.end_clauses = _clause_text(text)
848
+ continue
849
+ if last is not None and last.kind == "dir" and \
850
+ last.directive.name == d.name:
851
+ last.end_clauses = _clause_text(text)
852
+ continue
853
+ raise TranslateError(f"unpaired end directive {text!r}")
854
+ node = Node("dir", directive=d, line=text)
855
+ how = association(d.name, _MODEL[0])
856
+ if _MODEL[0] == "acc" and d.name == "atomic" and any(
857
+ kk == "omp" and re.match(r"^!\$acc\s+end\s*atomic\b",
858
+ tt.strip(), re.I)
859
+ for kk, tt in lines[k:k + 3]):
860
+ # An OpenACC atomic capture of two statements
861
+ # closed by end atomic: in C, a structured block
862
+ # (3.4 §2.12, p.81)
863
+ how = "block"
864
+ node.text = "block"
865
+ cur().append(node)
866
+ if how == "block":
867
+ stack.append((node, node.body))
868
+ elif how in ("loop", "statement"):
869
+ pending_loop.append(node)
870
+ stack.append((node, node.body))
871
+ node.text = "pending"
872
+ continue
873
+ # statements
874
+ if re.match(r"^do\s+while\s*\(", low):
875
+ node = Node("while", text=re.match(r"^do\s+while\s*\((.*)\)$",
876
+ text.strip(), re.I).group(1))
877
+ cur().append(node)
878
+ stack.append((node, node.body))
879
+ continue
880
+ m = re.match(r"^do\s+([a-z_]\w*)\s*=\s*(.*)$", low)
881
+ if m:
882
+ node = Node("do", text=text.strip()[2:].strip())
883
+ cur().append(node)
884
+ stack.append((node, node.body))
885
+ continue
886
+ if re.match(r"^end\s*do$", low):
887
+ while stack and stack[-1][0].kind not in ("do", "while"):
888
+ raise TranslateError(f"end do inside {stack[-1][0].kind}")
889
+ stack.pop()
890
+ _close_pending(stack)
891
+ continue
892
+ m = re.match(r"^if\s*\((.*)\)\s*then$", text.strip(), re.I)
893
+ if m and _balanced(m.group(1)):
894
+ node = Node("if", text=m.group(1))
895
+ cur().append(node)
896
+ stack.append((node, node.body))
897
+ continue
898
+ if re.match(r"^else\s*if\b", low):
899
+ raise TranslateError("else if is not ported")
900
+ if low == "else":
901
+ node = stack[-1][0]
902
+ stack[-1] = (node, node.orelse)
903
+ continue
904
+ if re.match(r"^end\s*if$", low):
905
+ stack.pop()
906
+ _close_pending(stack)
907
+ continue
908
+ cond_rest = _if_parts(text.strip())
909
+ if cond_rest is not None:
910
+ cur().append(Node("ifone", text=cond_rest[0],
911
+ body=[Node("stmt", text=cond_rest[1])]))
912
+ _close_pending(stack)
913
+ continue
914
+ cur().append(Node("stmt", text=text.strip()))
915
+ _close_pending(stack)
916
+ if stack:
917
+ raise TranslateError(f"unclosed {stack[-1][0].kind}")
918
+ return root
919
+
920
+
921
+ def _if_parts(text: str):
922
+ """(condition, statement) of a one-line logical IF, else None."""
923
+ m = re.match(r"^if\s*\(", text, re.I)
924
+ if not m:
925
+ return None
926
+ depth = 0
927
+ for j in range(m.end() - 1, len(text)):
928
+ depth += text[j] == "("
929
+ depth -= text[j] == ")"
930
+ if depth == 0:
931
+ rest = text[j + 1:].strip()
932
+ if not rest or rest.lower() == "then":
933
+ return None
934
+ return text[m.end():j], rest
935
+ return None
936
+
937
+
938
+ def _close_pending(stack):
939
+ """Close loop/statement directives whose one associated construct is
940
+ complete."""
941
+ while stack and stack[-1][0].kind == "dir" and \
942
+ stack[-1][0].text == "pending" and stack[-1][0].body:
943
+ node = stack.pop()[0]
944
+ node.text = ""
945
+
946
+
947
+ def _clause_text(line: str) -> str:
948
+ """The clauses of a directive line (after the directive name)."""
949
+ d_text = line.strip()[5:].strip()
950
+ return _split_name(d_text)[1]
951
+
952
+
953
+ def _split_name(text: str) -> tuple[str, str]:
954
+ """(directive name as written, with its parenthesised argument if any;
955
+ clause text) of a directive without its sentinel: the longest prefix
956
+ of words that the grammar reads as the directive (or end directive)
957
+ name."""
958
+ cuts = sorted({m.start() for m in re.finditer(r"[ (]", text)}
959
+ | {len(text)}, reverse=True)
960
+ for cut in cuts:
961
+ head = text[:cut].strip()
962
+ if not head or "(" in head:
963
+ continue
964
+ try:
965
+ d = parse_directive(f"!${_MODEL[0]} " + head, "fortran",
966
+ _VERSION[0])
967
+ if d.clauses:
968
+ continue
969
+ except GrammarError as err:
970
+ if err.code != "missing_required":
971
+ continue
972
+ rest = text[cut:].strip()
973
+ if rest.startswith("("): # a directive argument: keep with the name
974
+ depth = 0
975
+ for j, ch in enumerate(rest):
976
+ depth += ch == "("
977
+ depth -= ch == ")"
978
+ if depth == 0:
979
+ break
980
+ head += rest[:j + 1]
981
+ rest = rest[j + 1:].strip()
982
+ return head, rest
983
+ raise TranslateError(f"no directive name in {text!r}")
984
+
985
+
986
+ # --- the translator -------------------------------------------------------------
987
+
988
+ _CTYPE = {"integer": "int", "logical": "bool", "double": "double",
989
+ "c_ptr": "void *", "depend": "omp_depend_t",
990
+ "alloc": "omp_allocator_handle_t",
991
+ "alloctrait": "omp_alloctrait_t"}
992
+ _KEYWORDS = {
993
+ "to", "from", "tofrom", "alloc", "release", "delete", "present",
994
+ "always", "close", "self", "storage", "ref_ptee", "ref_ptr",
995
+ "ref_ptr_ptee", "static", "dynamic", "guided", "auto", "runtime",
996
+ "monotonic", "nonmonotonic", "simd", "inscan", "task", "default",
997
+ "conditional", "concurrent", "reproducible", "unconstrained", "in", "out",
998
+ "inout", "inoutset", "mutexinoutset", "depobj", "ancestor", "device_num",
999
+ "any", "host", "nohost", "primary", "master", "spread", "seq_cst",
1000
+ "acq_rel", "acquire", "relaxed", "none", "shared", "private",
1001
+ "firstprivate", "scalar", "aggregate", "pointer", "all", "parallel",
1002
+ "teams", "thread", "val", "strict", "saved", "automap", "fatal",
1003
+ "warning", "max", "min", "+", "-", "*", "compilation", "execution",
1004
+ "omp_all_memory"}
1005
+ _COMPLEX = re.compile(r"^(mapper|traits|memspace|allocator|align|step|"
1006
+ r"original)\s*\((.*)\)$", re.I | re.S)
1007
+ _REDUCTION_CLAUSES = {"reduction", "in_reduction", "task_reduction"}
1008
+ # clauses whose pieces are never directive names (only list items)
1009
+ _LIST_ONLY = {"shared", "private", "firstprivate", "lastprivate"}
1010
+
1011
+
1012
+ def _directive_names() -> frozenset:
1013
+ from offload.engine.catalog import default_grammar, default_skeleton
1014
+ if not _DNAMES:
1015
+ sk, g = default_skeleton(), default_grammar()
1016
+ _DNAMES.update(s.text for d in sk.directives.values()
1017
+ for s in d.spellings)
1018
+ _DNAMES.update(e.spelling for e in g.spellings)
1019
+ return frozenset(_DNAMES)
1020
+
1021
+
1022
+ _DNAMES: set = set()
1023
+ _MAP_CLAUSES = {"map", "to", "from"}
1024
+ # The OpenACC data clauses (a pointer list item is mapped as the
1025
+ # array section of its pointee, as in a map clause)
1026
+ _ACC_DATA_CLAUSES = {"copy", "copyin", "copyout", "create", "present",
1027
+ "no_create", "delete", "attach", "detach", "deviceptr",
1028
+ "device_resident", "link", "self", "host", "device",
1029
+ "use_device", "pcopy", "pcopyin", "pcopyout",
1030
+ "pcreate"}
1031
+
1032
+
1033
+ class Translator:
1034
+ def __init__(self, source: str, version: int):
1035
+ from offload.engine.catalog import model_of
1036
+ _VERSION[0] = version
1037
+ _MODEL[0] = model_of(version)
1038
+ self.model = _MODEL[0]
1039
+ self.version = version
1040
+ self.lines = logical_lines(source)
1041
+ self.allocated: dict[str, list[str]] = {}
1042
+ self.ntmp = 0
1043
+ self.pre: list[str] = []
1044
+ self.needs_stdlib = False
1045
+ self.functions: dict[str, list] = {} # name -> intents of dummies
1046
+ self.file_scope: list[str] = []
1047
+ self.clause_names: set[str] = set()
1048
+ self._raw_alloc: dict[str, list[str]] = {}
1049
+ self.types: dict[str, dict] = {}
1050
+
1051
+ # ---- helpers ----
1052
+ def fresh(self, stem: str) -> str:
1053
+ self.ntmp += 1
1054
+ return f"{stem}{self.ntmp}_"
1055
+
1056
+ def lift(self, e: E, em: "Emitter") -> str:
1057
+ """A reduction intrinsic (all/any/count/sum) as a temporary computed
1058
+ by loops in self.pre; returns its name."""
1059
+ fn = e.args[0].value.lower()
1060
+ args = e.args[1:]
1061
+ if any(a.kind == "kwarg" for a in args):
1062
+ raise TranslateError(f"{fn} with dim= outside all()")
1063
+ arg = args[0]
1064
+ shp = em.shape(arg)
1065
+ if not shp:
1066
+ raise TranslateError(f"{fn} of a scalar")
1067
+ t = self.fresh("t")
1068
+ init, upd = {
1069
+ "all": ("bool", "true", "{t} = {t} && ({x});"),
1070
+ "any": ("bool", "false", "{t} = {t} || ({x});"),
1071
+ "count": ("int", "0", "if ({x}) {t}++;"),
1072
+ "sum": ("int", "0", "{t} += {x};"),
1073
+ }[fn][0:2], {"all": "{t} = {t} && ({x});",
1074
+ "any": "{t} = {t} || ({x});",
1075
+ "count": "if ({x}) {t}++;",
1076
+ "sum": "{t} += {x};"}[fn]
1077
+ idx = [self.fresh("k") for _ in shp]
1078
+ body = self.elements(arg, em, idx)
1079
+ self.pre.append(f"{init[0]} {t} = {init[1]};")
1080
+ self.pre += _loops(shp, idx, [upd.format(t=t, x=body)])
1081
+ return t
1082
+
1083
+ def elements(self, e: E, em: "Emitter", idx: list[str]) -> str:
1084
+ """Element text of an array-valued expression at `idx`, with sum(...,
1085
+ dim=) parts precomputed into temporaries."""
1086
+ e = self._presum(e, em)
1087
+ return em.c(e, idx)
1088
+
1089
+ def _presum(self, e: E, em: "Emitter") -> E:
1090
+ if e.kind == "call" and e.args[0].kind == "name" and \
1091
+ e.args[0].value.lower() == "sum" and any(
1092
+ a.kind == "kwarg" for a in e.args[1:]):
1093
+ arr = e.args[1]
1094
+ dim = int(next(a for a in e.args[1:]
1095
+ if a.kind == "kwarg").args[0].value)
1096
+ full = em.shape(arr)
1097
+ keep = [x for j, x in enumerate(full) if j != dim - 1]
1098
+ t = self.fresh("t")
1099
+ idx = [self.fresh("k") for _ in full]
1100
+ out_idx = [x for j, x in enumerate(idx) if j != dim - 1]
1101
+ decl = f"int {t}" + "".join(f"[{x}]" for x in keep) + ";"
1102
+ self.pre.append(decl)
1103
+ self.pre += _loops(keep, out_idx,
1104
+ [f"{t}{''.join(f'[{x}]' for x in out_idx)}"
1105
+ " = 0;"])
1106
+ self.pre += _loops(full, idx, [
1107
+ f"{t}{''.join(f'[{x}]' for x in out_idx)} += "
1108
+ f"{em.c(arr, idx)};"])
1109
+ em.ctx.scopes[-1][t] = Var(t, "integer", keep)
1110
+ return E("name", t)
1111
+ if e.args:
1112
+ e = E(e.kind, e.value, [self._presum(a, em) if isinstance(a, E)
1113
+ else a for a in e.args])
1114
+ return e
1115
+
1116
+ # ---- symbols ----
1117
+ def declare(self, scope: dict, spec: list) -> list[tuple]:
1118
+ """Fill `scope` from a specification part; returns the derived types
1119
+ [(name, [Var])] it defines."""
1120
+ types, cur = [], None
1121
+ for kind, text in spec:
1122
+ if kind != "stmt":
1123
+ continue
1124
+ low = text.lower().strip()
1125
+ m = re.match(r"^type\s*::\s*(\w+)$", low)
1126
+ if m:
1127
+ cur = (m.group(1), [])
1128
+ types.append(cur)
1129
+ continue
1130
+ if re.match(r"^end\s*type\b", low):
1131
+ cur = None
1132
+ continue
1133
+ if low.startswith(("use", "implicit")):
1134
+ continue
1135
+ vs = parse_declaration(text)
1136
+ if vs is None:
1137
+ raise TranslateError(f"declaration {text!r}")
1138
+ for v in vs:
1139
+ if cur is not None:
1140
+ cur[1].append(v)
1141
+ else:
1142
+ scope[v.name.lower()] = v
1143
+ return types
1144
+
1145
+ def c_decl(self, v: Var, em: Emitter, static: bool = False) -> str:
1146
+ if "external" in v.attrs:
1147
+ return "" # An external function, defined before main
1148
+ if v.ftype.startswith("struct:"):
1149
+ base = f"struct {v.ftype[7:]}"
1150
+ else:
1151
+ base = _CTYPE[v.ftype]
1152
+ star = ""
1153
+ if "pointer" in v.attrs and (v.dims or v.deferred):
1154
+ star = "*"
1155
+ dims = []
1156
+ elif v.deferred:
1157
+ dims = self.allocated.get(v.name.lower())
1158
+ if dims is None:
1159
+ raise TranslateError(f"{v.name} is never allocated")
1160
+ else:
1161
+ dims = [em.c(parse_expr(d)) for d in v.dims]
1162
+ if base.endswith("*"):
1163
+ text = f"{base}{v.name}"
1164
+ else:
1165
+ text = f"{base} {star}{v.name}"
1166
+ text += "".join(f"[{d}]" for d in dims)
1167
+ if v.init is not None:
1168
+ init = parse_expr(v.init)
1169
+ text += " = " + em.c(init)
1170
+ if "parameter" in v.attrs and v.ftype != "integer":
1171
+ text = "const " + text
1172
+ return ("static " if static else "") + text + ";"
1173
+
1174
+ # ---- statements ----
1175
+ def stmt(self, text: str, em: Emitter) -> list[str]:
1176
+ """C lines of one Fortran statement (with lifted temporaries)."""
1177
+ self.pre = []
1178
+ low = text.lower().strip()
1179
+ out: list[str]
1180
+ if low.startswith("print"):
1181
+ if "result ran_on_host=" not in low:
1182
+ raise TranslateError(f"print {text!r}")
1183
+ out = ['printf("RESULT ran_on_host=%d check=%s\\n", host_flag, '
1184
+ 'ok ? "pass" : "fail");']
1185
+ elif low.startswith(("allocate(", "allocate (")):
1186
+ out = []
1187
+ for it in _split_top(re.match(r"^allocate\s*\((.*)\)$", text.strip(),
1188
+ re.I).group(1)):
1189
+ name = it.split("(")[0].strip().lower()
1190
+ v = em.ctx.var(name)
1191
+ if v is not None and "pointer" in v.attrs:
1192
+ self.needs_stdlib = True
1193
+ ext = self.allocated[name]
1194
+ size = " * ".join(ext)
1195
+ out.append(f"{name} = malloc({size} * sizeof *{name});")
1196
+ elif low.startswith(("deallocate(", "deallocate (")):
1197
+ out = []
1198
+ for it in _split_top(re.match(r"^deallocate\s*\((.*)\)$",
1199
+ text.strip(), re.I).group(1)):
1200
+ v = em.ctx.var(it.strip())
1201
+ if v is not None and "pointer" in v.attrs:
1202
+ out.append(f"free({it.strip()});")
1203
+ elif low.startswith("call "):
1204
+ out = self.call_stmt(text.strip()[5:].strip(), em)
1205
+ elif low in ("exit", "cycle"):
1206
+ out = ["break;" if low == "exit" else "continue;"]
1207
+ elif "=>" in text:
1208
+ lhs, rhs = (x.strip() for x in text.split("=>", 1))
1209
+ out = [f"{lhs} = {em.c(parse_expr(rhs))};"]
1210
+ else:
1211
+ m = re.match(r"^(.*?[^=<>/])=(?!=)(.*)$", text.strip())
1212
+ if not m:
1213
+ raise TranslateError(f"statement {text!r}")
1214
+ out = self.assign(m.group(1).strip(), m.group(2).strip(), em)
1215
+ return self.pre + out
1216
+
1217
+ def assign(self, lhs_t: str, rhs_t: str, em: Emitter) -> list[str]:
1218
+ lhs, rhs = parse_expr(lhs_t), parse_expr(rhs_t)
1219
+ if em.ctx.tr.result is not None and lhs.kind == "name" and \
1220
+ lhs.value.lower() == em.ctx.tr.result:
1221
+ return [f"r_ = {em.c(rhs)};"]
1222
+ shp = em.shape(lhs)
1223
+ if not shp:
1224
+ if em.shape(rhs):
1225
+ raise TranslateError(f"array value to scalar: {lhs_t}")
1226
+ return [f"{em.c(lhs)} = {em.c(rhs)};"]
1227
+ idx = [self.fresh("k") for _ in shp]
1228
+ rhs_el = self.elements(rhs, em, idx) if em.shape(rhs) else em.c(rhs)
1229
+ lhs_el = em.c(lhs, idx)
1230
+ return _loops(shp, idx, [f"{lhs_el} = {rhs_el};"])
1231
+
1232
+ def call_stmt(self, text: str, em: Emitter) -> list[str]:
1233
+ e = parse_expr(text)
1234
+ if e.kind == "name":
1235
+ return [f"{e.value}();"]
1236
+ name = e.args[0].value.lower()
1237
+ args = e.args[1:]
1238
+ if name == "c_f_pointer":
1239
+ src, dst = em.c(args[0]), args[1].value
1240
+ if len(args) > 2:
1241
+ self.allocated[dst.lower()] = [em.c(x) for x in args[2].args]
1242
+ return [f"{dst} = {src};"]
1243
+ return [em.call(e, None) + ";"]
1244
+
1245
+ # ---- directives ----
1246
+ @staticmethod
1247
+ def c_param(v: "Var", name: str) -> str:
1248
+ """A dummy argument: int (intent in or none) or int * (inout, out);
1249
+ A type(c_ptr) dummy (the 5.0 is_device_ptr programs) is a
1250
+ void * passed by value."""
1251
+ if v.dims and v.ftype == "integer":
1252
+ return "int *" + name # An explicit-shape dummy array
1253
+ if v.ftype == "c_ptr" and not v.dims:
1254
+ if v.intent not in (None, "in"):
1255
+ raise TranslateError(f"c_ptr dummy {name} with intent "
1256
+ f"{v.intent}")
1257
+ return "void *" + name
1258
+ return ("int " if v.intent in (None, "in") else "int *") + name
1259
+
1260
+ def directive(self, node: Node, em: Emitter) -> str:
1261
+ text = node.line.strip()[5:].strip()
1262
+ name, clauses = _split_name(text)
1263
+ cname = self.c_name(name)
1264
+ m = re.match(r"^cache\s*\((.*)\)$", cname, re.I | re.S)
1265
+ if self.model == "acc" and m:
1266
+ # The cache directive's vars (elements, subarrays)
1267
+ inner = m.group(1)
1268
+ mod = re.match(r"^\s*(readonly)\s*:\s*", inner, re.I)
1269
+ items = _split_top(inner[mod.end():] if mod else inner)
1270
+ cname = "cache(" + (f"{mod.group(1)}: " if mod else "") + \
1271
+ ", ".join(em.item(x) for x in items) + ")"
1272
+ extra = (clauses + " " + node.end_clauses).strip()
1273
+ return (f"#pragma {self.model} " + cname + (" " + self.c_clauses(
1274
+ extra, em)
1275
+ if extra else "")).rstrip()
1276
+
1277
+ def c_name(self, name: str) -> str:
1278
+ """A directive name (with its argument) in C: do -> for; the
1279
+ argument's list items translated."""
1280
+ m = re.match(r"^([^(]*)(\((.*)\))?$", name.strip(), re.S)
1281
+ words = m.group(1).split()
1282
+ if "workdistribute" in [w.lower() for w in words]:
1283
+ raise TranslateError("workdistribute is Fortran-only")
1284
+ words = ["for" if w.lower() == "do" else w for w in words]
1285
+ out = " ".join(words)
1286
+ if m.group(2):
1287
+ arg = m.group(3)
1288
+ if out.lower().replace("_", " ") == "declare mapper":
1289
+ # [mapper-identifier :] type :: var -> [id :] struct type var
1290
+ mm = re.match(r"^(?:\s*(\w+)\s*:(?!:))?\s*(\w+)\s*::\s*"
1291
+ r"(\w+)\s*$", arg)
1292
+ if not mm:
1293
+ raise TranslateError(f"declare mapper({arg})")
1294
+ ident = f"{mm.group(1)}: " if mm.group(1) else ""
1295
+ arg = f"{ident}struct {mm.group(2)} {mm.group(3)}"
1296
+ elif out.lower().replace("_", " ") in ("declare target",
1297
+ "threadprivate"):
1298
+ arg = ", ".join(_split_top(arg))
1299
+ out += "(" + arg + ")"
1300
+ return out
1301
+
1302
+ def c_clauses(self, text: str, em: Emitter) -> str:
1303
+ from offload.engine.grammar import _close_paren, _tokenize
1304
+ toks = _tokenize(text)
1305
+ out = []
1306
+ i = 0
1307
+ while i < len(toks):
1308
+ t = toks[i]
1309
+ if t.text == ",":
1310
+ i += 1
1311
+ continue
1312
+ if i + 1 < len(toks) and toks[i + 1].text == "(":
1313
+ j = _close_paren(toks, i + 1, t.text)
1314
+ arg = text[toks[i + 1].end:toks[j].start]
1315
+ out.append(f"{t.text}({self.c_arg(t.text.lower(), arg, em)})")
1316
+ i = j + 1
1317
+ else:
1318
+ out.append(t.text)
1319
+ i += 1
1320
+ return " ".join(out)
1321
+
1322
+ def c_arg(self, clause: str, text: str, em: Emitter) -> str:
1323
+ from offload.engine.grammar import _split
1324
+ pieces = _split(text, ",:;")
1325
+ out = []
1326
+ for k, p in enumerate(pieces):
1327
+ if k % 2:
1328
+ out.append(p + " " if p in ",;" else ": ")
1329
+ continue
1330
+ out.append(self.c_piece(clause, p, em))
1331
+ return "".join(out).replace(" : ", ": ").strip()
1332
+
1333
+ def c_piece(self, clause: str, p: str, em: Emitter) -> str:
1334
+ low = p.lower().strip()
1335
+ if not low:
1336
+ return ""
1337
+ if clause in _REDUCTION_CLAUSES and low in _REDOP:
1338
+ return _REDOP[low]
1339
+ if clause in _REDUCTION_CLAUSES and low in (".eqv.", ".neqv."):
1340
+ raise TranslateError(f"reduction identifier {low} is "
1341
+ "Fortran-only")
1342
+ if low == "do":
1343
+ return "for"
1344
+ if low in _KEYWORDS:
1345
+ return low
1346
+ if low in _directive_names() and clause not in _LIST_ONLY:
1347
+ return " ".join("for" if w == "do" else w for w in low.split())
1348
+ m = re.match(r"^iterator\s*\((.*)\)$", p.strip(), re.I | re.S)
1349
+ if m:
1350
+ return "iterator(" + ", ".join(self.c_iter(s, em) for s in
1351
+ _split_top(m.group(1))) + ")"
1352
+ m = _COMPLEX.match(p.strip())
1353
+ if m:
1354
+ inner = m.group(2)
1355
+ if m.group(1).lower() == "mapper":
1356
+ return f"{m.group(1)}({inner.strip()})"
1357
+ return f"{m.group(1)}({em.c(parse_expr(inner))})"
1358
+ e = parse_expr(p)
1359
+ if clause == "uses_allocators" and e.kind == "call" and \
1360
+ len(e.args) == 2 and all(a.kind == "name" for a in e.args):
1361
+ # The 5.0 form allocator(traits-array) (5.0 §2.12.5)
1362
+ return f"{e.args[0].value}({e.args[1].value})"
1363
+ if e.kind in ("name", "member") or (
1364
+ e.kind == "call" and e.args[0].kind in ("name", "member")
1365
+ and em.ctx.of(e.args[0]) is not None):
1366
+ return em.item(p, mapping=clause in _MAP_CLAUSES or (
1367
+ _MODEL[0] == "acc" and clause in _ACC_DATA_CLAUSES))
1368
+ return em.c(e)
1369
+
1370
+ def c_iter(self, spec: str, em: Emitter) -> str:
1371
+ m = re.match(r"^(?:(.*?)::)?\s*([a-z_]\w*)\s*=\s*(.*)$", spec.strip(),
1372
+ re.I | re.S)
1373
+ if not m:
1374
+ raise TranslateError(f"iterator {spec!r}")
1375
+ typ = m.group(1)
1376
+ if typ and typ.strip().lower() != "integer":
1377
+ raise TranslateError(f"iterator type {typ!r}")
1378
+ name = m.group(2)
1379
+ parts = _split_top(m.group(3), ":")
1380
+ em.ctx.scopes.append({name.lower(): Var(name, "integer")})
1381
+ try:
1382
+ lb, ub = em.c(parse_expr(parts[0])), em.c(parse_expr(parts[1]))
1383
+ step = em.c(parse_expr(parts[2])) if len(parts) > 2 else None
1384
+ finally:
1385
+ em.ctx.scopes.pop()
1386
+ neg = step is not None and step.startswith("-")
1387
+ end = _simplify_minus_one(ub) if neg else _plus_one(ub)
1388
+ return f"{name} = {lb}:{end}" + (f":{step}" if step else "")
1389
+
1390
+ # ---- emission of an executable part ----
1391
+ def emit(self, nodes: list[Node], em: Emitter, ind: int) -> list[str]:
1392
+ out = []
1393
+ pad = " " * ind
1394
+ for node in nodes:
1395
+ k = node.kind
1396
+ if k == "stmt":
1397
+ out += [pad + x for x in self.stmt(node.text, em)]
1398
+ elif k == "ifone":
1399
+ self.pre = []
1400
+ cond = em.c(parse_expr(node.text))
1401
+ pre = self.pre
1402
+ body = self.stmt(node.body[0].text, em)
1403
+ out += [pad + x for x in pre]
1404
+ if len(body) == 1:
1405
+ out.append(f"{pad}if ({cond}) {body[0]}")
1406
+ else:
1407
+ out.append(f"{pad}if ({cond}) {{")
1408
+ out += [pad + " " + x for x in body]
1409
+ out.append(pad + "}")
1410
+ elif k == "if":
1411
+ self.pre = []
1412
+ cond = em.c(parse_expr(node.text))
1413
+ out += [pad + x for x in self.pre]
1414
+ out.append(f"{pad}if ({cond}) {{")
1415
+ out += self.emit(node.body, em, ind + 1)
1416
+ if node.orelse:
1417
+ out.append(f"{pad}}} else {{")
1418
+ out += self.emit(node.orelse, em, ind + 1)
1419
+ out.append(pad + "}")
1420
+ elif k == "while":
1421
+ self.pre = []
1422
+ cond = em.c(parse_expr(node.text))
1423
+ if self.pre:
1424
+ raise TranslateError("reduction in a while condition")
1425
+ inner = self.emit(node.body, em, ind + 1)
1426
+ out.append(f"{pad}while ({cond}) {{" + ("" if inner
1427
+ else " }"))
1428
+ if inner:
1429
+ out += inner + [pad + "}"]
1430
+ elif k == "do":
1431
+ out += self.do_loop(node, em, ind)
1432
+ elif k == "dir":
1433
+ out += self.dir_node(node, em, ind)
1434
+ else:
1435
+ raise TranslateError(f"node {k}")
1436
+ return out
1437
+
1438
+ def do_loop(self, node: Node, em: Emitter, ind: int) -> list[str]:
1439
+ pad = " " * ind
1440
+ m = re.match(r"^([a-z_]\w*)\s*=\s*(.*)$", node.text, re.I)
1441
+ var = m.group(1)
1442
+ parts = _split_top(m.group(2))
1443
+ if len(parts) not in (2, 3):
1444
+ raise TranslateError(f"do {node.text!r}")
1445
+ lb, ub = em.c(parse_expr(parts[0])), em.c(parse_expr(parts[1]))
1446
+ decl = "" if var.lower() in self.outer_loop_vars else "int "
1447
+ if len(parts) == 3:
1448
+ st = em.c(parse_expr(parts[2]))
1449
+ if st.startswith("-"):
1450
+ head = (f"for ({decl}{var} = {lb}; {var} >= {ub}; "
1451
+ f"{var} -= {st[1:].strip()})")
1452
+ else:
1453
+ head = f"for ({decl}{var} = {lb}; {var} <= {ub}; {var} += {st})"
1454
+ else:
1455
+ head = f"for ({decl}{var} = {lb}; {var} <= {ub}; {var}++)"
1456
+ inner = self.emit(node.body, em, ind + 1)
1457
+ return [f"{pad}{head} {{"] + inner + [pad + "}"]
1458
+
1459
+ def dir_node(self, node: Node, em: Emitter, ind: int) -> list[str]:
1460
+ from offload.engine.rules import association
1461
+ pad = " " * ind
1462
+ line = self.directive(node, em)
1463
+ how = "block" if node.text == "block" else association(
1464
+ node.directive.name, self.model)
1465
+ out = _wrap_c(pad + line)
1466
+ if how == "block":
1467
+ inner = self.emit(node.body, em, ind + 1)
1468
+ return out + [pad + "{"] + inner + [pad + "}"]
1469
+ if how in ("loop", "statement"):
1470
+ if not node.body:
1471
+ raise TranslateError(f"{node.directive.name} without its "
1472
+ "loop")
1473
+ return out + self.emit(node.body, em, ind)
1474
+ return out
1475
+
1476
+ # ---- the whole program ----
1477
+ def run(self) -> str:
1478
+ head = [t for k, t in self.lines if k == "head"]
1479
+ units = _units(self.lines)
1480
+ module = next((u for u in units if u.kind == "module"), None)
1481
+ prog = next((u for u in units if u.kind == "program"), None)
1482
+ externals = [u for u in units if u.kind in ("function",
1483
+ "subroutine")]
1484
+ if prog is None:
1485
+ raise TranslateError("no main program")
1486
+ self.result = None
1487
+ mod_scope: dict = {}
1488
+ prog_scope: dict = {}
1489
+ types = []
1490
+ if module is not None:
1491
+ types += self.declare(mod_scope, module.spec)
1492
+ types += self.declare(prog_scope, prog.spec)
1493
+ self.types = {t: {v.name.lower(): v for v in members}
1494
+ for t, members in types}
1495
+ # extents of allocatable/pointer arrays from ALLOCATE statements
1496
+ # (and of a pointer associated with a whole array: p => a)
1497
+ for u in ([module] if module else []) + [prog] + (
1498
+ module.procs if module else []):
1499
+ for kind, text in u.body:
1500
+ pm = re.match(r"^(\w+)\s*=>\s*(\w+)$", text.strip())
1501
+ if kind == "stmt" and pm:
1502
+ tgt = (prog_scope.get(pm.group(2).lower())
1503
+ or mod_scope.get(pm.group(2).lower()))
1504
+ if tgt is not None and (tgt.dims or tgt.deferred):
1505
+ self.allocated[pm.group(1).lower()] = \
1506
+ tgt.dims or self._raw_alloc.get(
1507
+ pm.group(2).lower(), [])
1508
+ m = re.match(r"^allocate\s*\((.*)\)$", text.strip(), re.I)
1509
+ if kind == "stmt" and m:
1510
+ for it in _split_top(m.group(1)):
1511
+ mm = re.match(r"^(\w+)\s*\((.*)\)$", it.strip())
1512
+ self.allocated[mm.group(1).lower()] = _split_top(
1513
+ mm.group(2))
1514
+ self._raw_alloc[mm.group(1).lower()] = _split_top(
1515
+ mm.group(2))
1516
+ # C texts of the extents
1517
+ ctx0 = Ctx([mod_scope, prog_scope], self.functions, self)
1518
+ em0 = Emitter(ctx0)
1519
+ self.allocated = {k: [em0.c(parse_expr(x)) for x in v]
1520
+ for k, v in self.allocated.items()}
1521
+ # names the program's directives give static storage
1522
+ static_names = set()
1523
+ for kind, text in prog.spec:
1524
+ if kind == "omp":
1525
+ d = parse_directive(text, "fortran", self.version)
1526
+ if d.name in ("declare target", "threadprivate"):
1527
+ static_names |= {a.lower() for a in d.args}
1528
+ for c in d.clauses:
1529
+ if c.name in ("enter", "to", "link", "local"):
1530
+ static_names |= {a.lower() for a in c.args}
1531
+ # names that clauses mention (loop variables named there stay
1532
+ # declared outside their loops)
1533
+ for u in [prog] + (module.procs if module else []):
1534
+ for kind, text in u.body + u.spec:
1535
+ if kind == "omp":
1536
+ clauses = _clause_text(text)
1537
+ self.clause_names |= {
1538
+ w.lower() for w in re.findall(r"[A-Za-z_]\w*",
1539
+ clauses)}
1540
+ lines: list[str] = []
1541
+ includes = ["#include <stdio.h>", "#include <stdbool.h>",
1542
+ "#include <omp.h>" if self.model == "omp" else
1543
+ "#include <openacc.h>"]
1544
+ # the main program's named constants, at file scope (module data
1545
+ # may use them in C, where a Fortran module has its own)
1546
+ params = [v for v in prog_scope.values()
1547
+ if "parameter" in v.attrs and v.ftype == "integer"
1548
+ and not v.dims]
1549
+ if params:
1550
+ lines.append("enum { " + ", ".join(
1551
+ f"{v.name} = {em0.c(parse_expr(v.init))}" for v in params)
1552
+ + " };")
1553
+ # derived types
1554
+ for tname, members in types:
1555
+ lines.append(f"struct {tname} {{")
1556
+ for v in members:
1557
+ lines.append(" " + self.c_decl(v, em0))
1558
+ lines.append("};")
1559
+ # module data and its directives
1560
+ if module is not None:
1561
+ for kind, text in module.spec:
1562
+ if kind == "omp":
1563
+ lines.append(self.directive(Node(
1564
+ "dir", line=text, directive=parse_directive(
1565
+ text, "fortran", self.version)), em0))
1566
+ elif parse_declaration(text) is not None:
1567
+ for v in parse_declaration(text):
1568
+ lines.append(self.c_decl(v, em0))
1569
+ # program variables with static storage, program declarative
1570
+ # directives
1571
+ prog_dirs = [t for k, t in prog.spec if k == "omp"]
1572
+ for v in prog_scope.values():
1573
+ if v.name.lower() in static_names:
1574
+ lines.append(self.c_decl(v, em0))
1575
+ main_dirs = []
1576
+ main_decl_dirs = [] # Acc declare, after the declarations
1577
+ named_routines = [] # Acc routine(name), before main
1578
+ for text in prog_dirs:
1579
+ d = parse_directive(text, "fortran", self.version)
1580
+ if self.model == "acc" and d.name == "declare":
1581
+ main_decl_dirs.append(self.directive(Node(
1582
+ "dir", line=text, directive=d), em0))
1583
+ elif self.model == "acc" and d.name == "routine" and d.args:
1584
+ named_routines.append(self.directive(Node(
1585
+ "dir", line=text, directive=d), em0))
1586
+ elif d.name in ("declare target", "threadprivate", "requires",
1587
+ "declare mapper"):
1588
+ lines.append(self.directive(Node(
1589
+ "dir", line=text, directive=d), em0))
1590
+ elif d.name == "error":
1591
+ # a compile-time error directive of the main program's
1592
+ # specification part: the first line of main
1593
+ main_dirs.append(self.directive(Node(
1594
+ "dir", line=text, directive=d), em0))
1595
+ else:
1596
+ raise TranslateError(f"{d.name} in the main program's "
1597
+ "specification part")
1598
+ # external procedures, then module procedures
1599
+ for proc in externals:
1600
+ lines += self.procedure(proc, {})
1601
+ if module is not None:
1602
+ for proc in module.procs:
1603
+ lines += self.procedure(proc, mod_scope)
1604
+ lines += named_routines
1605
+ # main
1606
+ loop_vars = set()
1607
+ for kind, text in prog.body:
1608
+ m = re.match(r"^do\s+([a-z_]\w*)\s*=", text.strip(), re.I)
1609
+ if kind == "stmt" and m:
1610
+ loop_vars.add(m.group(1).lower())
1611
+ self.outer_loop_vars = {v for v in loop_vars
1612
+ if v in self.clause_names}
1613
+ ctx = Ctx([mod_scope, prog_scope], self.functions, self)
1614
+ em = Emitter(ctx)
1615
+ main = ["int main(void) {"] + [" " + x for x in main_dirs]
1616
+ for v in prog_scope.values():
1617
+ if v in params or v.name.lower() in static_names:
1618
+ continue
1619
+ if v.name.lower() in loop_vars - self.outer_loop_vars and \
1620
+ not v.dims:
1621
+ continue
1622
+ if v.ftype == "alloctrait" and "parameter" in v.attrs:
1623
+ main.append(" " + self.c_decl(v, em).replace(
1624
+ "omp_alloctrait_t", "const omp_alloctrait_t", 1))
1625
+ continue
1626
+ if self.c_decl(v, em):
1627
+ main.append(" " + self.c_decl(v, em))
1628
+ main += [" " + x for x in main_decl_dirs]
1629
+ body = self.emit(_tree(prog.body, self.version), em, 1)
1630
+ main += body + [" return 0;", "}"]
1631
+ if self.needs_stdlib:
1632
+ includes.insert(1, "#include <stdlib.h>")
1633
+ out = [f"// {h}" for h in head] + includes + [""] + lines + (
1634
+ [""] if lines else []) + main
1635
+ return "\n".join(out) + "\n"
1636
+
1637
+ def procedure(self, proc: Unit, mod_scope: dict) -> list[str]:
1638
+ scope: dict = {}
1639
+ self.declare(scope, proc.spec)
1640
+ intents = []
1641
+ for p in proc.params:
1642
+ v = scope.get(p)
1643
+ if v is None:
1644
+ raise TranslateError(f"dummy {p} undeclared")
1645
+ if v.intent is None and any(
1646
+ k == "stmt" and re.search(
1647
+ rf"(?:^|\))\s*{re.escape(p)}\s*=(?!=)", t, re.I)
1648
+ for k, t in proc.body):
1649
+ # A dummy without intent is passed by reference,
1650
+ # so one the procedure assigns is inout (the 5.0
1651
+ # is_device_ptr program's hf)
1652
+ v = scope[p] = dataclasses.replace(v, intent="inout")
1653
+ if v.deferred or (v.dims and (len(v.dims) != 1 or ":" in
1654
+ v.dims[0])):
1655
+ raise TranslateError("array dummy arguments are not ported")
1656
+ # A rank-1 explicit-shape dummy array is a pointer
1657
+ # parameter (the array's address; deviceptr programs)
1658
+ intents.append("array" if v.dims else v.intent or "in")
1659
+ self.functions[proc.name] = intents
1660
+ ctx = Ctx([mod_scope, scope], self.functions, self)
1661
+ em = Emitter(ctx)
1662
+ self.result = proc.name if proc.kind == "function" else None
1663
+ params = ", ".join(self.c_param(scope[p], p) for p in proc.params) \
1664
+ or "void"
1665
+ rtype = {"integer": "int", "logical": "bool", "": "void"}[
1666
+ proc.result_type]
1667
+ dirs = [t for k, t in proc.spec if k == "omp"]
1668
+ before, after = [], []
1669
+ for text in dirs:
1670
+ d = parse_directive(text, "fortran", self.version)
1671
+ if self.model == "acc" and d.name == "routine":
1672
+ # Without a name the C routine directive goes
1673
+ # immediately before the definition (3.4 §2.15.1, p.91);
1674
+ # with one, anywhere a prototype is allowed: after it
1675
+ line = self.directive(Node("dir", line=text, directive=d),
1676
+ em)
1677
+ (after if d.args else before).append(line)
1678
+ continue
1679
+ if d.name != "declare target":
1680
+ raise TranslateError(f"{d.name} in a procedure")
1681
+ listed = d.args or any(c.name in ("enter", "to", "link", "local")
1682
+ for c in d.clauses)
1683
+ if listed:
1684
+ after.append(self.directive(Node("dir", line=text,
1685
+ directive=d), em))
1686
+ else:
1687
+ # clause-less (or device_type/indirect only): the delimited
1688
+ # form around the definition (5.2 §7.8.2, 6.0 §9.9.2)
1689
+ name, clauses = _split_name(text.strip()[5:].strip())
1690
+ begin = "#pragma omp begin declare target"
1691
+ if self.version < 51:
1692
+ # 5.0 has no begin declare target; its
1693
+ # delimited form is declare target ... end declare
1694
+ # target, without clauses (5.0 §2.12.7, p.181)
1695
+ if clauses:
1696
+ raise TranslateError("a clause on the 5.0 delimited "
1697
+ "declare target")
1698
+ begin = "#pragma omp declare target"
1699
+ if clauses:
1700
+ begin += " " + self.c_clauses(clauses, em)
1701
+ before.append(begin)
1702
+ after.insert(0, "#pragma omp end declare target")
1703
+ loop_vars = {m.group(1).lower() for k, t in proc.body
1704
+ if k == "stmt" and (m := re.match(
1705
+ r"^do\s+([a-z_]\w*)\s*=", t.strip(), re.I))}
1706
+ saved = self.outer_loop_vars if hasattr(self, "outer_loop_vars") \
1707
+ else set()
1708
+ self.outer_loop_vars = {v for v in loop_vars
1709
+ if v in self.clause_names}
1710
+ out = before + [f"{rtype} {proc.name}({params}) {{"]
1711
+ for v in scope.values():
1712
+ if v.name.lower() in proc.params or v.name.lower() == proc.name:
1713
+ continue
1714
+ if v.name.lower() in loop_vars - self.outer_loop_vars and \
1715
+ not v.dims:
1716
+ continue
1717
+ out.append(" " + self.c_decl(v, em))
1718
+ if self.result:
1719
+ out.append(f" {rtype} r_;")
1720
+ out += self.emit(_tree(proc.body, self.version), em, 1)
1721
+ if self.result:
1722
+ out.append(" return r_;")
1723
+ out.append("}")
1724
+ self.result = None
1725
+ self.outer_loop_vars = saved
1726
+ return out + after
1727
+
1728
+
1729
+ def _plus_one(text: str) -> str:
1730
+ t = text.strip()
1731
+ if re.fullmatch(r"-?\d+", t):
1732
+ return str(int(t) + 1)
1733
+ m = re.fullmatch(r"(.*\S)\s*-\s*(\d+)", t)
1734
+ if m and _balanced(m.group(1)):
1735
+ k = int(m.group(2)) - 1
1736
+ return m.group(1) if k == 0 else f"{m.group(1)} - {k}"
1737
+ return f"{t} + 1"
1738
+
1739
+
1740
+ def _loops(shape: list[str], idx: list[str], body: list[str]) -> list[str]:
1741
+ out, pad = [], ""
1742
+ for ext, k in zip(shape, idx):
1743
+ out.append(f"{pad}for (int {k} = 0; {k} < {ext}; {k}++)")
1744
+ pad += " "
1745
+ out += [pad + b for b in body]
1746
+ return out
1747
+
1748
+
1749
+ C_MAX_LINE = 96
1750
+
1751
+
1752
+ def _wrap_c(line: str) -> list[str]:
1753
+ """A long #pragma line split at clause boundaries with backslash
1754
+ continuations."""
1755
+ if len(line) <= C_MAX_LINE:
1756
+ return [line]
1757
+ ind = line[:len(line) - len(line.lstrip())]
1758
+ parts, depth, cur = [], 0, ""
1759
+ for ch in line.strip():
1760
+ depth += ch == "("
1761
+ depth -= ch == ")"
1762
+ if ch == " " and depth == 0:
1763
+ parts.append(cur)
1764
+ cur = ""
1765
+ continue
1766
+ cur += ch
1767
+ parts.append(cur)
1768
+ out, cur = [], ""
1769
+ for p in parts:
1770
+ if cur and len(ind) + len(cur) + len(p) + 3 > C_MAX_LINE:
1771
+ out.append(cur)
1772
+ cur = " " + p
1773
+ else:
1774
+ cur = f"{cur} {p}" if cur else p
1775
+ out.append(cur)
1776
+ return [ind + x + (" \\" if k < len(out) - 1 else "")
1777
+ for k, x in enumerate(out)]
1778
+
1779
+
1780
+ def translate(source: str, version: int) -> str:
1781
+ """The C11 program of a generated Fortran program (see the module
1782
+ docstring); raises TranslateError for what is not ported."""
1783
+ return Translator(source, version).run()