offtarget 0.1.0__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (886) hide show
  1. offload/__init__.py +10 -0
  2. offload/__main__.py +5 -0
  3. offload/_bundle.py +74 -0
  4. offload/_root/catalog/acc/claims.yaml +197 -0
  5. offload/_root/catalog/acc/clauses.yaml +391 -0
  6. offload/_root/catalog/acc/no_oracle.yaml +89 -0
  7. offload/_root/catalog/acc/out_of_scope.yaml +17 -0
  8. offload/_root/catalog/acc/rules.yaml +433 -0
  9. offload/_root/catalog/acc/semantic_atoms.yaml +27 -0
  10. offload/_root/catalog/acc/skeleton.yaml +1567 -0
  11. offload/_root/catalog/acc/spec_overrides.yaml +72 -0
  12. offload/_root/catalog/later_forms.yaml +76 -0
  13. offload/_root/catalog/machines.yaml +218 -0
  14. offload/_root/catalog/omp/claims.yaml +2047 -0
  15. offload/_root/catalog/omp/clauses.yaml +914 -0
  16. offload/_root/catalog/omp/derivations.yaml +177 -0
  17. offload/_root/catalog/omp/memory_modes.yaml +40 -0
  18. offload/_root/catalog/omp/no_oracle.yaml +373 -0
  19. offload/_root/catalog/omp/omp50_delta.yaml +377 -0
  20. offload/_root/catalog/omp/out_of_scope.yaml +64 -0
  21. offload/_root/catalog/omp/port_equivalence.yaml +352 -0
  22. offload/_root/catalog/omp/rules.yaml +3131 -0
  23. offload/_root/catalog/omp/rules_coverage.yaml +9939 -0
  24. offload/_root/catalog/omp/semantic_atoms.yaml +34 -0
  25. offload/_root/catalog/omp/skeleton.yaml +9181 -0
  26. offload/_root/catalog/omp/spec_overrides.yaml +932 -0
  27. offload/_root/catalog/toolchains.yaml +472 -0
  28. offload/_root/catalog/vendor_claims_generic.yaml +40925 -0
  29. offload/_root/data/canuse/b.json +1 -0
  30. offload/_root/data/canuse/c.json +1 -0
  31. offload/_root/data/canuse/columns.json +1 -0
  32. offload/_root/data/canuse/d.json +1 -0
  33. offload/_root/data/canuse/f.json +1 -0
  34. offload/_root/data/canuse/index.json +1 -0
  35. offload/_root/data/canuse/p.json +1 -0
  36. offload/_root/data/compilers/afar.json +1 -0
  37. offload/_root/data/compilers/cce19.json +1 -0
  38. offload/_root/data/compilers/cce20.json +1 -0
  39. offload/_root/data/compilers/cce21.json +1 -0
  40. offload/_root/data/compilers/cce21_4.json +1 -0
  41. offload/_root/data/compilers/gcc.json +1 -0
  42. offload/_root/data/compilers/gcc_sm80.json +1 -0
  43. offload/_root/data/compilers/nvhpc.json +1 -0
  44. offload/_root/data/compilers/nvhpc269.json +1 -0
  45. offload/_root/data/findings/AUTHORING.md +107 -0
  46. offload/_root/data/findings/README.md +33 -0
  47. offload/_root/data/findings/afar-c-error-directive-in-target-link.c +37 -0
  48. offload/_root/data/findings/afar-c-lastprivate-distribute-parallel-for-small-type.c +56 -0
  49. offload/_root/data/findings/afar-c-teams-distribute-reduction-first-team.c +59 -0
  50. offload/_root/data/findings/afar-c-update-iterator-copy-mode.c +45 -0
  51. offload/_root/data/findings/afar-c-xnack1-target-is-present.c +31 -0
  52. offload/_root/data/findings/afar-cce19-character-defaultmap.f90 +27 -0
  53. offload/_root/data/findings/afar-cce19-task-in-target-ice.f90 +23 -0
  54. offload/_root/data/findings/afar-clang-requires-device-safesync-hang.c +24 -0
  55. offload/_root/data/findings/afar-flang-firstprivate-map-two-targets.f90 +34 -0
  56. offload/_root/data/findings/afar-flang-loop-bind-teams-reduction.f90 +27 -0
  57. offload/_root/data/findings/afar-flang-task-reduction-max.f90 +31 -0
  58. offload/_root/data/findings/afar-flang-thread-limit-target-parallel-do.f90 +22 -0
  59. offload/_root/data/findings/afar-linear-ref-omp50.f90 +29 -0
  60. offload/_root/data/findings/afar-loop-bind-thread-in-teams.f90 +44 -0
  61. offload/_root/data/findings/afar-nontemporal-assumed-shape-ice.f90 +38 -0
  62. offload/_root/data/findings/afar-udr-derived-type-link.f90 +41 -0
  63. offload/_root/data/findings/afar-xnack1-atomic-min-nested-parallel.f90 +53 -0
  64. offload/_root/data/findings/afar-xnack1-present-not-enforced.f90 +36 -0
  65. offload/_root/data/findings/afar-xnack1-target-is-present.f90 +47 -0
  66. offload/_root/data/findings/apps/afar-cce-teams-private-array-nested-parallel-wrong.f90 +100 -0
  67. offload/_root/data/findings/apps/cce20-device-link-infer-address-spaces-crash.f90 +159 -0
  68. offload/_root/data/findings/apps/cce21-device-link-agpr-copy-mfma-assert.f90 +343 -0
  69. offload/_root/data/findings/apps/cce21-private-array-loaded-subscript-wrong.f90 +113 -0
  70. offload/_root/data/findings/apps/controls/bubble-simple-rddot.f90 +284 -0
  71. offload/_root/data/findings/apps/controls/bubble-two-substeps.f90 +287 -0
  72. offload/_root/data/findings/apps/controls/cbc-inline.f90 +97 -0
  73. offload/_root/data/findings/apps/controls/cbc-integers.f90 +91 -0
  74. offload/_root/data/findings/apps/controls/cbc-only-density.f90 +97 -0
  75. offload/_root/data/findings/apps/controls/cbc-only-velocity.f90 +97 -0
  76. offload/_root/data/findings/apps/controls/gcc-acc-c-tile-control.c +26 -0
  77. offload/_root/data/findings/apps/controls/gcc-acc-tile-control.f90 +29 -0
  78. offload/_root/data/findings/apps/controls/private-array-subscript-probes.f90 +45 -0
  79. offload/_root/data/findings/apps/controls/teams-private-array-read-par.f90 +31 -0
  80. offload/_root/data/findings/apps/controls/teams-private-array-seq.f90 +30 -0
  81. offload/_root/data/findings/apps/controls/teams-private-array-shared.f90 +34 -0
  82. offload/_root/data/findings/apps/controls/teams-private-array-split.f90 +36 -0
  83. offload/_root/data/findings/apps/controls/teams-private-array-write-par.f90 +31 -0
  84. offload/_root/data/findings/apps/gcc-acc-c-tile-partial-tiles-wrong.c +60 -0
  85. offload/_root/data/findings/apps/gcc-acc-tile-partial-tiles-wrong.f90 +64 -0
  86. offload/_root/data/findings/catalog/afar-c-complex-reduction-link.c +66 -0
  87. offload/_root/data/findings/catalog/afar-c-critical-hint-link.c +68 -0
  88. offload/_root/data/findings/catalog/afar-c-ordered-doacross-link.c +62 -0
  89. offload/_root/data/findings/catalog/afar-c-reduction-task-link.c +81 -0
  90. offload/_root/data/findings/catalog/afar-flang-absent-optional-target-crash.f90 +76 -0
  91. offload/_root/data/findings/catalog/afar-flang-critical-target-parallel-wrong.f90 +74 -0
  92. offload/_root/data/findings/catalog/afar-flang-dist-schedule-chunk.f90 +80 -0
  93. offload/_root/data/findings/catalog/afar-flang-linear-parallel-ice.f90 +68 -0
  94. offload/_root/data/findings/catalog/afar-flang-named-critical-link.f90 +67 -0
  95. offload/_root/data/findings/catalog/afar-flang-ordered-wrong.f90 +78 -0
  96. offload/_root/data/findings/catalog/afar-flang-reduction-minus-rejected.f90 +77 -0
  97. offload/_root/data/findings/catalog/afar-flang-reduction-task-ice.f90 +68 -0
  98. offload/_root/data/findings/catalog/afar-flang-sections-in-target-ice.f90 +67 -0
  99. offload/_root/data/findings/catalog/afar-flang-workdistribute-ice.f90 +71 -0
  100. offload/_root/data/findings/catalog/c-allocate-const-mem-firstprivate-wrong.c +79 -0
  101. offload/_root/data/findings/catalog/cce-acc-allocate-in-compute-crash.f90 +65 -0
  102. offload/_root/data/findings/catalog/cce-acc-character-dummy-routine-ice.f90 +81 -0
  103. offload/_root/data/findings/catalog/cce-acc-loop-seq-in-routine-wrong.f90 +81 -0
  104. offload/_root/data/findings/catalog/cce-acc-stop-in-compute-crash.f90 +62 -0
  105. offload/_root/data/findings/catalog/cce-allocators-stack-ice.f90 +81 -0
  106. offload/_root/data/findings/catalog/cce-atomic-default-mem-order-acquire-release-rejected.f90 +61 -0
  107. offload/_root/data/findings/catalog/cce-c-allocate-align-link.c +83 -0
  108. offload/_root/data/findings/catalog/cce-c-allocate-allocator-modifier-rejected.c +77 -0
  109. offload/_root/data/findings/catalog/cce-c-device-type-directive-name-ice.c +70 -0
  110. offload/_root/data/findings/catalog/cce-c-dist-schedule-chunk.c +81 -0
  111. offload/_root/data/findings/catalog/cce-c-f-pointer-device-link.f90 +70 -0
  112. offload/_root/data/findings/catalog/cce-c-lastprivate-parallel-in-seq-loop-wrong.c +64 -0
  113. offload/_root/data/findings/catalog/cce-c-long-double-ice.c +61 -0
  114. offload/_root/data/findings/catalog/cce-c-map-iterator-ice.c +92 -0
  115. offload/_root/data/findings/catalog/cce-c-motion-iterator-rejected.c +68 -0
  116. offload/_root/data/findings/catalog/cce-c-ordered-doacross-link.c +64 -0
  117. offload/_root/data/findings/catalog/cce-c-ordered-link.c +77 -0
  118. offload/_root/data/findings/catalog/cce-c-recursive-function-ice.c +62 -0
  119. offload/_root/data/findings/catalog/cce-c-reduction-inscan-ice.c +67 -0
  120. offload/_root/data/findings/catalog/cce-c-reduction-task-link.c +73 -0
  121. offload/_root/data/findings/catalog/cce-c-sections-in-target-wrong.c +70 -0
  122. offload/_root/data/findings/catalog/cce-c-single-masked-task-link.c +66 -0
  123. offload/_root/data/findings/catalog/cce-c-task-in-target-link.c +75 -0
  124. offload/_root/data/findings/catalog/cce-c-uses-allocators-traits-rejected.c +71 -0
  125. offload/_root/data/findings/catalog/cce-flang-allocate-const-mem-ice.f90 +67 -0
  126. offload/_root/data/findings/catalog/cce-flang-allocate-in-target-crash.f90 +68 -0
  127. offload/_root/data/findings/catalog/cce-flang-lastprivate-parallel-in-seq-loop-wrong.f90 +83 -0
  128. offload/_root/data/findings/catalog/cce-flang-stop-in-target-crash.f90 +64 -0
  129. offload/_root/data/findings/catalog/cce-iterator-link.f90 +67 -0
  130. offload/_root/data/findings/catalog/cce-linear-lastprivate-ice.f90 +69 -0
  131. offload/_root/data/findings/catalog/cce-nohost-link.f90 +90 -0
  132. offload/_root/data/findings/catalog/cce-reduction-inscan-ice.f90 +66 -0
  133. offload/_root/data/findings/catalog/cce-reduction-task-link.f90 +76 -0
  134. offload/_root/data/findings/catalog/cce19-reduction-task-addrspacecast-ice.f90 +77 -0
  135. offload/_root/data/findings/catalog/cce20-c-defaultmap-private-storage-rejected.c +85 -0
  136. offload/_root/data/findings/catalog/cce20-map-self-rejected.f90 +64 -0
  137. offload/_root/data/findings/catalog/cce21-c-declare-target-local-rejected.c +73 -0
  138. offload/_root/data/findings/catalog/cce21-c-target-loop-ice.c +77 -0
  139. offload/_root/data/findings/catalog/defaultmap-present-private-array-abort.f90 +73 -0
  140. offload/_root/data/findings/catalog/nvhpc-acc-associate-illegal-address.f90 +66 -0
  141. offload/_root/data/findings/catalog/nvhpc-c-function-pointer-kernel-missing.c +68 -0
  142. offload/_root/data/findings/catalog/nvhpc-c-long-double-kernel-missing.c +64 -0
  143. offload/_root/data/findings/catalog/nvhpc-c-static-local-kernel-missing.c +73 -0
  144. offload/_root/data/findings/catalog/nvhpc-c-vla-kernel-missing.c +63 -0
  145. offload/_root/data/findings/catalog/nvhpc-flang-type-bound-kernel-missing.f90 +86 -0
  146. offload/_root/data/findings/cce-acc-init-set-runtime-assert.f90 +35 -0
  147. offload/_root/data/findings/cce-acc-reduction-200-int8-scalars-wrong.f90 +1278 -0
  148. offload/_root/data/findings/cce-acc-routine-bind-module-ice.f90 +35 -0
  149. offload/_root/data/findings/cce-acc-self-condition-ignored.f90 +17 -0
  150. offload/_root/data/findings/cce-c-dist-schedule-segv.c +34 -0
  151. offload/_root/data/findings/cce-c-map-delete-refcount.c +47 -0
  152. offload/_root/data/findings/cce-c-map-present-assert.c +45 -0
  153. offload/_root/data/findings/cce-c-openmp45-device-link.c +34 -0
  154. offload/_root/data/findings/cce-c-parallel-for-in-target.c +73 -0
  155. offload/_root/data/findings/cce-defaultmap-tofrom-explicit-map.f90 +92 -0
  156. offload/_root/data/findings/cce-mapper-next-map-copy-back.f90 +48 -0
  157. offload/_root/data/findings/cce-trim-merge-output-one-character.f90 +40 -0
  158. offload/_root/data/findings/cce-uses-allocators-traits-omp50.f90 +28 -0
  159. offload/_root/data/findings/cce19-acc-if-false-link.f90 +17 -0
  160. offload/_root/data/findings/cce19-c-reduction-63-scalars-one-wrong.c +235 -0
  161. offload/_root/data/findings/cce19-target-parallel-guarded-loop.f90 +35 -0
  162. offload/_root/data/findings/cce19-target-parallel-single-ice.f90 +38 -0
  163. offload/_root/data/findings/cce21-alloc-2e32-sum-wrong.f90 +68 -0
  164. offload/_root/data/findings/cce21-defaultmap-aggregate-flag.f90 +52 -0
  165. offload/_root/data/findings/cce21-in-reduction-assumed-shape-write-lost.f90 +61 -0
  166. offload/_root/data/findings/cce21-in-reduction-taskwait-link.f90 +59 -0
  167. offload/_root/data/findings/cce21-linear-modifier-default-none.f90 +59 -0
  168. offload/_root/data/findings/clang-c-declare-target-to-omp52.c +50 -0
  169. offload/_root/data/findings/clang-c-linear-directive-name-hang.c +30 -0
  170. offload/_root/data/findings/clang-c-map-iterator-omp51.c +51 -0
  171. offload/_root/data/findings/clang-c-shared-declare-target-combined.c +58 -0
  172. offload/_root/data/findings/dataenv/cce-value-dummy-target-write-visible.f90 +74 -0
  173. offload/_root/data/findings/defaultmap-none-loop-variable.f90 +69 -0
  174. offload/_root/data/findings/fortran-loop-bind-thread-in-parallel.f90 +53 -0
  175. offload/_root/data/findings/fortran-schedule-static-in-target.f90 +55 -0
  176. offload/_root/data/findings/fresh/cce-common-block-name-in-map-rejected.f90 +47 -0
  177. offload/_root/data/findings/fresh/cce-if-stop-in-target-ice-one-condition.f90 +38 -0
  178. offload/_root/data/findings/fresh/cce-if-stop-in-target-ice.f90 +43 -0
  179. offload/_root/data/findings/fresh/cce-list-directed-print-in-target-copy-crash.f90 +40 -0
  180. offload/_root/data/findings/fresh/cce19-acc-automatic-array-copyout-copy-crash.f90 +56 -0
  181. offload/_root/data/findings/fresh/cce21-combined-if-runtime-expr-loop-skipped.f90 +57 -0
  182. offload/_root/data/findings/fresh/nvhpc-acc-gang-worker-collapse-nested-vector-reduction-lost.f90 +67 -0
  183. offload/_root/data/findings/fresh/nvhpc-teams-loop-module-allocatable-assign-fort2-crash.f90 +73 -0
  184. offload/_root/data/findings/fuzz/1131-afar.f90 +48 -0
  185. offload/_root/data/findings/fuzz/1391-cce20.f90 +40 -0
  186. offload/_root/data/findings/fuzz/14-cce20.f90 +36 -0
  187. offload/_root/data/findings/fuzz/1505-cce20.f90 +88 -0
  188. offload/_root/data/findings/fuzz/1540-afar.f90 +44 -0
  189. offload/_root/data/findings/fuzz/158-afar.f90 +63 -0
  190. offload/_root/data/findings/fuzz/16-cce20.f90 +39 -0
  191. offload/_root/data/findings/fuzz/1644-cce21.f90 +31 -0
  192. offload/_root/data/findings/fuzz/165-cce19.f90 +52 -0
  193. offload/_root/data/findings/fuzz/1749-cce20.f90 +34 -0
  194. offload/_root/data/findings/fuzz/1936-afar.f90 +61 -0
  195. offload/_root/data/findings/fuzz/1978-cce19.f90 +41 -0
  196. offload/_root/data/findings/fuzz/2014-cce19.f90 +46 -0
  197. offload/_root/data/findings/fuzz/2224-cce19.f90 +30 -0
  198. offload/_root/data/findings/fuzz/2334-cce19.f90 +57 -0
  199. offload/_root/data/findings/fuzz/536-cce19.f90 +38 -0
  200. offload/_root/data/findings/fuzz/591-cce19.f90 +54 -0
  201. offload/_root/data/findings/fuzz/650-afar.f90 +58 -0
  202. offload/_root/data/findings/fuzz/698-afar.f90 +68 -0
  203. offload/_root/data/findings/fuzz/700-afar.f90 +46 -0
  204. offload/_root/data/findings/fuzz/775-cce21.f90 +33 -0
  205. offload/_root/data/findings/fuzz/87-afar.f90 +47 -0
  206. offload/_root/data/findings/fuzz/916-afar.f90 +67 -0
  207. offload/_root/data/findings/fuzz/958-cce20.f90 +44 -0
  208. offload/_root/data/findings/fuzz/98-cce19.f90 +40 -0
  209. offload/_root/data/findings/fuzz/README.md +236 -0
  210. offload/_root/data/findings/fuzz/b1-121-afar.f90 +47 -0
  211. offload/_root/data/findings/fuzz/b1-183-afar.f90 +55 -0
  212. offload/_root/data/findings/fuzz/b1-22-cce20.f90 +38 -0
  213. offload/_root/data/findings/fuzz/b1-231-afar.f90 +56 -0
  214. offload/_root/data/findings/fuzz/b1-268-afar.f90 +46 -0
  215. offload/_root/data/findings/fuzz/b2-183-afar.f90 +57 -0
  216. offload/_root/data/findings/fuzz/b2-209-cce19.f90 +51 -0
  217. offload/_root/data/findings/fuzz/b2-213-afar.f90 +63 -0
  218. offload/_root/data/findings/fuzz/b2-52-afar.f90 +56 -0
  219. offload/_root/data/findings/fuzz/b2-68-afar.f90 +54 -0
  220. offload/_root/data/findings/fuzz/b2-85-cce20.f90 +55 -0
  221. offload/_root/data/findings/fuzz/b3-188-cce19.f90 +90 -0
  222. offload/_root/data/findings/fuzz/b3-190-cce21.f90 +88 -0
  223. offload/_root/data/findings/fuzz/b3-197-cce19.f90 +77 -0
  224. offload/_root/data/findings/fuzz/b3-250-cce20.f90 +89 -0
  225. offload/_root/data/findings/fuzz/b3-278-cce19.f90 +70 -0
  226. offload/_root/data/findings/fuzz/b3-45-cce21.f90 +83 -0
  227. offload/_root/data/findings/fuzz/b3-54-afar.f90 +67 -0
  228. offload/_root/data/findings/fuzz/b3-61-cce20.f90 +100 -0
  229. offload/_root/data/findings/fuzz/b3-9-afar.f90 +100 -0
  230. offload/_root/data/findings/fuzz/b3-9-cce21.f90 +103 -0
  231. offload/_root/data/findings/fuzz/b3-94-afar.f90 +80 -0
  232. offload/_root/data/findings/fuzz/b4-39-afar.f90 +141 -0
  233. offload/_root/data/findings/fuzz/b4-86-cce19.f90 +71 -0
  234. offload/_root/data/findings/fuzz/controls/gcc-complex-pointer-store-control.f90 +28 -0
  235. offload/_root/data/findings/fuzz/controls/gcc-declare-reduction-module-control.f90 +29 -0
  236. offload/_root/data/findings/fuzz/controls/gcc-target-simd-map-nontemporal-control.f90 +21 -0
  237. offload/_root/data/findings/fuzz/controls/nvhpc-allocatable-component-mapped-control.f90 +22 -0
  238. offload/_root/data/findings/fuzz/controls/nvhpc-allocatable-component-unreferenced-control.f90 +22 -0
  239. offload/_root/data/findings/fuzz/controls/nvhpc-default-none-removed-control.f90 +18 -0
  240. offload/_root/data/findings/fuzz/controls/nvhpc-default-shared-control.f90 +18 -0
  241. offload/_root/data/findings/fuzz/controls/nvhpc-defaultmap-firstprivate-removed-control.f90 +15 -0
  242. offload/_root/data/findings/fuzz/controls/nvhpc-defaultmap-to-scalar-reduction-mapped-control.f90 +17 -0
  243. offload/_root/data/findings/fuzz/controls/nvhpc-defaultmap-to-scalar-removed-control.f90 +17 -0
  244. offload/_root/data/findings/fuzz/controls/nvhpc-defaultmap-tofrom-lastprivate-control.f90 +15 -0
  245. offload/_root/data/findings/fuzz/controls/nvhpc-depend-explicit-map-control.f90 +22 -0
  246. offload/_root/data/findings/fuzz/controls/nvhpc-depend-removed-control.f90 +22 -0
  247. offload/_root/data/findings/fuzz/controls/nvhpc-distribute-end-distribute-control.f90 +16 -0
  248. offload/_root/data/findings/fuzz/controls/nvhpc-distribute-parallel-num-threads-removed-control.f90 +26 -0
  249. offload/_root/data/findings/fuzz/controls/nvhpc-distribute-parallel-removed-control.f90 +22 -0
  250. offload/_root/data/findings/fuzz/controls/nvhpc-distribute-simd-no-end-directive-control.f90 +15 -0
  251. offload/_root/data/findings/fuzz/controls/nvhpc-explicit-length-character-dummy-control.f90 +18 -0
  252. offload/_root/data/findings/fuzz/controls/nvhpc-loop-character-array-value-control.f90 +23 -0
  253. offload/_root/data/findings/fuzz/controls/nvhpc-loop-character-distribute-control.f90 +20 -0
  254. offload/_root/data/findings/fuzz/controls/nvhpc-map-always-first-control.f90 +15 -0
  255. offload/_root/data/findings/fuzz/controls/nvhpc-map-always-removed-control.f90 +15 -0
  256. offload/_root/data/findings/fuzz/controls/nvhpc-num-threads-removed-control.f90 +12 -0
  257. offload/_root/data/findings/fuzz/controls/nvhpc-target-parallel-firstprivate-dropped-control.f90 +15 -0
  258. offload/_root/data/findings/fuzz/controls/nvhpc-target-parallel-single-nowait-control.f90 +13 -0
  259. offload/_root/data/findings/fuzz/controls/nvhpc-target-parallel-split-control.f90 +15 -0
  260. offload/_root/data/findings/fuzz/controls/nvhpc-target-simd-collapse-split-control.f90 +21 -0
  261. offload/_root/data/findings/fuzz/controls/nvhpc-target-simd-end-directive-control.f90 +14 -0
  262. offload/_root/data/findings/fuzz/controls/nvhpc-target-simd-no-collapse-control.f90 +19 -0
  263. offload/_root/data/findings/fuzz/controls/nvhpc-target-simd-split-no-end-directive-control.f90 +15 -0
  264. offload/_root/data/findings/fuzz/gcc-declare-reduction-module-not-found.f90 +66 -0
  265. offload/_root/data/findings/fuzz/gcc-strided-target-update-rejected.f90 +58 -0
  266. offload/_root/data/findings/fuzz/gcc-target-simd-map-nontemporal-rejected.f90 +54 -0
  267. offload/_root/data/findings/fuzz/nvhpc-allocatable-component-implicit-map-illegal-address.f90 +84 -0
  268. offload/_root/data/findings/fuzz/nvhpc-assumed-length-character-dummy-map-ice.f90 +69 -0
  269. offload/_root/data/findings/fuzz/nvhpc-default-none-reduction-lastprivate-fort1-crash.f90 +70 -0
  270. offload/_root/data/findings/fuzz/nvhpc-defaultmap-firstprivate-lastprivate-ice.f90 +71 -0
  271. offload/_root/data/findings/fuzz/nvhpc-defaultmap-to-scalar-reduction-lost.f90 +82 -0
  272. offload/_root/data/findings/fuzz/nvhpc-depend-implicit-map-illegal-address.f90 +81 -0
  273. offload/_root/data/findings/fuzz/nvhpc-distribute-parallel-num-threads-writes-lost.f90 +79 -0
  274. offload/_root/data/findings/fuzz/nvhpc-end-distribute-simd-rejected.f90 +70 -0
  275. offload/_root/data/findings/fuzz/nvhpc-loop-character-achar-unsupported.f90 +75 -0
  276. offload/_root/data/findings/fuzz/nvhpc-map-always-after-map-to-not-copied-back.f90 +70 -0
  277. offload/_root/data/findings/fuzz/nvhpc-num-threads-reduction-identity-lost.f90 +54 -0
  278. offload/_root/data/findings/fuzz/nvhpc-target-parallel-firstprivate-translate-failure.f90 +66 -0
  279. offload/_root/data/findings/fuzz/nvhpc-target-parallel-single-hang.f90 +68 -0
  280. offload/_root/data/findings/fuzz/nvhpc-target-simd-collapse-translate-failure.f90 +73 -0
  281. offload/_root/data/findings/fuzz/nvhpc-target-simd-no-end-directive-rejected.f90 +68 -0
  282. offload/_root/data/findings/fuzz/par-s1-2082-gcc_g90.f90 +71 -0
  283. offload/_root/data/findings/fuzz/s1-2370-cce21.f90 +67 -0
  284. offload/_root/data/findings/fuzz/s1-2592-cce21.f90 +56 -0
  285. offload/_root/data/findings/fuzz/s1-3463-cce21.f90 +92 -0
  286. offload/_root/data/findings/fuzz/s1-4339-afar.f90 +79 -0
  287. offload/_root/data/findings/fuzz/s1-6085-cce21.f90 +96 -0
  288. offload/_root/data/findings/fuzz/s1-6760-cce20.f90 +65 -0
  289. offload/_root/data/findings/fuzz/s1-6888-cce21.f90 +76 -0
  290. offload/_root/data/findings/fuzz/s1-7882-cce20.f90 +63 -0
  291. offload/_root/data/findings/fuzz/s1-8634-cce21.f90 +45 -0
  292. offload/_root/data/findings/fuzz/s1-91-cce21.f90 +92 -0
  293. offload/_root/data/findings/fuzz/s1-9443-afar.f90 +59 -0
  294. offload/_root/data/findings/fuzz/s1-9914-cce19.f90 +78 -0
  295. offload/_root/data/findings/gcc/controls/gcc-acc-c-detach-control.c +34 -0
  296. offload/_root/data/findings/gcc/controls/gcc-acc-detach-control.f90 +26 -0
  297. offload/_root/data/findings/gcc/controls/gcc-defaultmap-to-pointer-control.f90 +31 -0
  298. offload/_root/data/findings/gcc/controls/gcc-target-in-task-control.c +26 -0
  299. offload/_root/data/findings/gcc/controls/gcc-target-in-task-control.f90 +21 -0
  300. offload/_root/data/findings/gcc/gcc-acc-bind-device-type-rejected.f90 +71 -0
  301. offload/_root/data/findings/gcc/gcc-acc-c-bind-device-type-rejected.c +76 -0
  302. offload/_root/data/findings/gcc/gcc-acc-c-detach-delete-attach-underflow.c +74 -0
  303. offload/_root/data/findings/gcc/gcc-acc-c-gang-dim-rejected.c +79 -0
  304. offload/_root/data/findings/gcc/gcc-acc-c-link-in-routine-rejected.c +82 -0
  305. offload/_root/data/findings/gcc/gcc-acc-detach-delete-attach-underflow.f90 +66 -0
  306. offload/_root/data/findings/gcc/gcc-acc-gang-dim-collapse-force-rejected.f90 +69 -0
  307. offload/_root/data/findings/gcc/gcc-acc-init-set-shutdown-rejected.f90 +70 -0
  308. offload/_root/data/findings/gcc/gcc-acc-link-in-routine-rejected.f90 +82 -0
  309. offload/_root/data/findings/gcc/gcc-acc-use-device-allocatable-rejected.f90 +88 -0
  310. offload/_root/data/findings/gcc/gcc-c-motion-mapper-rejected.c +110 -0
  311. offload/_root/data/findings/gcc/gcc-c-omp60-undocumented-rejected.c +76 -0
  312. offload/_root/data/findings/gcc/gcc-c-omp60-unimplemented-rejected.c +119 -0
  313. offload/_root/data/findings/gcc/gcc-c-target-in-task-mandatory-device-not-found.c +87 -0
  314. offload/_root/data/findings/gcc/gcc-c-uses-allocators-traits-unimplemented.c +85 -0
  315. offload/_root/data/findings/gcc/gcc-declare-mapper-rejected.f90 +85 -0
  316. offload/_root/data/findings/gcc/gcc-defaultmap-to-pointer-copy-back.f90 +66 -0
  317. offload/_root/data/findings/gcc/gcc-loop-bind-default-none-rejected.f90 +93 -0
  318. offload/_root/data/findings/gcc/gcc-omp60-undocumented-rejected.f90 +72 -0
  319. offload/_root/data/findings/gcc/gcc-omp60-unimplemented-rejected.f90 +112 -0
  320. offload/_root/data/findings/gcc/gcc-target-in-task-mandatory-device-not-found.f90 +83 -0
  321. offload/_root/data/findings/gcc/gcc-uses-allocators-traits-unimplemented.f90 +78 -0
  322. offload/_root/data/findings/harvest/afar-flang-strided-target-update.f90 +96 -0
  323. offload/_root/data/findings/harvest/cce-acc-declare-create-module-allocatable-xnack1-fault.f90 +58 -0
  324. offload/_root/data/findings/harvest/cce-c-implicit-struct-map-partly-present.c +100 -0
  325. offload/_root/data/findings/harvest/cce-c-strided-target-update.c +74 -0
  326. offload/_root/data/findings/harvest/cce-ftn-target-parallel-thread-query-ice.f90 +67 -0
  327. offload/_root/data/findings/harvest/cce-named-constant-array-declare-target-routine-rejected.f90 +69 -0
  328. offload/_root/data/findings/harvest/cce-use-device-ptr-c-ptr-not-converted.f90 +64 -0
  329. offload/_root/data/findings/harvest/cce21-declare-target-link-module-variable-write-lost.f90 +63 -0
  330. offload/_root/data/findings/harvest/cce21-internal-procedure-calls-internal-in-target-fault.f90 +71 -0
  331. offload/_root/data/findings/harvest/controls/cce-c-implicit-struct-map-partly-present-target-only-control.c +22 -0
  332. offload/_root/data/findings/harvest/controls/cce-c-implicit-struct-map-partly-present-whole-control.c +23 -0
  333. offload/_root/data/findings/harvest/controls/gcc-acc-declare-create-allocatable-control.f90 +34 -0
  334. offload/_root/data/findings/harvest/controls/gcc-c-same-item-two-maps-control.c +17 -0
  335. offload/_root/data/findings/harvest/controls/gcc-c-target-data-struct-pointer-section-control.c +27 -0
  336. offload/_root/data/findings/harvest/controls/gcc-c-target-data-two-maps-control.c +20 -0
  337. offload/_root/data/findings/harvest/controls/gcc-same-item-two-maps-control.f90 +16 -0
  338. offload/_root/data/findings/harvest/controls/gcc-teams-simd-matmul-allocatable-control.f90 +27 -0
  339. offload/_root/data/findings/harvest/gcc-acc-declare-create-allocatable-not-mapped.f90 +66 -0
  340. offload/_root/data/findings/harvest/gcc-c-same-item-two-maps-rejected.c +45 -0
  341. offload/_root/data/findings/harvest/gcc-c-strided-section-rejected.c +70 -0
  342. offload/_root/data/findings/harvest/gcc-c-target-data-struct-pointer-section-ice.c +78 -0
  343. offload/_root/data/findings/harvest/gcc-c-target-data-two-maps-ice.c +49 -0
  344. offload/_root/data/findings/harvest/gcc-same-item-two-maps-rejected.f90 +46 -0
  345. offload/_root/data/findings/harvest/gcc-teams-simd-matmul-allocatable-ice.f90 +53 -0
  346. offload/_root/data/findings/harvest/nvhpc-c-target-data-if-false-use-device-ptr-garbage.c +49 -0
  347. offload/_root/data/findings/harvest/nvhpc-named-constant-array-declare-target-routine-rejected.f90 +65 -0
  348. offload/_root/data/findings/harvest/nvhpc-use-device-ptr-c-ptr-not-found.f90 +60 -0
  349. offload/_root/data/findings/harvest/nvhpc2511-target-nowait-in-parallel-for-ice.c +59 -0
  350. offload/_root/data/findings/hecbench/controls/f16-ctl-float-array.c +28 -0
  351. offload/_root/data/findings/hecbench/controls/pc-ctl-builtin-popcount.c +37 -0
  352. offload/_root/data/findings/hecbench/controls/pc-ctl-shift-sum.c +43 -0
  353. offload/_root/data/findings/hecbench/gcc-c-float16-array-in-target-lto-ice.c +65 -0
  354. offload/_root/data/findings/hecbench/gcc-c-swar-popcount-assembler-error.c +80 -0
  355. offload/_root/data/findings/index.yaml +2453 -0
  356. offload/_root/data/findings/malloc/afar-device-malloc-in-kernel-corrupts-records.c +371 -0
  357. offload/_root/data/findings/malloc/controls/afar-first-use-malloc-direct.c +52 -0
  358. offload/_root/data/findings/malloc/controls/afar-first-use-malloc-fence.c +57 -0
  359. offload/_root/data/findings/malloc/controls/afar-first-use-malloc-flush.c +57 -0
  360. offload/_root/data/findings/malloc/controls/afar-first-use-malloc-stack.c +52 -0
  361. offload/_root/data/findings/multithread-allocatable-section-maps.f90 +91 -0
  362. offload/_root/data/findings/nested/afar-cce-c-call-result-member-in-target-rejected.c +69 -0
  363. offload/_root/data/findings/nested/afar-cce-c-update-struct-and-member-rejected.c +92 -0
  364. offload/_root/data/findings/nested/afar-flang-pointer-root-allocatable-component-enter-data-fault.f90 +121 -0
  365. offload/_root/data/findings/nested/cce-c-struct-and-nested-pointee-sections-ice.c +79 -0
  366. offload/_root/data/findings/nested/cce-fortran-nested-allocatable-component-copy-fault.f90 +64 -0
  367. offload/_root/data/findings/nested/cce-fortran-pointer-to-type-with-allocatable-scalar-component-typed-transfer.f90 +93 -0
  368. offload/_root/data/findings/nested/cce-fortran-update-to-pointer-root-allocatable-scalar-component-no-accelerator-object.f90 +80 -0
  369. offload/_root/data/findings/nested/controls/c3-ctl-nested-data.c +27 -0
  370. offload/_root/data/findings/nested/controls/c5-acc-serial-struct-and-array.c +26 -0
  371. offload/_root/data/findings/nested/controls/e2-ctl-two-directives.c +42 -0
  372. offload/_root/data/findings/nested/controls/e3-ctl-attach-clause.c +42 -0
  373. offload/_root/data/findings/nested/controls/f3-pointer-array-only.c +33 -0
  374. offload/_root/data/findings/nested/controls/f5-ctl-copyout-exit.c +33 -0
  375. offload/_root/data/findings/nested/controls/f6-ctl-pointer-to-struct-array.c +28 -0
  376. offload/_root/data/findings/nested/controls/g2-ctl-allocatable.f90 +34 -0
  377. offload/_root/data/findings/nested/controls/g2-ctl-entered-to.f90 +34 -0
  378. offload/_root/data/findings/nested/controls/g3-ctl-from-struct-no-element.c +27 -0
  379. offload/_root/data/findings/nested/controls/g3-ptrs-two-elements-to.c +27 -0
  380. offload/_root/data/findings/nested/controls/g3-ptrs-two-elements-tofrom.c +27 -0
  381. offload/_root/data/findings/nested/controls/g5-ctl-element-pointers-only.f90 +36 -0
  382. offload/_root/data/findings/nested/controls/g5-ctl-root-pointer-only.f90 +36 -0
  383. offload/_root/data/findings/nested/controls/gp2-ctl-no-mapper-explicit-maps.c +24 -0
  384. offload/_root/data/findings/nested/controls/gt2-ctl-no-always.c +26 -0
  385. offload/_root/data/findings/nested/controls/gt3-ctl-always-on-structure-only.c +26 -0
  386. offload/_root/data/findings/nested/controls/j1-embedded-struct-pointer-to-struct.c +24 -0
  387. offload/_root/data/findings/nested/controls/j2-ctl-pointer-instead-of-embedded.c +24 -0
  388. offload/_root/data/findings/nested/controls/j6-ctl-struct-and-one-pointee-level.c +23 -0
  389. offload/_root/data/findings/nested/controls/j7-ctl-struct-and-embedded-pointee.c +24 -0
  390. offload/_root/data/findings/nested/controls/m2-ctl-variable-root.f90 +32 -0
  391. offload/_root/data/findings/nested/controls/m3-ctl-fixed-array-component.f90 +32 -0
  392. offload/_root/data/findings/nested/controls/m5-ctl-no-enter-data.f90 +33 -0
  393. offload/_root/data/findings/nested/controls/n8-ctl-fixed-array-in-component.f90 +33 -0
  394. offload/_root/data/findings/nested/controls/n9-ctl-allocatable-in-the-variable.f90 +33 -0
  395. offload/_root/data/findings/nested/controls/ns4-ctl-two-directives-struct-then-pointee.c +27 -0
  396. offload/_root/data/findings/nested/controls/ns8-ctl-enter-together-exit-split.c +26 -0
  397. offload/_root/data/findings/nested/controls/nu3-ctl-update-pointee-only.c +28 -0
  398. offload/_root/data/findings/nested/controls/p2-ctl-pointer-variable.c +27 -0
  399. offload/_root/data/findings/nested/controls/p3-ctl-direct-member.c +26 -0
  400. offload/_root/data/findings/nested/controls/q2-ctl-fixed-array.f90 +37 -0
  401. offload/_root/data/findings/nested/controls/q3-ctl-allocatable-component-of-the-variable.f90 +38 -0
  402. offload/_root/data/findings/nested/controls/ta2-ctl-no-allocatable-component.f90 +42 -0
  403. offload/_root/data/findings/nested/controls/ta3-ctl-allocatable-scalar-in-the-variable.f90 +38 -0
  404. offload/_root/data/findings/nested/controls/ta4-ctl-pointer-component-only.f90 +42 -0
  405. offload/_root/data/findings/nested/controls/u3-ctl-update-member-only.c +24 -0
  406. offload/_root/data/findings/nested/controls/u4-ctl-two-updates.c +25 -0
  407. offload/_root/data/findings/nested/controls/u5-ctl-same-list-in-map.c +25 -0
  408. offload/_root/data/findings/nested/controls/ua2-ctl-variable-root.f90 +37 -0
  409. offload/_root/data/findings/nested/controls/ua4-ctl-to-in-place-of-alloc-and-update.f90 +37 -0
  410. offload/_root/data/findings/nested/controls/v2-ctl-parent-first.c +25 -0
  411. offload/_root/data/findings/nested/controls/v4-ctl-embedded-member.c +24 -0
  412. offload/_root/data/findings/nested/gcc-acc-c-exit-data-of-a-pointer-array-element-target-hangs.c +83 -0
  413. offload/_root/data/findings/nested/gcc-acc-c-parent-and-shared-pointee-one-directive.c +88 -0
  414. offload/_root/data/findings/nested/gcc-acc-c-struct-and-member-array-one-directive.c +84 -0
  415. offload/_root/data/findings/nested/gcc-c-always-on-pointer-member-section-ice.c +75 -0
  416. offload/_root/data/findings/nested/gcc-c-declare-mapper-pointer-member-section-gpu-fault.c +93 -0
  417. offload/_root/data/findings/nested/gcc-c-from-struct-and-pointee-section-rejected.c +83 -0
  418. offload/_root/data/findings/nested/gcc-fortran-pointer-component-alloc-bounds-lost.f90 +62 -0
  419. offload/_root/data/findings/nested/gcc-fortran-root-and-element-pointer-components-ice.f90 +77 -0
  420. offload/_root/data/findings/nested/nvhpc-c-pointee-before-parent-in-one-map-list-copy-fault.c +55 -0
  421. offload/_root/data/findings/nested/nvhpc-c-update-from-structure-overwrites-attached-pointer-segv.c +86 -0
  422. offload/_root/data/findings/nvhpc-acc-atomic-update-sum-fort2-crash.f90 +53 -0
  423. offload/_root/data/findings/nvhpc-c-acc-atomic-update-sum-ice.c +43 -0
  424. offload/_root/data/findings/nvhpc-c-dist-schedule-chunk-compile-hang.c +41 -0
  425. offload/_root/data/findings/nvhpc-c-map-present-ignored.c +42 -0
  426. offload/_root/data/findings/nvhpc-c-ordered-in-target-nvcpfe-crash.c +92 -0
  427. offload/_root/data/findings/nvhpc-c-parallel-for-firstprivate-in-target.c +62 -0
  428. offload/_root/data/findings/nvhpc-c-parallel-if-in-target-nvvm-ice.c +56 -0
  429. offload/_root/data/findings/nvhpc-defaultmap-firstprivate-explicit-map.f90 +45 -0
  430. offload/_root/data/findings/nvhpc-defaultmap-from-allocatable-indexing.f90 +60 -0
  431. offload/_root/data/findings/nvhpc-depend-inoutset-ignored.f90 +64 -0
  432. offload/_root/data/findings/nvhpc-dist-schedule-chunk-illegal-address.f90 +52 -0
  433. offload/_root/data/findings/nvhpc-managed-acc-shutdown-host-access.f90 +42 -0
  434. offload/_root/data/findings/nvhpc-parallel-if-in-target-nvvm-ice.f90 +60 -0
  435. offload/_root/data/findings/oop/afar-final-dealloc-device-link.f90 +85 -0
  436. offload/_root/data/findings/oop/afar-pdt-length-parameter-not-implemented.f90 +65 -0
  437. offload/_root/data/findings/oop/cce-class-is-device-link.f90 +86 -0
  438. offload/_root/data/findings/oop/cce-copy-alloc-component-section-fault.f90 +73 -0
  439. offload/_root/data/findings/oop/cce-copy-parent-to-component-tofrom-lost.f90 +65 -0
  440. offload/_root/data/findings/oop/cce-copy-second-member-section-lost.f90 +65 -0
  441. offload/_root/data/findings/oop/cce-element-component-map-lost.f90 +64 -0
  442. offload/_root/data/findings/oop/cce-final-dealloc-device-abort.f90 +85 -0
  443. offload/_root/data/findings/oop/cce-pdt-default-mapper-rejected.f90 +71 -0
  444. offload/_root/data/findings/oop/cce-polymorphic-dispatch-device-link.f90 +100 -0
  445. offload/_root/data/findings/oop/cce-section-of-element-component-overlap.f90 +76 -0
  446. offload/_root/data/findings/oop/cce-select-type-guard-not-taken.f90 +91 -0
  447. offload/_root/data/findings/oop/cce-udr-derived-type-unsupported.f90 +69 -0
  448. offload/_root/data/findings/oop/cce21-element-component-map-lost.f90 +62 -0
  449. offload/_root/data/findings/oop/controls/alloccomp-comp-only.f90 +44 -0
  450. offload/_root/data/findings/oop/controls/alloccomp-whole-explicit-component.f90 +50 -0
  451. offload/_root/data/findings/oop/controls/alloccomp-whole.f90 +49 -0
  452. offload/_root/data/findings/oop/controls/elemsec-element.f90 +47 -0
  453. offload/_root/data/findings/oop/controls/final-local.f90 +64 -0
  454. offload/_root/data/findings/oop/controls/host-class-star-select-type.f90 +58 -0
  455. offload/_root/data/findings/oop/controls/host-firstprivate-defined-assignment.f90 +54 -0
  456. offload/_root/data/findings/oop/controls/host-lastprivate-defined-assignment.f90 +58 -0
  457. offload/_root/data/findings/oop/controls/host-private-finalization.f90 +51 -0
  458. offload/_root/data/findings/oop/controls/host-select-type.f90 +65 -0
  459. offload/_root/data/findings/oop/controls/parent-and-comp-component-only.f90 +45 -0
  460. offload/_root/data/findings/oop/controls/pdt-kind.f90 +46 -0
  461. offload/_root/data/findings/oop/controls/pdt-len-host.f90 +43 -0
  462. offload/_root/data/findings/oop/controls/pdt-len-unparameterized.f90 +46 -0
  463. offload/_root/data/findings/oop/controls/poly-dispatch-static.f90 +75 -0
  464. offload/_root/data/findings/oop/controls/section-alloc-whole-component.f90 +49 -0
  465. offload/_root/data/findings/oop/controls/section-element-whole-array.f90 +50 -0
  466. offload/_root/data/findings/oop/controls/section-element-whole-component.f90 +50 -0
  467. offload/_root/data/findings/oop/controls/section-fixed.f90 +43 -0
  468. offload/_root/data/findings/oop/controls/tbp-override.f90 +64 -0
  469. offload/_root/data/findings/oop/gcc-acc-parent-and-member-data-rejected.f90 +63 -0
  470. offload/_root/data/findings/oop/gcc-pdt-length-parameter-abort.f90 +68 -0
  471. offload/_root/data/findings/oop/gcc-polymorphic-dispatch-abort.f90 +97 -0
  472. offload/_root/data/findings/oop/gcc-vtab-not-marked-for-offload.f90 +94 -0
  473. offload/_root/data/findings/oop/nvhpc-copy-alloc-component-illegal-address.f90 +76 -0
  474. offload/_root/data/findings/oop/nvhpc-copy-pdt-length-parameter-illegal-address.f90 +69 -0
  475. offload/_root/data/findings/oop/nvhpc-named-mapper-rejected.f90 +65 -0
  476. offload/_root/data/findings/oop/nvhpc-polymorphic-dispatch-translate-failure.f90 +90 -0
  477. offload/_root/data/findings/oop/nvhpc-polymorphism-runtime-unsupported.f90 +94 -0
  478. offload/_root/data/findings/oop/nvhpc-type-bound-call-rejected.f90 +89 -0
  479. offload/_root/data/findings/oop/nvhpc-udr-derived-type-rejected.f90 +67 -0
  480. offload/_root/data/findings/reviews/afar-c-error-directive-in-target-link.json +217 -0
  481. offload/_root/data/findings/reviews/afar-c-lastprivate-distribute-parallel-for-small-type.json +113 -0
  482. offload/_root/data/findings/reviews/afar-c-teams-distribute-reduction-first-team.json +130 -0
  483. offload/_root/data/findings/reviews/afar-c-update-iterator-copy-mode.json +113 -0
  484. offload/_root/data/findings/reviews/afar-cce19-character-defaultmap.json +292 -0
  485. offload/_root/data/findings/reviews/afar-clang-requires-device-safesync-hang.json +191 -0
  486. offload/_root/data/findings/reviews/afar-flang-firstprivate-map-two-targets.json +130 -0
  487. offload/_root/data/findings/reviews/afar-flang-loop-bind-teams-reduction.json +126 -0
  488. offload/_root/data/findings/reviews/afar-flang-task-reduction-max.json +113 -0
  489. offload/_root/data/findings/reviews/afar-flang-thread-limit-target-parallel-do.json +113 -0
  490. offload/_root/data/findings/reviews/afar-loop-bind-thread-in-teams.json +191 -0
  491. offload/_root/data/findings/reviews/afar-nontemporal-assumed-shape-ice.json +113 -0
  492. offload/_root/data/findings/reviews/afar-udr-derived-type-link.json +113 -0
  493. offload/_root/data/findings/reviews/afar-xnack1-atomic-min-nested-parallel.json +113 -0
  494. offload/_root/data/findings/reviews/afar-xnack1-target-is-present.json +113 -0
  495. offload/_root/data/findings/reviews/apps--afar-cce-teams-private-array-nested-parallel-wrong.json +113 -0
  496. offload/_root/data/findings/reviews/apps--cce20-device-link-infer-address-spaces-crash.json +113 -0
  497. offload/_root/data/findings/reviews/apps--cce21-device-link-agpr-copy-mfma-assert.json +113 -0
  498. offload/_root/data/findings/reviews/apps--cce21-private-array-loaded-subscript-wrong.json +113 -0
  499. offload/_root/data/findings/reviews/apps--gcc-acc-c-tile-partial-tiles-wrong.json +113 -0
  500. offload/_root/data/findings/reviews/catalog--afar-c-ordered-doacross-link.json +113 -0
  501. offload/_root/data/findings/reviews/catalog--afar-c-reduction-task-link.json +113 -0
  502. offload/_root/data/findings/reviews/catalog--afar-flang-absent-optional-target-crash.json +113 -0
  503. offload/_root/data/findings/reviews/catalog--afar-flang-critical-target-parallel-wrong.json +113 -0
  504. offload/_root/data/findings/reviews/catalog--afar-flang-dist-schedule-chunk.json +113 -0
  505. offload/_root/data/findings/reviews/catalog--afar-flang-linear-parallel-ice.json +113 -0
  506. offload/_root/data/findings/reviews/catalog--afar-flang-named-critical-link.json +126 -0
  507. offload/_root/data/findings/reviews/catalog--afar-flang-ordered-wrong.json +113 -0
  508. offload/_root/data/findings/reviews/catalog--afar-flang-reduction-minus-rejected.json +113 -0
  509. offload/_root/data/findings/reviews/catalog--afar-flang-sections-in-target-ice.json +113 -0
  510. offload/_root/data/findings/reviews/catalog--afar-flang-workdistribute-ice.json +113 -0
  511. offload/_root/data/findings/reviews/catalog--c-allocate-const-mem-firstprivate-wrong.json +113 -0
  512. offload/_root/data/findings/reviews/catalog--cce-acc-character-dummy-routine-ice.json +113 -0
  513. offload/_root/data/findings/reviews/catalog--cce-acc-loop-seq-in-routine-wrong.json +113 -0
  514. offload/_root/data/findings/reviews/catalog--cce-allocators-stack-ice.json +113 -0
  515. offload/_root/data/findings/reviews/catalog--cce-c-allocate-align-link.json +113 -0
  516. offload/_root/data/findings/reviews/catalog--cce-c-allocate-allocator-modifier-rejected.json +113 -0
  517. offload/_root/data/findings/reviews/catalog--cce-c-dist-schedule-chunk.json +113 -0
  518. offload/_root/data/findings/reviews/catalog--cce-c-f-pointer-device-link.json +130 -0
  519. offload/_root/data/findings/reviews/catalog--cce-c-long-double-ice.json +217 -0
  520. offload/_root/data/findings/reviews/catalog--cce-c-map-iterator-ice.json +217 -0
  521. offload/_root/data/findings/reviews/catalog--cce-c-recursive-function-ice.json +113 -0
  522. offload/_root/data/findings/reviews/catalog--cce-c-sections-in-target-wrong.json +113 -0
  523. offload/_root/data/findings/reviews/catalog--cce-flang-allocate-in-target-crash.json +113 -0
  524. offload/_root/data/findings/reviews/catalog--cce-flang-lastprivate-parallel-in-seq-loop-wrong.json +113 -0
  525. offload/_root/data/findings/reviews/catalog--cce-flang-stop-in-target-crash.json +113 -0
  526. offload/_root/data/findings/reviews/catalog--cce-iterator-link.json +113 -0
  527. offload/_root/data/findings/reviews/catalog--cce-linear-lastprivate-ice.json +113 -0
  528. offload/_root/data/findings/reviews/catalog--cce-reduction-inscan-ice.json +113 -0
  529. offload/_root/data/findings/reviews/catalog--cce-reduction-task-link.json +113 -0
  530. offload/_root/data/findings/reviews/catalog--cce19-reduction-task-addrspacecast-ice.json +113 -0
  531. offload/_root/data/findings/reviews/catalog--cce20-c-defaultmap-private-storage-rejected.json +217 -0
  532. offload/_root/data/findings/reviews/catalog--cce20-map-self-rejected.json +204 -0
  533. offload/_root/data/findings/reviews/catalog--cce21-c-target-loop-ice.json +126 -0
  534. offload/_root/data/findings/reviews/catalog--defaultmap-present-private-array-abort.json +236 -0
  535. offload/_root/data/findings/reviews/catalog--nvhpc-acc-associate-illegal-address.json +113 -0
  536. offload/_root/data/findings/reviews/catalog--nvhpc-c-function-pointer-kernel-missing.json +268 -0
  537. offload/_root/data/findings/reviews/cce-acc-init-set-runtime-assert.json +113 -0
  538. offload/_root/data/findings/reviews/cce-acc-reduction-200-int8-scalars-wrong.json +113 -0
  539. offload/_root/data/findings/reviews/cce-acc-routine-bind-module-ice.json +113 -0
  540. offload/_root/data/findings/reviews/cce-c-dist-schedule-segv.json +113 -0
  541. offload/_root/data/findings/reviews/cce-c-map-delete-refcount.json +149 -0
  542. offload/_root/data/findings/reviews/cce-c-map-present-assert.json +126 -0
  543. offload/_root/data/findings/reviews/cce-c-openmp45-device-link.json +113 -0
  544. offload/_root/data/findings/reviews/cce-c-parallel-for-in-target.json +141 -0
  545. offload/_root/data/findings/reviews/cce-mapper-next-map-copy-back.json +208 -0
  546. offload/_root/data/findings/reviews/cce-uses-allocators-traits-omp50.json +191 -0
  547. offload/_root/data/findings/reviews/cce19-c-reduction-63-scalars-one-wrong.json +113 -0
  548. offload/_root/data/findings/reviews/cce19-target-parallel-guarded-loop.json +113 -0
  549. offload/_root/data/findings/reviews/cce19-target-parallel-single-ice.json +113 -0
  550. offload/_root/data/findings/reviews/cce21-alloc-2e32-sum-wrong.json +113 -0
  551. offload/_root/data/findings/reviews/cce21-defaultmap-aggregate-flag.json +210 -0
  552. offload/_root/data/findings/reviews/cce21-in-reduction-assumed-shape-write-lost.json +113 -0
  553. offload/_root/data/findings/reviews/cce21-in-reduction-taskwait-link.json +113 -0
  554. offload/_root/data/findings/reviews/clang-c-declare-target-to-omp52.json +113 -0
  555. offload/_root/data/findings/reviews/clang-c-linear-directive-name-hang.json +113 -0
  556. offload/_root/data/findings/reviews/clang-c-shared-declare-target-combined.json +132 -0
  557. offload/_root/data/findings/reviews/dataenv--cce-value-dummy-target-write-visible.json +113 -0
  558. offload/_root/data/findings/reviews/defaultmap-none-loop-variable.json +113 -0
  559. offload/_root/data/findings/reviews/fortran-schedule-static-in-target.json +113 -0
  560. offload/_root/data/findings/reviews/fresh--cce-common-block-name-in-map-rejected.json +113 -0
  561. offload/_root/data/findings/reviews/fresh--cce-list-directed-print-in-target-copy-crash.json +217 -0
  562. offload/_root/data/findings/reviews/fresh--cce19-acc-automatic-array-copyout-copy-crash.json +113 -0
  563. offload/_root/data/findings/reviews/fresh--cce21-combined-if-runtime-expr-loop-skipped.json +113 -0
  564. offload/_root/data/findings/reviews/fresh--nvhpc-acc-gang-worker-collapse-nested-vector-reduction-lost.json +113 -0
  565. offload/_root/data/findings/reviews/fresh--nvhpc-teams-loop-module-allocatable-assign-fort2-crash.json +113 -0
  566. offload/_root/data/findings/reviews/fuzz--1505-cce20.json +113 -0
  567. offload/_root/data/findings/reviews/fuzz--1540-afar.json +113 -0
  568. offload/_root/data/findings/reviews/fuzz--1978-cce19.json +130 -0
  569. offload/_root/data/findings/reviews/fuzz--2334-cce19.json +113 -0
  570. offload/_root/data/findings/reviews/fuzz--591-cce19.json +147 -0
  571. offload/_root/data/findings/reviews/fuzz--650-afar.json +113 -0
  572. offload/_root/data/findings/reviews/fuzz--916-afar.json +130 -0
  573. offload/_root/data/findings/reviews/fuzz--98-cce19.json +113 -0
  574. offload/_root/data/findings/reviews/fuzz--b1-121-afar.json +160 -0
  575. offload/_root/data/findings/reviews/fuzz--b2-209-cce19.json +141 -0
  576. offload/_root/data/findings/reviews/fuzz--b2-68-afar.json +113 -0
  577. offload/_root/data/findings/reviews/fuzz--b2-85-cce20.json +217 -0
  578. offload/_root/data/findings/reviews/fuzz--b3-188-cce19.json +113 -0
  579. offload/_root/data/findings/reviews/fuzz--b3-278-cce19.json +212 -0
  580. offload/_root/data/findings/reviews/fuzz--b3-54-afar.json +113 -0
  581. offload/_root/data/findings/reviews/fuzz--b3-61-cce20.json +191 -0
  582. offload/_root/data/findings/reviews/fuzz--b4-86-cce19.json +113 -0
  583. offload/_root/data/findings/reviews/fuzz--gcc-declare-reduction-module-not-found.json +113 -0
  584. offload/_root/data/findings/reviews/fuzz--gcc-target-simd-map-nontemporal-rejected.json +113 -0
  585. offload/_root/data/findings/reviews/fuzz--nvhpc-allocatable-component-implicit-map-illegal-address.json +141 -0
  586. offload/_root/data/findings/reviews/fuzz--nvhpc-assumed-length-character-dummy-map-ice.json +113 -0
  587. offload/_root/data/findings/reviews/fuzz--nvhpc-default-none-reduction-lastprivate-fort1-crash.json +113 -0
  588. offload/_root/data/findings/reviews/fuzz--nvhpc-defaultmap-firstprivate-lastprivate-ice.json +113 -0
  589. offload/_root/data/findings/reviews/fuzz--nvhpc-defaultmap-to-scalar-reduction-lost.json +113 -0
  590. offload/_root/data/findings/reviews/fuzz--nvhpc-depend-implicit-map-illegal-address.json +113 -0
  591. offload/_root/data/findings/reviews/fuzz--nvhpc-distribute-parallel-num-threads-writes-lost.json +113 -0
  592. offload/_root/data/findings/reviews/fuzz--nvhpc-end-distribute-simd-rejected.json +113 -0
  593. offload/_root/data/findings/reviews/fuzz--nvhpc-loop-character-achar-unsupported.json +113 -0
  594. offload/_root/data/findings/reviews/fuzz--nvhpc-map-always-after-map-to-not-copied-back.json +113 -0
  595. offload/_root/data/findings/reviews/fuzz--nvhpc-num-threads-reduction-identity-lost.json +113 -0
  596. offload/_root/data/findings/reviews/fuzz--nvhpc-target-parallel-firstprivate-translate-failure.json +191 -0
  597. offload/_root/data/findings/reviews/fuzz--nvhpc-target-parallel-single-hang.json +113 -0
  598. offload/_root/data/findings/reviews/fuzz--nvhpc-target-simd-collapse-translate-failure.json +113 -0
  599. offload/_root/data/findings/reviews/fuzz--nvhpc-target-simd-no-end-directive-rejected.json +113 -0
  600. offload/_root/data/findings/reviews/fuzz--par-s1-2082-gcc_g90.json +126 -0
  601. offload/_root/data/findings/reviews/fuzz--s1-2370-cce21.json +113 -0
  602. offload/_root/data/findings/reviews/fuzz--s1-2592-cce21.json +113 -0
  603. offload/_root/data/findings/reviews/fuzz--s1-3463-cce21.json +113 -0
  604. offload/_root/data/findings/reviews/fuzz--s1-6760-cce20.json +130 -0
  605. offload/_root/data/findings/reviews/fuzz--s1-6888-cce21.json +113 -0
  606. offload/_root/data/findings/reviews/fuzz--s1-7882-cce20.json +113 -0
  607. offload/_root/data/findings/reviews/fuzz--s1-8634-cce21.json +113 -0
  608. offload/_root/data/findings/reviews/fuzz--s1-91-cce21.json +113 -0
  609. offload/_root/data/findings/reviews/fuzz--s1-9443-afar.json +113 -0
  610. offload/_root/data/findings/reviews/fuzz--s1-9914-cce19.json +141 -0
  611. offload/_root/data/findings/reviews/gcc--gcc-acc-bind-device-type-rejected.json +113 -0
  612. offload/_root/data/findings/reviews/gcc--gcc-acc-detach-delete-attach-underflow.json +314 -0
  613. offload/_root/data/findings/reviews/gcc--gcc-acc-gang-dim-collapse-force-rejected.json +113 -0
  614. offload/_root/data/findings/reviews/gcc--gcc-acc-init-set-shutdown-rejected.json +113 -0
  615. offload/_root/data/findings/reviews/gcc--gcc-acc-link-in-routine-rejected.json +113 -0
  616. offload/_root/data/findings/reviews/gcc--gcc-acc-use-device-allocatable-rejected.json +113 -0
  617. offload/_root/data/findings/reviews/gcc--gcc-c-motion-mapper-rejected.json +113 -0
  618. offload/_root/data/findings/reviews/gcc--gcc-c-omp60-undocumented-rejected.json +217 -0
  619. offload/_root/data/findings/reviews/gcc--gcc-c-omp60-unimplemented-rejected.json +236 -0
  620. offload/_root/data/findings/reviews/gcc--gcc-c-target-in-task-mandatory-device-not-found.json +236 -0
  621. offload/_root/data/findings/reviews/gcc--gcc-c-uses-allocators-traits-unimplemented.json +113 -0
  622. offload/_root/data/findings/reviews/gcc--gcc-declare-mapper-rejected.json +113 -0
  623. offload/_root/data/findings/reviews/gcc--gcc-defaultmap-to-pointer-copy-back.json +217 -0
  624. offload/_root/data/findings/reviews/gcc--gcc-loop-bind-default-none-rejected.json +113 -0
  625. offload/_root/data/findings/reviews/harvest--afar-flang-strided-target-update.json +141 -0
  626. offload/_root/data/findings/reviews/harvest--cce-acc-declare-create-module-allocatable-xnack1-fault.json +113 -0
  627. offload/_root/data/findings/reviews/harvest--cce-c-implicit-struct-map-partly-present.json +217 -0
  628. offload/_root/data/findings/reviews/harvest--cce-c-strided-target-update.json +141 -0
  629. offload/_root/data/findings/reviews/harvest--cce-ftn-target-parallel-thread-query-ice.json +130 -0
  630. offload/_root/data/findings/reviews/harvest--cce-named-constant-array-declare-target-routine-rejected.json +113 -0
  631. offload/_root/data/findings/reviews/harvest--cce-use-device-ptr-c-ptr-not-converted.json +113 -0
  632. offload/_root/data/findings/reviews/harvest--cce21-declare-target-link-module-variable-write-lost.json +113 -0
  633. offload/_root/data/findings/reviews/harvest--cce21-internal-procedure-calls-internal-in-target-fault.json +158 -0
  634. offload/_root/data/findings/reviews/harvest--gcc-acc-declare-create-allocatable-not-mapped.json +204 -0
  635. offload/_root/data/findings/reviews/harvest--gcc-c-same-item-two-maps-rejected.json +143 -0
  636. offload/_root/data/findings/reviews/harvest--gcc-c-strided-section-rejected.json +164 -0
  637. offload/_root/data/findings/reviews/harvest--gcc-c-target-data-struct-pointer-section-ice.json +113 -0
  638. offload/_root/data/findings/reviews/harvest--gcc-c-target-data-two-maps-ice.json +113 -0
  639. offload/_root/data/findings/reviews/harvest--gcc-teams-simd-matmul-allocatable-ice.json +113 -0
  640. offload/_root/data/findings/reviews/harvest--nvhpc-c-target-data-if-false-use-device-ptr-garbage.json +113 -0
  641. offload/_root/data/findings/reviews/harvest--nvhpc-named-constant-array-declare-target-routine-rejected.json +126 -0
  642. offload/_root/data/findings/reviews/harvest--nvhpc-use-device-ptr-c-ptr-not-found.json +113 -0
  643. offload/_root/data/findings/reviews/harvest--nvhpc2511-target-nowait-in-parallel-for-ice.json +130 -0
  644. offload/_root/data/findings/reviews/hecbench--gcc-c-float16-array-in-target-lto-ice.json +217 -0
  645. offload/_root/data/findings/reviews/hecbench--gcc-c-swar-popcount-assembler-error.json +126 -0
  646. offload/_root/data/findings/reviews/malloc--afar-device-malloc-in-kernel-corrupts-records.json +270 -0
  647. offload/_root/data/findings/reviews/multithread-allocatable-section-maps.json +191 -0
  648. offload/_root/data/findings/reviews/nested--afar-cce-c-call-result-member-in-target-rejected.json +113 -0
  649. offload/_root/data/findings/reviews/nested--afar-cce-c-update-struct-and-member-rejected.json +126 -0
  650. offload/_root/data/findings/reviews/nested--afar-flang-pointer-root-allocatable-component-enter-data-fault.json +191 -0
  651. offload/_root/data/findings/reviews/nested--cce-c-struct-and-nested-pointee-sections-ice.json +113 -0
  652. offload/_root/data/findings/reviews/nested--cce-fortran-nested-allocatable-component-copy-fault.json +214 -0
  653. offload/_root/data/findings/reviews/nested--cce-fortran-pointer-to-type-with-allocatable-scalar-component-typed-transfer.json +191 -0
  654. offload/_root/data/findings/reviews/nested--cce-fortran-update-to-pointer-root-allocatable-scalar-component-no-accelerator-object.json +297 -0
  655. offload/_root/data/findings/reviews/nested--gcc-acc-c-exit-data-of-a-pointer-array-element-target-hangs.json +204 -0
  656. offload/_root/data/findings/reviews/nested--gcc-acc-c-parent-and-shared-pointee-one-directive.json +130 -0
  657. offload/_root/data/findings/reviews/nested--gcc-acc-c-struct-and-member-array-one-directive.json +141 -0
  658. offload/_root/data/findings/reviews/nested--gcc-c-always-on-pointer-member-section-ice.json +113 -0
  659. offload/_root/data/findings/reviews/nested--gcc-c-declare-mapper-pointer-member-section-gpu-fault.json +113 -0
  660. offload/_root/data/findings/reviews/nested--gcc-c-from-struct-and-pointee-section-rejected.json +113 -0
  661. offload/_root/data/findings/reviews/nested--gcc-fortran-pointer-component-alloc-bounds-lost.json +217 -0
  662. offload/_root/data/findings/reviews/nested--gcc-fortran-root-and-element-pointer-components-ice.json +217 -0
  663. offload/_root/data/findings/reviews/nested--nvhpc-c-pointee-before-parent-in-one-map-list-copy-fault.json +204 -0
  664. offload/_root/data/findings/reviews/nested--nvhpc-c-update-from-structure-overwrites-attached-pointer-segv.json +191 -0
  665. offload/_root/data/findings/reviews/nvhpc-c-acc-atomic-update-sum-ice.json +277 -0
  666. offload/_root/data/findings/reviews/nvhpc-c-dist-schedule-chunk-compile-hang.json +113 -0
  667. offload/_root/data/findings/reviews/nvhpc-c-map-present-ignored.json +113 -0
  668. offload/_root/data/findings/reviews/nvhpc-c-ordered-in-target-nvcpfe-crash.json +113 -0
  669. offload/_root/data/findings/reviews/nvhpc-c-parallel-for-firstprivate-in-target.json +113 -0
  670. offload/_root/data/findings/reviews/nvhpc-defaultmap-firstprivate-explicit-map.json +113 -0
  671. offload/_root/data/findings/reviews/nvhpc-defaultmap-from-allocatable-indexing.json +132 -0
  672. offload/_root/data/findings/reviews/nvhpc-depend-inoutset-ignored.json +113 -0
  673. offload/_root/data/findings/reviews/nvhpc-dist-schedule-chunk-illegal-address.json +113 -0
  674. offload/_root/data/findings/reviews/nvhpc-managed-acc-shutdown-host-access.json +113 -0
  675. offload/_root/data/findings/reviews/nvhpc-parallel-if-in-target-nvvm-ice.json +113 -0
  676. offload/_root/data/findings/reviews/oop--afar-final-dealloc-device-link.json +132 -0
  677. offload/_root/data/findings/reviews/oop--afar-pdt-length-parameter-not-implemented.json +113 -0
  678. offload/_root/data/findings/reviews/oop--cce-class-is-device-link.json +130 -0
  679. offload/_root/data/findings/reviews/oop--cce-copy-alloc-component-section-fault.json +217 -0
  680. offload/_root/data/findings/reviews/oop--cce-copy-parent-to-component-tofrom-lost.json +217 -0
  681. offload/_root/data/findings/reviews/oop--cce-copy-second-member-section-lost.json +113 -0
  682. offload/_root/data/findings/reviews/oop--cce-element-component-map-lost.json +113 -0
  683. offload/_root/data/findings/reviews/oop--cce-final-dealloc-device-abort.json +208 -0
  684. offload/_root/data/findings/reviews/oop--cce-pdt-default-mapper-rejected.json +191 -0
  685. offload/_root/data/findings/reviews/oop--cce-polymorphic-dispatch-device-link.json +247 -0
  686. offload/_root/data/findings/reviews/oop--cce-section-of-element-component-overlap.json +113 -0
  687. offload/_root/data/findings/reviews/oop--cce-select-type-guard-not-taken.json +191 -0
  688. offload/_root/data/findings/reviews/oop--cce-udr-derived-type-unsupported.json +132 -0
  689. offload/_root/data/findings/reviews/oop--gcc-acc-parent-and-member-data-rejected.json +141 -0
  690. offload/_root/data/findings/reviews/oop--gcc-pdt-length-parameter-abort.json +141 -0
  691. offload/_root/data/findings/reviews/oop--gcc-polymorphic-dispatch-abort.json +217 -0
  692. offload/_root/data/findings/reviews/oop--gcc-vtab-not-marked-for-offload.json +113 -0
  693. offload/_root/data/findings/reviews/oop--nvhpc-copy-alloc-component-illegal-address.json +113 -0
  694. offload/_root/data/findings/reviews/oop--nvhpc-copy-pdt-length-parameter-illegal-address.json +236 -0
  695. offload/_root/data/findings/reviews/oop--nvhpc-named-mapper-rejected.json +113 -0
  696. offload/_root/data/findings/reviews/oop--nvhpc-polymorphic-dispatch-translate-failure.json +223 -0
  697. offload/_root/data/findings/reviews/oop--nvhpc-polymorphism-runtime-unsupported.json +126 -0
  698. offload/_root/data/findings/reviews/oop--nvhpc-type-bound-call-rejected.json +113 -0
  699. offload/_root/data/findings/reviews/oop--nvhpc-udr-derived-type-rejected.json +113 -0
  700. offload/_root/data/findings/reviews/stress--afar-c-lastprivate-combined-target-not-mapped.json +113 -0
  701. offload/_root/data/findings/reviews/stress--afar-target-scalar-implicit-firstprivate.json +175 -0
  702. offload/_root/data/findings/reviews/stress--cce-acc-declare-create-scalar-serial-firstprivate.json +113 -0
  703. offload/_root/data/findings/reviews/stress--cce-c-distribute-lastprivate-lost.json +113 -0
  704. offload/_root/data/findings/reviews/stress--cce-c-flto-offload-dropped.json +204 -0
  705. offload/_root/data/findings/reviews/stress--cce-ftn-cif-record-split-abort.json +113 -0
  706. offload/_root/data/findings/reviews/stress--cce-lastprivate-num-threads-collapse-simd.json +113 -0
  707. offload/_root/data/findings/reviews/stress--cce-teams-reduction-many-teams-wrap.json +113 -0
  708. offload/_root/data/findings/reviews/stress--cce21-declare-target-scalar-map-write-lost.json +113 -0
  709. offload/_root/data/findings/reviews/stress--gcc-declare-target-allocatable-component-ice.json +191 -0
  710. offload/_root/data/findings/reviews/stress--nvhpc-acc-derived-type-component-not-copied.json +126 -0
  711. offload/_root/data/findings/reviews/stress--nvhpc-c-lastprivate-teams-distribute-parallel-for-lost.json +113 -0
  712. offload/_root/data/findings/reviews/stress--nvhpc-declare-target-scalar-write-lost.json +113 -0
  713. offload/_root/data/findings/reviews/stress--nvhpc-lastprivate-combined-target-not-mapped.json +113 -0
  714. offload/_root/data/findings/reviews/stress--nvhpc-target-scalar-implicit-firstprivate.json +130 -0
  715. offload/_root/data/findings/reviews/target-update-sections-in-parallel.json +113 -0
  716. offload/_root/data/findings/stress/afar-c-lastprivate-combined-target-not-mapped.c +72 -0
  717. offload/_root/data/findings/stress/afar-target-scalar-implicit-firstprivate.f90 +47 -0
  718. offload/_root/data/findings/stress/cce-acc-declare-create-scalar-serial-firstprivate.f90 +43 -0
  719. offload/_root/data/findings/stress/cce-c-distribute-lastprivate-lost.c +52 -0
  720. offload/_root/data/findings/stress/cce-c-flto-offload-dropped.c +73 -0
  721. offload/_root/data/findings/stress/cce-ftn-cif-record-split-abort.f90 +109 -0
  722. offload/_root/data/findings/stress/cce-lastprivate-num-threads-collapse-simd.f90 +66 -0
  723. offload/_root/data/findings/stress/cce-teams-reduction-many-teams-wrap.f90 +55 -0
  724. offload/_root/data/findings/stress/cce21-declare-target-scalar-map-write-lost.f90 +58 -0
  725. offload/_root/data/findings/stress/controls/gcc-declare-target-allocatable-component-control.f90 +29 -0
  726. offload/_root/data/findings/stress/gcc-declare-target-allocatable-component-ice.f90 +61 -0
  727. offload/_root/data/findings/stress/nvhpc-acc-derived-type-component-not-copied.f90 +33 -0
  728. offload/_root/data/findings/stress/nvhpc-c-lastprivate-teams-distribute-parallel-for-lost.c +62 -0
  729. offload/_root/data/findings/stress/nvhpc-declare-target-scalar-write-lost.f90 +43 -0
  730. offload/_root/data/findings/stress/nvhpc-lastprivate-combined-target-not-mapped.f90 +60 -0
  731. offload/_root/data/findings/stress/nvhpc-target-scalar-implicit-firstprivate.f90 +41 -0
  732. offload/_root/data/findings/target-update-sections-in-parallel.f90 +53 -0
  733. offload/_root/data/issues.json +1 -0
  734. offload/_root/data/search.json +1 -0
  735. offload/_root/data/vendor/checks/build.py +288 -0
  736. offload/_version.py +24 -0
  737. offload/canuse.py +88 -0
  738. offload/cli.py +52 -0
  739. offload/data.py +85 -0
  740. offload/engine/__init__.py +0 -0
  741. offload/engine/acc_c_gen.py +415 -0
  742. offload/engine/acc_gen.py +1104 -0
  743. offload/engine/acc_rules.py +656 -0
  744. offload/engine/apps.py +804 -0
  745. offload/engine/baseline.py +324 -0
  746. offload/engine/c_gen.py +883 -0
  747. offload/engine/c_program.py +913 -0
  748. offload/engine/c_rules.py +503 -0
  749. offload/engine/campaign.py +1180 -0
  750. offload/engine/campaigns/__init__.py +2 -0
  751. offload/engine/campaigns/hecbench.py +153 -0
  752. offload/engine/campaigns/nested.py +76 -0
  753. offload/engine/campaigns/oop.py +61 -0
  754. offload/engine/canary.py +275 -0
  755. offload/engine/catalog.py +860 -0
  756. offload/engine/citations.py +532 -0
  757. offload/engine/clang_oracle.py +208 -0
  758. offload/engine/combos.py +234 -0
  759. offload/engine/confirm/__init__.py +2 -0
  760. offload/engine/confirm/backlog.py +159 -0
  761. offload/engine/confirm/claims.py +423 -0
  762. offload/engine/confirm/collectors.py +665 -0
  763. offload/engine/confirm/decisions.py +202 -0
  764. offload/engine/confirm/draft.py +195 -0
  765. offload/engine/confirm/engine.py +157 -0
  766. offload/engine/confirm/execute.py +382 -0
  767. offload/engine/confirm/facts.py +467 -0
  768. offload/engine/confirm/findings.py +617 -0
  769. offload/engine/confirm/forms.py +145 -0
  770. offload/engine/confirm/ingest.py +372 -0
  771. offload/engine/confirm/jobs.py +215 -0
  772. offload/engine/confirm/legality.py +323 -0
  773. offload/engine/confirm/machines.py +254 -0
  774. offload/engine/confirm/minimize.py +268 -0
  775. offload/engine/confirm/model.py +249 -0
  776. offload/engine/confirm/ports.py +107 -0
  777. offload/engine/confirm/programs.py +222 -0
  778. offload/engine/confirm/registry.py +151 -0
  779. offload/engine/confirm/regress.py +278 -0
  780. offload/engine/confirm/rules.py +565 -0
  781. offload/engine/confirm/store.py +63 -0
  782. offload/engine/confirm/triage.py +838 -0
  783. offload/engine/confirm/validate.py +607 -0
  784. offload/engine/confirm/witness.py +355 -0
  785. offload/engine/corpus_check.py +388 -0
  786. offload/engine/coverage.py +318 -0
  787. offload/engine/dataenv_gen.py +1318 -0
  788. offload/engine/dataenv_rules.py +278 -0
  789. offload/engine/devtemps.py +146 -0
  790. offload/engine/expected.py +2559 -0
  791. offload/engine/f2c.py +1783 -0
  792. offload/engine/finding_claims.py +330 -0
  793. offload/engine/finding_header.py +229 -0
  794. offload/engine/finding_rows.py +382 -0
  795. offload/engine/flang_oracle.py +299 -0
  796. offload/engine/fsource.py +620 -0
  797. offload/engine/fuzz.py +2455 -0
  798. offload/engine/fuzz_base.py +2016 -0
  799. offload/engine/fuzz_campaign.py +592 -0
  800. offload/engine/fuzz_exec.py +798 -0
  801. offload/engine/fuzz_min.py +1049 -0
  802. offload/engine/fuzz_profile.py +340 -0
  803. offload/engine/fuzz_report.py +1270 -0
  804. offload/engine/fuzz_steer.py +181 -0
  805. offload/engine/gate.py +1013 -0
  806. offload/engine/gate_report.py +711 -0
  807. offload/engine/gate_run.py +118 -0
  808. offload/engine/gate_stored.py +466 -0
  809. offload/engine/gen.py +1114 -0
  810. offload/engine/gen_templates.py +2583 -0
  811. offload/engine/grammar.py +695 -0
  812. offload/engine/harness.py +1472 -0
  813. offload/engine/harvest/__init__.py +3 -0
  814. offload/engine/harvest/c_runtime.py +465 -0
  815. offload/engine/harvest/checks.py +534 -0
  816. offload/engine/harvest/convert.py +784 -0
  817. offload/engine/harvest/f_runtime.py +668 -0
  818. offload/engine/harvest/filters.py +338 -0
  819. offload/engine/harvest/history.py +122 -0
  820. offload/engine/harvest/inventory.py +399 -0
  821. offload/engine/harvest2/__init__.py +5 -0
  822. offload/engine/harvest2/aomp.py +119 -0
  823. offload/engine/harvest2/examples.py +116 -0
  824. offload/engine/harvest2/gomp.py +679 -0
  825. offload/engine/harvest2/hand.py +150 -0
  826. offload/engine/harvest2/split.py +78 -0
  827. offload/engine/harvest_known/__init__.py +2 -0
  828. offload/engine/harvest_known/apps.py +65 -0
  829. offload/engine/harvest_known/cases.py +128 -0
  830. offload/engine/harvest_known/centres.py +184 -0
  831. offload/engine/harvest_known/forum.py +180 -0
  832. offload/engine/harvest_known/relnotes.py +42 -0
  833. offload/engine/harvest_known/textscan.py +107 -0
  834. offload/engine/hdrwrap.py +42 -0
  835. offload/engine/hecbench.py +568 -0
  836. offload/engine/hecbench_report.py +265 -0
  837. offload/engine/hecbench_run.py +483 -0
  838. offload/engine/idioms.py +1427 -0
  839. offload/engine/kbody_cites.py +81 -0
  840. offload/engine/kbody_emit.py +949 -0
  841. offload/engine/kbody_gen.py +795 -0
  842. offload/engine/legality_review.py +236 -0
  843. offload/engine/localcfg.py +58 -0
  844. offload/engine/malloc_dd.py +267 -0
  845. offload/engine/mutate.py +1933 -0
  846. offload/engine/nested_cites.py +196 -0
  847. offload/engine/nested_emit.py +789 -0
  848. offload/engine/nested_gen.py +1721 -0
  849. offload/engine/offload_scope.py +197 -0
  850. offload/engine/ompvv.py +624 -0
  851. offload/engine/oop_gen.py +2249 -0
  852. offload/engine/prerun.py +1435 -0
  853. offload/engine/program_source.py +739 -0
  854. offload/engine/provenance.py +103 -0
  855. offload/engine/reduce.py +2098 -0
  856. offload/engine/report.py +3374 -0
  857. offload/engine/root.py +33 -0
  858. offload/engine/rules.py +4256 -0
  859. offload/engine/run_matrix.py +325 -0
  860. offload/engine/site/__init__.py +1 -0
  861. offload/engine/site/columns.py +53 -0
  862. offload/engine/site/data.py +648 -0
  863. offload/engine/site/header.py +228 -0
  864. offload/engine/site/inputs.py +115 -0
  865. offload/engine/site/matrix.py +434 -0
  866. offload/engine/site/scrub.py +294 -0
  867. offload/engine/skeleton.py +121 -0
  868. offload/engine/spec_text.py +242 -0
  869. offload/engine/stress.py +4122 -0
  870. offload/engine/stress_c.py +1000 -0
  871. offload/engine/stress_exec.py +805 -0
  872. offload/engine/stress_min.py +248 -0
  873. offload/engine/stress_report.py +552 -0
  874. offload/engine/textclean.py +97 -0
  875. offload/engine/toolchains.py +1070 -0
  876. offload/engine/transforms.py +511 -0
  877. offload/engine/usage.py +1252 -0
  878. offload/engine/widen.py +673 -0
  879. offload/engine/widen_progs.py +2396 -0
  880. offload/issues.py +146 -0
  881. offtarget-0.1.0.dist-info/METADATA +86 -0
  882. offtarget-0.1.0.dist-info/RECORD +886 -0
  883. offtarget-0.1.0.dist-info/WHEEL +4 -0
  884. offtarget-0.1.0.dist-info/entry_points.txt +2 -0
  885. offtarget-0.1.0.dist-info/licenses/LICENSE +21 -0
  886. offtarget-0.1.0.dist-info/licenses/THIRD_PARTY_NOTICES.md +20 -0
