meep-gpu 0.9.2__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 (537) hide show
  1. meep_gpu/LICENSE +339 -0
  2. meep_gpu/NOTICE +21 -0
  3. meep_gpu/__init__.py +208 -0
  4. meep_gpu/absorber.py +316 -0
  5. meep_gpu/amp_interpolation.py +158 -0
  6. meep_gpu/backends.py +362 -0
  7. meep_gpu/code_identity.py +144 -0
  8. meep_gpu/conftest.py +399 -0
  9. meep_gpu/cuda_kernels/__init__.py +6 -0
  10. meep_gpu/cuda_kernels/ade_kernels.py +519 -0
  11. meep_gpu/cuda_kernels/arms.py +1311 -0
  12. meep_gpu/cuda_kernels/bfast_curl.py +757 -0
  13. meep_gpu/cuda_kernels/bfast_fused_electric_pair.py +730 -0
  14. meep_gpu/cuda_kernels/bfast_fused_magnetic_pair.py +611 -0
  15. meep_gpu/cuda_kernels/certification.json +21804 -0
  16. meep_gpu/cuda_kernels/compile_cache.py +259 -0
  17. meep_gpu/cuda_kernels/complex_beta_fused_electric_pair.py +593 -0
  18. meep_gpu/cuda_kernels/complex_beta_fused_hd_pair.py +1067 -0
  19. meep_gpu/cuda_kernels/complex_beta_fused_magnetic_pair.py +560 -0
  20. meep_gpu/cuda_kernels/complex_beta_kernels.py +857 -0
  21. meep_gpu/cuda_kernels/complex_electric_fill_carry.py +766 -0
  22. meep_gpu/cuda_kernels/complex_emitter.py +645 -0
  23. meep_gpu/cuda_kernels/complex_fill_carry.py +717 -0
  24. meep_gpu/cuda_kernels/complex_folded_fused_electric_pair.py +561 -0
  25. meep_gpu/cuda_kernels/complex_folded_fused_magnetic_pair.py +652 -0
  26. meep_gpu/cuda_kernels/complex_folded_kernels.py +895 -0
  27. meep_gpu/cuda_kernels/complex_fused_electric_pair.py +1024 -0
  28. meep_gpu/cuda_kernels/complex_fused_hd_pair.py +1270 -0
  29. meep_gpu/cuda_kernels/complex_fused_magnetic_pair.py +885 -0
  30. meep_gpu/cuda_kernels/complex_no_pml_fused_polarization_pair.py +677 -0
  31. meep_gpu/cuda_kernels/complex_no_pml_kernels.py +1709 -0
  32. meep_gpu/cuda_kernels/complex_no_pml_offdiag_fused_electric_pair.py +754 -0
  33. meep_gpu/cuda_kernels/complex_no_pml_three_slot_dispersive_weld.py +824 -0
  34. meep_gpu/cuda_kernels/complex_offdiag_stencil_weld.py +1090 -0
  35. meep_gpu/cuda_kernels/complex_offdiag_update_e.py +1941 -0
  36. meep_gpu/cuda_kernels/complex_pml_kernels.py +473 -0
  37. meep_gpu/cuda_kernels/conductive_bfast_fused_hd_pair.py +1445 -0
  38. meep_gpu/cuda_kernels/conductive_fused_electric_pair.py +1006 -0
  39. meep_gpu/cuda_kernels/conductive_kernels.py +1104 -0
  40. meep_gpu/cuda_kernels/constitutive_kernels.py +606 -0
  41. meep_gpu/cuda_kernels/coverage.py +3151 -0
  42. meep_gpu/cuda_kernels/cylindrical_complex_kernels.py +1101 -0
  43. meep_gpu/cuda_kernels/cylindrical_coverage.py +540 -0
  44. meep_gpu/cuda_kernels/cylindrical_fused_electric_pair.py +1316 -0
  45. meep_gpu/cuda_kernels/cylindrical_fused_hd_pair.py +771 -0
  46. meep_gpu/cuda_kernels/cylindrical_fused_magnetic_pair.py +1143 -0
  47. meep_gpu/cuda_kernels/cylindrical_kernels.py +534 -0
  48. meep_gpu/cuda_kernels/cylindrical_prefix.py +83 -0
  49. meep_gpu/cuda_kernels/cylindrical_real_fused_electric_pair.py +837 -0
  50. meep_gpu/cuda_kernels/cylindrical_real_fused_hd_pair.py +685 -0
  51. meep_gpu/cuda_kernels/cylindrical_real_fused_magnetic_pair.py +708 -0
  52. meep_gpu/cuda_kernels/dispersive_fused_electric_pair.py +950 -0
  53. meep_gpu/cuda_kernels/dispersive_kernels.py +1403 -0
  54. meep_gpu/cuda_kernels/dispersive_offdiag_fused_polarization_pair.py +649 -0
  55. meep_gpu/cuda_kernels/dispersive_offdiag_update_e.py +1719 -0
  56. meep_gpu/cuda_kernels/fingerprints.json +4694 -0
  57. meep_gpu/cuda_kernels/folded_complex_offdiag_fused_electric_pair.py +858 -0
  58. meep_gpu/cuda_kernels/folded_offdiag_fused_electric_pair.py +931 -0
  59. meep_gpu/cuda_kernels/folded_offdiag_kernels.py +1375 -0
  60. meep_gpu/cuda_kernels/fused_electric_pair.py +1706 -0
  61. meep_gpu/cuda_kernels/fused_hd_pair.py +1313 -0
  62. meep_gpu/cuda_kernels/fused_magnetic_pair.py +1880 -0
  63. meep_gpu/cuda_kernels/fused_pairs.py +5127 -0
  64. meep_gpu/cuda_kernels/fused_polarization_pair.py +1145 -0
  65. meep_gpu/cuda_kernels/in_seam_coverage.py +504 -0
  66. meep_gpu/cuda_kernels/in_seam_passes.py +736 -0
  67. meep_gpu/cuda_kernels/no_pml_complex_fused_electric_pair.py +1387 -0
  68. meep_gpu/cuda_kernels/no_pml_constitutive.py +733 -0
  69. meep_gpu/cuda_kernels/no_pml_curl.py +1055 -0
  70. meep_gpu/cuda_kernels/no_pml_dispersive_fused_electric_pair.py +1100 -0
  71. meep_gpu/cuda_kernels/no_pml_three_slot_dispersive_weld.py +244 -0
  72. meep_gpu/cuda_kernels/nonlinear_constitutive.py +989 -0
  73. meep_gpu/cuda_kernels/offdiag_constitutive_kernels.py +401 -0
  74. meep_gpu/cuda_kernels/offdiag_emitter.py +504 -0
  75. meep_gpu/cuda_kernels/offdiag_fused_electric_pair.py +979 -0
  76. meep_gpu/cuda_kernels/offdiag_stencil_weld.py +763 -0
  77. meep_gpu/cuda_kernels/own_cell_hoist.py +266 -0
  78. meep_gpu/cuda_kernels/own_cell_hoist_reference.json +2150 -0
  79. meep_gpu/cuda_kernels/registry.py +763 -0
  80. meep_gpu/cuda_kernels/special_kz_curl.py +677 -0
  81. meep_gpu/cuda_kernels/special_kz_fused_electric_pair.py +722 -0
  82. meep_gpu/cuda_kernels/special_kz_fused_hd_pair.py +847 -0
  83. meep_gpu/cuda_kernels/special_kz_fused_magnetic_pair.py +724 -0
  84. meep_gpu/cuda_kernels/step_curl_kernels.py +833 -0
  85. meep_gpu/cuda_kernels/test_ade_strings_parse_cache.py +186 -0
  86. meep_gpu/cuda_kernels/test_ade_update_p.py +1200 -0
  87. meep_gpu/cuda_kernels/test_arms.py +614 -0
  88. meep_gpu/cuda_kernels/test_bfast_curl.py +450 -0
  89. meep_gpu/cuda_kernels/test_certification_metadata.py +532 -0
  90. meep_gpu/cuda_kernels/test_certification_record.py +798 -0
  91. meep_gpu/cuda_kernels/test_compile_cache.py +431 -0
  92. meep_gpu/cuda_kernels/test_complex_beta.py +642 -0
  93. meep_gpu/cuda_kernels/test_complex_beta_fused_hd_pair.py +340 -0
  94. meep_gpu/cuda_kernels/test_complex_folded.py +969 -0
  95. meep_gpu/cuda_kernels/test_complex_fused_electric_pairs.py +1181 -0
  96. meep_gpu/cuda_kernels/test_complex_no_pml.py +1000 -0
  97. meep_gpu/cuda_kernels/test_complex_no_pml_three_slot_dispersive_weld.py +315 -0
  98. meep_gpu/cuda_kernels/test_complex_offdiag_stencil_welds.py +702 -0
  99. meep_gpu/cuda_kernels/test_complex_offdiag_update_e.py +1503 -0
  100. meep_gpu/cuda_kernels/test_complex_pml.py +1211 -0
  101. meep_gpu/cuda_kernels/test_conductive_bfast_fused_hd_pair.py +392 -0
  102. meep_gpu/cuda_kernels/test_conductive_fused_electric_pair.py +573 -0
  103. meep_gpu/cuda_kernels/test_conductive_kernels.py +988 -0
  104. meep_gpu/cuda_kernels/test_constitutive_pml_real.py +2671 -0
  105. meep_gpu/cuda_kernels/test_cylindrical_complex.py +842 -0
  106. meep_gpu/cuda_kernels/test_cylindrical_fused_electric_pair_hoist.py +95 -0
  107. meep_gpu/cuda_kernels/test_cylindrical_fused_magnetic_pair_hoist.py +91 -0
  108. meep_gpu/cuda_kernels/test_cylindrical_pml_real.py +727 -0
  109. meep_gpu/cuda_kernels/test_dispersive.py +910 -0
  110. meep_gpu/cuda_kernels/test_dispersive_fused_electric_pair.py +761 -0
  111. meep_gpu/cuda_kernels/test_dispersive_offdiag_polarization_pair.py +354 -0
  112. meep_gpu/cuda_kernels/test_dispersive_offdiag_update_e.py +1590 -0
  113. meep_gpu/cuda_kernels/test_folded_offdiag.py +1625 -0
  114. meep_gpu/cuda_kernels/test_fused_electric_pair.py +896 -0
  115. meep_gpu/cuda_kernels/test_fused_hd_pair.py +370 -0
  116. meep_gpu/cuda_kernels/test_fused_magnetic_pair_fill_carry.py +982 -0
  117. meep_gpu/cuda_kernels/test_fused_pair_held_source.py +701 -0
  118. meep_gpu/cuda_kernels/test_fused_pairs.py +1046 -0
  119. meep_gpu/cuda_kernels/test_fused_polarization_pair.py +583 -0
  120. meep_gpu/cuda_kernels/test_in_seam_passes.py +685 -0
  121. meep_gpu/cuda_kernels/test_kernel_partition.py +378 -0
  122. meep_gpu/cuda_kernels/test_no_pml_complex_fused_electric_pair.py +1366 -0
  123. meep_gpu/cuda_kernels/test_no_pml_constitutive.py +1061 -0
  124. meep_gpu/cuda_kernels/test_no_pml_curl.py +1067 -0
  125. meep_gpu/cuda_kernels/test_no_pml_dispersive_fused_electric_pair.py +648 -0
  126. meep_gpu/cuda_kernels/test_nonlinear_constitutive.py +1038 -0
  127. meep_gpu/cuda_kernels/test_offdiag_constitutive_pml_real.py +2315 -0
  128. meep_gpu/cuda_kernels/test_offdiag_stencil_welds.py +858 -0
  129. meep_gpu/cuda_kernels/test_own_cell_hoist_store_sequence.py +1248 -0
  130. meep_gpu/cuda_kernels/test_residual_fused_electric_pairs.py +451 -0
  131. meep_gpu/cuda_kernels/test_residual_fused_magnetic_pairs.py +574 -0
  132. meep_gpu/cuda_kernels/test_single_arm_launches.py +822 -0
  133. meep_gpu/cuda_kernels/test_special_kz_bfast_admission.py +260 -0
  134. meep_gpu/cuda_kernels/test_special_kz_curl.py +470 -0
  135. meep_gpu/cuda_kernels/test_special_kz_fused_hd_pair.py +284 -0
  136. meep_gpu/cuda_kernels/test_step_curl_pml_real.py +1662 -0
  137. meep_gpu/cuda_kernels/test_three_slot_dispersive_weld.py +570 -0
  138. meep_gpu/cuda_kernels/three_slot_dispersive_weld.py +778 -0
  139. meep_gpu/cuda_kernels/timing_cc86.json +1154 -0
  140. meep_gpu/cuda_kernels/timing_cc86.report.txt +64 -0
  141. meep_gpu/deposit_repair.py +1854 -0
  142. meep_gpu/device_identity.py +265 -0
  143. meep_gpu/dft.py +5538 -0
  144. meep_gpu/dispatch_preference.py +977 -0
  145. meep_gpu/dispersion.py +769 -0
  146. meep_gpu/driver.py +4617 -0
  147. meep_gpu/expansion_refusal.py +439 -0
  148. meep_gpu/fastpath.py +7652 -0
  149. meep_gpu/fastpath_cuda.py +2371 -0
  150. meep_gpu/fields.py +1957 -0
  151. meep_gpu/from_meep.py +8638 -0
  152. meep_gpu/gaussian_beam.py +303 -0
  153. meep_gpu/grid.py +1479 -0
  154. meep_gpu/harminv.py +680 -0
  155. meep_gpu/host_writes.py +331 -0
  156. meep_gpu/metal_dispatch.py +3120 -0
  157. meep_gpu/metal_kernels/__init__.py +104 -0
  158. meep_gpu/metal_kernels/ade_update_p.py +493 -0
  159. meep_gpu/metal_kernels/arms.py +289 -0
  160. meep_gpu/metal_kernels/barrier.py +367 -0
  161. meep_gpu/metal_kernels/beta_complex_fused_electric_pair.py +671 -0
  162. meep_gpu/metal_kernels/beta_complex_fused_hd_pair.py +1265 -0
  163. meep_gpu/metal_kernels/beta_complex_fused_magnetic_pair.py +549 -0
  164. meep_gpu/metal_kernels/beta_fused_electric_pair.py +640 -0
  165. meep_gpu/metal_kernels/beta_fused_magnetic_pair.py +573 -0
  166. meep_gpu/metal_kernels/beta_real_fused_hd_pair.py +1048 -0
  167. meep_gpu/metal_kernels/bfast_curl.py +1081 -0
  168. meep_gpu/metal_kernels/bfast_fused_electric_pair.py +681 -0
  169. meep_gpu/metal_kernels/bfast_fused_hd_pair.py +852 -0
  170. meep_gpu/metal_kernels/bfast_fused_magnetic_pair.py +568 -0
  171. meep_gpu/metal_kernels/coefficient_pack.py +201 -0
  172. meep_gpu/metal_kernels/complex_conductive_fused_pair.py +885 -0
  173. meep_gpu/metal_kernels/complex_conductive_pml.py +525 -0
  174. meep_gpu/metal_kernels/complex_dispersive_spine.py +173 -0
  175. meep_gpu/metal_kernels/complex_dispersive_update_e.py +300 -0
  176. meep_gpu/metal_kernels/complex_fields.py +1393 -0
  177. meep_gpu/metal_kernels/complex_folded_offdiag_update_e.py +365 -0
  178. meep_gpu/metal_kernels/complex_fused_ade_chain.py +825 -0
  179. meep_gpu/metal_kernels/complex_fused_electric_pair.py +920 -0
  180. meep_gpu/metal_kernels/complex_fused_hd_pair.py +1267 -0
  181. meep_gpu/metal_kernels/complex_fused_magnetic_pair.py +1010 -0
  182. meep_gpu/metal_kernels/complex_no_pml_conductive.py +446 -0
  183. meep_gpu/metal_kernels/complex_no_pml_curl.py +199 -0
  184. meep_gpu/metal_kernels/complex_no_pml_offdiag_fused_electric_pair.py +579 -0
  185. meep_gpu/metal_kernels/complex_no_pml_offdiag_update_e.py +391 -0
  186. meep_gpu/metal_kernels/complex_no_pml_stored_e.py +272 -0
  187. meep_gpu/metal_kernels/conductive_fused_electric_pair.py +675 -0
  188. meep_gpu/metal_kernels/conductive_fused_hd_pair.py +944 -0
  189. meep_gpu/metal_kernels/conductive_pml.py +273 -0
  190. meep_gpu/metal_kernels/corpus.py +170 -0
  191. meep_gpu/metal_kernels/coverage.py +631 -0
  192. meep_gpu/metal_kernels/cylindrical_complex.py +1780 -0
  193. meep_gpu/metal_kernels/cylindrical_complex_fused_hd_pair.py +841 -0
  194. meep_gpu/metal_kernels/cylindrical_complex_scan.py +273 -0
  195. meep_gpu/metal_kernels/cylindrical_fused_electric_pair.py +1073 -0
  196. meep_gpu/metal_kernels/cylindrical_fused_magnetic_pair.py +1087 -0
  197. meep_gpu/metal_kernels/cylindrical_real.py +1426 -0
  198. meep_gpu/metal_kernels/cylindrical_real_fused_electric_pair.py +1022 -0
  199. meep_gpu/metal_kernels/cylindrical_real_fused_hd_pair.py +955 -0
  200. meep_gpu/metal_kernels/cylindrical_real_fused_magnetic_pair.py +876 -0
  201. meep_gpu/metal_kernels/device.py +1659 -0
  202. meep_gpu/metal_kernels/dispersive_update_e.py +310 -0
  203. meep_gpu/metal_kernels/fingerprints.json +35997 -0
  204. meep_gpu/metal_kernels/folded_beta.py +1710 -0
  205. meep_gpu/metal_kernels/folded_beta_complex_fused_magnetic_pair.py +1443 -0
  206. meep_gpu/metal_kernels/folded_beta_complex_fused_pair.py +872 -0
  207. meep_gpu/metal_kernels/folded_beta_real_fused_magnetic_pair.py +638 -0
  208. meep_gpu/metal_kernels/folded_beta_real_fused_pair.py +670 -0
  209. meep_gpu/metal_kernels/folded_complex.py +1804 -0
  210. meep_gpu/metal_kernels/folded_complex_fused_hd_pair.py +889 -0
  211. meep_gpu/metal_kernels/folded_complex_fused_magnetic_pair.py +1918 -0
  212. meep_gpu/metal_kernels/folded_complex_fused_pair.py +1478 -0
  213. meep_gpu/metal_kernels/folded_complex_offdiag_fused_electric_pair.py +637 -0
  214. meep_gpu/metal_kernels/folded_dispersive_update_e.py +187 -0
  215. meep_gpu/metal_kernels/folded_fused_dispersive_pair.py +1043 -0
  216. meep_gpu/metal_kernels/folded_fused_hd_pair.py +796 -0
  217. meep_gpu/metal_kernels/folded_fused_magnetic_pair.py +1542 -0
  218. meep_gpu/metal_kernels/folded_fused_pair.py +1449 -0
  219. meep_gpu/metal_kernels/folded_offdiag_dispersive_update_e.py +457 -0
  220. meep_gpu/metal_kernels/folded_offdiag_fused_electric_pair.py +572 -0
  221. meep_gpu/metal_kernels/folded_offdiag_update_e.py +1422 -0
  222. meep_gpu/metal_kernels/fused_ade_chain.py +882 -0
  223. meep_gpu/metal_kernels/fused_dispersive_pair.py +821 -0
  224. meep_gpu/metal_kernels/fused_electric_pair.py +843 -0
  225. meep_gpu/metal_kernels/fused_hd_pair.py +1167 -0
  226. meep_gpu/metal_kernels/fused_magnetic_pair.py +765 -0
  227. meep_gpu/metal_kernels/launch.py +2125 -0
  228. meep_gpu/metal_kernels/no_pml_conductive.py +383 -0
  229. meep_gpu/metal_kernels/no_pml_conductive_fused_electric_pair.py +797 -0
  230. meep_gpu/metal_kernels/no_pml_constitutive.py +737 -0
  231. meep_gpu/metal_kernels/no_pml_curl.py +339 -0
  232. meep_gpu/metal_kernels/no_pml_fused_electric_pair.py +553 -0
  233. meep_gpu/metal_kernels/no_pml_stored_e.py +285 -0
  234. meep_gpu/metal_kernels/nonlinear_fused_magnetic_pair.py +305 -0
  235. meep_gpu/metal_kernels/nonlinear_update_e.py +1575 -0
  236. meep_gpu/metal_kernels/offdiag_fused_electric_pair.py +720 -0
  237. meep_gpu/metal_kernels/offdiag_update_e.py +1134 -0
  238. meep_gpu/metal_kernels/offdiag_weld_common.py +588 -0
  239. meep_gpu/metal_kernels/plans.py +90 -0
  240. meep_gpu/metal_kernels/preconditions.py +265 -0
  241. meep_gpu/metal_kernels/registry.py +385 -0
  242. meep_gpu/metal_kernels/shaders.py +430 -0
  243. meep_gpu/metal_kernels/special_kz.py +1804 -0
  244. meep_gpu/metal_kernels/subnormal.py +313 -0
  245. meep_gpu/metal_kernels/symmetry.py +1829 -0
  246. meep_gpu/metal_kernels/templates.py +224 -0
  247. meep_gpu/metal_runs.py +329 -0
  248. meep_gpu/pml.py +857 -0
  249. meep_gpu/sigma_lookup.py +327 -0
  250. meep_gpu/sigma_recovery.py +261 -0
  251. meep_gpu/smoothing.py +1440 -0
  252. meep_gpu/sources.py +2272 -0
  253. meep_gpu/stepping.py +2544 -0
  254. meep_gpu/subnormal_policy.py +2332 -0
  255. meep_gpu/test_absorber.py +311 -0
  256. meep_gpu/test_backends.py +311 -0
  257. meep_gpu/test_bytecode_cache_matches_source.py +117 -0
  258. meep_gpu/test_capability_records.py +667 -0
  259. meep_gpu/test_code_identity.py +148 -0
  260. meep_gpu/test_compile_cache_consistency.py +122 -0
  261. meep_gpu/test_conftest_guards.py +281 -0
  262. meep_gpu/test_cuda_certified_fused_products.py +1072 -0
  263. meep_gpu/test_cuda_complex_fused_hd_pair.py +464 -0
  264. meep_gpu/test_cuda_cylindrical_fused_hd_pair.py +268 -0
  265. meep_gpu/test_cuda_cylindrical_real_fused_hd_pair.py +284 -0
  266. meep_gpu/test_cuda_weld_contract.py +1760 -0
  267. meep_gpu/test_cylindrical.py +727 -0
  268. meep_gpu/test_cylindrical_near2far.py +626 -0
  269. meep_gpu/test_deposit_repair.py +1227 -0
  270. meep_gpu/test_deposit_repair_component_restriction.py +1867 -0
  271. meep_gpu/test_deposit_repair_linear_route.py +817 -0
  272. meep_gpu/test_deposit_repair_restriction_bench_record.py +156 -0
  273. meep_gpu/test_device_identity.py +159 -0
  274. meep_gpu/test_dft.py +3829 -0
  275. meep_gpu/test_diagonal_epsilon.py +180 -0
  276. meep_gpu/test_dispatch_contract.py +5493 -0
  277. meep_gpu/test_dispatch_expansion_refusal.py +1033 -0
  278. meep_gpu/test_dispatch_policy_uniformity.py +584 -0
  279. meep_gpu/test_dispatch_preference.py +1008 -0
  280. meep_gpu/test_dispatch_route_tables_are_complete.py +86 -0
  281. meep_gpu/test_dispatch_subnormal_gate.py +426 -0
  282. meep_gpu/test_dispersion.py +1057 -0
  283. meep_gpu/test_driver_integration.py +4886 -0
  284. meep_gpu/test_driver_vs_meep.py +5330 -0
  285. meep_gpu/test_fastpath.py +618 -0
  286. meep_gpu/test_field_reducers.py +633 -0
  287. meep_gpu/test_fields.py +1237 -0
  288. meep_gpu/test_folded_deposit_closure.py +192 -0
  289. meep_gpu/test_folded_fused_pair_routing.py +822 -0
  290. meep_gpu/test_from_meep.py +8694 -0
  291. meep_gpu/test_fused_pair_deposit_wiring.py +2543 -0
  292. meep_gpu/test_gate_provenance.py +336 -0
  293. meep_gpu/test_gaussian_beam.py +392 -0
  294. meep_gpu/test_grid_pml.py +1498 -0
  295. meep_gpu/test_harminv.py +1404 -0
  296. meep_gpu/test_meep_precision_notice.py +173 -0
  297. meep_gpu/test_metal_ade_update_p.py +332 -0
  298. meep_gpu/test_metal_artifact_provenance.py +1011 -0
  299. meep_gpu/test_metal_below_the_cut_fused_pairs.py +749 -0
  300. meep_gpu/test_metal_beta_complex_fused_hd_pair.py +571 -0
  301. meep_gpu/test_metal_beta_real_fused_hd_pair.py +546 -0
  302. meep_gpu/test_metal_bfast.py +803 -0
  303. meep_gpu/test_metal_bfast_fused_hd_pair.py +421 -0
  304. meep_gpu/test_metal_coefficient_pack.py +223 -0
  305. meep_gpu/test_metal_complex_conductive_fused_pair.py +412 -0
  306. meep_gpu/test_metal_complex_conductive_pml.py +284 -0
  307. meep_gpu/test_metal_complex_dispersive_update_e.py +195 -0
  308. meep_gpu/test_metal_complex_fields.py +818 -0
  309. meep_gpu/test_metal_complex_folded_offdiag_update_e.py +131 -0
  310. meep_gpu/test_metal_complex_fused_ade_chain.py +341 -0
  311. meep_gpu/test_metal_complex_fused_hd_pair.py +668 -0
  312. meep_gpu/test_metal_complex_fused_magnetic_pair.py +549 -0
  313. meep_gpu/test_metal_complex_no_pml_conductive.py +226 -0
  314. meep_gpu/test_metal_complex_no_pml_curl.py +220 -0
  315. meep_gpu/test_metal_complex_no_pml_offdiag_update_e.py +167 -0
  316. meep_gpu/test_metal_complex_no_pml_stored_e.py +162 -0
  317. meep_gpu/test_metal_conductive_fused_hd_pair.py +527 -0
  318. meep_gpu/test_metal_conductive_pml.py +174 -0
  319. meep_gpu/test_metal_cylindrical_complex.py +1132 -0
  320. meep_gpu/test_metal_cylindrical_complex_fused_hd_pair.py +378 -0
  321. meep_gpu/test_metal_cylindrical_complex_scan.py +367 -0
  322. meep_gpu/test_metal_cylindrical_fused_electric_pair.py +612 -0
  323. meep_gpu/test_metal_cylindrical_fused_magnetic_pair.py +453 -0
  324. meep_gpu/test_metal_cylindrical_real.py +721 -0
  325. meep_gpu/test_metal_cylindrical_real_fused_electric_pair.py +912 -0
  326. meep_gpu/test_metal_cylindrical_real_fused_hd_pair.py +397 -0
  327. meep_gpu/test_metal_cylindrical_real_fused_magnetic_pair.py +678 -0
  328. meep_gpu/test_metal_dispatch.py +1096 -0
  329. meep_gpu/test_metal_dispersive_update_e.py +147 -0
  330. meep_gpu/test_metal_environment.py +316 -0
  331. meep_gpu/test_metal_folded_beta.py +1043 -0
  332. meep_gpu/test_metal_folded_complex.py +1353 -0
  333. meep_gpu/test_metal_folded_complex_fused_hd_pair.py +566 -0
  334. meep_gpu/test_metal_folded_complex_fused_magnetic_pair.py +590 -0
  335. meep_gpu/test_metal_folded_dispersive_update_e.py +139 -0
  336. meep_gpu/test_metal_folded_fused_hd_pair.py +953 -0
  337. meep_gpu/test_metal_folded_fused_magnetic_pair.py +507 -0
  338. meep_gpu/test_metal_folded_fused_pair.py +425 -0
  339. meep_gpu/test_metal_folded_offdiag.py +1194 -0
  340. meep_gpu/test_metal_folded_offdiag_dispersive_update_e.py +128 -0
  341. meep_gpu/test_metal_fused_ade_chain.py +420 -0
  342. meep_gpu/test_metal_fused_dispersive_pair.py +331 -0
  343. meep_gpu/test_metal_fused_electric_pair.py +447 -0
  344. meep_gpu/test_metal_fused_hd_pair.py +1546 -0
  345. meep_gpu/test_metal_fused_hd_pair_nonlinear.py +420 -0
  346. meep_gpu/test_metal_fused_magnetic_pair.py +365 -0
  347. meep_gpu/test_metal_fused_pair_deposit_wiring.py +1177 -0
  348. meep_gpu/test_metal_held_fallback.py +706 -0
  349. meep_gpu/test_metal_kernels.py +624 -0
  350. meep_gpu/test_metal_no_pml_conductive.py +219 -0
  351. meep_gpu/test_metal_no_pml_constitutive.py +1470 -0
  352. meep_gpu/test_metal_no_pml_curl.py +197 -0
  353. meep_gpu/test_metal_no_pml_fused_electric_pairs.py +535 -0
  354. meep_gpu/test_metal_no_pml_stored_e.py +174 -0
  355. meep_gpu/test_metal_nonlinear_update_e.py +820 -0
  356. meep_gpu/test_metal_offdiag.py +798 -0
  357. meep_gpu/test_metal_offdiag_stencil_welds.py +505 -0
  358. meep_gpu/test_metal_planner_composition.py +646 -0
  359. meep_gpu/test_metal_residency_barrier.py +246 -0
  360. meep_gpu/test_metal_residency_ownership.py +913 -0
  361. meep_gpu/test_metal_residue_fused_pairs.py +348 -0
  362. meep_gpu/test_metal_runs.py +294 -0
  363. meep_gpu/test_metal_special_kz.py +999 -0
  364. meep_gpu/test_metal_symmetry.py +1190 -0
  365. meep_gpu/test_metal_weld_contract.py +1013 -0
  366. meep_gpu/test_package_boundary.py +441 -0
  367. meep_gpu/test_prefer_gpu.py +799 -0
  368. meep_gpu/test_regate_writers.py +1078 -0
  369. meep_gpu/test_sigma_lookup.py +916 -0
  370. meep_gpu/test_sigma_recovery.py +689 -0
  371. meep_gpu/test_smoothing.py +2389 -0
  372. meep_gpu/test_sources.py +2493 -0
  373. meep_gpu/test_stepping.py +3420 -0
  374. meep_gpu/test_subnormal_policy.py +2184 -0
  375. meep_gpu/test_sync_pass_channel.py +578 -0
  376. meep_gpu/test_tensor_epsilon.py +562 -0
  377. meep_gpu/test_triton_beta_fused_electric_pair.py +669 -0
  378. meep_gpu/test_triton_beta_fused_magnetic_pair.py +363 -0
  379. meep_gpu/test_triton_bfast.py +1339 -0
  380. meep_gpu/test_triton_bfast_fused_electric_pair.py +657 -0
  381. meep_gpu/test_triton_bfast_fused_magnetic_pair.py +358 -0
  382. meep_gpu/test_triton_certified_fused_products.py +1409 -0
  383. meep_gpu/test_triton_complex_ade.py +291 -0
  384. meep_gpu/test_triton_complex_beta_fused_electric_pair.py +391 -0
  385. meep_gpu/test_triton_complex_beta_fused_magnetic_pair.py +407 -0
  386. meep_gpu/test_triton_complex_conductive_fused_pair.py +512 -0
  387. meep_gpu/test_triton_complex_fields.py +2900 -0
  388. meep_gpu/test_triton_complex_fused_ade_chain.py +700 -0
  389. meep_gpu/test_triton_complex_fused_electric_pair.py +856 -0
  390. meep_gpu/test_triton_complex_fused_hd_pair.py +747 -0
  391. meep_gpu/test_triton_complex_fused_magnetic_pair.py +857 -0
  392. meep_gpu/test_triton_complex_no_pml_conductive.py +301 -0
  393. meep_gpu/test_triton_complex_no_pml_curl.py +699 -0
  394. meep_gpu/test_triton_complex_no_pml_stored_e.py +394 -0
  395. meep_gpu/test_triton_complex_offdiag_update_e.py +306 -0
  396. meep_gpu/test_triton_conductive_fused_electric_pair.py +792 -0
  397. meep_gpu/test_triton_conductivity.py +628 -0
  398. meep_gpu/test_triton_cylindrical.py +669 -0
  399. meep_gpu/test_triton_cylindrical_complex.py +2523 -0
  400. meep_gpu/test_triton_cylindrical_composition.py +253 -0
  401. meep_gpu/test_triton_cylindrical_fused_electric_pair.py +695 -0
  402. meep_gpu/test_triton_cylindrical_fused_hd_pair.py +578 -0
  403. meep_gpu/test_triton_cylindrical_fused_magnetic_pair.py +440 -0
  404. meep_gpu/test_triton_cylindrical_real_fused_electric_pair.py +760 -0
  405. meep_gpu/test_triton_cylindrical_real_fused_hd_pair.py +675 -0
  406. meep_gpu/test_triton_cylindrical_real_fused_magnetic_pair.py +529 -0
  407. meep_gpu/test_triton_device_identity.py +142 -0
  408. meep_gpu/test_triton_dispersive_fused_pair.py +365 -0
  409. meep_gpu/test_triton_dispersive_update_e.py +682 -0
  410. meep_gpu/test_triton_folded_beta_complex_fused_magnetic_pair.py +698 -0
  411. meep_gpu/test_triton_folded_beta_complex_fused_pair.py +649 -0
  412. meep_gpu/test_triton_folded_beta_fused_electric_pair.py +617 -0
  413. meep_gpu/test_triton_folded_beta_fused_magnetic_pair.py +546 -0
  414. meep_gpu/test_triton_folded_complex.py +3538 -0
  415. meep_gpu/test_triton_folded_complex_fused_magnetic_pair.py +1377 -0
  416. meep_gpu/test_triton_folded_complex_fused_pair.py +1349 -0
  417. meep_gpu/test_triton_folded_complex_offdiag_admission.py +543 -0
  418. meep_gpu/test_triton_folded_dispersive_fused_pair.py +873 -0
  419. meep_gpu/test_triton_folded_dispersive_update_e.py +460 -0
  420. meep_gpu/test_triton_folded_fused_hd_pair.py +810 -0
  421. meep_gpu/test_triton_folded_fused_magnetic_pair.py +1088 -0
  422. meep_gpu/test_triton_folded_fused_pair.py +1129 -0
  423. meep_gpu/test_triton_folded_offdiag_dispersive_update_e.py +385 -0
  424. meep_gpu/test_triton_folded_offdiag_fused_ade_chain.py +987 -0
  425. meep_gpu/test_triton_folded_offdiag_fused_electric_pair.py +604 -0
  426. meep_gpu/test_triton_folded_offdiag_update_e.py +1217 -0
  427. meep_gpu/test_triton_fused_ade_chain.py +665 -0
  428. meep_gpu/test_triton_fused_ade_state.py +256 -0
  429. meep_gpu/test_triton_fused_dispersive_chain.py +489 -0
  430. meep_gpu/test_triton_fused_hd_pair.py +827 -0
  431. meep_gpu/test_triton_hd_tail_products.py +650 -0
  432. meep_gpu/test_triton_kernels.py +1580 -0
  433. meep_gpu/test_triton_no_pml.py +819 -0
  434. meep_gpu/test_triton_no_pml_ade.py +553 -0
  435. meep_gpu/test_triton_no_pml_conductive.py +686 -0
  436. meep_gpu/test_triton_no_pml_constitutive.py +2310 -0
  437. meep_gpu/test_triton_no_pml_fused_electric_pair.py +775 -0
  438. meep_gpu/test_triton_no_pml_stored_e.py +515 -0
  439. meep_gpu/test_triton_nonlinear_fused_magnetic_pair.py +292 -0
  440. meep_gpu/test_triton_nonlinear_update_e.py +1187 -0
  441. meep_gpu/test_triton_offdiag_fused_electric_pair.py +662 -0
  442. meep_gpu/test_triton_offdiag_update_e.py +1041 -0
  443. meep_gpu/test_triton_planner_composition.py +4064 -0
  444. meep_gpu/test_triton_residual_group_wiring.py +503 -0
  445. meep_gpu/test_triton_residual_probe_discipline.py +401 -0
  446. meep_gpu/test_triton_source_seams.py +261 -0
  447. meep_gpu/test_triton_special_kz.py +1142 -0
  448. meep_gpu/test_triton_symmetry.py +548 -0
  449. meep_gpu/test_triton_symmetry_composition.py +252 -0
  450. meep_gpu/test_triton_weld_contract.py +2365 -0
  451. meep_gpu/test_uncertified_opt_in.py +1032 -0
  452. meep_gpu/test_version.py +87 -0
  453. meep_gpu/test_weld_record_walk.py +504 -0
  454. meep_gpu/test_withdraw_hoist.py +600 -0
  455. meep_gpu/triton_kernels/__init__.py +959 -0
  456. meep_gpu/triton_kernels/beta_complex_fused_hd_pair.py +1376 -0
  457. meep_gpu/triton_kernels/beta_fused_electric_pair.py +755 -0
  458. meep_gpu/triton_kernels/beta_fused_magnetic_pair.py +648 -0
  459. meep_gpu/triton_kernels/beta_real_fused_hd_pair.py +1118 -0
  460. meep_gpu/triton_kernels/bfast_curl.py +1032 -0
  461. meep_gpu/triton_kernels/bfast_fused_electric_pair.py +782 -0
  462. meep_gpu/triton_kernels/bfast_fused_magnetic_pair.py +697 -0
  463. meep_gpu/triton_kernels/complex_ade.py +400 -0
  464. meep_gpu/triton_kernels/complex_beta_fused_electric_pair.py +880 -0
  465. meep_gpu/triton_kernels/complex_beta_fused_magnetic_pair.py +838 -0
  466. meep_gpu/triton_kernels/complex_conductive_fused_pair.py +892 -0
  467. meep_gpu/triton_kernels/complex_fields.py +2295 -0
  468. meep_gpu/triton_kernels/complex_fused_ade_chain.py +1118 -0
  469. meep_gpu/triton_kernels/complex_fused_electric_pair.py +1038 -0
  470. meep_gpu/triton_kernels/complex_fused_hd_pair.py +1558 -0
  471. meep_gpu/triton_kernels/complex_fused_magnetic_pair.py +867 -0
  472. meep_gpu/triton_kernels/complex_no_pml_conductive.py +497 -0
  473. meep_gpu/triton_kernels/complex_no_pml_curl.py +415 -0
  474. meep_gpu/triton_kernels/complex_no_pml_stored_e.py +432 -0
  475. meep_gpu/triton_kernels/complex_offdiag_update_e.py +639 -0
  476. meep_gpu/triton_kernels/conductive_bfast_fused_hd_pair.py +1255 -0
  477. meep_gpu/triton_kernels/conductive_fused_electric_pair.py +868 -0
  478. meep_gpu/triton_kernels/conductivity.py +810 -0
  479. meep_gpu/triton_kernels/coverage.py +761 -0
  480. meep_gpu/triton_kernels/cylindrical_complex.py +1718 -0
  481. meep_gpu/triton_kernels/cylindrical_fused_electric_pair.py +1284 -0
  482. meep_gpu/triton_kernels/cylindrical_fused_hd_pair.py +882 -0
  483. meep_gpu/triton_kernels/cylindrical_fused_magnetic_pair.py +1071 -0
  484. meep_gpu/triton_kernels/cylindrical_real_fused_electric_pair.py +750 -0
  485. meep_gpu/triton_kernels/cylindrical_real_fused_hd_pair.py +745 -0
  486. meep_gpu/triton_kernels/cylindrical_real_fused_magnetic_pair.py +744 -0
  487. meep_gpu/triton_kernels/cylindrical_triton.py +983 -0
  488. meep_gpu/triton_kernels/dispersive_fused_pair.py +451 -0
  489. meep_gpu/triton_kernels/dispersive_update_e.py +719 -0
  490. meep_gpu/triton_kernels/fingerprints.json +8359 -0
  491. meep_gpu/triton_kernels/folded_beta_complex_fused_magnetic_pair.py +1470 -0
  492. meep_gpu/triton_kernels/folded_beta_complex_fused_pair.py +1764 -0
  493. meep_gpu/triton_kernels/folded_beta_fused_electric_pair.py +1031 -0
  494. meep_gpu/triton_kernels/folded_beta_fused_magnetic_pair.py +919 -0
  495. meep_gpu/triton_kernels/folded_complex.py +3244 -0
  496. meep_gpu/triton_kernels/folded_complex_fused_hd_pair.py +1187 -0
  497. meep_gpu/triton_kernels/folded_complex_fused_magnetic_pair.py +1747 -0
  498. meep_gpu/triton_kernels/folded_complex_fused_pair.py +1905 -0
  499. meep_gpu/triton_kernels/folded_dispersive_fused_pair.py +1200 -0
  500. meep_gpu/triton_kernels/folded_dispersive_update_e.py +340 -0
  501. meep_gpu/triton_kernels/folded_fused_hd_pair.py +991 -0
  502. meep_gpu/triton_kernels/folded_fused_magnetic_pair.py +1171 -0
  503. meep_gpu/triton_kernels/folded_fused_pair.py +1408 -0
  504. meep_gpu/triton_kernels/folded_offdiag_dispersive_update_e.py +587 -0
  505. meep_gpu/triton_kernels/folded_offdiag_fused_ade_chain.py +1238 -0
  506. meep_gpu/triton_kernels/folded_offdiag_fused_electric_pair.py +1124 -0
  507. meep_gpu/triton_kernels/folded_offdiag_update_e.py +1396 -0
  508. meep_gpu/triton_kernels/fused_ade_chain.py +1299 -0
  509. meep_gpu/triton_kernels/fused_ade_state.py +315 -0
  510. meep_gpu/triton_kernels/fused_dispersive_chain.py +673 -0
  511. meep_gpu/triton_kernels/fused_hd_pair.py +1200 -0
  512. meep_gpu/triton_kernels/kernels.py +728 -0
  513. meep_gpu/triton_kernels/launch.py +4402 -0
  514. meep_gpu/triton_kernels/no_pml.py +819 -0
  515. meep_gpu/triton_kernels/no_pml_ade.py +413 -0
  516. meep_gpu/triton_kernels/no_pml_conductive.py +943 -0
  517. meep_gpu/triton_kernels/no_pml_constitutive.py +889 -0
  518. meep_gpu/triton_kernels/no_pml_fused_electric_pair.py +1043 -0
  519. meep_gpu/triton_kernels/no_pml_stored_e.py +759 -0
  520. meep_gpu/triton_kernels/nonlinear_fused_hd_pair.py +473 -0
  521. meep_gpu/triton_kernels/nonlinear_fused_magnetic_pair.py +392 -0
  522. meep_gpu/triton_kernels/nonlinear_update_e.py +1384 -0
  523. meep_gpu/triton_kernels/offdiag_fused_electric_pair.py +994 -0
  524. meep_gpu/triton_kernels/offdiag_scratch_weld.py +366 -0
  525. meep_gpu/triton_kernels/offdiag_update_e.py +958 -0
  526. meep_gpu/triton_kernels/special_kz.py +1637 -0
  527. meep_gpu/triton_kernels/symmetry.py +1190 -0
  528. meep_gpu/triton_kernels/timing_cc86.json +2375 -0
  529. meep_gpu/triton_kernels/timing_cc86.report.txt +93 -0
  530. meep_gpu/weld_record_walk.py +646 -0
  531. meep_gpu/withdraw_hoist.py +581 -0
  532. meep_gpu-0.9.2.dist-info/METADATA +652 -0
  533. meep_gpu-0.9.2.dist-info/RECORD +537 -0
  534. meep_gpu-0.9.2.dist-info/WHEEL +5 -0
  535. meep_gpu-0.9.2.dist-info/licenses/LICENSE +339 -0
  536. meep_gpu-0.9.2.dist-info/licenses/NOTICE +21 -0
  537. meep_gpu-0.9.2.dist-info/top_level.txt +1 -0
