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.
- meep_gpu/LICENSE +339 -0
- meep_gpu/NOTICE +21 -0
- meep_gpu/__init__.py +208 -0
- meep_gpu/absorber.py +316 -0
- meep_gpu/amp_interpolation.py +158 -0
- meep_gpu/backends.py +362 -0
- meep_gpu/code_identity.py +144 -0
- meep_gpu/conftest.py +399 -0
- meep_gpu/cuda_kernels/__init__.py +6 -0
- meep_gpu/cuda_kernels/ade_kernels.py +519 -0
- meep_gpu/cuda_kernels/arms.py +1311 -0
- meep_gpu/cuda_kernels/bfast_curl.py +757 -0
- meep_gpu/cuda_kernels/bfast_fused_electric_pair.py +730 -0
- meep_gpu/cuda_kernels/bfast_fused_magnetic_pair.py +611 -0
- meep_gpu/cuda_kernels/certification.json +21804 -0
- meep_gpu/cuda_kernels/compile_cache.py +259 -0
- meep_gpu/cuda_kernels/complex_beta_fused_electric_pair.py +593 -0
- meep_gpu/cuda_kernels/complex_beta_fused_hd_pair.py +1067 -0
- meep_gpu/cuda_kernels/complex_beta_fused_magnetic_pair.py +560 -0
- meep_gpu/cuda_kernels/complex_beta_kernels.py +857 -0
- meep_gpu/cuda_kernels/complex_electric_fill_carry.py +766 -0
- meep_gpu/cuda_kernels/complex_emitter.py +645 -0
- meep_gpu/cuda_kernels/complex_fill_carry.py +717 -0
- meep_gpu/cuda_kernels/complex_folded_fused_electric_pair.py +561 -0
- meep_gpu/cuda_kernels/complex_folded_fused_magnetic_pair.py +652 -0
- meep_gpu/cuda_kernels/complex_folded_kernels.py +895 -0
- meep_gpu/cuda_kernels/complex_fused_electric_pair.py +1024 -0
- meep_gpu/cuda_kernels/complex_fused_hd_pair.py +1270 -0
- meep_gpu/cuda_kernels/complex_fused_magnetic_pair.py +885 -0
- meep_gpu/cuda_kernels/complex_no_pml_fused_polarization_pair.py +677 -0
- meep_gpu/cuda_kernels/complex_no_pml_kernels.py +1709 -0
- meep_gpu/cuda_kernels/complex_no_pml_offdiag_fused_electric_pair.py +754 -0
- meep_gpu/cuda_kernels/complex_no_pml_three_slot_dispersive_weld.py +824 -0
- meep_gpu/cuda_kernels/complex_offdiag_stencil_weld.py +1090 -0
- meep_gpu/cuda_kernels/complex_offdiag_update_e.py +1941 -0
- meep_gpu/cuda_kernels/complex_pml_kernels.py +473 -0
- meep_gpu/cuda_kernels/conductive_bfast_fused_hd_pair.py +1445 -0
- meep_gpu/cuda_kernels/conductive_fused_electric_pair.py +1006 -0
- meep_gpu/cuda_kernels/conductive_kernels.py +1104 -0
- meep_gpu/cuda_kernels/constitutive_kernels.py +606 -0
- meep_gpu/cuda_kernels/coverage.py +3151 -0
- meep_gpu/cuda_kernels/cylindrical_complex_kernels.py +1101 -0
- meep_gpu/cuda_kernels/cylindrical_coverage.py +540 -0
- meep_gpu/cuda_kernels/cylindrical_fused_electric_pair.py +1316 -0
- meep_gpu/cuda_kernels/cylindrical_fused_hd_pair.py +771 -0
- meep_gpu/cuda_kernels/cylindrical_fused_magnetic_pair.py +1143 -0
- meep_gpu/cuda_kernels/cylindrical_kernels.py +534 -0
- meep_gpu/cuda_kernels/cylindrical_prefix.py +83 -0
- meep_gpu/cuda_kernels/cylindrical_real_fused_electric_pair.py +837 -0
- meep_gpu/cuda_kernels/cylindrical_real_fused_hd_pair.py +685 -0
- meep_gpu/cuda_kernels/cylindrical_real_fused_magnetic_pair.py +708 -0
- meep_gpu/cuda_kernels/dispersive_fused_electric_pair.py +950 -0
- meep_gpu/cuda_kernels/dispersive_kernels.py +1403 -0
- meep_gpu/cuda_kernels/dispersive_offdiag_fused_polarization_pair.py +649 -0
- meep_gpu/cuda_kernels/dispersive_offdiag_update_e.py +1719 -0
- meep_gpu/cuda_kernels/fingerprints.json +4694 -0
- meep_gpu/cuda_kernels/folded_complex_offdiag_fused_electric_pair.py +858 -0
- meep_gpu/cuda_kernels/folded_offdiag_fused_electric_pair.py +931 -0
- meep_gpu/cuda_kernels/folded_offdiag_kernels.py +1375 -0
- meep_gpu/cuda_kernels/fused_electric_pair.py +1706 -0
- meep_gpu/cuda_kernels/fused_hd_pair.py +1313 -0
- meep_gpu/cuda_kernels/fused_magnetic_pair.py +1880 -0
- meep_gpu/cuda_kernels/fused_pairs.py +5127 -0
- meep_gpu/cuda_kernels/fused_polarization_pair.py +1145 -0
- meep_gpu/cuda_kernels/in_seam_coverage.py +504 -0
- meep_gpu/cuda_kernels/in_seam_passes.py +736 -0
- meep_gpu/cuda_kernels/no_pml_complex_fused_electric_pair.py +1387 -0
- meep_gpu/cuda_kernels/no_pml_constitutive.py +733 -0
- meep_gpu/cuda_kernels/no_pml_curl.py +1055 -0
- meep_gpu/cuda_kernels/no_pml_dispersive_fused_electric_pair.py +1100 -0
- meep_gpu/cuda_kernels/no_pml_three_slot_dispersive_weld.py +244 -0
- meep_gpu/cuda_kernels/nonlinear_constitutive.py +989 -0
- meep_gpu/cuda_kernels/offdiag_constitutive_kernels.py +401 -0
- meep_gpu/cuda_kernels/offdiag_emitter.py +504 -0
- meep_gpu/cuda_kernels/offdiag_fused_electric_pair.py +979 -0
- meep_gpu/cuda_kernels/offdiag_stencil_weld.py +763 -0
- meep_gpu/cuda_kernels/own_cell_hoist.py +266 -0
- meep_gpu/cuda_kernels/own_cell_hoist_reference.json +2150 -0
- meep_gpu/cuda_kernels/registry.py +763 -0
- meep_gpu/cuda_kernels/special_kz_curl.py +677 -0
- meep_gpu/cuda_kernels/special_kz_fused_electric_pair.py +722 -0
- meep_gpu/cuda_kernels/special_kz_fused_hd_pair.py +847 -0
- meep_gpu/cuda_kernels/special_kz_fused_magnetic_pair.py +724 -0
- meep_gpu/cuda_kernels/step_curl_kernels.py +833 -0
- meep_gpu/cuda_kernels/test_ade_strings_parse_cache.py +186 -0
- meep_gpu/cuda_kernels/test_ade_update_p.py +1200 -0
- meep_gpu/cuda_kernels/test_arms.py +614 -0
- meep_gpu/cuda_kernels/test_bfast_curl.py +450 -0
- meep_gpu/cuda_kernels/test_certification_metadata.py +532 -0
- meep_gpu/cuda_kernels/test_certification_record.py +798 -0
- meep_gpu/cuda_kernels/test_compile_cache.py +431 -0
- meep_gpu/cuda_kernels/test_complex_beta.py +642 -0
- meep_gpu/cuda_kernels/test_complex_beta_fused_hd_pair.py +340 -0
- meep_gpu/cuda_kernels/test_complex_folded.py +969 -0
- meep_gpu/cuda_kernels/test_complex_fused_electric_pairs.py +1181 -0
- meep_gpu/cuda_kernels/test_complex_no_pml.py +1000 -0
- meep_gpu/cuda_kernels/test_complex_no_pml_three_slot_dispersive_weld.py +315 -0
- meep_gpu/cuda_kernels/test_complex_offdiag_stencil_welds.py +702 -0
- meep_gpu/cuda_kernels/test_complex_offdiag_update_e.py +1503 -0
- meep_gpu/cuda_kernels/test_complex_pml.py +1211 -0
- meep_gpu/cuda_kernels/test_conductive_bfast_fused_hd_pair.py +392 -0
- meep_gpu/cuda_kernels/test_conductive_fused_electric_pair.py +573 -0
- meep_gpu/cuda_kernels/test_conductive_kernels.py +988 -0
- meep_gpu/cuda_kernels/test_constitutive_pml_real.py +2671 -0
- meep_gpu/cuda_kernels/test_cylindrical_complex.py +842 -0
- meep_gpu/cuda_kernels/test_cylindrical_fused_electric_pair_hoist.py +95 -0
- meep_gpu/cuda_kernels/test_cylindrical_fused_magnetic_pair_hoist.py +91 -0
- meep_gpu/cuda_kernels/test_cylindrical_pml_real.py +727 -0
- meep_gpu/cuda_kernels/test_dispersive.py +910 -0
- meep_gpu/cuda_kernels/test_dispersive_fused_electric_pair.py +761 -0
- meep_gpu/cuda_kernels/test_dispersive_offdiag_polarization_pair.py +354 -0
- meep_gpu/cuda_kernels/test_dispersive_offdiag_update_e.py +1590 -0
- meep_gpu/cuda_kernels/test_folded_offdiag.py +1625 -0
- meep_gpu/cuda_kernels/test_fused_electric_pair.py +896 -0
- meep_gpu/cuda_kernels/test_fused_hd_pair.py +370 -0
- meep_gpu/cuda_kernels/test_fused_magnetic_pair_fill_carry.py +982 -0
- meep_gpu/cuda_kernels/test_fused_pair_held_source.py +701 -0
- meep_gpu/cuda_kernels/test_fused_pairs.py +1046 -0
- meep_gpu/cuda_kernels/test_fused_polarization_pair.py +583 -0
- meep_gpu/cuda_kernels/test_in_seam_passes.py +685 -0
- meep_gpu/cuda_kernels/test_kernel_partition.py +378 -0
- meep_gpu/cuda_kernels/test_no_pml_complex_fused_electric_pair.py +1366 -0
- meep_gpu/cuda_kernels/test_no_pml_constitutive.py +1061 -0
- meep_gpu/cuda_kernels/test_no_pml_curl.py +1067 -0
- meep_gpu/cuda_kernels/test_no_pml_dispersive_fused_electric_pair.py +648 -0
- meep_gpu/cuda_kernels/test_nonlinear_constitutive.py +1038 -0
- meep_gpu/cuda_kernels/test_offdiag_constitutive_pml_real.py +2315 -0
- meep_gpu/cuda_kernels/test_offdiag_stencil_welds.py +858 -0
- meep_gpu/cuda_kernels/test_own_cell_hoist_store_sequence.py +1248 -0
- meep_gpu/cuda_kernels/test_residual_fused_electric_pairs.py +451 -0
- meep_gpu/cuda_kernels/test_residual_fused_magnetic_pairs.py +574 -0
- meep_gpu/cuda_kernels/test_single_arm_launches.py +822 -0
- meep_gpu/cuda_kernels/test_special_kz_bfast_admission.py +260 -0
- meep_gpu/cuda_kernels/test_special_kz_curl.py +470 -0
- meep_gpu/cuda_kernels/test_special_kz_fused_hd_pair.py +284 -0
- meep_gpu/cuda_kernels/test_step_curl_pml_real.py +1662 -0
- meep_gpu/cuda_kernels/test_three_slot_dispersive_weld.py +570 -0
- meep_gpu/cuda_kernels/three_slot_dispersive_weld.py +778 -0
- meep_gpu/cuda_kernels/timing_cc86.json +1154 -0
- meep_gpu/cuda_kernels/timing_cc86.report.txt +64 -0
- meep_gpu/deposit_repair.py +1854 -0
- meep_gpu/device_identity.py +265 -0
- meep_gpu/dft.py +5538 -0
- meep_gpu/dispatch_preference.py +977 -0
- meep_gpu/dispersion.py +769 -0
- meep_gpu/driver.py +4617 -0
- meep_gpu/expansion_refusal.py +439 -0
- meep_gpu/fastpath.py +7652 -0
- meep_gpu/fastpath_cuda.py +2371 -0
- meep_gpu/fields.py +1957 -0
- meep_gpu/from_meep.py +8638 -0
- meep_gpu/gaussian_beam.py +303 -0
- meep_gpu/grid.py +1479 -0
- meep_gpu/harminv.py +680 -0
- meep_gpu/host_writes.py +331 -0
- meep_gpu/metal_dispatch.py +3120 -0
- meep_gpu/metal_kernels/__init__.py +104 -0
- meep_gpu/metal_kernels/ade_update_p.py +493 -0
- meep_gpu/metal_kernels/arms.py +289 -0
- meep_gpu/metal_kernels/barrier.py +367 -0
- meep_gpu/metal_kernels/beta_complex_fused_electric_pair.py +671 -0
- meep_gpu/metal_kernels/beta_complex_fused_hd_pair.py +1265 -0
- meep_gpu/metal_kernels/beta_complex_fused_magnetic_pair.py +549 -0
- meep_gpu/metal_kernels/beta_fused_electric_pair.py +640 -0
- meep_gpu/metal_kernels/beta_fused_magnetic_pair.py +573 -0
- meep_gpu/metal_kernels/beta_real_fused_hd_pair.py +1048 -0
- meep_gpu/metal_kernels/bfast_curl.py +1081 -0
- meep_gpu/metal_kernels/bfast_fused_electric_pair.py +681 -0
- meep_gpu/metal_kernels/bfast_fused_hd_pair.py +852 -0
- meep_gpu/metal_kernels/bfast_fused_magnetic_pair.py +568 -0
- meep_gpu/metal_kernels/coefficient_pack.py +201 -0
- meep_gpu/metal_kernels/complex_conductive_fused_pair.py +885 -0
- meep_gpu/metal_kernels/complex_conductive_pml.py +525 -0
- meep_gpu/metal_kernels/complex_dispersive_spine.py +173 -0
- meep_gpu/metal_kernels/complex_dispersive_update_e.py +300 -0
- meep_gpu/metal_kernels/complex_fields.py +1393 -0
- meep_gpu/metal_kernels/complex_folded_offdiag_update_e.py +365 -0
- meep_gpu/metal_kernels/complex_fused_ade_chain.py +825 -0
- meep_gpu/metal_kernels/complex_fused_electric_pair.py +920 -0
- meep_gpu/metal_kernels/complex_fused_hd_pair.py +1267 -0
- meep_gpu/metal_kernels/complex_fused_magnetic_pair.py +1010 -0
- meep_gpu/metal_kernels/complex_no_pml_conductive.py +446 -0
- meep_gpu/metal_kernels/complex_no_pml_curl.py +199 -0
- meep_gpu/metal_kernels/complex_no_pml_offdiag_fused_electric_pair.py +579 -0
- meep_gpu/metal_kernels/complex_no_pml_offdiag_update_e.py +391 -0
- meep_gpu/metal_kernels/complex_no_pml_stored_e.py +272 -0
- meep_gpu/metal_kernels/conductive_fused_electric_pair.py +675 -0
- meep_gpu/metal_kernels/conductive_fused_hd_pair.py +944 -0
- meep_gpu/metal_kernels/conductive_pml.py +273 -0
- meep_gpu/metal_kernels/corpus.py +170 -0
- meep_gpu/metal_kernels/coverage.py +631 -0
- meep_gpu/metal_kernels/cylindrical_complex.py +1780 -0
- meep_gpu/metal_kernels/cylindrical_complex_fused_hd_pair.py +841 -0
- meep_gpu/metal_kernels/cylindrical_complex_scan.py +273 -0
- meep_gpu/metal_kernels/cylindrical_fused_electric_pair.py +1073 -0
- meep_gpu/metal_kernels/cylindrical_fused_magnetic_pair.py +1087 -0
- meep_gpu/metal_kernels/cylindrical_real.py +1426 -0
- meep_gpu/metal_kernels/cylindrical_real_fused_electric_pair.py +1022 -0
- meep_gpu/metal_kernels/cylindrical_real_fused_hd_pair.py +955 -0
- meep_gpu/metal_kernels/cylindrical_real_fused_magnetic_pair.py +876 -0
- meep_gpu/metal_kernels/device.py +1659 -0
- meep_gpu/metal_kernels/dispersive_update_e.py +310 -0
- meep_gpu/metal_kernels/fingerprints.json +35997 -0
- meep_gpu/metal_kernels/folded_beta.py +1710 -0
- meep_gpu/metal_kernels/folded_beta_complex_fused_magnetic_pair.py +1443 -0
- meep_gpu/metal_kernels/folded_beta_complex_fused_pair.py +872 -0
- meep_gpu/metal_kernels/folded_beta_real_fused_magnetic_pair.py +638 -0
- meep_gpu/metal_kernels/folded_beta_real_fused_pair.py +670 -0
- meep_gpu/metal_kernels/folded_complex.py +1804 -0
- meep_gpu/metal_kernels/folded_complex_fused_hd_pair.py +889 -0
- meep_gpu/metal_kernels/folded_complex_fused_magnetic_pair.py +1918 -0
- meep_gpu/metal_kernels/folded_complex_fused_pair.py +1478 -0
- meep_gpu/metal_kernels/folded_complex_offdiag_fused_electric_pair.py +637 -0
- meep_gpu/metal_kernels/folded_dispersive_update_e.py +187 -0
- meep_gpu/metal_kernels/folded_fused_dispersive_pair.py +1043 -0
- meep_gpu/metal_kernels/folded_fused_hd_pair.py +796 -0
- meep_gpu/metal_kernels/folded_fused_magnetic_pair.py +1542 -0
- meep_gpu/metal_kernels/folded_fused_pair.py +1449 -0
- meep_gpu/metal_kernels/folded_offdiag_dispersive_update_e.py +457 -0
- meep_gpu/metal_kernels/folded_offdiag_fused_electric_pair.py +572 -0
- meep_gpu/metal_kernels/folded_offdiag_update_e.py +1422 -0
- meep_gpu/metal_kernels/fused_ade_chain.py +882 -0
- meep_gpu/metal_kernels/fused_dispersive_pair.py +821 -0
- meep_gpu/metal_kernels/fused_electric_pair.py +843 -0
- meep_gpu/metal_kernels/fused_hd_pair.py +1167 -0
- meep_gpu/metal_kernels/fused_magnetic_pair.py +765 -0
- meep_gpu/metal_kernels/launch.py +2125 -0
- meep_gpu/metal_kernels/no_pml_conductive.py +383 -0
- meep_gpu/metal_kernels/no_pml_conductive_fused_electric_pair.py +797 -0
- meep_gpu/metal_kernels/no_pml_constitutive.py +737 -0
- meep_gpu/metal_kernels/no_pml_curl.py +339 -0
- meep_gpu/metal_kernels/no_pml_fused_electric_pair.py +553 -0
- meep_gpu/metal_kernels/no_pml_stored_e.py +285 -0
- meep_gpu/metal_kernels/nonlinear_fused_magnetic_pair.py +305 -0
- meep_gpu/metal_kernels/nonlinear_update_e.py +1575 -0
- meep_gpu/metal_kernels/offdiag_fused_electric_pair.py +720 -0
- meep_gpu/metal_kernels/offdiag_update_e.py +1134 -0
- meep_gpu/metal_kernels/offdiag_weld_common.py +588 -0
- meep_gpu/metal_kernels/plans.py +90 -0
- meep_gpu/metal_kernels/preconditions.py +265 -0
- meep_gpu/metal_kernels/registry.py +385 -0
- meep_gpu/metal_kernels/shaders.py +430 -0
- meep_gpu/metal_kernels/special_kz.py +1804 -0
- meep_gpu/metal_kernels/subnormal.py +313 -0
- meep_gpu/metal_kernels/symmetry.py +1829 -0
- meep_gpu/metal_kernels/templates.py +224 -0
- meep_gpu/metal_runs.py +329 -0
- meep_gpu/pml.py +857 -0
- meep_gpu/sigma_lookup.py +327 -0
- meep_gpu/sigma_recovery.py +261 -0
- meep_gpu/smoothing.py +1440 -0
- meep_gpu/sources.py +2272 -0
- meep_gpu/stepping.py +2544 -0
- meep_gpu/subnormal_policy.py +2332 -0
- meep_gpu/test_absorber.py +311 -0
- meep_gpu/test_backends.py +311 -0
- meep_gpu/test_bytecode_cache_matches_source.py +117 -0
- meep_gpu/test_capability_records.py +667 -0
- meep_gpu/test_code_identity.py +148 -0
- meep_gpu/test_compile_cache_consistency.py +122 -0
- meep_gpu/test_conftest_guards.py +281 -0
- meep_gpu/test_cuda_certified_fused_products.py +1072 -0
- meep_gpu/test_cuda_complex_fused_hd_pair.py +464 -0
- meep_gpu/test_cuda_cylindrical_fused_hd_pair.py +268 -0
- meep_gpu/test_cuda_cylindrical_real_fused_hd_pair.py +284 -0
- meep_gpu/test_cuda_weld_contract.py +1760 -0
- meep_gpu/test_cylindrical.py +727 -0
- meep_gpu/test_cylindrical_near2far.py +626 -0
- meep_gpu/test_deposit_repair.py +1227 -0
- meep_gpu/test_deposit_repair_component_restriction.py +1867 -0
- meep_gpu/test_deposit_repair_linear_route.py +817 -0
- meep_gpu/test_deposit_repair_restriction_bench_record.py +156 -0
- meep_gpu/test_device_identity.py +159 -0
- meep_gpu/test_dft.py +3829 -0
- meep_gpu/test_diagonal_epsilon.py +180 -0
- meep_gpu/test_dispatch_contract.py +5493 -0
- meep_gpu/test_dispatch_expansion_refusal.py +1033 -0
- meep_gpu/test_dispatch_policy_uniformity.py +584 -0
- meep_gpu/test_dispatch_preference.py +1008 -0
- meep_gpu/test_dispatch_route_tables_are_complete.py +86 -0
- meep_gpu/test_dispatch_subnormal_gate.py +426 -0
- meep_gpu/test_dispersion.py +1057 -0
- meep_gpu/test_driver_integration.py +4886 -0
- meep_gpu/test_driver_vs_meep.py +5330 -0
- meep_gpu/test_fastpath.py +618 -0
- meep_gpu/test_field_reducers.py +633 -0
- meep_gpu/test_fields.py +1237 -0
- meep_gpu/test_folded_deposit_closure.py +192 -0
- meep_gpu/test_folded_fused_pair_routing.py +822 -0
- meep_gpu/test_from_meep.py +8694 -0
- meep_gpu/test_fused_pair_deposit_wiring.py +2543 -0
- meep_gpu/test_gate_provenance.py +336 -0
- meep_gpu/test_gaussian_beam.py +392 -0
- meep_gpu/test_grid_pml.py +1498 -0
- meep_gpu/test_harminv.py +1404 -0
- meep_gpu/test_meep_precision_notice.py +173 -0
- meep_gpu/test_metal_ade_update_p.py +332 -0
- meep_gpu/test_metal_artifact_provenance.py +1011 -0
- meep_gpu/test_metal_below_the_cut_fused_pairs.py +749 -0
- meep_gpu/test_metal_beta_complex_fused_hd_pair.py +571 -0
- meep_gpu/test_metal_beta_real_fused_hd_pair.py +546 -0
- meep_gpu/test_metal_bfast.py +803 -0
- meep_gpu/test_metal_bfast_fused_hd_pair.py +421 -0
- meep_gpu/test_metal_coefficient_pack.py +223 -0
- meep_gpu/test_metal_complex_conductive_fused_pair.py +412 -0
- meep_gpu/test_metal_complex_conductive_pml.py +284 -0
- meep_gpu/test_metal_complex_dispersive_update_e.py +195 -0
- meep_gpu/test_metal_complex_fields.py +818 -0
- meep_gpu/test_metal_complex_folded_offdiag_update_e.py +131 -0
- meep_gpu/test_metal_complex_fused_ade_chain.py +341 -0
- meep_gpu/test_metal_complex_fused_hd_pair.py +668 -0
- meep_gpu/test_metal_complex_fused_magnetic_pair.py +549 -0
- meep_gpu/test_metal_complex_no_pml_conductive.py +226 -0
- meep_gpu/test_metal_complex_no_pml_curl.py +220 -0
- meep_gpu/test_metal_complex_no_pml_offdiag_update_e.py +167 -0
- meep_gpu/test_metal_complex_no_pml_stored_e.py +162 -0
- meep_gpu/test_metal_conductive_fused_hd_pair.py +527 -0
- meep_gpu/test_metal_conductive_pml.py +174 -0
- meep_gpu/test_metal_cylindrical_complex.py +1132 -0
- meep_gpu/test_metal_cylindrical_complex_fused_hd_pair.py +378 -0
- meep_gpu/test_metal_cylindrical_complex_scan.py +367 -0
- meep_gpu/test_metal_cylindrical_fused_electric_pair.py +612 -0
- meep_gpu/test_metal_cylindrical_fused_magnetic_pair.py +453 -0
- meep_gpu/test_metal_cylindrical_real.py +721 -0
- meep_gpu/test_metal_cylindrical_real_fused_electric_pair.py +912 -0
- meep_gpu/test_metal_cylindrical_real_fused_hd_pair.py +397 -0
- meep_gpu/test_metal_cylindrical_real_fused_magnetic_pair.py +678 -0
- meep_gpu/test_metal_dispatch.py +1096 -0
- meep_gpu/test_metal_dispersive_update_e.py +147 -0
- meep_gpu/test_metal_environment.py +316 -0
- meep_gpu/test_metal_folded_beta.py +1043 -0
- meep_gpu/test_metal_folded_complex.py +1353 -0
- meep_gpu/test_metal_folded_complex_fused_hd_pair.py +566 -0
- meep_gpu/test_metal_folded_complex_fused_magnetic_pair.py +590 -0
- meep_gpu/test_metal_folded_dispersive_update_e.py +139 -0
- meep_gpu/test_metal_folded_fused_hd_pair.py +953 -0
- meep_gpu/test_metal_folded_fused_magnetic_pair.py +507 -0
- meep_gpu/test_metal_folded_fused_pair.py +425 -0
- meep_gpu/test_metal_folded_offdiag.py +1194 -0
- meep_gpu/test_metal_folded_offdiag_dispersive_update_e.py +128 -0
- meep_gpu/test_metal_fused_ade_chain.py +420 -0
- meep_gpu/test_metal_fused_dispersive_pair.py +331 -0
- meep_gpu/test_metal_fused_electric_pair.py +447 -0
- meep_gpu/test_metal_fused_hd_pair.py +1546 -0
- meep_gpu/test_metal_fused_hd_pair_nonlinear.py +420 -0
- meep_gpu/test_metal_fused_magnetic_pair.py +365 -0
- meep_gpu/test_metal_fused_pair_deposit_wiring.py +1177 -0
- meep_gpu/test_metal_held_fallback.py +706 -0
- meep_gpu/test_metal_kernels.py +624 -0
- meep_gpu/test_metal_no_pml_conductive.py +219 -0
- meep_gpu/test_metal_no_pml_constitutive.py +1470 -0
- meep_gpu/test_metal_no_pml_curl.py +197 -0
- meep_gpu/test_metal_no_pml_fused_electric_pairs.py +535 -0
- meep_gpu/test_metal_no_pml_stored_e.py +174 -0
- meep_gpu/test_metal_nonlinear_update_e.py +820 -0
- meep_gpu/test_metal_offdiag.py +798 -0
- meep_gpu/test_metal_offdiag_stencil_welds.py +505 -0
- meep_gpu/test_metal_planner_composition.py +646 -0
- meep_gpu/test_metal_residency_barrier.py +246 -0
- meep_gpu/test_metal_residency_ownership.py +913 -0
- meep_gpu/test_metal_residue_fused_pairs.py +348 -0
- meep_gpu/test_metal_runs.py +294 -0
- meep_gpu/test_metal_special_kz.py +999 -0
- meep_gpu/test_metal_symmetry.py +1190 -0
- meep_gpu/test_metal_weld_contract.py +1013 -0
- meep_gpu/test_package_boundary.py +441 -0
- meep_gpu/test_prefer_gpu.py +799 -0
- meep_gpu/test_regate_writers.py +1078 -0
- meep_gpu/test_sigma_lookup.py +916 -0
- meep_gpu/test_sigma_recovery.py +689 -0
- meep_gpu/test_smoothing.py +2389 -0
- meep_gpu/test_sources.py +2493 -0
- meep_gpu/test_stepping.py +3420 -0
- meep_gpu/test_subnormal_policy.py +2184 -0
- meep_gpu/test_sync_pass_channel.py +578 -0
- meep_gpu/test_tensor_epsilon.py +562 -0
- meep_gpu/test_triton_beta_fused_electric_pair.py +669 -0
- meep_gpu/test_triton_beta_fused_magnetic_pair.py +363 -0
- meep_gpu/test_triton_bfast.py +1339 -0
- meep_gpu/test_triton_bfast_fused_electric_pair.py +657 -0
- meep_gpu/test_triton_bfast_fused_magnetic_pair.py +358 -0
- meep_gpu/test_triton_certified_fused_products.py +1409 -0
- meep_gpu/test_triton_complex_ade.py +291 -0
- meep_gpu/test_triton_complex_beta_fused_electric_pair.py +391 -0
- meep_gpu/test_triton_complex_beta_fused_magnetic_pair.py +407 -0
- meep_gpu/test_triton_complex_conductive_fused_pair.py +512 -0
- meep_gpu/test_triton_complex_fields.py +2900 -0
- meep_gpu/test_triton_complex_fused_ade_chain.py +700 -0
- meep_gpu/test_triton_complex_fused_electric_pair.py +856 -0
- meep_gpu/test_triton_complex_fused_hd_pair.py +747 -0
- meep_gpu/test_triton_complex_fused_magnetic_pair.py +857 -0
- meep_gpu/test_triton_complex_no_pml_conductive.py +301 -0
- meep_gpu/test_triton_complex_no_pml_curl.py +699 -0
- meep_gpu/test_triton_complex_no_pml_stored_e.py +394 -0
- meep_gpu/test_triton_complex_offdiag_update_e.py +306 -0
- meep_gpu/test_triton_conductive_fused_electric_pair.py +792 -0
- meep_gpu/test_triton_conductivity.py +628 -0
- meep_gpu/test_triton_cylindrical.py +669 -0
- meep_gpu/test_triton_cylindrical_complex.py +2523 -0
- meep_gpu/test_triton_cylindrical_composition.py +253 -0
- meep_gpu/test_triton_cylindrical_fused_electric_pair.py +695 -0
- meep_gpu/test_triton_cylindrical_fused_hd_pair.py +578 -0
- meep_gpu/test_triton_cylindrical_fused_magnetic_pair.py +440 -0
- meep_gpu/test_triton_cylindrical_real_fused_electric_pair.py +760 -0
- meep_gpu/test_triton_cylindrical_real_fused_hd_pair.py +675 -0
- meep_gpu/test_triton_cylindrical_real_fused_magnetic_pair.py +529 -0
- meep_gpu/test_triton_device_identity.py +142 -0
- meep_gpu/test_triton_dispersive_fused_pair.py +365 -0
- meep_gpu/test_triton_dispersive_update_e.py +682 -0
- meep_gpu/test_triton_folded_beta_complex_fused_magnetic_pair.py +698 -0
- meep_gpu/test_triton_folded_beta_complex_fused_pair.py +649 -0
- meep_gpu/test_triton_folded_beta_fused_electric_pair.py +617 -0
- meep_gpu/test_triton_folded_beta_fused_magnetic_pair.py +546 -0
- meep_gpu/test_triton_folded_complex.py +3538 -0
- meep_gpu/test_triton_folded_complex_fused_magnetic_pair.py +1377 -0
- meep_gpu/test_triton_folded_complex_fused_pair.py +1349 -0
- meep_gpu/test_triton_folded_complex_offdiag_admission.py +543 -0
- meep_gpu/test_triton_folded_dispersive_fused_pair.py +873 -0
- meep_gpu/test_triton_folded_dispersive_update_e.py +460 -0
- meep_gpu/test_triton_folded_fused_hd_pair.py +810 -0
- meep_gpu/test_triton_folded_fused_magnetic_pair.py +1088 -0
- meep_gpu/test_triton_folded_fused_pair.py +1129 -0
- meep_gpu/test_triton_folded_offdiag_dispersive_update_e.py +385 -0
- meep_gpu/test_triton_folded_offdiag_fused_ade_chain.py +987 -0
- meep_gpu/test_triton_folded_offdiag_fused_electric_pair.py +604 -0
- meep_gpu/test_triton_folded_offdiag_update_e.py +1217 -0
- meep_gpu/test_triton_fused_ade_chain.py +665 -0
- meep_gpu/test_triton_fused_ade_state.py +256 -0
- meep_gpu/test_triton_fused_dispersive_chain.py +489 -0
- meep_gpu/test_triton_fused_hd_pair.py +827 -0
- meep_gpu/test_triton_hd_tail_products.py +650 -0
- meep_gpu/test_triton_kernels.py +1580 -0
- meep_gpu/test_triton_no_pml.py +819 -0
- meep_gpu/test_triton_no_pml_ade.py +553 -0
- meep_gpu/test_triton_no_pml_conductive.py +686 -0
- meep_gpu/test_triton_no_pml_constitutive.py +2310 -0
- meep_gpu/test_triton_no_pml_fused_electric_pair.py +775 -0
- meep_gpu/test_triton_no_pml_stored_e.py +515 -0
- meep_gpu/test_triton_nonlinear_fused_magnetic_pair.py +292 -0
- meep_gpu/test_triton_nonlinear_update_e.py +1187 -0
- meep_gpu/test_triton_offdiag_fused_electric_pair.py +662 -0
- meep_gpu/test_triton_offdiag_update_e.py +1041 -0
- meep_gpu/test_triton_planner_composition.py +4064 -0
- meep_gpu/test_triton_residual_group_wiring.py +503 -0
- meep_gpu/test_triton_residual_probe_discipline.py +401 -0
- meep_gpu/test_triton_source_seams.py +261 -0
- meep_gpu/test_triton_special_kz.py +1142 -0
- meep_gpu/test_triton_symmetry.py +548 -0
- meep_gpu/test_triton_symmetry_composition.py +252 -0
- meep_gpu/test_triton_weld_contract.py +2365 -0
- meep_gpu/test_uncertified_opt_in.py +1032 -0
- meep_gpu/test_version.py +87 -0
- meep_gpu/test_weld_record_walk.py +504 -0
- meep_gpu/test_withdraw_hoist.py +600 -0
- meep_gpu/triton_kernels/__init__.py +959 -0
- meep_gpu/triton_kernels/beta_complex_fused_hd_pair.py +1376 -0
- meep_gpu/triton_kernels/beta_fused_electric_pair.py +755 -0
- meep_gpu/triton_kernels/beta_fused_magnetic_pair.py +648 -0
- meep_gpu/triton_kernels/beta_real_fused_hd_pair.py +1118 -0
- meep_gpu/triton_kernels/bfast_curl.py +1032 -0
- meep_gpu/triton_kernels/bfast_fused_electric_pair.py +782 -0
- meep_gpu/triton_kernels/bfast_fused_magnetic_pair.py +697 -0
- meep_gpu/triton_kernels/complex_ade.py +400 -0
- meep_gpu/triton_kernels/complex_beta_fused_electric_pair.py +880 -0
- meep_gpu/triton_kernels/complex_beta_fused_magnetic_pair.py +838 -0
- meep_gpu/triton_kernels/complex_conductive_fused_pair.py +892 -0
- meep_gpu/triton_kernels/complex_fields.py +2295 -0
- meep_gpu/triton_kernels/complex_fused_ade_chain.py +1118 -0
- meep_gpu/triton_kernels/complex_fused_electric_pair.py +1038 -0
- meep_gpu/triton_kernels/complex_fused_hd_pair.py +1558 -0
- meep_gpu/triton_kernels/complex_fused_magnetic_pair.py +867 -0
- meep_gpu/triton_kernels/complex_no_pml_conductive.py +497 -0
- meep_gpu/triton_kernels/complex_no_pml_curl.py +415 -0
- meep_gpu/triton_kernels/complex_no_pml_stored_e.py +432 -0
- meep_gpu/triton_kernels/complex_offdiag_update_e.py +639 -0
- meep_gpu/triton_kernels/conductive_bfast_fused_hd_pair.py +1255 -0
- meep_gpu/triton_kernels/conductive_fused_electric_pair.py +868 -0
- meep_gpu/triton_kernels/conductivity.py +810 -0
- meep_gpu/triton_kernels/coverage.py +761 -0
- meep_gpu/triton_kernels/cylindrical_complex.py +1718 -0
- meep_gpu/triton_kernels/cylindrical_fused_electric_pair.py +1284 -0
- meep_gpu/triton_kernels/cylindrical_fused_hd_pair.py +882 -0
- meep_gpu/triton_kernels/cylindrical_fused_magnetic_pair.py +1071 -0
- meep_gpu/triton_kernels/cylindrical_real_fused_electric_pair.py +750 -0
- meep_gpu/triton_kernels/cylindrical_real_fused_hd_pair.py +745 -0
- meep_gpu/triton_kernels/cylindrical_real_fused_magnetic_pair.py +744 -0
- meep_gpu/triton_kernels/cylindrical_triton.py +983 -0
- meep_gpu/triton_kernels/dispersive_fused_pair.py +451 -0
- meep_gpu/triton_kernels/dispersive_update_e.py +719 -0
- meep_gpu/triton_kernels/fingerprints.json +8359 -0
- meep_gpu/triton_kernels/folded_beta_complex_fused_magnetic_pair.py +1470 -0
- meep_gpu/triton_kernels/folded_beta_complex_fused_pair.py +1764 -0
- meep_gpu/triton_kernels/folded_beta_fused_electric_pair.py +1031 -0
- meep_gpu/triton_kernels/folded_beta_fused_magnetic_pair.py +919 -0
- meep_gpu/triton_kernels/folded_complex.py +3244 -0
- meep_gpu/triton_kernels/folded_complex_fused_hd_pair.py +1187 -0
- meep_gpu/triton_kernels/folded_complex_fused_magnetic_pair.py +1747 -0
- meep_gpu/triton_kernels/folded_complex_fused_pair.py +1905 -0
- meep_gpu/triton_kernels/folded_dispersive_fused_pair.py +1200 -0
- meep_gpu/triton_kernels/folded_dispersive_update_e.py +340 -0
- meep_gpu/triton_kernels/folded_fused_hd_pair.py +991 -0
- meep_gpu/triton_kernels/folded_fused_magnetic_pair.py +1171 -0
- meep_gpu/triton_kernels/folded_fused_pair.py +1408 -0
- meep_gpu/triton_kernels/folded_offdiag_dispersive_update_e.py +587 -0
- meep_gpu/triton_kernels/folded_offdiag_fused_ade_chain.py +1238 -0
- meep_gpu/triton_kernels/folded_offdiag_fused_electric_pair.py +1124 -0
- meep_gpu/triton_kernels/folded_offdiag_update_e.py +1396 -0
- meep_gpu/triton_kernels/fused_ade_chain.py +1299 -0
- meep_gpu/triton_kernels/fused_ade_state.py +315 -0
- meep_gpu/triton_kernels/fused_dispersive_chain.py +673 -0
- meep_gpu/triton_kernels/fused_hd_pair.py +1200 -0
- meep_gpu/triton_kernels/kernels.py +728 -0
- meep_gpu/triton_kernels/launch.py +4402 -0
- meep_gpu/triton_kernels/no_pml.py +819 -0
- meep_gpu/triton_kernels/no_pml_ade.py +413 -0
- meep_gpu/triton_kernels/no_pml_conductive.py +943 -0
- meep_gpu/triton_kernels/no_pml_constitutive.py +889 -0
- meep_gpu/triton_kernels/no_pml_fused_electric_pair.py +1043 -0
- meep_gpu/triton_kernels/no_pml_stored_e.py +759 -0
- meep_gpu/triton_kernels/nonlinear_fused_hd_pair.py +473 -0
- meep_gpu/triton_kernels/nonlinear_fused_magnetic_pair.py +392 -0
- meep_gpu/triton_kernels/nonlinear_update_e.py +1384 -0
- meep_gpu/triton_kernels/offdiag_fused_electric_pair.py +994 -0
- meep_gpu/triton_kernels/offdiag_scratch_weld.py +366 -0
- meep_gpu/triton_kernels/offdiag_update_e.py +958 -0
- meep_gpu/triton_kernels/special_kz.py +1637 -0
- meep_gpu/triton_kernels/symmetry.py +1190 -0
- meep_gpu/triton_kernels/timing_cc86.json +2375 -0
- meep_gpu/triton_kernels/timing_cc86.report.txt +93 -0
- meep_gpu/weld_record_walk.py +646 -0
- meep_gpu/withdraw_hoist.py +581 -0
- meep_gpu-0.9.2.dist-info/METADATA +652 -0
- meep_gpu-0.9.2.dist-info/RECORD +537 -0
- meep_gpu-0.9.2.dist-info/WHEEL +5 -0
- meep_gpu-0.9.2.dist-info/licenses/LICENSE +339 -0
- meep_gpu-0.9.2.dist-info/licenses/NOTICE +21 -0
- 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()
|