@@ -0,0 +1,2016 @@
1
+ """The base-language axis of the fuzz generator.
2
+
3
+ ``offload.engine.fuzz`` varies OpenMP constructs over a trivial Fortran base of
4
+ integer arrays and scalars. This module adds base-language groups, each
5
+ switchable with ``--base-features`` and each with its own swarm of
6
+ sub-features, so a feature one compiler rejects does not hide the others.
7
+ Groups: ``types`` (element types and kinds, typed reductions), ``derived``
8
+ (derived types, component-level maps), ``alloc`` (allocatable and pointer
9
+ arrays, TARGET, internal subroutines), ``declare`` (declare target
10
+ variables, mappers, declare reduction and functions) and ``multitu`` (a
11
+ bundle of files marked by ``!@file <name>.f90`` lines, compiled with ``-c``
12
+ and linked by ``offload.engine.fuzz_exec``). Each program records its features
13
+ in ``FuzzProgram.features`` and a header line.
14
+ Real values are dyadic rationals bounded statically (``BOUND``, ``DEN``), so
15
+ reassociation and contraction stay exact; the model uses ``Fraction``."""
16
+ from __future__ import annotations
17
+
18
+ import re
19
+ from dataclasses import dataclass
20
+ from fractions import Fraction as Q
21
+
22
+ # --- the groups ---------------------------------------------------------------------
23
+
24
+ BASE_GROUPS = ("types", "derived", "alloc", "declare", "multitu")
25
+ # fortran-oop (generator fuzz-5 only): type extension, type-bound
26
+ # procedures, dispatch, SELECT TYPE and CLASS(*) inside device functions
27
+ OOP_GROUPS = ("oop",)
28
+ ALL_GROUPS = BASE_GROUPS + OOP_GROUPS
29
+ # the first generator version of each group added after fuzz-3
30
+ GROUP_SINCE = {"oop": "fuzz-5"}
31
+ GROUP_SWARM = {
32
+ "types": ("real4", "real8", "dp", "complex4", "complex8", "logical",
33
+ "char", "int1", "int2", "int8", "typed_out", "typed_red",
34
+ "typed_view", "atomic_typed"),
35
+ # stage 2: a structure dr (type rec_t) with fixed-size components, a
36
+ # nested structure component dr%nd (type nd_t), an array of
37
+ # structures ds(n) (type el_t); maps of whole variables, of
38
+ # components, or implicit; default component initialisation
39
+ "derived": ("dt_nested", "dt_aos", "dt_scalar", "dt_typed", "dt_out",
40
+ "dt_whole", "dt_comp", "dt_implicit", "dt_default_init",
41
+ "dt_section"),
42
+ # stage 3: allocatable, pointer and target variables and components,
43
+ # strided array sections in target update and sections in depend,
44
+ # kernels moved into internal procedures with assumed-shape,
45
+ # explicit-shape, allocatable and pointer dummies, intent, value,
46
+ # optional (present, and absent in a map clause), assumed length
47
+ "alloc": ("al_ptr_out", "al_target", "al_alloc_scalar",
48
+ "al_comp_alloc", "al_comp_ptr", "al_stride_update",
49
+ "al_depend_section", "al_proc", "al_explicit_dummy",
50
+ "al_alloc_dummy", "al_ptr_dummy", "al_value", "al_optional",
51
+ "al_optional_absent", "al_intent_out", "al_assumed_len"),
52
+ # stage 4: module fuzz_dmod with declare target variables (an array,
53
+ # an output array, a structure of a module type), a declare mapper
54
+ # (default or named) for a module type, a declare reduction on a
55
+ # module type, and declare target functions in fuzz_dmod and
56
+ # fuzz_dfun (which uses fuzz_dmod) called from kernels
57
+ "declare": ("dc_modvar", "dc_modvar_out", "dc_static_init",
58
+ "dc_modtype", "dc_mapper", "dc_named_mapper", "dc_udr",
59
+ "dc_calls", "dc_chain", "dc_enter"),
60
+ # stage 5: the program as a set of files (translation units), each
61
+ # compiled with -c, then linked: every module in its own file, a
62
+ # module chain fuzz_amod <- fuzz_bmod, a module with a separate module
63
+ # procedure implemented in a submodule (its own file), an external
64
+ # declare target function with an interface block in the main program
65
+ "multitu": ("mt_chain", "mt_submodule", "mt_external", "mt_amod"),
66
+ # fuzz-5 (fortran-oop): module fuzz_omod with a type ob_t (bindings f,
67
+ # g) and its extension ox_t (overriding f, which calls the parent's f
68
+ # through the parent component); declare target functions oo1..oo5
69
+ # called from kernels, each building a local object and calling
70
+ # through a CLASS(ob_t) dummy (dispatch), an inherited binding that
71
+ # dispatches (inherit), SELECT TYPE (select) or a CLASS(*) dummy
72
+ # (unlimited)
73
+ "oop": ("oo_dispatch", "oo_override", "oo_inherit", "oo_select",
74
+ "oo_unlimited"),
75
+ }
76
+ FILE_MARK = "!@file " # a bundle: "!@file <name>.f90" starts a file
77
+
78
+ # What each group leaves out, and why (the model could not predict it, or
79
+ # the spec leaves it open); data/reports/fuzz-base-language.md prints this.
80
+ EXCLUSIONS = {
81
+ "types": [
82
+ "floating-point values that are not exactly representable, "
83
+ "floating-point division (other than by a power of two inside mod), "
84
+ "transcendental intrinsics, products of two variables: the result "
85
+ "would depend on rounding, contraction or reduction order",
86
+ "product reductions of reals; max/min reductions of complex and any "
87
+ "character reduction (not allowed by 5.2 §5.5.5)",
88
+ "atomic updates of complex and character items",
89
+ "character scalars referenced without an explicit map (5.2 defines "
90
+ "a Fortran scalar variable to exclude character type, so the "
91
+ "implicit rule for one is unclear; "
92
+ "data/findings/afar-cce19-character-defaultmap.f90)",
93
+ "logical values compared with == (not Fortran; .eqv. is used)",
94
+ "lastprivate and in_reduction of typed items (integers only)",
95
+ ],
96
+ "derived": [
97
+ "a structure mapped whole with from or alloc (it would copy back or "
98
+ "leave undefined the components the kernel does not write)",
99
+ "an array of structures mapped by component (ds(:)%u is not "
100
+ "contiguous storage, 5.2 §5.8.3)",
101
+ "structure elements in data-sharing or depend clauses (not variable "
102
+ "or locator list items in Fortran, 5.2 §3.2.1)",
103
+ "reductions, lastprivate or firstprivate of structure components",
104
+ "polymorphic (class), parameterized and extended derived types",
105
+ ],
106
+ "alloc": [
107
+ "a pointer component referenced while its structure is mapped whole "
108
+ "or implicitly (association status undefined through the default "
109
+ "mapper, 5.2 §5.8.3)",
110
+ "pointers or allocatables changing association or allocation inside "
111
+ "a data region, and allocatable or pointer arrays referenced "
112
+ "implicitly through defaultmap (a firstprivate pointer would not "
113
+ "map its target)",
114
+ "non-contiguous array sections in map clauses (5.2 §5.8.3); strided "
115
+ "sections only in target update",
116
+ "dummy procedures (procedure arguments) called in a target region: "
117
+ "an indirect call needs declare target indirect (5.2 §7.8.3), whose "
118
+ "support the model cannot predict",
119
+ "internal procedures holding a kernel of a nowait sequence (the "
120
+ "dummies end before the target task)",
121
+ "intent(in) dummies of arrays a kernel maps other than to (the "
122
+ "copy back would define them)",
123
+ ],
124
+ "declare": [
125
+ "declare target variables in map clauses or in data-sharing clauses "
126
+ "other than shared (infinite reference count, 5.2 §5.8.1)",
127
+ "link clauses and device_type(nohost/host)",
128
+ "mappers that leave out a component a kernel references",
129
+ "declare reduction with a combiner or initializer subroutine; user "
130
+ "reductions in atomic/critical updates or in task reductions",
131
+ "declare variant, metadirective and indirect calls",
132
+ ],
133
+ "oop": [
134
+ "polymorphic objects in map or data-sharing clauses (OpenMP 6.0 "
135
+ "§7.9.6 p.288: unspecified), and mapped objects of the module types: "
136
+ "every object is a local variable of a device function",
137
+ "abstract types, deferred bindings, finalization and defined "
138
+ "assignment (the campaign's hand-written families cover them)",
139
+ "polymorphic allocatable locals (device-side allocation)",
140
+ ],
141
+ "multitu": [
142
+ "a compile order other than the dependency order (modules before "
143
+ "their users)",
144
+ "kernels in procedures of other files (the kernels stay in the main "
145
+ "program file; device functions cross files)",
146
+ "common blocks, block data, and declare target on external variables",
147
+ ],
148
+ }
149
+
150
+ # type key -> (Fortran type, kind)
151
+ TYPES = {"real4": ("real", 4), "real8": ("real", 8),
152
+ "complex4": ("complex", 4), "complex8": ("complex", 8),
153
+ "logical": ("logical", 4), "char": ("character", 4),
154
+ "int1": ("integer", 1), "int2": ("integer", 2),
155
+ "int8": ("integer", 8)}
156
+ REAL_BITS = {4: 24, 8: 53}
157
+ DEN = 64 # every real value times DEN is an integer
158
+ CHAR_LEN = 4
159
+ SCALAR_LEN = 8
160
+ INT_MAX = {1: 127, 2: 32767, 8: 2 ** 62}
161
+ # typed reductions: legal identifiers whose result does not depend on the
162
+ # combination order for the values the generator draws (OpenMP 5.2 §5.5.5)
163
+ RED_OPS_TYPED = {
164
+ "real": ("+", "max", "min"), "complex": ("+",),
165
+ "logical": (".and.", ".or.", ".eqv.", ".neqv."),
166
+ "integer1": ("max", "min", "iand", "ior", "ieor"),
167
+ "integer2": ("max", "min", "iand", "ior", "ieor"),
168
+ "integer8": ("+", "max", "min", "iand", "ior", "ieor"),
169
+ }
170
+
171
+
172
+ class Overflow(Exception):
173
+ """A value of the model left the bounded range (the kernel is
174
+ redrawn)."""
175
+
176
+
177
+ def real_limit(kind: int) -> Q:
178
+ """Largest magnitude a real of `kind` may take: value * DEN must fit
179
+ the significand with a margin."""
180
+ return Q(2 ** (REAL_BITS[kind] - 1), DEN) if kind == 4 else Q(2 ** 40)
181
+
182
+
183
+ def fortran_mod_q(a: Q, p: Q) -> Q:
184
+ """Fortran MOD for reals: a - int(a/p)*p (the sign of a)."""
185
+ return a - int(a / p) * p
186
+
187
+
188
+ def nint_q(a: Q) -> int:
189
+ """Fortran NINT: round half away from zero."""
190
+ s = -1 if a < 0 else 1
191
+ return s * int(abs(a) + Q(1, 2))
192
+
193
+
194
+ def rlit(v: Q, kind: int, dp: bool = False, paren: bool = True) -> str:
195
+ """A real literal of `kind` with the exact value v (a dyadic); a
196
+ negative one in parentheses unless `paren` is false (the parts of a
197
+ complex literal constant are signed literals)."""
198
+ whole = int(v)
199
+ frac = abs(v - whole)
200
+ digits = ""
201
+ if frac:
202
+ # a dyadic fraction has a finite decimal expansion
203
+ x, digits = frac, ""
204
+ while x:
205
+ x *= 10
206
+ digits += str(int(x))
207
+ x -= int(x)
208
+ sign = "-" if v < 0 else ""
209
+ text = f"{abs(whole)}.{digits or '0'}"
210
+ if kind == 8:
211
+ text = text + ("d0" if dp else "_8")
212
+ return f"({sign}{text})" if sign and paren else f"{sign}{text}"
213
+
214
+
215
+ # --- typed expressions (Fortran text, model value, static bound) -------------------
216
+
217
+ class TEx:
218
+ """A typed expression: ``f()`` Fortran text, ``ev(env, arrs)`` the
219
+ model value (Fraction, (Fraction, Fraction), bool, str or int),
220
+ ``bound()`` a static bound of the magnitude of the value and of any
221
+ partial result of a reassociation (reals, components of complex,
222
+ integers)."""
223
+ def f(self) -> str:
224
+ raise NotImplementedError
225
+
226
+ def ev(self, env, arrs):
227
+ raise NotImplementedError
228
+
229
+ def bound(self):
230
+ return 0
231
+
232
+
233
+ @dataclass(frozen=True)
234
+ class TRef(TEx):
235
+ arr: str
236
+ idx: tuple # integer Ex subscripts (rank 0: a scalar)
237
+ bnd: object = 0 # static bound of the array's values
238
+
239
+ def f(self):
240
+ if not self.idx:
241
+ return self.arr
242
+ sub = ", ".join(x.f() for x in self.idx)
243
+ if "(@)" in self.arr:
244
+ return self.arr.replace("@", sub)
245
+ return f"{self.arr}({sub})"
246
+
247
+ def ev(self, env, arrs):
248
+ if not self.idx:
249
+ return arrs[self.arr][()]
250
+ return arrs[self.arr][tuple(x.ev(env, arrs) for x in self.idx)]
251
+
252
+ def bound(self):
253
+ return self.bnd
254
+
255
+
256
+ @dataclass(frozen=True)
257
+ class RConst(TEx):
258
+ v: Q
259
+ kind: int
260
+ dp: bool = False
261
+
262
+ def f(self):
263
+ return rlit(self.v, self.kind, self.dp)
264
+
265
+ def ev(self, env, arrs):
266
+ return self.v
267
+
268
+ def bound(self):
269
+ return abs(self.v)
270
+
271
+
272
+ @dataclass(frozen=True)
273
+ class RConv(TEx):
274
+ """real(e, kind) of an integer expression whose |value| < bnd."""
275
+ e: object
276
+ kind: int
277
+ bnd: int
278
+
279
+ def f(self):
280
+ return f"real({self.e.f()}, {self.kind})"
281
+
282
+ def ev(self, env, arrs):
283
+ return Q(self.e.ev(env, arrs))
284
+
285
+ def bound(self):
286
+ return Q(self.bnd)
287
+
288
+
289
+ @dataclass(frozen=True)
290
+ class RCast(TEx):
291
+ """real(x, kind) of a real expression of another kind."""
292
+ x: TEx
293
+ kind: int
294
+
295
+ def f(self):
296
+ return f"real({self.x.f()}, {self.kind})"
297
+
298
+ def ev(self, env, arrs):
299
+ return self.x.ev(env, arrs)
300
+
301
+ def bound(self):
302
+ return self.x.bound()
303
+
304
+
305
+ @dataclass(frozen=True)
306
+ class RBin(TEx):
307
+ op: str # + - *(the right operand a constant)
308
+ a: TEx
309
+ b: TEx
310
+
311
+ def f(self):
312
+ return f"({self.a.f()} {self.op} {self.b.f()})"
313
+
314
+ def ev(self, env, arrs):
315
+ x, y = self.a.ev(env, arrs), self.b.ev(env, arrs)
316
+ return x + y if self.op == "+" else x - y if self.op == "-" \
317
+ else x * y
318
+
319
+ def bound(self):
320
+ if self.op == "*":
321
+ return self.a.bound() * self.b.bound()
322
+ return self.a.bound() + self.b.bound()
323
+
324
+
325
+ @dataclass(frozen=True)
326
+ class RFun(TEx):
327
+ name: str # max | min | abs | mod (b a power-of-two constant)
328
+ a: TEx
329
+ b: TEx | None = None
330
+
331
+ def f(self):
332
+ args = self.a.f() + (f", {self.b.f()}" if self.b is not None else "")
333
+ return f"{self.name}({args})"
334
+
335
+ def ev(self, env, arrs):
336
+ x = self.a.ev(env, arrs)
337
+ if self.name == "abs":
338
+ return abs(x)
339
+ y = self.b.ev(env, arrs)
340
+ if self.name == "mod":
341
+ return fortran_mod_q(x, y)
342
+ return max(x, y) if self.name == "max" else min(x, y)
343
+
344
+ def bound(self):
345
+ if self.name == "mod":
346
+ return min(self.a.bound(), self.b.bound())
347
+ if self.name == "abs":
348
+ return self.a.bound()
349
+ return max(self.a.bound(), self.b.bound())
350
+
351
+
352
+ @dataclass(frozen=True)
353
+ class CMake(TEx):
354
+ re: TEx
355
+ im: TEx
356
+ kind: int
357
+
358
+ def f(self):
359
+ return f"cmplx({self.re.f()}, {self.im.f()}, {self.kind})"
360
+
361
+ def ev(self, env, arrs):
362
+ return (self.re.ev(env, arrs), self.im.ev(env, arrs))
363
+
364
+ def bound(self):
365
+ return max(self.re.bound(), self.im.bound())
366
+
367
+
368
+ @dataclass(frozen=True)
369
+ class CConst(TEx):
370
+ re: Q
371
+ im: Q
372
+ kind: int
373
+
374
+ def f(self):
375
+ return (f"({rlit(self.re, self.kind, paren=False)}, "
376
+ f"{rlit(self.im, self.kind, paren=False)})")
377
+
378
+ def ev(self, env, arrs):
379
+ return (self.re, self.im)
380
+
381
+ def bound(self):
382
+ return max(abs(self.re), abs(self.im))
383
+
384
+
385
+ @dataclass(frozen=True)
386
+ class CBin(TEx):
387
+ op: str # + - * (the right operand a CConst)
388
+ a: TEx
389
+ b: TEx
390
+
391
+ def f(self):
392
+ return f"({self.a.f()} {self.op} {self.b.f()})"
393
+
394
+ def ev(self, env, arrs):
395
+ (p, q), (r, s) = self.a.ev(env, arrs), self.b.ev(env, arrs)
396
+ if self.op == "+":
397
+ return (p + r, q + s)
398
+ if self.op == "-":
399
+ return (p - r, q - s)
400
+ return (p * r - q * s, p * s + q * r)
401
+
402
+ def bound(self):
403
+ if self.op == "*":
404
+ return self.a.bound() * 2 * self.b.bound()
405
+ return self.a.bound() + self.b.bound()
406
+
407
+
408
+ @dataclass(frozen=True)
409
+ class CFun(TEx):
410
+ name: str # conjg
411
+ a: TEx
412
+
413
+ def f(self):
414
+ return f"{self.name}({self.a.f()})"
415
+
416
+ def ev(self, env, arrs):
417
+ p, q = self.a.ev(env, arrs)
418
+ return (p, -q)
419
+
420
+ def bound(self):
421
+ return self.a.bound()
422
+
423
+
424
+ @dataclass(frozen=True)
425
+ class CPart(TEx):
426
+ """real(z) or aimag(z): a real of the complex kind."""
427
+ name: str
428
+ z: TEx
429
+
430
+ def f(self):
431
+ return f"{self.name}({self.z.f()})"
432
+
433
+ def ev(self, env, arrs):
434
+ v = self.z.ev(env, arrs)
435
+ return v[0] if self.name == "real" else v[1]
436
+
437
+ def bound(self):
438
+ return self.z.bound()
439
+
440
+
441
+ @dataclass(frozen=True)
442
+ class LCmp(TEx):
443
+ op: str
444
+ a: object # integer Ex
445
+ b: object
446
+
447
+ def f(self):
448
+ return f"({self.a.f()} {self.op} {self.b.f()})"
449
+
450
+ def ev(self, env, arrs):
451
+ x, y = self.a.ev(env, arrs), self.b.ev(env, arrs)
452
+ return {"<": x < y, "<=": x <= y, ">": x > y, ">=": x >= y,
453
+ "==": x == y, "/=": x != y}[self.op]
454
+
455
+
456
+ @dataclass(frozen=True)
457
+ class LBin(TEx):
458
+ op: str # .and. .or. .eqv. .neqv.
459
+ a: TEx
460
+ b: TEx
461
+
462
+ def f(self):
463
+ return f"({self.a.f()} {self.op} {self.b.f()})"
464
+
465
+ def ev(self, env, arrs):
466
+ return lapply(self.op, self.a.ev(env, arrs), self.b.ev(env, arrs))
467
+
468
+
469
+ @dataclass(frozen=True)
470
+ class LNot(TEx):
471
+ a: TEx
472
+
473
+ def f(self):
474
+ return f"(.not. {self.a.f()})"
475
+
476
+ def ev(self, env, arrs):
477
+ return not self.a.ev(env, arrs)
478
+
479
+
480
+ def lapply(op: str, x: bool, y: bool) -> bool:
481
+ return {".and.": x and y, ".or.": x or y, ".eqv.": x == y,
482
+ ".neqv.": x != y}[op]
483
+
484
+
485
+ @dataclass(frozen=True)
486
+ class ChMake(TEx):
487
+ """achar(65 + iand(e, 15)) // src(2:4), or src(3:4) // achar(97 +
488
+ iand(e, 15)) // achar(48 + iand(e2, 7)): a character(len=4) value."""
489
+ form: int
490
+ e: object
491
+ src: TEx
492
+ e2: object = None
493
+
494
+ def f(self):
495
+ if self.form == 0:
496
+ return (f"achar(65 + iand({self.e.f()}, 15)) // "
497
+ f"{self.src.f()}(2:4)")
498
+ return (f"{self.src.f()}(3:4) // achar(97 + iand({self.e.f()}, 15))"
499
+ f" // achar(48 + iand({self.e2.f()}, 7))")
500
+
501
+ def ev(self, env, arrs):
502
+ s = self.src.ev(env, arrs)
503
+ if self.form == 0:
504
+ return chr(65 + (self.e.ev(env, arrs) & 15)) + s[1:4]
505
+ return s[2:4] + chr(97 + (self.e.ev(env, arrs) & 15)) + \
506
+ chr(48 + (self.e2.ev(env, arrs) & 7))
507
+
508
+
509
+ @dataclass(frozen=True)
510
+ class KExpr(TEx):
511
+ """An integer expression of kind 1, 2 or 8 (Fortran text given; the
512
+ model function computes it)."""
513
+ text: str
514
+ fn: object
515
+ bnd: int
516
+
517
+ def f(self):
518
+ return self.text
519
+
520
+ def ev(self, env, arrs):
521
+ return self.fn(env, arrs)
522
+
523
+ def bound(self):
524
+ return self.bnd
525
+
526
+
527
+ # integer views of typed values (integer Ex: f/ev only)
528
+
529
+ @dataclass(frozen=True)
530
+ class IView:
531
+ """An integer of default kind computed from a typed value: `how` is
532
+ int | nint | merge | ichar | intk (int(x) of an integer kind) |
533
+ mod8 (int(mod(x, 1000003_8)))."""
534
+ how: str
535
+ x: TEx
536
+ pos: int = 1 # ichar: the character position
537
+
538
+ def f(self):
539
+ x = self.x.f()
540
+ return {"int": f"int({x})", "nint": f"nint({x})",
541
+ "merge": f"merge(1, 0, {x})",
542
+ "ichar": f"ichar({x}({self.pos}:{self.pos}))",
543
+ "intk": f"int({x})",
544
+ "mod8": f"int(mod({x}, 1000003_8))"}[self.how]
545
+
546
+ def ev(self, env, arrs):
547
+ v = self.x.ev(env, arrs)
548
+ if self.how == "int":
549
+ return int(v)
550
+ if self.how == "nint":
551
+ return nint_q(v)
552
+ if self.how == "merge":
553
+ return 1 if v else 0
554
+ if self.how == "ichar":
555
+ return ord(v[self.pos - 1])
556
+ if self.how == "intk":
557
+ return v
558
+ r = abs(v) % 1000003
559
+ return r if v >= 0 else -r
560
+
561
+
562
+ # --- model values ---------------------------------------------------------------------
563
+
564
+ def zero(typ: str):
565
+ if typ == "pair":
566
+ return (0, 0)
567
+ base = TYPES[typ][0] if typ in TYPES else "integer"
568
+ if base == "real":
569
+ return Q(0)
570
+ if base == "complex":
571
+ return (Q(0), Q(0))
572
+ if base == "logical":
573
+ return False
574
+ if base == "character":
575
+ return " " * CHAR_LEN
576
+ return 0
577
+
578
+
579
+ def contributions(typ: str, v) -> list[int]:
580
+ """The checksum contributions of one value (Fortran: ``checksum_terms``)."""
581
+ if typ == "pair":
582
+ return [v[0], v[1]]
583
+ base = TYPES[typ][0] if typ in TYPES else "integer"
584
+ if base == "real":
585
+ x = v * DEN
586
+ if x.denominator != 1:
587
+ raise Overflow(f"real value {v} is not a multiple of 1/{DEN}")
588
+ return [int(x)]
589
+ if base == "complex":
590
+ return contributions("real8", v[0]) + contributions("real8", v[1])
591
+ if base == "logical":
592
+ return [1 if v else 0]
593
+ if base == "character":
594
+ return [ord(c) for c in v]
595
+ return [v]
596
+
597
+
598
+ def checksum_terms(typ: str, ref: str) -> list[str]:
599
+ """Fortran integer(8) expressions of the contributions of `ref`."""
600
+ if typ == "pair":
601
+ return [f"int({ref}%x, 8)", f"int({ref}%y, 8)"]
602
+ base, kind = TYPES[typ] if typ in TYPES else ("integer", 4)
603
+ if base == "real":
604
+ return [f"int({ref} * {DEN}, 8)"]
605
+ if base == "complex":
606
+ return [f"int(real({ref}) * {DEN}, 8)",
607
+ f"int(aimag({ref}) * {DEN}, 8)"]
608
+ if base == "logical":
609
+ return [f"merge(1_8, 0_8, {ref})"]
610
+ if base == "character":
611
+ return [f"int(ichar({ref}({k}:{k})), 8)"
612
+ for k in range(1, CHAR_LEN + 1)]
613
+ return [f"int({ref}, 8)"]
614
+
615
+
616
+ def red_apply_typed(base: str, op: str, acc, v):
617
+ if base == "complex":
618
+ return (acc[0] + v[0], acc[1] + v[1])
619
+ if base == "logical":
620
+ return lapply(op, acc, v)
621
+ if op == "+":
622
+ return acc + v
623
+ if op == "max":
624
+ return max(acc, v)
625
+ if op == "min":
626
+ return min(acc, v)
627
+ if op == "iand":
628
+ return acc & v
629
+ if op == "ior":
630
+ return acc | v
631
+ return acc ^ v
632
+
633
+
634
+ # --- the generator side (mixed into offload.engine.fuzz._Gen) ---------------------------------
635
+
636
+ class BaseMixin:
637
+ """Base-language decisions of one program. Uses ``self.rb`` (a random
638
+ stream of its own, so a fuzz-3 program without base groups is the
639
+ fuzz-2 program of its seed) and the swarm ``self.bsw``."""
640
+
641
+ def base_init(self, base: tuple) -> None:
642
+ import random
643
+ unknown = [g for g in base if g not in ALL_GROUPS]
644
+ if unknown:
645
+ raise ValueError(f"unknown base-feature group(s) {unknown}")
646
+ if base and self.v < 3:
647
+ raise ValueError("base-feature groups need generator fuzz-3")
648
+ # by version order: fuzz-5's self.v is 6, since
649
+ # fuzz-4s50 takes the index after fuzz-4; every check is ">="
650
+ from offload.engine.fuzz import GEN_VERSIONS
651
+ for g in base:
652
+ if g in GROUP_SINCE and GEN_VERSIONS.index(self.gen_version) < \
653
+ GEN_VERSIONS.index(GROUP_SINCE[g]):
654
+ raise ValueError(f"base-feature group {g} needs generator "
655
+ f"{GROUP_SINCE[g]}")
656
+ self.base = tuple(g for g in ALL_GROUPS if g in base)
657
+ self.rb = random.Random(f"fuzz-3-base:{self.seed}")
658
+ self.bsw = {}
659
+ for g in self.base:
660
+ for f in GROUP_SWARM[g]:
661
+ self.bsw[f] = self.rb.random() < 0.6
662
+ self.features.add(f"base:group:{g}")
663
+ self.tscalars: dict[str, str] = {} # typed scalar -> type key
664
+ self.tbound: dict[str, object] = {} # typed input -> value bound
665
+ self.spell: dict[str, str] = {} # array/scalar -> decl type
666
+ self.dvars: dict[str, str] = {} # structure -> type (stage 2)
667
+ self.dt_defaults: dict[str, str] = {}
668
+ self.ptrs: dict[str, str] = {} # pointer -> target | alloc
669
+ self.tgt_attr: set = set() # arrays with TARGET
670
+ self.procs: list[str] = [] # internal procedures
671
+ self.full_out: dict[str, bool] = {} # output -> written whole
672
+ self.dtv: set = set() # declare target (stage 4)
673
+ self.dfuncs: list = [] # device functions (stage 4)
674
+ self.mfuncs: list = [] # functions of fuzz_dmod
675
+ self.xfuncs: list = [] # functions of stage 5
676
+ self.mt_funcs: dict = {}
677
+ self.ofuncs: list = [] # oop device functions (fuzz-5)
678
+ self.oop_consts: dict = {}
679
+
680
+ def bon(self, name: str) -> bool:
681
+ return self.bsw.get(name, False)
682
+
683
+ # -- names of arrays and components --
684
+
685
+ def var_of(self, name: str) -> str:
686
+ a = self.arrays.get(name)
687
+ return a.var if a is not None and a.var else name
688
+
689
+ @staticmethod
690
+ def ref_text(name: str, idx: str, rank: int = 1) -> str:
691
+ """The reference of an element (`idx`: the subscript text)."""
692
+ if "(@)" in name:
693
+ return name.replace("@", idx)
694
+ return f"{name}({idx})" if rank else name
695
+
696
+ @staticmethod
697
+ def whole_text(name: str) -> str:
698
+ return name.replace("(@)", "")
699
+
700
+ @staticmethod
701
+ def ref_re(name: str) -> str:
702
+ """A regular expression matching a reference of `name`."""
703
+ if "(@)" in name:
704
+ head, tail = name.split("(@)", 1)
705
+ return rf"\b{re.escape(head)}\([^%\n]*?\){re.escape(tail)}\b"
706
+ return rf"\b{re.escape(name)}\b"
707
+
708
+ def btypes(self) -> list[str]:
709
+ """The type keys enabled in this program."""
710
+ out = []
711
+ for t in TYPES:
712
+ if self.bon(t) or (t == "real8" and self.bon("dp")):
713
+ out.append(t)
714
+ return out
715
+
716
+ # -- inputs --
717
+
718
+ def setup_types(self) -> None:
719
+ """Typed input arrays (rank 1, extent n) and the character scalar,
720
+ initialised on the host from i (the model computes the same)."""
721
+ rb = self.rb
722
+ for t in self.btypes():
723
+ name = {"real4": "xr4", "real8": "xr8", "complex4": "xz4",
724
+ "complex8": "xz8", "logical": "xl", "char": "xc",
725
+ "int1": "xk1", "int2": "xk2", "int8": "xk8"}[t]
726
+ a = self.new_array(name, 1, "input", typ=t)
727
+ dp = t == "real8" and self.bon("dp") and (
728
+ not self.bon("real8") or rb.random() < 0.5)
729
+ self.spell[name] = self.decl_spelling(t, dp)
730
+ c1, c2 = rb.randint(3, 61), rb.randint(0, 50)
731
+ p = rb.choice((97, 101, 211, 1009))
732
+ off = rb.randint(0, p // 2)
733
+ vals = {}
734
+ for (i,) in self.points(a):
735
+ lin = (i * c1 + c2) % p - off
736
+ if t in ("real4", "real8"):
737
+ vals[(i,)] = Q(lin, 2)
738
+ elif t in ("complex4", "complex8"):
739
+ vals[(i,)] = (Q(lin), Q((i * c2) % 17 - 8))
740
+ elif t == "logical":
741
+ vals[(i,)] = (i * c1 + c2) % 3 == 0
742
+ elif t == "char":
743
+ vals[(i,)] = (chr(65 + (i * c1) % 26) +
744
+ chr(97 + (i + c2) % 26) +
745
+ chr(48 + i % 10) + "#")
746
+ elif t == "int1":
747
+ vals[(i,)] = (i * c1 + c2) % 127
748
+ elif t == "int2":
749
+ vals[(i,)] = (i * c1 + c2) % 16001 - 8000
750
+ else:
751
+ vals[(i,)] = i * 1000000007 + c2
752
+ self.arrs[name] = vals
753
+ lin = f"mod(i * {c1} + {c2}, {p}) - {off}"
754
+ k = TYPES[t][1]
755
+ half = rlit(Q(1, 2), k, dp)
756
+ self.inits[name] = {
757
+ "real4": f"{name}(i) = real({lin}, 4) * {half}",
758
+ "real8": f"{name}(i) = real({lin}, 8) * {half}",
759
+ "complex4": f"{name}(i) = cmplx({lin}, mod(i * {c2}, 17) "
760
+ "- 8, 4)",
761
+ "complex8": f"{name}(i) = cmplx({lin}, mod(i * {c2}, 17) "
762
+ "- 8, 8)",
763
+ "logical": f"{name}(i) = mod(i * {c1} + {c2}, 3) == 0",
764
+ "char": f"{name}(i) = achar(65 + mod(i * {c1}, 26)) // "
765
+ f"achar(97 + mod(i + {c2}, 26)) // "
766
+ "achar(48 + mod(i, 10)) // '#'",
767
+ "int1": f"{name}(i) = int(mod(i * {c1} + {c2}, 127), 1)",
768
+ "int2": f"{name}(i) = int(mod(i * {c1} + {c2}, 16001) - "
769
+ "8000, 2)",
770
+ "int8": f"{name}(i) = int(i, 8) * 1000000007_8 + "
771
+ f"int({c2}, 8)"}[t]
772
+ self.tbound[name] = self.value_bound(t, vals.values())
773
+ self.features.add(f"base:type:{t}")
774
+ if dp:
775
+ self.features.add("base:spell:double_precision")
776
+ if self.bon("char"):
777
+ # a character scalar: always mapped explicitly (see the module
778
+ # docstring)
779
+ s = "".join(chr(rb.choice((65, 97)) + rb.randint(0, 25))
780
+ for _ in range(SCALAR_LEN))
781
+ a = self.new_array("xs", 0, "input", typ="char")
782
+ self.arrs["xs"] = {(): s}
783
+ self.spell["xs"] = f"character(len={SCALAR_LEN})"
784
+ self.inits["xs"] = f"xs = '{s}'"
785
+ self.features.add("base:type:char_scalar")
786
+
787
+ def decl_spelling(self, t: str, dp: bool = False) -> str:
788
+ if t == "pair":
789
+ return "type(pair_t)"
790
+ base, kind = TYPES[t]
791
+ if dp:
792
+ return "double precision"
793
+ if base == "character":
794
+ return f"character(len={CHAR_LEN})"
795
+ if base == "logical":
796
+ return "logical"
797
+ form = self.rb.choice(("p", "kind", "default"))
798
+ if form == "default" and kind == 4 and base in ("real", "complex"):
799
+ return base
800
+ if form == "kind":
801
+ return f"{base}(kind={kind})"
802
+ return f"{base}({kind})"
803
+
804
+ @staticmethod
805
+ def value_bound(t: str, vals) -> object:
806
+ base = TYPES[t][0]
807
+ vals = list(vals)
808
+ if base == "real":
809
+ return max(abs(v) for v in vals)
810
+ if base == "complex":
811
+ return max(max(abs(v[0]), abs(v[1])) for v in vals)
812
+ if base == "integer":
813
+ return max(abs(v) for v in vals)
814
+ return 0
815
+
816
+ # -- which typed data a kernel may read --
817
+
818
+ def typed_inputs(self, typ: str | None = None) -> list[str]:
819
+ return [a.name for a in self.arrays.values()
820
+ if a.type != "integer" and a.role == "input"
821
+ and (typ is None or a.type == typ)]
822
+
823
+ def typed_outputs(self, but: str) -> list[str]:
824
+ return [a.name for a in self.arrays.values()
825
+ if a.type != "integer" and a.role == "output"
826
+ and a.name != but]
827
+
828
+ def tref(self, name: str, ivars: dict) -> TRef:
829
+ a = self.arrays[name]
830
+ idx = tuple(self.index(d, ivars) for d in ("n", "m")[:a.rank])
831
+ return TRef(name, idx, self.tbound.get(name, 0))
832
+
833
+ def typed_leaves(self, ivars: dict, but: str) -> list:
834
+ """Integer leaves that read typed data (views), for the integer
835
+ expressions of any kernel."""
836
+ if not (self.bon("typed_view") or self.bon("dt_typed")):
837
+ return []
838
+ rb = self.rb
839
+ out = []
840
+ names = self.typed_inputs() + self.typed_outputs(but)
841
+ for name in names:
842
+ if rb.random() < 0.5:
843
+ continue
844
+ a = self.arrays[name]
845
+ ref = self.tref(name, ivars)
846
+ out.append(self.view(a.type, ref, a.role == "output"))
847
+ self.features.add(f"base:view:{a.type}")
848
+ return out
849
+
850
+ def view(self, t: str, ref: TRef, output: bool):
851
+ """A bounded integer view of a typed reference."""
852
+ base, kind = TYPES[t]
853
+ rb = self.rb
854
+ if base == "real":
855
+ if output or ref.bound() >= 2 ** 12:
856
+ return IView("int", RFun("mod", ref, RConst(Q(1024), kind)))
857
+ return IView(rb.choice(("int", "nint")), ref)
858
+ if base == "complex":
859
+ part = CPart(rb.choice(("real", "aimag")), ref)
860
+ if output:
861
+ return IView("int", RFun("mod", part, RConst(Q(1024), kind)))
862
+ return IView("int", part)
863
+ if base == "logical":
864
+ return IView("merge", ref)
865
+ if base == "character":
866
+ n = SCALAR_LEN if not ref.idx else CHAR_LEN
867
+ return IView("ichar", ref, rb.randint(1, n))
868
+ if kind == 8:
869
+ return IView("mod8", ref)
870
+ return IView("intk", ref)
871
+
872
+ # -- typed outputs --
873
+
874
+ def out_type(self, nlev: int) -> str:
875
+ """The element type of a kernel's output array."""
876
+ if not self.bon("typed_out") or self.rb.random() < 0.35:
877
+ return "integer"
878
+ opts = [t for t in self.btypes() if not (t == "char" and nlev > 1)]
879
+ return self.rb.choice(opts) if opts else "integer"
880
+
881
+ def typed_store(self, t: str, lv: list, ivars: dict, but: str):
882
+ """A typed expression for an element of an output of type `t`,
883
+ built from the integer leaves `lv` (bounded) and typed data."""
884
+ from offload.engine.fuzz import Const, Intr
885
+ rb = self.rb
886
+ base, kind = TYPES[t]
887
+ self.features.add(f"base:out:{t}")
888
+
889
+ def ie(p=(97, 1009)):
890
+ q = rb.choice(p)
891
+ return Intr("mod", (self.expr(1, lv), Const(q))), q
892
+
893
+ if base == "real":
894
+ return self.rexpr(kind, 2, lv, ivars, but)
895
+ if base == "complex":
896
+ if rb.random() < 0.6:
897
+ z = CMake(self.rexpr(kind, 1, lv, ivars, but),
898
+ self.rexpr(kind, 1, lv, ivars, but), kind)
899
+ else:
900
+ src = self.typed_inputs(t)
901
+ z = self.tref(src[0], ivars) if src else CMake(
902
+ self.rexpr(kind, 1, lv, ivars, but), RConst(Q(1), kind),
903
+ kind)
904
+ k = rb.random()
905
+ if k < 0.3:
906
+ c = rb.choice(((0, 1), (1, 1), (2, 0), (Q(1, 2), 0)))
907
+ z = CBin("*", z, CConst(Q(c[0]), Q(c[1]), kind))
908
+ elif k < 0.5:
909
+ z = CFun("conjg", z)
910
+ elif k < 0.7:
911
+ z = CBin(rb.choice("+-"), z, CMake(
912
+ self.rexpr(kind, 1, lv, ivars, but),
913
+ self.rexpr(kind, 0, lv, ivars, but), kind))
914
+ self.check_real(z, kind)
915
+ return z
916
+ if base == "logical":
917
+ return self.lexpr(2, lv, ivars)
918
+ if base == "character":
919
+ src = self.typed_inputs("char")
920
+ sref = self.tref(src[0], ivars)
921
+ a, _ = ie()
922
+ if rb.random() < 0.5:
923
+ return ChMake(0, a, sref)
924
+ b, _ = ie()
925
+ return ChMake(1, a, sref, b)
926
+ return self.kexpr(kind, lv, ivars)
927
+
928
+ def check_real(self, x: TEx, kind: int) -> None:
929
+ if x.bound() >= real_limit(kind):
930
+ raise Overflow(f"real bound {x.bound()} for kind {kind}")
931
+
932
+ def rexpr(self, kind: int, depth: int, lv: list, ivars: dict,
933
+ but: str) -> TEx:
934
+ """A real expression of `kind` (bounded, see the module
935
+ docstring)."""
936
+ from offload.engine.fuzz import Const, Intr
937
+ rb = self.rb
938
+
939
+ def leaf():
940
+ k = rb.random()
941
+ same = self.typed_inputs(f"real{kind}")
942
+ other = self.typed_inputs(f"real{12 - kind}")
943
+ outs = [n for n in self.typed_outputs(but)
944
+ if self.arrays[n].type == f"real{kind}"]
945
+ if k < 0.3 and same:
946
+ return self.tref(rb.choice(same), ivars)
947
+ if k < 0.4 and other:
948
+ self.features.add("base:real_kind_conversion")
949
+ return RCast(self.tref(rb.choice(other), ivars), kind)
950
+ if k < 0.5 and outs:
951
+ return RFun("mod", self.tref(rb.choice(outs), ivars),
952
+ RConst(Q(1024), kind))
953
+ if k < 0.6:
954
+ return RConst(Q(rb.choice((1, 2, 3, 5, -7, 1)), 2) * 2
955
+ if rb.random() < 0.5 else
956
+ Q(rb.choice((1, 3, -1)), 2), kind,
957
+ self.dp_spell(kind))
958
+ q = rb.choice((97, 1009))
959
+ return RConv(Intr("mod", (self.expr(1, lv), Const(q))), kind, q)
960
+
961
+ def sub(d):
962
+ if d <= 0 or rb.random() < 0.3:
963
+ return leaf()
964
+ k = rb.choice(("add", "sub", "mulc", "max", "abs", "mod"))
965
+ if k in ("add", "sub"):
966
+ return RBin("+" if k == "add" else "-", sub(d - 1),
967
+ sub(d - 1))
968
+ if k == "mulc":
969
+ c = Q(rb.choice((2, 3, -1, 1, -3)), rb.choice((1, 2)))
970
+ return RBin("*", sub(d - 1), RConst(c, kind,
971
+ self.dp_spell(kind)))
972
+ if k == "max":
973
+ return RFun(rb.choice(("max", "min")), sub(d - 1), sub(d - 1))
974
+ if k == "abs":
975
+ return RFun("abs", sub(d - 1))
976
+ return RFun("mod", sub(d - 1), RConst(Q(256), kind))
977
+ x = sub(depth)
978
+ self.check_real(x, kind)
979
+ return x
980
+
981
+ def dp_spell(self, kind: int) -> bool:
982
+ return kind == 8 and self.bon("dp")
983
+
984
+ def lexpr(self, depth: int, lv: list, ivars: dict) -> TEx:
985
+ rb = self.rb
986
+
987
+ def leaf():
988
+ src = self.typed_inputs("logical")
989
+ if src and rb.random() < 0.4:
990
+ return self.tref(rb.choice(src), ivars)
991
+ return LCmp(rb.choice(("<", "<=", ">", ">=", "==", "/=")),
992
+ self.expr(1, lv), self.expr(1, lv))
993
+
994
+ def sub(d):
995
+ if d <= 0 or rb.random() < 0.35:
996
+ return leaf()
997
+ if rb.random() < 0.2:
998
+ return LNot(sub(d - 1))
999
+ return LBin(rb.choice((".and.", ".or.", ".eqv.", ".neqv.")),
1000
+ sub(d - 1), sub(d - 1))
1001
+ return sub(depth)
1002
+
1003
+ def kexpr(self, kind: int, lv: list, ivars: dict) -> TEx:
1004
+ """An integer expression of kind 1, 2 or 8."""
1005
+ from offload.engine.fuzz import Const, Intr
1006
+ rb = self.rb
1007
+ e = self.expr(1, lv)
1008
+ src = self.typed_inputs(f"int{kind}")
1009
+ ref = self.tref(rb.choice(src), ivars) if src and \
1010
+ rb.random() < 0.6 else None
1011
+ if kind == 1:
1012
+ a = f"int(iand({e.f()}, 127), 1)"
1013
+
1014
+ def av(env, arrs, e=e):
1015
+ return e.ev(env, arrs) & 127
1016
+ if ref is None:
1017
+ return KExpr(a, av, 127)
1018
+ op = rb.choice(("ieor", "max", "min", "iand", "ior"))
1019
+ fn = {"ieor": lambda x, y: x ^ y, "max": max, "min": min,
1020
+ "iand": lambda x, y: x & y, "ior": lambda x, y: x | y}[op]
1021
+ return KExpr(f"{op}({ref.f()}, {a})",
1022
+ lambda env, arrs, ref=ref, av=av, fn=fn:
1023
+ fn(ref.ev(env, arrs), av(env, arrs)), 127)
1024
+ if kind == 2:
1025
+ a = f"int(mod({e.f()}, 16001), 2)"
1026
+
1027
+ def av(env, arrs, e=e):
1028
+ v = e.ev(env, arrs)
1029
+ r = abs(v) % 16001
1030
+ return r if v >= 0 else -r
1031
+ if ref is None:
1032
+ return KExpr(a, av, 16000)
1033
+ if rb.random() < 0.5 and ref.bound() <= 16000:
1034
+ return KExpr(f"({ref.f()} + {a})",
1035
+ lambda env, arrs, ref=ref, av=av:
1036
+ ref.ev(env, arrs) + av(env, arrs), 32000)
1037
+ op = rb.choice(("max", "min", "ieor"))
1038
+ fn = {"ieor": lambda x, y: x ^ y, "max": max, "min": min}[op]
1039
+ return KExpr(f"{op}({ref.f()}, {a})",
1040
+ lambda env, arrs, ref=ref, av=av, fn=fn:
1041
+ fn(ref.ev(env, arrs), av(env, arrs)), 32767)
1042
+ e2 = self.expr(1, lv)
1043
+ text = f"(int({e.f()}, 8) * int({e2.f()}, 8))"
1044
+
1045
+ def pv(env, arrs, e=e, e2=e2):
1046
+ return e.ev(env, arrs) * e2.ev(env, arrs)
1047
+ if ref is None:
1048
+ return KExpr(text, pv, 2 ** 60)
1049
+ return KExpr(f"({ref.f()} + {text})",
1050
+ lambda env, arrs, ref=ref, pv=pv:
1051
+ ref.ev(env, arrs) + pv(env, arrs), 2 ** 61)
1052
+
1053
+ # -- typed reductions --
1054
+
1055
+ def typed_red_type(self) -> str | None:
1056
+ if not self.bon("typed_red") or self.rb.random() < 0.4:
1057
+ return None
1058
+ opts = [t for t in self.btypes() if t != "char"]
1059
+ return self.rb.choice(opts) if opts else None
1060
+
1061
+ @staticmethod
1062
+ def red_key(t: str) -> str:
1063
+ base, kind = TYPES[t]
1064
+ return f"integer{kind}" if base == "integer" else base
1065
+
1066
+ def typed_red_init(self, t: str, op: str):
1067
+ rb = self.rb
1068
+ base, kind = TYPES[t]
1069
+ if base == "real":
1070
+ return {"+": Q(rb.randint(-50, 50), 2), "max": Q(-1000),
1071
+ "min": Q(1000)}[op]
1072
+ if base == "complex":
1073
+ return (Q(rb.randint(-9, 9)), Q(rb.randint(-9, 9)))
1074
+ if base == "logical":
1075
+ return {".and.": True, ".or.": False, ".eqv.": True,
1076
+ ".neqv.": False}[op] if rb.random() < 0.7 else \
1077
+ rb.random() < 0.5
1078
+ if op in ("max",):
1079
+ return -INT_MAX[kind] // 2
1080
+ if op == "min":
1081
+ return INT_MAX[kind] // 2
1082
+ if op == "iand":
1083
+ return {1: 127, 2: 32767, 8: 2 ** 40 - 1}[kind]
1084
+ if op in ("ior", "ieor"):
1085
+ return rb.randint(0, 15)
1086
+ return rb.randint(-1000, 1000)
1087
+
1088
+ def typed_red_term(self, t: str, op: str, lv: list, ivars: dict,
1089
+ iters: int, init) -> TEx:
1090
+ """The contribution of one iteration; for a sum the static bound
1091
+ times the number of iterations must stay exact."""
1092
+ from offload.engine.fuzz import Const, Intr
1093
+ rb = self.rb
1094
+ base, kind = TYPES[t]
1095
+ if base == "real":
1096
+ q = 97 if op == "+" else 1009
1097
+ term = RConv(Intr("mod", (self.expr(1, lv), Const(q))), kind, q)
1098
+ if rb.random() < 0.4:
1099
+ term = RBin("*", term, RConst(Q(1, 2), kind,
1100
+ self.dp_spell(kind)))
1101
+ if op == "+" and (term.bound() * iters + abs(init)
1102
+ >= real_limit(kind)):
1103
+ raise Overflow("real sum reduction bound")
1104
+ return term
1105
+ if base == "complex":
1106
+ return CMake(RConv(Intr("mod", (self.expr(1, lv), Const(97))),
1107
+ kind, 97),
1108
+ RConv(Intr("mod", (self.expr(1, lv), Const(13))),
1109
+ kind, 13), kind)
1110
+ if base == "logical":
1111
+ return LCmp(rb.choice(("<", ">", "==", "/=")), self.expr(1, lv),
1112
+ self.expr(1, lv))
1113
+ if kind == 8:
1114
+ e = self.expr(1, lv)
1115
+ if op == "+":
1116
+ return KExpr(f"(int(mod({e.f()}, 1009), 8) * 1000003_8)",
1117
+ lambda env, arrs, e=e: (lambda v: (
1118
+ abs(v) % 1009 if v >= 0 else
1119
+ -(abs(v) % 1009)))(e.ev(env, arrs))
1120
+ * 1000003, 1009 * 1000003)
1121
+ return KExpr(f"int({e.f()}, 8)", lambda env, arrs, e=e:
1122
+ e.ev(env, arrs), 2 ** 30)
1123
+ return self.kexpr(kind, lv, ivars)
1124
+
1125
+ def typed_red_update(self, var: str, t: str, op: str, term: TEx) -> str:
1126
+ base = TYPES[t][0]
1127
+ if base == "logical":
1128
+ return f"{var} = {var} {op} {term.f()}"
1129
+ if op == "+":
1130
+ return f"{var} = {var} + {term.f()}"
1131
+ return f"{var} = {op}({var}, {term.f()})"
1132
+
1133
+ # -- declarations, initial values and the checksum --
1134
+
1135
+ def typed_decl_lines(self) -> list[str]:
1136
+ out = []
1137
+ for a in self.arrays.values():
1138
+ if a.type == "integer" or a.var:
1139
+ continue
1140
+ spell = self.spell.get(a.name) or self.decl_spelling(a.type)
1141
+ self.spell[a.name] = spell
1142
+ if a.rank == 0:
1143
+ out.append(f" {spell} :: {a.name}")
1144
+ elif a.name in self.ptrs:
1145
+ out.append(f" {spell}, pointer :: {a.name}"
1146
+ f"({':' if a.rank == 1 else ':, :'})")
1147
+ elif a.alloc:
1148
+ out.append(f" {spell}, allocatable :: {a.name}"
1149
+ f"({':' if a.rank == 1 else ':, :'})")
1150
+ else:
1151
+ out.append(f" {spell} :: {a.name}"
1152
+ f"({'n' if a.rank == 1 else 'n, m'})")
1153
+ for name, (t, _) in self.tscalars.items():
1154
+ spell = self.spell.get(name) or self.decl_spelling(
1155
+ t, t == "real8" and self.bon("dp") and
1156
+ self.rb.random() < 0.5)
1157
+ self.spell[name] = spell
1158
+ out.append(f" {spell} :: {name}")
1159
+ return out
1160
+
1161
+ def typed_value_text(self, t: str, v) -> str:
1162
+ if t == "pair":
1163
+ return f"pair_t({v[0]}, {v[1]})"
1164
+ base, kind = TYPES[t]
1165
+ if base == "real":
1166
+ return rlit(v, kind, self.dp_spell(kind))
1167
+ if base == "complex":
1168
+ return (f"({rlit(v[0], kind, paren=False)}, "
1169
+ f"{rlit(v[1], kind, paren=False)})")
1170
+ if base == "logical":
1171
+ return ".true." if v else ".false."
1172
+ if base == "character":
1173
+ return f"'{v}'"
1174
+ return f"{v}_{kind}" if v >= 0 else f"({v}_{kind})"
1175
+
1176
+ def typed_zero_text(self, t: str) -> str:
1177
+ base = TYPES[t][0]
1178
+ return {"logical": ".false.", "character": "' '"}.get(base, "0")
1179
+
1180
+ # -- derived types (stage 2) --
1181
+
1182
+ DT_TYPES = {"dr": "rec_t", "dr%nd": "nd_t", "ds": "el_t"}
1183
+
1184
+ def setup_derived(self) -> None:
1185
+ """The structure dr, its nested component dr%nd and the array of
1186
+ structures ds, with input components initialised on the host."""
1187
+ rb = self.rb
1188
+ self.dvars = {"dr": "rec_t"}
1189
+ comps = [("dr%a", "integer", 1)]
1190
+ if self.bon("dt_typed"):
1191
+ comps.append(("dr%b", "real8", 1))
1192
+ if self.bon("dt_scalar"):
1193
+ comps.append(("dr%s", "integer", 0))
1194
+ if self.bon("dt_nested"):
1195
+ comps.append(("dr%nd%k", "integer", 1))
1196
+ if self.bon("dt_typed"):
1197
+ comps.append(("dr%nd%w", "real8", 1))
1198
+ if self.bon("dt_aos"):
1199
+ self.dvars["ds"] = "el_t"
1200
+ comps.append(("ds(@)%u", "integer", 1))
1201
+ if self.bon("dt_typed"):
1202
+ comps.append(("ds(@)%v", "real8", 1))
1203
+ for name, typ, rank in comps:
1204
+ var = name.split("%")[0].split("(")[0]
1205
+ a = self.new_array(name, rank, "input", typ=typ, var=var)
1206
+ c1, c2 = rb.randint(3, 61), rb.randint(0, 50)
1207
+ p = rb.choice((97, 101, 211, 1009))
1208
+ off = rb.randint(0, p // 2)
1209
+ lin = f"mod(i * {c1} + {c2}, {p}) - {off}"
1210
+ ref = self.ref_text(name, "i", rank)
1211
+ if rank == 0:
1212
+ v = rb.randint(-20, 40)
1213
+ self.arrs[name] = {(): v}
1214
+ if self.bon("dt_default_init"):
1215
+ self.dt_defaults[name] = str(v) if v >= 0 else f"({v})"
1216
+ self.features.add("base:dt:default_init")
1217
+ else:
1218
+ self.inits[name] = f"{ref} = {v}"
1219
+ self.features.add("base:dt:scalar_component")
1220
+ continue
1221
+ vals = {}
1222
+ for (i,) in self.points(a):
1223
+ x = (i * c1 + c2) % p - off
1224
+ vals[(i,)] = Q(x, 2) if typ == "real8" else x
1225
+ self.arrs[name] = vals
1226
+ self.inits[name] = (f"{ref} = real({lin}, 8) * 0.5_8"
1227
+ if typ == "real8" else f"{ref} = {lin}")
1228
+ if typ != "integer":
1229
+ self.tbound[name] = self.value_bound(typ, vals.values())
1230
+ self.features.add("base:dt:component:" +
1231
+ ("aos" if "(@)" in name else "nested"
1232
+ if name.count("%") > 1 else "struct")
1233
+ + f":{typ}")
1234
+ self.features.add("base:dt:struct")
1235
+ if self.bon("dt_nested"):
1236
+ self.features.add("base:dt:nested")
1237
+ if self.bon("dt_aos"):
1238
+ self.features.add("base:dt:aos")
1239
+
1240
+ def component_output(self, nlev: int, typ: str):
1241
+ """A new component of dr, dr%nd or ds as a kernel's output (rank
1242
+ 1), or None."""
1243
+ if not self.bon("dt_out") or nlev != 1 or self.rb.random() < 0.4:
1244
+ return None
1245
+ homes = ["dr"] + (["dr%nd"] if self.bon("dt_nested") else []) + \
1246
+ (["ds"] if self.bon("dt_aos") else [])
1247
+ home = self.rb.choice(homes)
1248
+ comp = f"o{self.k}"
1249
+ name = f"ds(@)%{comp}" if home == "ds" else f"{home}%{comp}"
1250
+ if typ == "integer" and self.bon("dt_typed") and \
1251
+ self.rb.random() < 0.3:
1252
+ typ = "real8"
1253
+ if typ == "char" and home == "ds":
1254
+ typ = "integer"
1255
+ self.features.add(f"base:dt:out:{home}")
1256
+ a = self.new_array(name, 1, "output", typ=typ,
1257
+ var=home.split("%")[0])
1258
+ if home != "ds" and self.bon("al_comp_alloc") and \
1259
+ self.rb.random() < 0.5:
1260
+ a.alloc = True
1261
+ self.features.add("base:al:allocatable_output_component")
1262
+ return a
1263
+
1264
+ def dt_decl_lines(self) -> list[str]:
1265
+ """The derived-type definitions (components from the generator's
1266
+ pseudo-arrays) and the structure declarations."""
1267
+ if not getattr(self, "dvars", None):
1268
+ return []
1269
+ comps: dict[str, list[str]] = {"rec_t": [], "nd_t": [], "el_t": []}
1270
+ for a in self.arrays.values():
1271
+ if not a.var or a.var in ("ms", "gs"): # module types
1272
+ continue
1273
+ if "(@)" in a.name:
1274
+ tname, comp, rank = "el_t", a.name.split("%", 1)[1], 0
1275
+ else:
1276
+ head, comp = a.name.rsplit("%", 1)
1277
+ tname, rank = self.DT_TYPES[head], a.rank
1278
+ if a.type == "integer":
1279
+ spell = "integer"
1280
+ else:
1281
+ spell = self.spell.get(a.name) or self.decl_spelling(a.type)
1282
+ self.spell[a.name] = spell
1283
+ init = self.dt_defaults.get(a.name)
1284
+ attr = ", allocatable" if a.alloc else ", pointer" \
1285
+ if a.name in self.ptrs else ""
1286
+ shape = "(:)" if attr else "(n)"
1287
+ comps[tname].append(f" {spell}{attr} :: {comp}"
1288
+ + (shape if rank else "")
1289
+ + (f" = {init}" if init else ""))
1290
+ out = []
1291
+ if comps["nd_t"]:
1292
+ out += [" type :: nd_t"] + comps["nd_t"] + [" end type nd_t"]
1293
+ comps["rec_t"].append(" type(nd_t) :: nd")
1294
+ if "dr" in self.dvars:
1295
+ out += [" type :: rec_t"] + comps["rec_t"] + \
1296
+ [" end type rec_t"]
1297
+ if "ds" in self.dvars:
1298
+ out += [" type :: el_t"] + comps["el_t"] + [" end type el_t"]
1299
+ if "dr" in self.dvars:
1300
+ out.append(" type(rec_t) :: dr")
1301
+ if "ds" in self.dvars:
1302
+ out.append(" type(el_t) :: ds(n)")
1303
+ if "ms" in self.dvars:
1304
+ out.append(" type(mt_t) :: ms")
1305
+ return out
1306
+
1307
+ def struct_maps(self, names: set, reads: set, writes: dict
1308
+ ) -> tuple[list, set, set]:
1309
+ """Map clauses of the structures referenced by a target construct:
1310
+ ([(map key, item)], implicitly mapped variables, component names
1311
+ handled). One mode per variable (module docstring)."""
1312
+ rb = self.rb
1313
+ groups: dict[str, list[str]] = {}
1314
+ for n in sorted(names):
1315
+ v = self.var_of(n)
1316
+ if v != n:
1317
+ groups.setdefault(v, []).append(n)
1318
+ pairs, implicit, handled = [], set(), set()
1319
+ for v, comps in sorted(groups.items()):
1320
+ handled |= set(comps)
1321
+ aos = v == "ds"
1322
+ written = any(writes.get(c) for c in comps)
1323
+ if "derived" in self.base:
1324
+ modes = (["whole"] if self.bon("dt_whole") else []) + \
1325
+ (["components"] if self.bon("dt_comp") and not aos
1326
+ else []) + (["implicit"] if self.bon("dt_implicit")
1327
+ else [])
1328
+ else:
1329
+ modes = ["whole", "implicit"] + ([] if aos else
1330
+ ["components"])
1331
+ mode = rb.choice(modes or ["implicit"])
1332
+ if any(c in self.ptrs for c in comps):
1333
+ # a pointer component: through the default mapper its
1334
+ # association status is undefined (5.2 §5.8.3)
1335
+ mode = "components"
1336
+ self.features.add(f"base:dt:map:{mode}")
1337
+ if mode == "implicit":
1338
+ implicit.add(v)
1339
+ continue
1340
+ if mode == "whole":
1341
+ t = "tofrom" if written else rb.choice(("to", "tofrom"))
1342
+ mods = []
1343
+ if v == "ms" and getattr(self, "mapper", ""):
1344
+ mods.append(f"mapper({self.mapper})")
1345
+ self.features.add("base:dc:map_with_named_mapper")
1346
+ if not self.in_data and rb.random() < 0.2:
1347
+ mods.append("always")
1348
+ if rb.random() < 0.15:
1349
+ mods.append("close")
1350
+ if self.in_data and rb.random() < 0.3:
1351
+ mods.append("present")
1352
+ for m in mods:
1353
+ self.features.add(f"base:dt:map:mod:{m}")
1354
+ pairs.append((", ".join(mods + [t]), v))
1355
+ continue
1356
+ for c in comps:
1357
+ kind = writes.get(c)
1358
+ opts = ("from", "tofrom") if kind == "full" and \
1359
+ c not in reads else ("tofrom",) if kind else \
1360
+ ("to", "tofrom")
1361
+ t = rb.choice(opts)
1362
+ mods = []
1363
+ if not self.in_data and rb.random() < 0.2:
1364
+ mods.append("always")
1365
+ if self.in_data and rb.random() < 0.3 and \
1366
+ c not in self.ptrs:
1367
+ # the data region maps the structure, not the target
1368
+ # of a pointer component (5.2 §5.8.3)
1369
+ mods.append("present")
1370
+ item = c
1371
+ if self.arrays[c].rank and self.bon("dt_section") and \
1372
+ rb.random() < 0.3:
1373
+ item = f"{c}(1:n)"
1374
+ self.features.add("base:dt:map:component_section")
1375
+ pairs.append((", ".join(mods + [t]), item))
1376
+ return pairs, implicit, handled
1377
+
1378
+ def dvar_written(self, v: str, writes: dict) -> bool:
1379
+ return any(writes.get(n) for n in writes if self.var_of(n) == v)
1380
+
1381
+ def struct_depend(self, reads: set, writes: set, head: str
1382
+ ) -> tuple[list, list]:
1383
+ """depend(in) and depend(out/inout) items of a nowait kernel by
1384
+ variable: in only when no component is written and every map item
1385
+ of the variable is `to` (or the variable is firstprivate)."""
1386
+ from offload.engine.fuzz import map_items
1387
+ to_items = set(map_items(head, ("to",)))
1388
+ other = set(map_items(head, ("tofrom", "from", "alloc")))
1389
+ fp = {x for c in re.findall(r"firstprivate\(([^)]*)\)", head)
1390
+ for x in re.split(r"\s*,\s*", c.strip())}
1391
+ vs: dict[str, set] = {}
1392
+ for n in reads | writes:
1393
+ vs.setdefault(self.var_of(n), set()).add(n)
1394
+ ins, outs = [], []
1395
+ for v, ns in sorted(vs.items()):
1396
+ ro = not (ns & writes)
1397
+ items = {x for x in to_items | other
1398
+ if x == v or x.startswith(v + "%")}
1399
+ if ro and (v in fp or (items and all(
1400
+ x in to_items and x not in other for x in items))):
1401
+ ins.append(v)
1402
+ else:
1403
+ outs.append(v)
1404
+ return ins, outs
1405
+
1406
+ # -- allocatable, pointer and target variables (stage 3) --
1407
+
1408
+ def setup_alloc(self) -> None:
1409
+ rb = self.rb
1410
+ if self.bon("al_alloc_scalar"):
1411
+ a = self.new_array("as1", 0, "input")
1412
+ a.alloc = True
1413
+ v = rb.randint(-30, 60)
1414
+ self.arrs["as1"] = {(): v}
1415
+ self.inits["as1"] = f"as1 = {v}"
1416
+ self.features.add("base:al:allocatable_scalar")
1417
+ if (self.bon("al_comp_alloc") or self.bon("al_comp_ptr")) and \
1418
+ not self.dvars:
1419
+ self.setup_derived()
1420
+ for name, kind in (("dr%q", "alloc"), ("dr%pc", "ptr")):
1421
+ if not self.bon("al_comp_" + kind):
1422
+ continue
1423
+ a = self.new_array(name, 1, "input", var="dr")
1424
+ if kind == "alloc":
1425
+ a.alloc = True
1426
+ else:
1427
+ self.ptrs[name] = "target"
1428
+ c1, c2 = rb.randint(3, 61), rb.randint(0, 50)
1429
+ p = rb.choice((97, 211, 1009))
1430
+ off = rb.randint(0, p // 2)
1431
+ self.arrs[name] = {(i,): (i * c1 + c2) % p - off
1432
+ for i in range(1, self.n + 1)}
1433
+ lhs = "tgc(i)" if kind == "ptr" else f"{name}(i)"
1434
+ self.inits[name] = f"{lhs} = mod(i * {c1} + {c2}, {p}) - {off}"
1435
+ self.features.add("base:al:" + ("allocatable" if kind == "alloc"
1436
+ else "pointer") + "_component")
1437
+ if self.bon("al_target"):
1438
+ for name in ("ia", "ib", "ic"):
1439
+ if rb.random() < 0.5:
1440
+ self.tgt_attr.add(name)
1441
+ self.features.add("base:al:target_attribute")
1442
+
1443
+ def pointer_output(self, out) -> None:
1444
+ """Make a new plain output array a POINTER (associated with a
1445
+ TARGET array, or allocated)."""
1446
+ if out.var or out.name in self.dtv or not self.bon("al_ptr_out") \
1447
+ or self.rb.random() < 0.5:
1448
+ return
1449
+ how = self.rb.choice(("target", "alloc"))
1450
+ self.ptrs[out.name] = how
1451
+ out.alloc = False
1452
+ self.features.add(f"base:al:pointer_output:{how}")
1453
+
1454
+ def check_ref(self, name: str, idx: str, rank: int = 1) -> str:
1455
+ """The host checksum's reference (through the target of a
1456
+ pointer associated with one)."""
1457
+ if self.ptrs.get(name) == "target" and "%" not in name:
1458
+ return self.ref_text(name + "t", idx, rank)
1459
+ return self.ref_text(name, idx, rank)
1460
+
1461
+ def alloc_decl_lines(self) -> list[str]:
1462
+ out = []
1463
+ for name, how in self.ptrs.items():
1464
+ a = self.arrays.get(name)
1465
+ if a is None or "%" in name or how != "target":
1466
+ continue
1467
+ spell = self.spell.get(name) or self.decl_spelling(a.type) \
1468
+ if a.type != "integer" else "integer"
1469
+ self.spell[name] = spell
1470
+ dims = "n" if a.rank == 1 else "n, m"
1471
+ out.append(f" {spell}, target :: {name}t({dims})")
1472
+ if "dr%pc" in self.ptrs and "dr%pc" in self.arrays:
1473
+ out.append(" integer, target :: tgc(n)")
1474
+ return out
1475
+
1476
+ def alloc_setup_lines(self) -> list[str]:
1477
+ """Allocations and pointer associations before the inputs are
1478
+ set."""
1479
+ out = []
1480
+ if "as1" in self.arrays:
1481
+ out.append(" allocate(as1)")
1482
+ for a in self.arrays.values():
1483
+ if a.var and a.alloc:
1484
+ out.append(f" allocate({a.name}(n))")
1485
+ for name, how in self.ptrs.items():
1486
+ if name not in self.arrays:
1487
+ continue
1488
+ a = self.arrays[name]
1489
+ dims = "n" if a.rank == 1 else "n, m"
1490
+ if name == "dr%pc":
1491
+ out.append(" dr%pc => tgc")
1492
+ elif how == "target":
1493
+ out.append(f" {name} => {name}t")
1494
+ else:
1495
+ out.append(f" allocate({name}({dims}))")
1496
+ return out
1497
+
1498
+ def decl_attrs(self, name: str) -> str:
1499
+ """Extra attributes of a plain array's declaration."""
1500
+ return ", target" if name in getattr(self, "tgt_attr", ()) else ""
1501
+
1502
+ # -- kernels in internal procedures (stage 3) --
1503
+
1504
+ def wrap_in_procedure(self, kern, ind: str):
1505
+ """Move a kernel into an internal subroutine kp<k> (module
1506
+ docstring); returns the kernel's replacement lines."""
1507
+ from offload.engine.fuzz import map_items, add_clauses
1508
+ rb = self.rb
1509
+ k = len(self.procs) + 1
1510
+ pname = f"kp{k}"
1511
+ text = "\n".join(kern.lines)
1512
+ to_items = set(map_items(text, ("to",)))
1513
+ other = set(map_items(text, ("tofrom", "from", "alloc")))
1514
+ dummies, decls = [], []
1515
+ for a in sorted(self.arrays.values(), key=lambda a: a.name):
1516
+ if a.var or a.name in self.dtv or \
1517
+ not re.search(self.ref_re(a.name), text):
1518
+ continue
1519
+ dummies.append(a.name)
1520
+ decls.append(self.dummy_decl(a, kern, to_items, other))
1521
+ for v in sorted(self.dvars):
1522
+ if v not in self.dtv and re.search(rf"\b{v}\b", text):
1523
+ dummies.append(v)
1524
+ shape = rb.choice(("(:)", "(n)")) if v == "ds" else ""
1525
+ decls.append(f"type({self.dvars[v]}), intent(inout) :: "
1526
+ f"{v}{shape}")
1527
+ self.features.add("base:al:structure_dummy")
1528
+ params = [p for p in self.params() if re.search(rf"\b{p}\b", text)]
1529
+ for p in params:
1530
+ dummies.append(p)
1531
+ form = rb.choice(["intent(in)"] +
1532
+ (["value"] if self.bon("al_value") else []) +
1533
+ (["intent(in), optional"]
1534
+ if self.bon("al_optional") else []))
1535
+ decls.append(f"integer, {form} :: {p}")
1536
+ self.features.add("base:al:dummy:" + form.replace(
1537
+ "intent(in), ", "").replace("(", "_").replace(")", ""))
1538
+ lines = list(kern.lines)
1539
+ if self.bon("al_optional_absent") and lines[0].lstrip().startswith(
1540
+ "!$omp target") and rb.random() < 0.5:
1541
+ dummies.append("zopt")
1542
+ decls.append("integer, intent(in), optional :: zopt(:)")
1543
+ lines = add_clauses(lines, ["map(to: zopt)"])
1544
+ self.features.add("base:al:optional_absent_in_map")
1545
+ locs = sorted(set(re.findall(r"\b((?:t|acc)\d+)\b", text)))
1546
+ body = [f" subroutine {pname}("
1547
+ f"{', '.join(dummies)})"] + \
1548
+ [f" {d}" for d in decls] + \
1549
+ [f" integer :: {', '.join(['i', 'j', 'jj'] + locs)}"]
1550
+ base_ind = len(ind)
1551
+ body += [" " + ln[base_ind:] for ln in lines]
1552
+ body.append(f" end subroutine {pname}")
1553
+ self.procs.append("\n".join(body))
1554
+ args = [d for d in dummies if d != "zopt"]
1555
+ self.features.add("base:al:kernel_in_internal_procedure")
1556
+ return [f"{ind}call {pname}({', '.join(args)})"]
1557
+
1558
+ def dummy_decl(self, a, kern, to_items: set, other: set) -> str:
1559
+ rb = self.rb
1560
+ name = a.name
1561
+ spell = "integer" if a.type == "integer" else \
1562
+ self.spell.get(name) or self.decl_spelling(a.type)
1563
+ if a.rank == 0:
1564
+ # intent(in) only when every map of the kernel is `to` (a
1565
+ # tofrom map would copy back into it)
1566
+ intent = "in" if name in to_items and name not in other \
1567
+ else "inout"
1568
+ if a.type == "char":
1569
+ self.features.add("base:al:dummy:char_len")
1570
+ if self.bon("al_assumed_len"):
1571
+ self.features.add("base:al:dummy:assumed_length")
1572
+ return f"character(len=*), intent({intent}) :: {name}"
1573
+ return f"{spell}, intent({intent}) :: {name}"
1574
+ alloc = ", allocatable" if a.alloc and self.bon(
1575
+ "al_alloc_dummy") else ""
1576
+ return f"{spell}{alloc}, intent({intent}) :: {name}"
1577
+ written = name in kern.writes
1578
+ if written:
1579
+ intent = "inout"
1580
+ if self.bon("al_intent_out") and rb.random() < 0.5 and \
1581
+ not a.alloc and name not in self.ptrs and \
1582
+ self.full_out.get(name) and name not in kern.reads:
1583
+ intent = "out"
1584
+ else:
1585
+ intent = "in" if name in to_items and name not in other \
1586
+ else "inout"
1587
+ deferred = "(:)" if a.rank == 1 else "(:, :)"
1588
+ explicit = "(n)" if a.rank == 1 else "(n, m)"
1589
+ k = rb.random()
1590
+ if a.alloc and self.bon("al_alloc_dummy") and k < 0.5:
1591
+ form, shape = "allocatable", deferred
1592
+ elif name in self.ptrs and self.bon("al_ptr_dummy") and k < 0.5:
1593
+ form, shape = "pointer", deferred
1594
+ intent = "in" # the association, not the target
1595
+ elif self.bon("al_explicit_dummy") and k < 0.7:
1596
+ form, shape = "explicit", explicit
1597
+ else:
1598
+ form, shape = "assumed_shape", deferred
1599
+ self.features.add(f"base:al:dummy:{form}")
1600
+ self.features.add(f"base:al:dummy:intent_{intent}")
1601
+ attr = f", {form}" if form in ("allocatable", "pointer") else ""
1602
+ return f"{spell}{attr}, intent({intent}) :: {name}{shape}"
1603
+
1604
+ # -- declare target, mappers, user reductions (stage 4) --
1605
+
1606
+ def setup_declare(self) -> None:
1607
+ from offload.engine.fuzz import (ARef, Bin, Call, Const, Func, Intr,
1608
+ Var)
1609
+ rb = self.rb
1610
+ self.dc_static = {}
1611
+ if self.bon("dc_modvar") or self.bon("dc_calls"):
1612
+ a = self.new_array("gtab", 1, "input")
1613
+ a.alloc = False
1614
+ self.dtv.add("gtab")
1615
+ c1, c2 = rb.randint(3, 61), rb.randint(0, 50)
1616
+ p = rb.choice((97, 211, 1009))
1617
+ off = rb.randint(0, p // 2)
1618
+ self.arrs["gtab"] = {(i,): (i * c1 + c2) % p - off
1619
+ for i in range(1, self.n + 1)}
1620
+ if self.bon("dc_static_init"):
1621
+ self.dc_static["gtab"] = (f"[(mod(kk * {c1} + {c2}, {p}) - "
1622
+ f"{off}, kk = 1, nm)]")
1623
+ self.features.add("base:dc:static_init")
1624
+ else:
1625
+ self.inits["gtab"] = (f"gtab(i) = mod(i * {c1} + {c2}, {p})"
1626
+ f" - {off}")
1627
+ self.features.add("base:dc:declare_target_array")
1628
+ if self.bon("dc_modtype"):
1629
+ self.dvars["gs"] = "gp_t"
1630
+ self.new_array("gs%k", 1, "input", var="gs")
1631
+ self.dtv |= {"gs", "gs%k"}
1632
+ c1, c2 = rb.randint(3, 61), rb.randint(0, 50)
1633
+ self.arrs["gs%k"] = {(i,): (i * c1 + c2) % 211 - 100
1634
+ for i in range(1, self.n + 1)}
1635
+ self.inits["gs%k"] = f"gs%k(i) = mod(i * {c1} + {c2}, 211) - 100"
1636
+ self.features.add("base:dc:declare_target_structure")
1637
+ if self.bon("dc_mapper"):
1638
+ self.dvars["ms"] = "mt_t"
1639
+ self.new_array("ms%a", 1, "input", var="ms")
1640
+ c1, c2 = rb.randint(3, 61), rb.randint(0, 50)
1641
+ self.arrs["ms%a"] = {(i,): (i * c1 + c2) % 101 - 50
1642
+ for i in range(1, self.n + 1)}
1643
+ self.inits["ms%a"] = f"ms%a(i) = mod(i * {c1} + {c2}, 101) - 50"
1644
+ self.mapper = "mmap" if self.bon("dc_named_mapper") else ""
1645
+ self.features.add("base:dc:declare_mapper:" +
1646
+ ("named" if self.mapper else "default"))
1647
+ if self.bon("dc_chain") or self.bon("dc_calls"):
1648
+ gm0 = Func("gm0", ("x",), Bin("+", Intr("iand", (Var("x"),
1649
+ Const(255))),
1650
+ Const(rb.randint(1, 9))))
1651
+ self.mfuncs.append(gm0)
1652
+ if self.bon("dc_calls") and "gtab" in self.arrs:
1653
+ idx = Bin("+", Intr("mod", (Intr("abs", (Var("x"),)),
1654
+ NConst("nm", self.n))), Const(1))
1655
+ self.dfuncs.append(Func("gd1", ("x",), Intr("mod", (
1656
+ Bin("+", Var("x"), ARef("gtab", (idx,))),
1657
+ Const(1009)))))
1658
+ self.features.add("base:dc:device_function_reads_module_var")
1659
+ if self.bon("dc_chain"):
1660
+ self.dfuncs.append(Func("gd2", ("x",), Intr("mod", (
1661
+ Bin("+", Call(gm0, (Var("x"),)), Bin("*", Var("x"),
1662
+ Const(3))),
1663
+ Const(1009)))))
1664
+ self.features.add("base:dc:call_across_modules")
1665
+ if self.bon("dc_udr"):
1666
+ self.features.add("base:dc:declare_reduction_available")
1667
+ if self.dtv:
1668
+ self.features.add("base:dc:declare_target_" + (
1669
+ "enter" if self.bon("dc_enter") else "to"))
1670
+
1671
+ def modvar_output(self, nlev: int):
1672
+ """A declare target module array as a kernel's output, or None."""
1673
+ if not self.bon("dc_modvar_out") or nlev != 1 or \
1674
+ self.rb.random() < 0.5:
1675
+ return None
1676
+ a = self.new_array(f"go{self.k}", 1, "output")
1677
+ a.alloc = False
1678
+ self.dtv.add(a.name)
1679
+ self.features.add("base:dc:declare_target_output")
1680
+ return a
1681
+
1682
+ def udr_red(self, idx: int):
1683
+ """A reduction with the user-defined identifier padd on pair_t, or
1684
+ None."""
1685
+ if not self.bon("dc_udr") or self.rb.random() < 0.6:
1686
+ return None
1687
+ from offload.engine.fuzz import Red
1688
+ init = (self.rb.randint(-20, 20), self.rb.randint(-20, 20))
1689
+ name = f"rp{self.k}{'ab'[idx]}"
1690
+ self.tscalars[name] = ("pair", init)
1691
+ self.env[name] = init
1692
+ self.check_items.append(name)
1693
+ self.features.add("base:dc:declare_reduction")
1694
+ return Red(name, "padd", "clause", init, "pair")
1695
+
1696
+ def udr_term(self, lv: list):
1697
+ from offload.engine.fuzz import Const, Intr
1698
+ return (Intr("mod", (self.expr(1, lv), Const(97))),
1699
+ Intr("mod", (self.expr(1, lv), Const(13))))
1700
+
1701
+ def dc_module_lines(self) -> list[str]:
1702
+ """Modules fuzz_dmod and fuzz_dfun (stage 4)."""
1703
+ from offload.engine.fuzz import wrap_stmt
1704
+ if not (self.dtv or self.mfuncs or "ms" in self.dvars or
1705
+ self.bon("dc_udr")):
1706
+ return []
1707
+ L = ["module fuzz_dmod", " implicit none",
1708
+ f" integer, parameter :: nm = {self.n}"]
1709
+ if self.dc_static:
1710
+ L.append(" integer, private :: kk")
1711
+ if "gs" in self.dvars:
1712
+ L += [" type :: gp_t", " integer :: k(nm)", " end type gp_t"]
1713
+ if "ms" in self.dvars:
1714
+ comps = [a.name.split("%", 1)[1] for a in self.arrays.values()
1715
+ if a.var == "ms"]
1716
+ L += [" type :: mt_t"] + [f" integer :: {c}(nm)"
1717
+ for c in comps] + [" end type mt_t"]
1718
+ if self.bon("dc_udr"):
1719
+ L += [" type :: pair_t", " integer :: x, y",
1720
+ " end type pair_t"]
1721
+ arrs = [a.name for a in self.arrays.values()
1722
+ if a.name in self.dtv and not a.var]
1723
+ for name in arrs:
1724
+ init = self.dc_static.get(name)
1725
+ L.append(f" integer :: {name}(nm)" + (f" = {init}" if init
1726
+ else ""))
1727
+ if "gs" in self.dvars:
1728
+ L.append(" type(gp_t) :: gs")
1729
+ dt = arrs + (["gs"] if "gs" in self.dvars else [])
1730
+ if dt:
1731
+ # 5.2 spells the clause enter; to is its deprecated synonym
1732
+ # (5.2 §7.8.2), which CCE 19/20 still require
1733
+ cl = "enter" if self.bon("dc_enter") else "to"
1734
+ L.append(f" !$omp declare target {cl}({', '.join(dt)})")
1735
+ if "ms" in self.dvars:
1736
+ comps = [a.name.split("%", 1)[1] for a in self.arrays.values()
1737
+ if a.var == "ms"]
1738
+ head = f"{self.mapper}: " if self.mapper else ""
1739
+ L.append(f" !$omp declare mapper({head}mt_t :: v) map(tofrom: "
1740
+ + ", ".join(f"v%{c}" for c in comps) + ")")
1741
+ if self.bon("dc_udr"):
1742
+ L += [" !$omp declare reduction(padd: pair_t: omp_out = &",
1743
+ " !$omp& pair_t(omp_out%x + omp_in%x, omp_out%y + "
1744
+ "omp_in%y)) &",
1745
+ " !$omp& initializer(omp_priv = pair_t(0, 0))"]
1746
+ if self.mfuncs:
1747
+ L.append("contains")
1748
+ for fn in self.mfuncs:
1749
+ L += self.func_lines(fn)
1750
+ L.append("end module fuzz_dmod")
1751
+ if self.dfuncs:
1752
+ L += ["module fuzz_dfun", " use fuzz_dmod", " implicit none",
1753
+ "contains"]
1754
+ for fn in self.dfuncs:
1755
+ L += self.func_lines(fn)
1756
+ L.append("end module fuzz_dfun")
1757
+ return L
1758
+
1759
+ @staticmethod
1760
+ def func_lines(fn) -> list[str]:
1761
+ from offload.engine.fuzz import wrap_stmt
1762
+ args = ", ".join(fn.params)
1763
+ return ([f" integer function {fn.name}({args})",
1764
+ " !$omp declare target",
1765
+ f" integer, intent(in) :: {args}"]
1766
+ + wrap_stmt(" ", f"{fn.name} = {fn.body.f()}")
1767
+ + [f" end function {fn.name}"])
1768
+
1769
+ def dc_setup_lines(self) -> list[str]:
1770
+ """Host statements after the inputs: zero the declare target
1771
+ outputs and copy the module variables set on the host to the
1772
+ device."""
1773
+ out = [f" {a.name} = 0" for a in self.arrays.values()
1774
+ if a.name in self.dtv and a.role == "output"]
1775
+ out = []
1776
+ upd = [a.name for a in self.arrays.values()
1777
+ if a.name in self.dtv and not a.var and
1778
+ (a.role == "output" or a.name in self.inits)]
1779
+ if "gs" in self.dvars:
1780
+ upd.append("gs")
1781
+ if upd:
1782
+ out.append(f" !$omp target update to({', '.join(upd)})")
1783
+ return out
1784
+
1785
+ def dc_final_lines(self) -> list[str]:
1786
+ outs = [a.name for a in self.arrays.values()
1787
+ if a.name in self.dtv and a.role == "output"]
1788
+ return [f" !$omp target update from({', '.join(outs)})"] \
1789
+ if outs else []
1790
+
1791
+ # -- type extension, type-bound procedures, polymorphism (fuzz-5) --
1792
+
1793
+ def setup_oop(self) -> None:
1794
+ """The device functions oo1..oo5 (module fuzz_omod) and their
1795
+ models. Every object is a local variable of a device function, so
1796
+ no polymorphic object is ever mapped (OpenMP 6.0 §7.9.6 p.288)."""
1797
+ from offload.engine.fuzz import Bin, Const, Func, Intr, Var
1798
+ rb = self.rb
1799
+ c = {"a1": rb.randint(2, 7), "p1": rb.choice((97, 211, 1009)),
1800
+ "a2": rb.randint(2, 5), "p2": rb.choice((89, 101, 997)),
1801
+ "k": {}, "j": {}, "k2": {}}
1802
+ x = Var("x")
1803
+ on = [f for f in GROUP_SWARM["oop"] if self.bon(f)] or \
1804
+ ["oo_dispatch"]
1805
+
1806
+ def ob(k):
1807
+ return Intr("mod", (Bin("+", Bin("*", x, Const(c["a1"])),
1808
+ Const(k)), Const(c["p1"])))
1809
+
1810
+ def ox(k, j):
1811
+ return Intr("mod", (Bin("+", ob(k), Const(j * c["a2"])),
1812
+ Const(c["p2"])))
1813
+ for n, feat in enumerate(GROUP_SWARM["oop"], start=1):
1814
+ if feat not in on:
1815
+ continue
1816
+ name = f"oo{n}"
1817
+ k, j, k2 = rb.randint(0, 50), rb.randint(1, 40), \
1818
+ rb.randint(0, 30)
1819
+ c["k"][name], c["j"][name], c["k2"][name] = k, j, k2
1820
+ body = {
1821
+ "oo_dispatch": lambda: ob(k),
1822
+ "oo_override": lambda: ox(k, j),
1823
+ "oo_inherit": lambda: Bin("+", ox(k, j), Const(k)),
1824
+ "oo_select": lambda: Bin("+", Bin("+", x, Const(j)),
1825
+ Bin("-", x, Const(k2))),
1826
+ "oo_unlimited": lambda: Bin("+", Intr("mod", (Bin(
1827
+ "+", Bin("*", x, Const(3)), Const(j)), Const(1009))),
1828
+ Intr("mod", (Bin("+", x, Const(k2)), Const(1009)))),
1829
+ }[feat]()
1830
+ self.ofuncs.append(Func(name, ("x",), body))
1831
+ self.features.add(f"base:oop:{feat[3:]}")
1832
+ self.oop_consts = c
1833
+
1834
+ def oop_module_lines(self) -> list[str]:
1835
+ """Module fuzz_omod (fuzz-5)."""
1836
+ c = self.oop_consts
1837
+ dt = " !$omp declare target"
1838
+
1839
+ def fn(name, args, decls, body):
1840
+ return ([f" integer function {name}({args})", dt] +
1841
+ [f" {d}" for d in decls] +
1842
+ [f" {b}" for b in body] +
1843
+ [f" end function {name}"])
1844
+ L = ["module fuzz_omod", " implicit none",
1845
+ " type :: ob_t", " integer :: k = 0", " contains",
1846
+ " procedure :: f => ob_f", " procedure :: g => ob_g",
1847
+ " end type ob_t", " type, extends(ob_t) :: ox_t",
1848
+ " integer :: j = 0", " contains",
1849
+ " procedure :: f => ox_f", " end type ox_t", "contains"]
1850
+ sx = ["class(ob_t), intent(in) :: s", "integer, intent(in) :: x"]
1851
+ L += fn("ob_f", "s, x", sx,
1852
+ [f"ob_f = mod(x * {c['a1']} + s%k, {c['p1']})"])
1853
+ L += fn("ob_g", "s, x", sx, ["ob_g = s%f(x) + s%k"])
1854
+ L += fn("ox_f", "s, x", ["class(ox_t), intent(in) :: s",
1855
+ "integer, intent(in) :: x"],
1856
+ [f"ox_f = mod(s%ob_t%f(x) + s%j * {c['a2']}, {c['p2']})"])
1857
+ L += fn("od", "s, x", sx, ["od = s%f(x)"])
1858
+ L += fn("osel", "s, x", sx,
1859
+ ["select type (s)", "type is (ox_t)", " osel = x + s%j",
1860
+ "class default", " osel = x - s%k", "end select"])
1861
+ L += fn("cany", "s, x", ["class(*), intent(in) :: s",
1862
+ "integer, intent(in) :: x"],
1863
+ ["select type (s)", "type is (ox_t)",
1864
+ " cany = mod(x * 3 + s%j, 1009)", "type is (integer)",
1865
+ " cany = mod(x + s, 1009)", "class default",
1866
+ " cany = 0", "end select"])
1867
+ xd = ["integer, intent(in) :: x"]
1868
+ for f in self.ofuncs:
1869
+ k, j, k2 = c["k"][f.name], c["j"][f.name], c["k2"][f.name]
1870
+ if f.name == "oo1":
1871
+ L += fn("oo1", "x", xd + ["type(ob_t) :: o"],
1872
+ [f"o%k = {k}", "oo1 = od(o, x)"])
1873
+ elif f.name == "oo2":
1874
+ L += fn("oo2", "x", xd + ["type(ox_t) :: o"],
1875
+ [f"o%k = {k}", f"o%j = {j}", "oo2 = od(o, x)"])
1876
+ elif f.name == "oo3":
1877
+ L += fn("oo3", "x", xd + ["type(ox_t) :: o"],
1878
+ [f"o%k = {k}", f"o%j = {j}", "oo3 = o%g(x)"])
1879
+ elif f.name == "oo4":
1880
+ L += fn("oo4", "x", xd + ["type(ox_t) :: o",
1881
+ "type(ob_t) :: b"],
1882
+ [f"o%k = {k}", f"o%j = {j}", f"b%k = {k2}",
1883
+ "oo4 = osel(o, x) + osel(b, x)"])
1884
+ else:
1885
+ L += fn("oo5", "x", xd + ["type(ox_t) :: o",
1886
+ "integer :: kk"],
1887
+ [f"o%k = {k}", f"o%j = {j}", f"kk = {k2}",
1888
+ "oo5 = cany(o, x) + cany(kk, x)"])
1889
+ L.append("end module fuzz_omod")
1890
+ return L
1891
+
1892
+ # -- translation units (stage 5) --
1893
+
1894
+ def setup_multitu(self) -> None:
1895
+ from offload.engine.fuzz import Bin, Call, Const, Func, Intr, Var
1896
+ rb = self.rb
1897
+ self.mt_funcs: dict[str, list] = {}
1898
+ x = Var("x")
1899
+ if self.bon("mt_amod") or self.bon("mt_chain") or not any(
1900
+ self.bon(f) for f in ("mt_submodule", "mt_external")):
1901
+ ga1 = Func("ga1", ("x",), Intr("mod", (Bin("+", Bin(
1902
+ "*", Intr("iand", (x, Const(1023))), Const(rb.randint(2, 7))),
1903
+ Const(rb.randint(0, 50))), Const(1013))))
1904
+ self.mt_funcs["fuzz_amod"] = [ga1]
1905
+ self.xfuncs.append(ga1)
1906
+ self.features.add("base:mt:module_file")
1907
+ if self.bon("mt_chain"):
1908
+ gb1 = Func("gb1", ("x",), Intr("mod", (Bin("+", Call(
1909
+ ga1, (x,)), Bin("*", x, Const(rb.choice((3, 5))))),
1910
+ Const(2003))))
1911
+ self.mt_funcs["fuzz_bmod"] = [gb1]
1912
+ self.xfuncs.append(gb1)
1913
+ self.features.add("base:mt:module_chain")
1914
+ if self.bon("mt_submodule"):
1915
+ gs1 = Func("gs1", ("x",), Intr("mod", (Intr("ieor", (x, Const(
1916
+ rb.randint(1, 255)))), Const(4093))))
1917
+ self.mt_funcs["fuzz_smod"] = [gs1]
1918
+ self.xfuncs.append(gs1)
1919
+ self.features.add("base:mt:submodule")
1920
+ if self.bon("mt_external"):
1921
+ ge1 = Func("ge1", ("x",), Intr("mod", (Bin("-", Intr("max", (
1922
+ x, Const(rb.randint(-30, 30)))), Const(rb.randint(0, 9))),
1923
+ Const(997))))
1924
+ self.mt_funcs["external"] = [ge1]
1925
+ self.xfuncs.append(ge1)
1926
+ self.features.add("base:mt:external_function")
1927
+ self.features.add("base:mt:file_set")
1928
+
1929
+ def mt_unit_lines(self) -> list[tuple[str, list[str]]]:
1930
+ """(file name, lines) of the stage-5 units, in compile order."""
1931
+ out = []
1932
+ for mod in ("fuzz_amod", "fuzz_bmod"):
1933
+ if mod not in self.mt_funcs:
1934
+ continue
1935
+ L = [f"module {mod}"]
1936
+ if mod == "fuzz_bmod":
1937
+ L.append(" use fuzz_amod, only: ga1")
1938
+ L += [" implicit none", "contains"]
1939
+ for fn in self.mt_funcs[mod]:
1940
+ L += self.func_lines(fn)
1941
+ L.append(f"end module {mod}")
1942
+ out.append((f"{mod}.f90", L))
1943
+ if "fuzz_smod" in self.mt_funcs:
1944
+ fn = self.mt_funcs["fuzz_smod"][0]
1945
+ out.append(("fuzz_smod.f90", [
1946
+ "module fuzz_smod", " implicit none", " interface",
1947
+ f" module integer function {fn.name}(x)",
1948
+ " !$omp declare target",
1949
+ " integer, intent(in) :: x",
1950
+ f" end function {fn.name}", " end interface",
1951
+ "end module fuzz_smod"]))
1952
+ body = self.func_lines(fn)
1953
+ body[0] = body[0].replace(" integer function",
1954
+ " module integer function")
1955
+ out.append(("fuzz_ssub.f90", [
1956
+ "submodule (fuzz_smod) fuzz_ssub", " implicit none",
1957
+ "contains"] + body + ["end submodule fuzz_ssub"]))
1958
+ if "external" in self.mt_funcs:
1959
+ fn = self.mt_funcs["external"][0]
1960
+ from offload.engine.fuzz import wrap_stmt
1961
+ out.append(("fuzz_ext.f90", [
1962
+ f"integer function {fn.name}(x)", " implicit none",
1963
+ " integer, intent(in) :: x", " !$omp declare target"]
1964
+ + wrap_stmt(" ", f"{fn.name} = {fn.body.f()}")
1965
+ + [f"end function {fn.name}"]))
1966
+ return out
1967
+
1968
+ def mt_use_lines(self) -> list[str]:
1969
+ out = []
1970
+ for mod in ("fuzz_amod", "fuzz_bmod", "fuzz_smod"):
1971
+ if mod in self.mt_funcs:
1972
+ out.append(f" use {mod}, only: "
1973
+ + ", ".join(f.name for f in self.mt_funcs[mod]))
1974
+ return out
1975
+
1976
+ def mt_interface_lines(self) -> list[str]:
1977
+ if "external" not in self.mt_funcs:
1978
+ return []
1979
+ fn = self.mt_funcs["external"][0]
1980
+ return [" interface", f" integer function {fn.name}(x)",
1981
+ " !$omp declare target",
1982
+ " integer, intent(in) :: x",
1983
+ f" end function {fn.name}", " end interface"]
1984
+
1985
+
1986
+ def split_bundle(source: str) -> list[tuple[str, str]] | None:
1987
+ """The files of a bundle (stage 5) in compile order: [(name, text)];
1988
+ None if `source` is a single file. Lines before the first marker (the
1989
+ generator's comment header) go to the first file."""
1990
+ if FILE_MARK not in source:
1991
+ return None
1992
+ files: list[list] = []
1993
+ head: list[str] = []
1994
+ for line in source.splitlines():
1995
+ if line.startswith(FILE_MARK):
1996
+ files.append([line[len(FILE_MARK):].strip(), []])
1997
+ elif files:
1998
+ files[-1][1].append(line)
1999
+ else:
2000
+ head.append(line)
2001
+ if files:
2002
+ files[0][1] = head + files[0][1]
2003
+ return [(n, "\n".join(ls) + "\n") for n, ls in files]
2004
+
2005
+
2006
+ @dataclass(frozen=True)
2007
+ class NConst:
2008
+ """A named integer constant (Fortran text `name`, value `v`)."""
2009
+ name: str
2010
+ v: int
2011
+
2012
+ def f(self):
2013
+ return self.name
2014
+
2015
+ def ev(self, env, arrs):
2016
+ return self.v