@@ -0,0 +1,675 @@
1
+ """The conductive PML ``step_D`` welded into the ORDINARY ``update_E``, both packed.
2
+
3
+ THE SECOND of the two cells the 2026-09-01 board scored ``UNFUSABLE ON METAL`` that
4
+ the SHIPPED :mod:`.coefficient_pack` technique closes — and the widest pack in the
5
+ tree: BOTH halves' coefficient vectors ride one buffer::
6
+
7
+ D->E (conductive PML curl, ordinary) tests:TestAdjointSolver.test_damping
8
+ conductive_pml.curl 24p + shaders.constitutive_E 18p, sharing 3
9
+ -> 39 pointers, ceiling 30 UNFUSABLE ON METAL (over by 9)
10
+
11
+ CROSS-BACKEND FACT, from the residue audit: the board's ``belongs to the CUDA
12
+ track`` position is unfulfilled — CUDA's same cell is priced POINTWISE-BUILDABLE
13
+ and serves 0 (no conductive-curl electric pair with a deposit carry exists there)
14
+ — so before this module NO backend served this instance.
15
+
16
+ WHAT MOVED IS NOT THE CEILING. One pack holds the TWELVE disjointly-named
17
+ read-only vectors of both halves — the curl's ``kmx``/``sinvx``/... and the
18
+ constitutive's ``kp0``/``km0``/... — with twelve element offsets in ``Params``,
19
+ saving eleven pointers: 39 -> 28, bound at :data:`PACKED_BINDINGS` = 29. The six
20
+ read-only conductivity VOLUMES (``cf``/``ci``) also meet the pack's
21
+ read-only-only rule but stay separate: the pack's members are PER-AXIS VECTORS
22
+ whose lengths are grid extents, and folding three-dimensional volumes in beside
23
+ them would make the offsets a mixed-geometry table for no binding need — 29 is
24
+ already two under the ceiling. The device-written ``f``/``u``/``c``/``w`` volumes
25
+ rightly stay unpacked (the read-only rule), as does everything the repair writes.
26
+
27
+ THE CURL HALF IS LIFTED WHOLE AND UNEDITED — decode, ghosts, loads, curl, mask,
28
+ per-target four-branch conductive tails, every in-place store — and the wall clear
29
+ plus the seam then work on a RELOAD: after the certified text stores each stepped
30
+ D component, the weld re-reads its own cell (the same thread, the value it just
31
+ wrote), masks the wall on the register, stores the masked value back, and hands
32
+ the register to the constitutive half. That is byte-for-byte the driver's own
33
+ order (step_D stores; zero_metal_D overwrites the wall plane; update_E reads), it
34
+ keeps the certified conductive tail text at ZERO edits, and the reload is the
35
+ declared-equivalence pattern the shipped gates already measure ("seam reloads the
36
+ flux it just stored").
37
+
38
+ THE SEAM'S CLAUSES. The one corpus row declares an ELECTRIC source, so
39
+ :data:`CARRIES_DEPOSIT_REPAIR` is True (split-field path — the absorber is
40
+ ACTIVE). The conductive whole-volume-rescale hazard that priced the no-PML
41
+ conductive cell at 0 of 2 is consulted here through the SAME clause, imported from
42
+ :mod:`.no_pml_conductive_fused_electric_pair` — one home — and with the driver's
43
+ sparse per-deposit-cell rescale landed that clause refuses only a scaled source
44
+ that publishes no deposit table, which no in-tree electric source class is.
45
+
46
+ NOT WIRED AS AN ARM; reached through ``launch.FUSED_PAIR_ARMS`` instead.
47
+ """
48
+
49
+ # Derived from MEEP (https://github.com/NanoComp/meep).
50
+ # Copyright (C) 2005-2025 Massachusetts Institute of Technology and MEEP contributors.
51
+ # SPDX-License-Identifier: GPL-2.0-or-later
52
+
53
+ from __future__ import annotations
54
+
55
+ from typing import Any, Dict, List, Mapping, Optional, Sequence, Tuple
56
+
57
+ from ..triton_kernels.conductivity import conductive_targets
58
+ from ..triton_kernels.coverage import Coverage
59
+ from . import coefficient_pack, conductive_pml, shaders, templates
60
+ from .coverage import constitutive_coverage, zero_metal_axes
61
+ from .device import MAX_BUFFER_BINDINGS, Residency, compile_source
62
+ from .fused_electric_pair import (
63
+ _BODY_ANCHOR,
64
+ certified_constitutive_body,
65
+ zero_metal_mask,
66
+ )
67
+ from .no_pml_conductive_fused_electric_pair import (
68
+ _scaled_conductive_injection_reasons,
69
+ )
70
+ from .plans import KernelPlan
71
+ from .. import deposit_repair as _deposit_repair
72
+
73
+ #: Does this product bracket its fused launch with the deposit repair? TRUE, and on
74
+ #: this cell the flag IS the row: the one corpus instance declares an ELECTRIC
75
+ #: source inside the seam. The repair path is the split-field default — the curl
76
+ #: half requires an ACTIVE absorber, so the recurrence the seam inverts is always
77
+ #: ``_apply_constitutive_pml``'s.
78
+ CARRIES_DEPOSIT_REPAIR = True
79
+
80
+ FAMILY = "conductive_fused_electric_pair"
81
+
82
+ #: The slot this arm holds a row on, and the driver passes one launch performs.
83
+ SLOT = "step_D"
84
+ REPLACES: Tuple[str, ...] = ("step_D", "zero_metal_D", "update_E")
85
+
86
+ #: BOTH halves' read-only per-axis coefficient vectors, IN PACK ORDER: the curl's
87
+ #: six, then the constitutive's six. Disjointly named, so one prologue re-creates
88
+ #: all twelve under their certified names.
89
+ PACKED_VECTORS: Tuple[str, ...] = ("kmx", "sinvx", "kmy", "sinvy", "kmz", "sinvz",
90
+ "kp0", "km0", "kp1", "km1", "kp2", "km2")
91
+
92
+ #: THREE BINDING COUNTS, ALL COMPILED BY THE GATE:
93
+ #:
94
+ #: * :data:`SEPARATE_SCALAR_BINDINGS` — 39 pointers + 5 separate scalars.
95
+ #: * :data:`UNPACKED_POINTER_BINDINGS` — 39 pointers + one packed ``Params&``: the
96
+ #: shape the board's ``UNFUSABLE ON METAL`` verdict priced, REFUSED at 40
97
+ #: bindings against 31 (over by nine).
98
+ #: * :data:`PACKED_BINDINGS` — the shipped shape, 28 pointers plus ``Params``.
99
+ SEPARATE_SCALAR_BINDINGS = 44
100
+ UNPACKED_POINTER_BINDINGS = 40
101
+ PACKED_BINDINGS = 29
102
+
103
+ #: The pointer counts, spelled apart from the binding counts.
104
+ PACKED_POINTERS = 28
105
+ UNPACKED_POINTERS = 39
106
+
107
+ if PACKED_BINDINGS > MAX_BUFFER_BINDINGS: # pragma: no cover - a design invariant
108
+ raise RuntimeError(
109
+ f"the conductive fused electric pair binds {PACKED_BINDINGS} buffers and "
110
+ f"Metal's ceiling on this toolchain is {MAX_BUFFER_BINDINGS}")
111
+
112
+ __all__ = [
113
+ "CARRIES_DEPOSIT_REPAIR", "FAMILY", "PACKED_BINDINGS", "PACKED_POINTERS",
114
+ "PACKED_VECTORS", "REPLACES", "SEPARATE_SCALAR_BINDINGS", "SLOT",
115
+ "UNPACKED_POINTERS", "UNPACKED_POINTER_BINDINGS",
116
+ "MetalConductiveFusedElectricPairPlan", "certified_conductive_curl_body",
117
+ "compile_conductive_fused_electric_pair",
118
+ "conductive_fused_electric_pair_source",
119
+ "metal_conductive_fused_electric_pair_coverage",
120
+ "plan_metal_conductive_fused_electric_pair",
121
+ "refuted_separate_scalar_source", "refuted_unpacked_pointer_source",
122
+ "register_arms",
123
+ ]
124
+
125
+
126
+ # ---------------------------------------------------------------------------
127
+ # The source
128
+ # ---------------------------------------------------------------------------
129
+
130
+ _TEMPLATE = r"""
131
+ #include <metal_stdlib>
132
+ using namespace metal;
133
+
134
+ __CONTRACT__
135
+
136
+ struct Params {
137
+ uint nx; uint ny; uint nz; uint n_elem; float dtdx;
138
+ __PACK_FIELDS__
139
+ };
140
+
141
+ kernel void conductive_fused_electric_pair_step(
142
+ device float* f0 [[buffer(0)]],
143
+ device float* f1 [[buffer(1)]],
144
+ device float* f2 [[buffer(2)]],
145
+ device float* u0 [[buffer(3)]],
146
+ device float* u1 [[buffer(4)]],
147
+ device float* u2 [[buffer(5)]],
148
+ device float* c0 [[buffer(6)]],
149
+ device float* c1 [[buffer(7)]],
150
+ device float* c2 [[buffer(8)]],
151
+ device const float* cf0 [[buffer(9)]],
152
+ device const float* cf1 [[buffer(10)]],
153
+ device const float* cf2 [[buffer(11)]],
154
+ device const float* ci0 [[buffer(12)]],
155
+ device const float* ci1 [[buffer(13)]],
156
+ device const float* ci2 [[buffer(14)]],
157
+ device const float* g0 [[buffer(15)]],
158
+ device const float* g1 [[buffer(16)]],
159
+ device const float* g2 [[buffer(17)]],
160
+ device float* e0 [[buffer(18)]],
161
+ device float* e1 [[buffer(19)]],
162
+ device float* e2 [[buffer(20)]],
163
+ device float* w0 [[buffer(21)]],
164
+ device float* w1 [[buffer(22)]],
165
+ device float* w2 [[buffer(23)]],
166
+ device const float* ie0 [[buffer(24)]],
167
+ device const float* ie1 [[buffer(25)]],
168
+ device const float* ie2 [[buffer(26)]],
169
+ device const float* cpack [[buffer(27)]],
170
+ constant Params& prm [[buffer(28)]],
171
+ uint idx [[thread_position_in_grid]])
172
+ {
173
+ // THE FIVE SCALARS AND THE TWELVE PACKED VECTORS ARE UNPACKED INTO THE
174
+ // CERTIFIED BODIES' OWN NAMES, once, before any of the lifted text runs.
175
+ // Everything below this line is then character-for-character what
176
+ // `conductive_pml.conductive_pml_curl_source` and `shaders.constitutive_source`
177
+ // emit, plus the wall clear on a reload and the one seam substitution.
178
+ uint nx = prm.nx, ny = prm.ny, nz = prm.nz, n_elem = prm.n_elem;
179
+ float dtdx = prm.dtdx;
180
+
181
+ // --- BOTH halves' coefficient vectors, one allocation, twelve offsets -------
182
+ // READ-ONLY: nothing on the device writes `cpack`. The conductivity volumes
183
+ // cf/ci are read-only too but are whole VOLUMES, not per-axis vectors, and
184
+ // keep their own bindings; f/u/c/w are device-written and may never enter a
185
+ // pack at all.
186
+ __PACK_PROLOGUE__
187
+
188
+ __BODY__
189
+ }
190
+ """
191
+
192
+
193
+ def certified_conductive_curl_body(codes: Sequence[int],
194
+ conductive: Sequence[bool],
195
+ contract: str = shaders.CONTRACT_OFF) -> str:
196
+ """The conductive PML ``step_D`` curl kernel's BODY, lifted from its own emitter.
197
+
198
+ Not a transcription: this is
199
+ :func:`.conductive_pml.conductive_pml_curl_source`'s own output with the
200
+ ``#include``/signature preamble and the closing brace removed — INCLUDING every
201
+ per-target four-branch tail and every in-place store, unedited. ``backward`` is
202
+ True and never a parameter: this is the D seam, and the certified emitter is
203
+ the one home of the branch structure.
204
+ """
205
+ source = conductive_pml.conductive_pml_curl_source(codes, True, conductive,
206
+ contract)
207
+ if _BODY_ANCHOR not in source:
208
+ raise AssertionError(
209
+ "the certified conductive PML curl source no longer carries the body "
210
+ "anchor; this family lifts that body and would otherwise splice a "
211
+ "truncated kernel")
212
+ body = source.split(_BODY_ANCHOR, 1)[1]
213
+ if not body.endswith("}\n"):
214
+ raise AssertionError(
215
+ "the certified conductive PML curl source does not end with '}'")
216
+ return body[: -len("}\n")]
217
+
218
+
219
+ #: Per target, the certified tail's FINAL store text for each arm — the anchors the
220
+ #: splice requires so a restructured emitter reaches this family as an
221
+ #: AssertionError rather than as a silently un-stored component.
222
+ def _tail_store_anchors(index: int, conductive: bool) -> Tuple[str, ...]:
223
+ if conductive:
224
+ return (
225
+ f"c{index}[ii] = c{index}_new; u{index}[ii] = u{index}_new; "
226
+ f"f{index}[ii] = f{index}_new;",
227
+ f" f{index}[ii] = ((f{index}_previous * cf{index}[ii]) - "
228
+ f"curl{index}) * ci{index}[ii];",
229
+ )
230
+ return (f" u{index}[ii] = u{index}_new;",
231
+ f" f{index}[ii] = f{index}_new;")
232
+
233
+
234
+ def conductive_fused_electric_pair_source(
235
+ codes: Sequence[int], conductive: Sequence[bool],
236
+ zero_metal: Sequence[bool], contract: str = shaders.CONTRACT_OFF) -> str:
237
+ """One specialised fused source: (boundaries, sigma flags, walls, contraction).
238
+
239
+ THE CURL TEXT IS UNEDITED; the weld appends a reload-mask-store epilogue and
240
+ then the certified constitutive half with the three-line seam substitution
241
+ reading the reloaded registers.
242
+ """
243
+ codes = tuple(int(code) for code in codes)
244
+ if len(codes) != 3:
245
+ raise ValueError(f"codes must be a per-axis triple, got {codes!r}")
246
+ conductive = tuple(bool(flag) for flag in conductive)
247
+ if len(conductive) != 3:
248
+ raise ValueError(f"conductive must be a per-axis triple, got {conductive!r}")
249
+ zero_metal = tuple(bool(value) for value in zero_metal)
250
+ if len(zero_metal) != 3:
251
+ raise ValueError(f"zero_metal must be a per-axis triple, got {zero_metal!r}")
252
+
253
+ curl = certified_conductive_curl_body(codes, conductive, contract)
254
+ for index in range(3):
255
+ for anchor in _tail_store_anchors(index, conductive[index]):
256
+ if anchor not in curl:
257
+ raise AssertionError(
258
+ f"the certified conductive tail for target {index} no longer "
259
+ f"carries {anchor!r}; the reload epilogue would read a value "
260
+ f"nothing stored")
261
+
262
+ epilogue = "\n".join((
263
+ "",
264
+ " // --- zero_metal_D on a RELOAD (stepping._zero_metal:2232) ----------",
265
+ " // The certified tails above stored every stepped D in place; this",
266
+ " // thread re-reads its OWN cell (the value it just wrote), masks the",
267
+ " // wall on the register, stores the masked value back, and hands the",
268
+ " // register to the constitutive half. Same bytes, driver order:",
269
+ " // step_D stores, zero_metal_D overwrites, update_E reads.",
270
+ " float v0 = f0[ii];",
271
+ " float v1 = f1[ii];",
272
+ " float v2 = f2[ii];",
273
+ zero_metal_mask(zero_metal),
274
+ " f0[ii] = v0; f1[ii] = v1; f2[ii] = v2;",
275
+ "",
276
+ ))
277
+
278
+ electric = certified_constitutive_body(contract)
279
+ # THE SEAM — the plain D/E weld's three lines, unchanged.
280
+ for target in range(3):
281
+ old = f" float src{target} = g{target}[ii] * ie{target}[ii];\n"
282
+ if old not in electric:
283
+ raise AssertionError(
284
+ f"the certified E constitutive body no longer reads its source as "
285
+ f"{old.strip()!r}; the seam has no anchor")
286
+ electric = electric.replace(
287
+ old,
288
+ f" // THE SEAM: the register the wall clear just settled, not a "
289
+ f"reload of D{'xyz'[target]}.\n"
290
+ f" float src{target} = v{target} * ie{target}[ii];\n")
291
+ # THE CURL'S `g` IS H AND THE CONSTITUTIVE'S `g` WAS D.
292
+ for target in range(3):
293
+ if f"g{target}[" in electric:
294
+ raise AssertionError(
295
+ f"the lifted E constitutive half still reads g{target}, which in "
296
+ f"the fused signature is H{'xyz'[target]} and not D{'xyz'[target]}")
297
+
298
+ body = "".join((
299
+ curl,
300
+ epilogue,
301
+ "\n // --- update_E (stepping.update_E / _apply_constitutive_pml:2083) --\n",
302
+ electric,
303
+ ))
304
+ return templates.substitute(_TEMPLATE, {
305
+ "__CONTRACT__": templates.contraction_pragma(contract),
306
+ "__PACK_FIELDS__": coefficient_pack.params_fields(PACKED_VECTORS),
307
+ "__PACK_PROLOGUE__": coefficient_pack.prologue("cpack", PACKED_VECTORS),
308
+ "__BODY__": body,
309
+ })
310
+
311
+
312
+ def compile_conductive_fused_electric_pair(
313
+ codes: Sequence[int], conductive: Sequence[bool],
314
+ zero_metal: Sequence[bool], contract: str = shaders.CONTRACT_OFF) -> Any:
315
+ """The specialised entry point for one (boundaries, sigma flags, walls, mode)."""
316
+ return compile_source(conductive_fused_electric_pair_source(
317
+ codes, conductive, zero_metal,
318
+ contract)).conductive_fused_electric_pair_step
319
+
320
+
321
+ #: The pointer names of the UNPACKED fused signature, in the order the two
322
+ #: certified halves declare them.
323
+ _UNPACKED_WRITTEN: Tuple[str, ...] = ("f0", "f1", "f2", "u0", "u1", "u2",
324
+ "c0", "c1", "c2",
325
+ "e0", "e1", "e2", "w0", "w1", "w2")
326
+ _UNPACKED_READ: Tuple[str, ...] = ("cf0", "cf1", "cf2", "ci0", "ci1", "ci2",
327
+ "g0", "g1", "g2",
328
+ "ie0", "ie1", "ie2",
329
+ "kmx", "sinvx", "kmy", "sinvy", "kmz", "sinvz",
330
+ "kp0", "km0", "kp1", "km1", "kp2", "km2")
331
+
332
+
333
+ def _touching_body(written: Sequence[str], read: Sequence[str], guard: str,
334
+ scale: str) -> List[str]:
335
+ touch = " + ".join(f"{name}[0]" for name in read)
336
+ return [f" {guard}",
337
+ f" float touch = {touch};",
338
+ f" f0[idx] = f0[idx] + touch;",
339
+ *(f" {name}[idx] = {name}[idx] * {scale};" for name in written)]
340
+
341
+
342
+ def refuted_unpacked_pointer_source(contract: str = shaders.CONTRACT_OFF) -> str:
343
+ """The 40-binding signature this platform REFUSES — 39 pointers plus ``Params``.
344
+
345
+ THIS IS THE MEASUREMENT THE PACK EXISTS FOR: the shape the board's verdict
346
+ priced, over the ceiling by nine.
347
+ """
348
+ lines: List[str] = []
349
+ slot = 0
350
+ for name in _UNPACKED_WRITTEN:
351
+ lines.append(f" device float* {name:<8}[[buffer({slot})]],")
352
+ slot += 1
353
+ for name in _UNPACKED_READ:
354
+ lines.append(f" device const float* {name:<8}[[buffer({slot})]],")
355
+ slot += 1
356
+ if slot != UNPACKED_POINTERS: # pragma: no cover - arithmetic guard
357
+ raise AssertionError((slot, UNPACKED_POINTERS))
358
+ lines.append(f" constant Params& prm [[buffer({slot})]],")
359
+ slot += 1
360
+ if slot != UNPACKED_POINTER_BINDINGS: # pragma: no cover - arithmetic guard
361
+ raise AssertionError((slot, UNPACKED_POINTER_BINDINGS))
362
+ return "\n".join((
363
+ "#include <metal_stdlib>",
364
+ "using namespace metal;",
365
+ "",
366
+ templates.contraction_pragma(contract),
367
+ "",
368
+ "struct Params { uint nx; uint ny; uint nz; uint n_elem; float dtdx; };",
369
+ "",
370
+ "kernel void refuted_unpacked_pointers(",
371
+ *lines,
372
+ " uint idx [[thread_position_in_grid]])",
373
+ "{",
374
+ *_touching_body(_UNPACKED_WRITTEN, _UNPACKED_READ,
375
+ "if (idx >= prm.n_elem) { return; }",
376
+ "prm.dtdx"),
377
+ "}",
378
+ "",
379
+ ))
380
+
381
+
382
+ def refuted_separate_scalar_source(contract: str = shaders.CONTRACT_OFF) -> str:
383
+ """The 44-binding separate-scalar signature this platform REFUSES."""
384
+ lines: List[str] = []
385
+ slot = 0
386
+ for name in _UNPACKED_WRITTEN:
387
+ lines.append(f" device float* {name:<8}[[buffer({slot})]],")
388
+ slot += 1
389
+ for name in _UNPACKED_READ:
390
+ lines.append(f" device const float* {name:<8}[[buffer({slot})]],")
391
+ slot += 1
392
+ for name in ("nx", "ny", "nz", "n_elem"):
393
+ lines.append(f" constant uint& {name:<8}[[buffer({slot})]],")
394
+ slot += 1
395
+ lines.append(f" constant float& dtdx [[buffer({slot})]],")
396
+ slot += 1
397
+ if slot != SEPARATE_SCALAR_BINDINGS: # pragma: no cover - arithmetic guard
398
+ raise AssertionError((slot, SEPARATE_SCALAR_BINDINGS))
399
+ return "\n".join((
400
+ "#include <metal_stdlib>",
401
+ "using namespace metal;",
402
+ "",
403
+ templates.contraction_pragma(contract),
404
+ "",
405
+ "kernel void refuted_separate_scalars(",
406
+ *lines,
407
+ " uint idx [[thread_position_in_grid]])",
408
+ "{",
409
+ *_touching_body(_UNPACKED_WRITTEN, _UNPACKED_READ,
410
+ "if (idx >= n_elem) { return; }", "dtdx"),
411
+ "}",
412
+ "",
413
+ ))
414
+
415
+
416
+ # ---------------------------------------------------------------------------
417
+ # Coverage
418
+ # ---------------------------------------------------------------------------
419
+
420
+ def metal_conductive_fused_electric_pair_coverage(
421
+ fields: Any, pml: Any, sources: Any = None,
422
+ residency: Any = None) -> Coverage:
423
+ """May ONE dispatch span conductive ``step_D`` -> wall -> ``update_E``?
424
+
425
+ The conjunction of the two halves' OWN shipped predicates plus the seam
426
+ clauses:
427
+
428
+ * :func:`.conductive_pml.metal_conductive_pml_curl_coverage` on ``step_D``;
429
+ * :func:`.coverage.constitutive_coverage` on side ``"E"`` — the ``ordinary``
430
+ arm's own body, which is what the board's cell names.
431
+ """
432
+ reasons: List[str] = []
433
+
434
+ curl = conductive_pml.metal_conductive_pml_curl_coverage(
435
+ fields, pml, "step_D", residency)
436
+ if not curl.covered:
437
+ reasons.extend(f"curl half: {reason}" for reason in curl.reasons)
438
+ electric = constitutive_coverage(fields, pml, "E", residency)
439
+ if not electric.covered:
440
+ reasons.extend(f"constitutive half: {reason}" for reason in electric.reasons)
441
+
442
+ # THE SOURCE SEAM. An ELECTRIC source is injected BETWEEN the two halves — on a
443
+ # conductive run through _inject_electric_through_conductivity (driver.py:3306).
444
+ reasons.extend(_deposit_repair.seam_source_reasons(
445
+ fields, sources, 'D',
446
+ undeclared=(
447
+ "the source set was not declared: this predicate cannot infer an empty "
448
+ "electric source seam from Fields"
449
+ ),
450
+ refusal=lambda index, source: (
451
+ f"source {index} ({type(source).__name__}) is electric: the driver "
452
+ f"injects it BETWEEN step_D and update_E (driver.py:3294-3299), and "
453
+ f"on a conductive row through _inject_electric_through_conductivity "
454
+ f"(driver.py:3306)"),
455
+ carries_repair=CARRIES_DEPOSIT_REPAIR))
456
+
457
+ # THE CONDUCTIVE INJECTION'S REMAINING HAZARD — imported from the no-PML
458
+ # conductive sibling, one home: with the driver's sparse rescale, only a scaled
459
+ # source that publishes NO deposit table still routes through the whole-volume
460
+ # fallback, and only that case is refused.
461
+ reasons.extend(_scaled_conductive_injection_reasons(fields, sources))
462
+
463
+ grid = getattr(fields, "grid", None)
464
+ if grid is None:
465
+ return Coverage(False,
466
+ tuple(dict.fromkeys(reasons + ["fields carries no grid"])))
467
+
468
+ # THE TWO FILLS, restated by NAME for THIS seam.
469
+ for axis in range(3):
470
+ mirrored = getattr(grid, "is_mirrored", None)
471
+ if callable(mirrored) and bool(mirrored(axis)):
472
+ reasons.append(
473
+ f"axis {axis} is folded: stepping.fill_symmetry_bc_D and "
474
+ f"stepping.fill_folded_far_ghosts_D both run inside this seam "
475
+ f"(driver.py:3300-3302) and neither is carried by this family")
476
+
477
+ # zero_metal_D is CARRIED, so the grid must be able to answer which axes are
478
+ # walled.
479
+ for name in ("has_metallic", "is_metallic", "is_mirrored"):
480
+ if getattr(grid, name, None) is None:
481
+ reasons.append(
482
+ f"grid does not expose {name}; zero_metal_D cannot be carried inline")
483
+
484
+ # A polarization would make the constitutive source (D - sum P) rather than D.
485
+ if tuple(getattr(fields, "polarizations", ()) or ()):
486
+ reasons.append("a susceptibility is registered: this kernel bakes the plain "
487
+ "constitutive product, whose source is D and not (D - sum P)")
488
+ return Coverage(not reasons, tuple(dict.fromkeys(reasons)))
489
+
490
+
491
+ # ---------------------------------------------------------------------------
492
+ # The plan
493
+ # ---------------------------------------------------------------------------
494
+
495
+ class MetalConductiveFusedElectricPairPlan(KernelPlan):
496
+ """ONE dispatch performing three driver passes on a conductive PML run's D seam.
497
+
498
+ ``launches_per_run`` is the base's 1. ``runs`` is an alias of ``launches``.
499
+ """
500
+
501
+ __slots__ = ("residency", "volumes", "codes", "conductive", "zero_metal",
502
+ "shape", "dtdx", "pack_layout", "params")
503
+
504
+ family = "conductive fused PML D-curl/stored-E pair"
505
+
506
+ replaces_sub_steps = REPLACES
507
+
508
+ REPR_FIELDS = ("shape", "codes", "conductive", "zero_metal")
509
+
510
+ #: This plan launches a kernel; the composer's planned/null split reads it.
511
+ performs_device_work = True
512
+
513
+ def __init__(self, residency: Residency, volumes: Sequence[str],
514
+ codes: Sequence[int], conductive: Sequence[bool],
515
+ zero_metal: Sequence[bool], shape: Sequence[int], dtdx: float,
516
+ pack_layout: Any, params: Any, pointers: Sequence[Any],
517
+ functions: Mapping[str, Any]) -> None:
518
+ self.residency = residency
519
+ self.volumes = tuple(dict.fromkeys(volumes))
520
+ self.codes = tuple(int(code) for code in codes)
521
+ self.conductive = tuple(bool(flag) for flag in conductive)
522
+ self.zero_metal = tuple(bool(value) for value in zero_metal)
523
+ self.shape = tuple(int(n) for n in shape)
524
+ self.dtdx = float(dtdx)
525
+ self.pack_layout = pack_layout
526
+ self.params = params
527
+ super().__init__(dict(functions), tuple(pointers) + (params,))
528
+
529
+ @property
530
+ def runs(self) -> int:
531
+ return self.launches
532
+
533
+
534
+ def _params_tensor(shape: Sequence[int], dtdx: float, offsets: Sequence[int],
535
+ device: str) -> Any:
536
+ """The five scalars AND the twelve pack offsets as one 68-byte device record."""
537
+ import numpy as np # noqa: PLC0415
538
+ import torch # noqa: PLC0415
539
+
540
+ fields = ([("nx", "<u4"), ("ny", "<u4"), ("nz", "<u4"), ("n_elem", "<u4"),
541
+ ("dtdx", "<f4")]
542
+ + coefficient_pack.record_dtype_fields(PACKED_VECTORS))
543
+ record = np.zeros(1, dtype=np.dtype(fields))
544
+ nx, ny, nz = (int(n) for n in shape)
545
+ offsets = tuple(int(offset) for offset in offsets)
546
+ if len(offsets) != len(PACKED_VECTORS): # pragma: no cover - arithmetic guard
547
+ raise AssertionError((len(offsets), len(PACKED_VECTORS)))
548
+ record[0] = (nx, ny, nz, nx * ny * nz, np.float32(dtdx)) + offsets
549
+ words = np.frombuffer(record.tobytes(), dtype=np.int32).copy()
550
+ return torch.from_numpy(words).to(torch.device(device))
551
+
552
+
553
+ def plan_metal_conductive_fused_electric_pair(
554
+ fields: Any, pml: Any, sources: Any = None,
555
+ residency: Optional[Residency] = None,
556
+ contract_variants: Sequence[str] = (shaders.CONTRACT_OFF,),
557
+ functions: Optional[Mapping[str, Any]] = None,
558
+ params: Optional[Any] = None,
559
+ ) -> Optional[MetalConductiveFusedElectricPairPlan]:
560
+ """Build the conductive fused D/E plan, or ``None`` when the seam is refused.
561
+
562
+ ``functions`` is the KERNEL mutation seam and ``params`` the HOST one — the
563
+ packed offsets are host arithmetic. Dropping either is a silent DISARMING.
564
+ """
565
+ if not metal_conductive_fused_electric_pair_coverage(
566
+ fields, pml, sources, residency).covered:
567
+ return None
568
+ import numpy as np # noqa: PLC0415
569
+ from ..stepping import _boundary_kinds # noqa: PLC0415
570
+
571
+ grid = fields.grid
572
+ codes = tuple(1 if kind == "metallic" else 0
573
+ for kind in _boundary_kinds(grid, pml))
574
+ walls = zero_metal_axes(grid)
575
+ flags = conductive_targets(fields, "step_D")
576
+
577
+ volumes: List[str] = []
578
+
579
+ def bind(name: str, host: Any, constant: bool = False) -> Any:
580
+ volumes.append(name)
581
+ return residency.mirror(name, host, constant=constant)
582
+
583
+ # THE ORDER HERE IS THE SIGNATURE'S ORDER and nothing else keeps them in step.
584
+ # The dead history/conductivity slots of a LOSSLESS target alias the target
585
+ # tensor, exactly as the certified conductive curl plan binds them
586
+ # (conductive_pml.py:221-232): the lossless tail never touches c/cf/ci, so the
587
+ # alias is never read and never written through.
588
+ targets = ("Dx", "Dy", "Dz")
589
+ flux = [bind(name, getattr(fields, name)) for name in targets]
590
+ auxiliary = [bind("fu_" + name, getattr(fields, "fu_" + name))
591
+ for name in targets]
592
+ history = [
593
+ (bind("f_cond_" + name, getattr(fields, "f_cond_" + name))
594
+ if flags[index] else flux[index])
595
+ for index, name in enumerate(targets)]
596
+ condfac = [
597
+ (bind(f"condfac_{name}:pml", fields.condfac_for(name), constant=True)
598
+ if flags[index] else flux[index])
599
+ for index, name in enumerate(targets)]
600
+ condinv = [
601
+ (bind(f"condinv_{name}:pml", fields.condinv_for(name), constant=True)
602
+ if flags[index] else flux[index])
603
+ for index, name in enumerate(targets)]
604
+ magnetic = [bind(name, getattr(fields, name)) for name in ("Hx", "Hy", "Hz")]
605
+ stored = [bind(name, getattr(fields, name)) for name in ("Ex", "Ey", "Ez")]
606
+ workspace = [bind("f_w_" + name, getattr(fields, "f_w_" + name))
607
+ for name in ("Ex", "Ey", "Ez")]
608
+ inverse_epsilon = [
609
+ bind("inv_eps_" + name, fields.inverse_epsilon_for(name), constant=True)
610
+ for name in ("Ex", "Ey", "Ez")]
611
+ # ONE PACK OVER BOTH HALVES' TWELVE VECTORS: the curl's integer-lattice
612
+ # kms/sinv and the constitutive's half-integer kps/kms, in PACKED_VECTORS
613
+ # order. The two lattices stay distinguishable through the offsets, which are
614
+ # generated from the same tuple the struct fields are.
615
+ pack, pack_layout = coefficient_pack.packed_mirror(
616
+ residency, "pml_pack:conductive_pair:step_D", np, PACKED_VECTORS,
617
+ [getattr(pml, f"{stem}_{axis}") for axis in "xyz"
618
+ for stem in ("kms", "sinv")]
619
+ + [getattr(pml, f"{stem}_{axis}_h") for axis in "xyz"
620
+ for stem in ("kps", "kms")])
621
+ volumes.append("pml_pack:conductive_pair:step_D")
622
+
623
+ pointers = (flux + auxiliary + history + condfac + condinv + magnetic
624
+ + stored + workspace + inverse_epsilon + [pack])
625
+ if len(pointers) != PACKED_POINTERS: # pragma: no cover - arithmetic guard
626
+ raise AssertionError((len(pointers), PACKED_POINTERS))
627
+ if len(pointers) + 1 != PACKED_BINDINGS: # pragma: no cover - arithmetic guard
628
+ raise AssertionError((len(pointers), PACKED_BINDINGS))
629
+
630
+ selected = dict(functions or {})
631
+ for mode in contract_variants:
632
+ if mode not in selected:
633
+ selected[mode] = compile_conductive_fused_electric_pair(
634
+ codes, flags, walls, mode)
635
+
636
+ dtdx = grid.dt / grid.dx
637
+ record = (_params_tensor(grid.shape, dtdx, pack_layout.offsets,
638
+ residency.device) if params is None else params)
639
+ return MetalConductiveFusedElectricPairPlan(
640
+ residency, volumes, codes, flags, walls, grid.shape, dtdx, pack_layout,
641
+ record, pointers, selected)
642
+
643
+
644
+ # ---------------------------------------------------------------------------
645
+ # Registration — NOT WIRED
646
+ # ---------------------------------------------------------------------------
647
+
648
+ def _arm_coverage(context: Any, slot: str) -> Coverage:
649
+ if slot != SLOT:
650
+ return Coverage(
651
+ False, (f"conductive fused electric pair cannot fill {slot}",))
652
+ return metal_conductive_fused_electric_pair_coverage(
653
+ context.fields, context.pml, context.sources, context.residency)
654
+
655
+
656
+ def _arm_plan(context: Any, slot: str
657
+ ) -> Optional[MetalConductiveFusedElectricPairPlan]:
658
+ if slot != SLOT:
659
+ return None
660
+ return plan_metal_conductive_fused_electric_pair(
661
+ context.fields, context.pml, context.sources, context.residency,
662
+ context.contract_variants)
663
+
664
+
665
+ def register_arms() -> Tuple[Any, ...]:
666
+ """One row on ``step_D``, ``wired=False`` — enumerable, never selectable."""
667
+ from . import arms # noqa: PLC0415
668
+ return (arms.register(FAMILY, SLOT, "conductive fused electric D/E pair",
669
+ _arm_coverage, _arm_plan,
670
+ prefix="conductive fused electric D/E pair: ",
671
+ noun="conductive fused PML D-curl/stored-E pair",
672
+ wired=False, replaces=REPLACES),)
673
+
674
+
675
+ ARMS = register_arms()