radia-gpu 0.1.0__py3-none-win_amd64.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 (126) hide show
  1. radia_gpu/LICENSE +165 -0
  2. radia_gpu/README.md +137 -0
  3. radia_gpu/__init__.py +33 -0
  4. radia_gpu/ams-build.json +9 -0
  5. radia_gpu/ams_exchange.py +101 -0
  6. radia_gpu/build.json +15 -0
  7. radia_gpu/cli.py +16 -0
  8. radia_gpu/ltspice/LICENSE +21 -0
  9. radia_gpu/ltspice/__init__.py +82 -0
  10. radia_gpu/ltspice/_artifact_identity.py +21 -0
  11. radia_gpu/ltspice/_identity_circuit.py +1295 -0
  12. radia_gpu/ltspice/_identity_common.py +36 -0
  13. radia_gpu/ltspice/_identity_dynamic.py +1514 -0
  14. radia_gpu/ltspice/_identity_signal.py +1393 -0
  15. radia_gpu/ltspice/_identity_topology.py +771 -0
  16. radia_gpu/ltspice/_shared.py +68 -0
  17. radia_gpu/ltspice/allpass_gate.py +139 -0
  18. radia_gpu/ltspice/bandwidth_gate.py +125 -0
  19. radia_gpu/ltspice/bipolar_efficiency_gate.py +87 -0
  20. radia_gpu/ltspice/bipolar_rail_gate.py +161 -0
  21. radia_gpu/ltspice/bipolar_startup_gate.py +183 -0
  22. radia_gpu/ltspice/boost_gate.py +11 -0
  23. radia_gpu/ltspice/bridge_rectifier_gate.py +136 -0
  24. radia_gpu/ltspice/cli.py +1009 -0
  25. radia_gpu/ltspice/complex_zero_gate.py +227 -0
  26. radia_gpu/ltspice/conversion.py +110 -0
  27. radia_gpu/ltspice/distributed_line_gate.py +133 -0
  28. radia_gpu/ltspice/filter_gates.py +104 -0
  29. radia_gpu/ltspice/hysteresis_gate.py +138 -0
  30. radia_gpu/ltspice/ideal_transformer_gate.py +629 -0
  31. radia_gpu/ltspice/knowledge.py +171 -0
  32. radia_gpu/ltspice/learning_quality.py +68 -0
  33. radia_gpu/ltspice/ltspice_v43_gates.py +162 -0
  34. radia_gpu/ltspice/ltspice_v44_gates.py +82 -0
  35. radia_gpu/ltspice/ltspice_v45_gates.py +42 -0
  36. radia_gpu/ltspice/ltspice_v46_gates.py +90 -0
  37. radia_gpu/ltspice/ltspice_v47_gates.py +87 -0
  38. radia_gpu/ltspice/ltspice_v48_gates.py +95 -0
  39. radia_gpu/ltspice/ltspice_v49_gates.py +67 -0
  40. radia_gpu/ltspice/ltspice_v50_gates.py +173 -0
  41. radia_gpu/ltspice/ltspice_v51_gates.py +167 -0
  42. radia_gpu/ltspice/ltspice_v52_gates.py +87 -0
  43. radia_gpu/ltspice/ltspice_v53_gates.py +112 -0
  44. radia_gpu/ltspice/ltspice_v54_gates.py +120 -0
  45. radia_gpu/ltspice/ltspice_v55_gates.py +103 -0
  46. radia_gpu/ltspice/measure.py +372 -0
  47. radia_gpu/ltspice/monte_carlo_gate.py +170 -0
  48. radia_gpu/ltspice/noise_gate.py +132 -0
  49. radia_gpu/ltspice/parser/__init__.py +5 -0
  50. radia_gpu/ltspice/parser/asc_parser.py +1835 -0
  51. radia_gpu/ltspice/parser/asc_to_schemdraw.py +499 -0
  52. radia_gpu/ltspice/parser/cir_to_schemdraw.py +613 -0
  53. radia_gpu/ltspice/parser/netlist_to_asc.py +1929 -0
  54. radia_gpu/ltspice/parser/schemdraw_to_cir.py +822 -0
  55. radia_gpu/ltspice/parser/schemdraw_to_ltspice.py +460 -0
  56. radia_gpu/ltspice/patentability.py +189 -0
  57. radia_gpu/ltspice/psrr_gate.py +12 -0
  58. radia_gpu/ltspice/py.typed +1 -0
  59. radia_gpu/ltspice/rectifier_gate.py +7 -0
  60. radia_gpu/ltspice/series_rlc_gate.py +122 -0
  61. radia_gpu/ltspice/three_phase_delta_gate.py +331 -0
  62. radia_gpu/ltspice/topology.py +162 -0
  63. radia_gpu/ltspice/voltage_multiplier_gate.py +86 -0
  64. radia_gpu/maglev.py +52 -0
  65. radia_gpu/manifest.json +142 -0
  66. radia_gpu/matlab/+radia/+gpu/+internal/systemStore.m +23 -0
  67. radia_gpu/matlab/+radia/+gpu/amsPCG.m +13 -0
  68. radia_gpu/matlab/+radia/+gpu/csrPCG.m +11 -0
  69. radia_gpu/matlab/+radia/+gpu/readAMSExchange.m +49 -0
  70. radia_gpu/matlab/+radia/+gpu/requireRuntime.m +13 -0
  71. radia_gpu/matlab/+radia/+ltspice/+internal/terminateProcessTree.m +15 -0
  72. radia_gpu/matlab/+radia/+ltspice/AscEditor.m +8 -0
  73. radia_gpu/matlab/+radia/+ltspice/LTSpiceLogReader.m +8 -0
  74. radia_gpu/matlab/+radia/+ltspice/LTspice.m +72 -0
  75. radia_gpu/matlab/+radia/+ltspice/LogReader.m +68 -0
  76. radia_gpu/matlab/+radia/+ltspice/RawRead.m +229 -0
  77. radia_gpu/matlab/+radia/+ltspice/RawWrite.m +52 -0
  78. radia_gpu/matlab/+radia/+ltspice/RunTask.m +27 -0
  79. radia_gpu/matlab/+radia/+ltspice/SchematicEditor.m +136 -0
  80. radia_gpu/matlab/+radia/+ltspice/SimCommander.m +12 -0
  81. radia_gpu/matlab/+radia/+ltspice/SimRunner.m +132 -0
  82. radia_gpu/matlab/+radia/+ltspice/SpiceCircuit.m +8 -0
  83. radia_gpu/matlab/+radia/+ltspice/SpiceEditor.m +217 -0
  84. radia_gpu/matlab/+radia/+ltspice/Trace.m +15 -0
  85. radia_gpu/matlab/+radia/+ltspice/analyzeFFT.m +21 -0
  86. radia_gpu/matlab/+radia/+ltspice/applyTransientState.m +26 -0
  87. radia_gpu/matlab/+radia/+ltspice/collectDependencies.m +29 -0
  88. radia_gpu/matlab/+radia/+ltspice/collectSchematicDependencies.m +33 -0
  89. radia_gpu/matlab/+radia/+ltspice/extractTransientState.m +98 -0
  90. radia_gpu/matlab/+radia/+ltspice/findExecutable.m +35 -0
  91. radia_gpu/matlab/+radia/+ltspice/measureSeriesResonance.m +96 -0
  92. radia_gpu/matlab/+radia/+ltspice/netlistToSchematic.m +39 -0
  93. radia_gpu/matlab/+radia/+ltspice/readRaw.m +47 -0
  94. radia_gpu/matlab/+radia/+ltspice/readRawAscii.m +120 -0
  95. radia_gpu/matlab/+radia/+ltspice/readRawBinary.m +88 -0
  96. radia_gpu/matlab/+radia/+ltspice/run.m +175 -0
  97. radia_gpu/matlab/+radia/+ltspice/runIntervals.m +28 -0
  98. radia_gpu/matlab/+radia/+ltspice/runNoise.m +12 -0
  99. radia_gpu/matlab/+radia/+ltspice/schematicToNetlist.m +39 -0
  100. radia_gpu/matlab/+radia/+ltspice/writePwl.m +40 -0
  101. radia_gpu/matlab/+radia/+simulink/+internal/runArtifacts.m +65 -0
  102. radia_gpu/matlab/+radia/+simulink/buildCudaPCGBlock.m +21 -0
  103. radia_gpu/matlab/+radia/+simulink/buildLTspiceBlock.m +18 -0
  104. radia_gpu/matlab/+radia/+simulink/cudaPCGSFunction.m +96 -0
  105. radia_gpu/matlab/+radia/+simulink/ltspiceSFunction.m +82 -0
  106. radia_gpu/matlab/+radia/+simulink/runLTspice.m +64 -0
  107. radia_gpu/matlab/+radia/+simulink/runLTspiceClosedLoop.m +22 -0
  108. radia_gpu/matlab/+radia/+simulink/runLTspiceInterval.m +26 -0
  109. radia_gpu/matlab/radia_cuda_ams.mexw64 +0 -0
  110. radia_gpu/matlab/radia_cuda_csr_pcg.mexw64 +0 -0
  111. radia_gpu/matlab/radia_gpu_pcg_sfun.m +4 -0
  112. radia_gpu/matlab/radia_ltspice_sfun.m +4 -0
  113. radia_gpu/motor_rom_export.py +235 -0
  114. radia_gpu/ports.py +148 -0
  115. radia_gpu/simulink/__init__.py +16 -0
  116. radia_gpu/simulink/application.py +430 -0
  117. radia_gpu/simulink/contracts/ih_coil_bema_v1.json +13 -0
  118. radia_gpu/simulink/contracts/ih_thermal_axisym_v1.json +7 -0
  119. radia_gpu/simulink/contracts/ih_workpiece_v1.json +13 -0
  120. radia_gpu/simulink/ih_operator_assembly.py +1171 -0
  121. radia_gpu/vim.py +199 -0
  122. radia_gpu-0.1.0.dist-info/METADATA +166 -0
  123. radia_gpu-0.1.0.dist-info/RECORD +126 -0
  124. radia_gpu-0.1.0.dist-info/WHEEL +5 -0
  125. radia_gpu-0.1.0.dist-info/entry_points.txt +8 -0
  126. radia_gpu-0.1.0.dist-info/top_level.txt +1 -0
radia_gpu/LICENSE ADDED
@@ -0,0 +1,165 @@
1
+ RADIA SOFTWARE LICENSE
2
+ ======================
3
+
4
+ This software contains multiple components with different licenses:
5
+
6
+ 1. RADIA Core (BSD-style License)
7
+ 2. HACApK Library (MIT License)
8
+ 3. sparseSolv integration (Mozilla Public License 2.0)
9
+ 4. Intel Math Kernel Library runtime notices
10
+ 5. Radia SPICE/LTspice integration (MIT License)
11
+ 6. Eqnedit64 (BSD 2-Clause License with separately licensed assets)
12
+
13
+ ================================================================================
14
+ PART 1: RADIA CORE
15
+ ================================================================================
16
+
17
+ Copyright © 1997 - 2018, European Synchrotron Radiation Facility
18
+
19
+ The RADIA software is distributed subject to the following license conditions:
20
+
21
+ Redistribution and use in source and binary forms, with or without
22
+ modification, are permitted provided that the following conditions are met:
23
+
24
+ 1. Redistributions of source code must retain the above copyright notice,
25
+ this list of conditions and the following disclaimer.
26
+
27
+ 2. Redistributions in binary form must reproduce the above copyright notice,
28
+ this list of conditions and the following disclaimer in the documentation
29
+ and/or other materials provided with the distribution.
30
+
31
+ DISCLAIMER: THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS "AS IS"
32
+ AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
33
+ IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
34
+ ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE FOR
35
+ ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
36
+ DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
37
+ SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
38
+ CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
39
+ OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
40
+ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
41
+
42
+ The views and conclusions contained in the software and documentation are
43
+ those of the authors and should not be interpreted as representing official
44
+ policies, either expressed or implied, of the RADIA project.
45
+
46
+ ================================================================================
47
+ PART 2: HACApK (H-matrix Library)
48
+ ================================================================================
49
+
50
+ Software Name : HACApK
51
+ Version : 1.3.0
52
+ Location: src/ext/HACApK/
53
+
54
+ Copyright (c) 2015 Akihiro Ida and Takeshi Iwashita
55
+
56
+ MIT License
57
+
58
+ Permission is hereby granted, free of charge, to any person obtaining a copy
59
+ of this software and associated documentation files (the "Software"), to deal
60
+ in the Software without restriction, including without limitation the rights
61
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
62
+ copies of the Software, and to permit persons to whom the Software is
63
+ furnished to do so, subject to the following conditions:
64
+
65
+ The above copyright notice and this permission notice shall be included in all
66
+ copies or substantial portions of the Software.
67
+
68
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
69
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
70
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
71
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
72
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
73
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
74
+ SOFTWARE.
75
+
76
+ ppOpen-HPC project:
77
+ Open Source Infrastructure for Development and Execution of Large-Scale
78
+ Scientific Applications on Post-Peta-Scale Supercomputers with Automatic
79
+ Tuning (AT).
80
+
81
+ Sponsorship:
82
+ Japan Science and Technology Agency (JST), Basic Research Programs: CREST,
83
+ Development of System Software Technologies for post-Peta Scale High
84
+ Performance Computing.
85
+
86
+ ================================================================================
87
+ PART 3: sparseSolv integration
88
+ ================================================================================
89
+
90
+ Location: src/ext/sparsesolv/
91
+
92
+ The sparseSolv integration is licensed under the Mozilla Public License Version
93
+ 2.0. See src/ext/sparsesolv/LICENSE for the full license text.
94
+
95
+ ================================================================================
96
+ PART 4: Intel Math Kernel Library (MKL) Runtime
97
+ ================================================================================
98
+
99
+ This software distribution includes Intel Math Kernel Library (Intel MKL)
100
+ runtime libraries for BLAS/LAPACK operations.
101
+
102
+ Intel MKL License:
103
+ The Intel MKL runtime libraries are redistributed under the terms of the
104
+ Intel Simplified Software License (version August 2021) which allows
105
+ redistribution of the software in binary form.
106
+
107
+ Copyright (c) Intel Corporation. All rights reserved.
108
+
109
+ The Intel MKL redistributable libraries included are:
110
+ - mkl_rt.3.dll (or equivalent)
111
+ - mkl_core.3.dll
112
+ - mkl_intel_thread.3.dll
113
+ - mkl_def.3.dll
114
+ - mkl_avx2.3.dll
115
+
116
+ Intel, the Intel logo, and Intel MKL are trademarks of Intel Corporation or
117
+ its subsidiaries in the U.S. and/or other countries.
118
+
119
+ ================================================================================
120
+ PART 5: RADIA SPICE/LTSPICE INTEGRATION
121
+ ================================================================================
122
+
123
+ Location: src/radia/ltspice/
124
+
125
+ Copyright (c) 2026 Mitsutoshi Sugahara
126
+
127
+ MIT License
128
+
129
+ Permission is hereby granted, free of charge, to any person obtaining a copy
130
+ of this software and associated documentation files (the "Software"), to deal
131
+ in the Software without restriction, including without limitation the rights
132
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
133
+ copies of the Software, and to permit persons to whom the Software is
134
+ furnished to do so, subject to the following conditions:
135
+
136
+ The above copyright notice and this permission notice shall be included in all
137
+ copies or substantial portions of the Software.
138
+
139
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
140
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
141
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
142
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
143
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
144
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
145
+ SOFTWARE.
146
+
147
+ For the full Intel Simplified Software License terms, please visit:
148
+ https://www.intel.com/content/www/us/en/developer/articles/license/end-user-license-agreement.html
149
+
150
+ ================================================================================
151
+ PART 6: EQNEDIT64
152
+ ================================================================================
153
+
154
+ Location: tools/eqnedit64/
155
+
156
+ Copyright (c) 2026 ksugahar
157
+
158
+ Eqnedit64 is licensed under the BSD 2-Clause License. See
159
+ tools/eqnedit64/LICENSE for the full license text.
160
+
161
+ Redistributable font and icon assets retain their respective licenses. See
162
+ tools/eqnedit64/assets/THIRD_PARTY_NOTICES.md and the license files beside
163
+ those assets.
164
+
165
+ ================================================================================
radia_gpu/README.md ADDED
@@ -0,0 +1,137 @@
1
+ # radia-gpu
2
+
3
+ Independent GPU distribution from the Radia monorepo: MATLAB CUDA MEX
4
+ kernels, readable Simulink blocks, and LTspice integration code.
5
+ CPU electromagnetic execution belongs to `radia` (Python/pybind11/NGSolve).
6
+ `radia-mcp` is the AI operation interface. Neither package is required merely
7
+ to locate and use the installed GPU MATLAB files.
8
+
9
+ Version 0.1.0 contains FP64 CUDA CSR Jacobi-PCG, a Simulink block for the same
10
+ kernel, and the selected standalone LTspice workflow. It also contains experimental FP64 assembled-operator AMS and its versioned
11
+ HDF5 exchange. This does not certify production AMS, ICCG, HDiv-MMM, or
12
+ migration of the older CPU MEX application models.
13
+ There is no CPU solver fallback.
14
+
15
+ ## Install
16
+
17
+ ```powershell
18
+ python -m pip install radia-gpu
19
+ radia-gpu-doctor --json
20
+ radia-gpu-path
21
+ ```
22
+
23
+ Add the reported directory to MATLAB's path. MATLAB R2026a, Parallel Computing
24
+ Toolbox, an NVIDIA GPU and a compatible NVIDIA driver are external requirements.
25
+ Python delivers and verifies the MATLAB payload; it does not execute GPU solves.
26
+ The installed CUDA solvers do not require the Python `radia` or `ngsolve`
27
+ packages. CSR-PCG consumes caller-provided matrix arrays; AMS consumes an
28
+ already-built hierarchy. The current CPU hierarchy-generation route uses
29
+ Radia/NGSolve in a separate preparation environment. Optional
30
+ `radia-gpu[coupling]` installs Radia for workflows that explicitly need it.
31
+ The Windows x64 binary contains sm_75/sm_80 code and compute_80 PTX.
32
+ Develop and build `radia-gpu` on 100. Required release acceptance compares each
33
+ published CUDA solver against Python/NGSolve on 100 (Quadro RTX 5000), and
34
+ requires an independent review of the exact source. Record source/runtime
35
+ versions, artifact hashes and machine-readable results. A100 validation and
36
+ scaling are optional additional evidence, not publication requirements.
37
+ Formal timing remains subject to the idle-mdx host policy; 100 timings are diagnostic. CPU-only mdx execution verifies
38
+ the reference calculation, not CUDA execution. RTX 5000 installation acceptance
39
+ does not certify A100 scaling.
40
+ Cubit mesh export is tested separately on 100 and 102. NGSolve validation
41
+ starts by checking and loading an exported `.vol` with its versioned label
42
+ contract; it does not require Cubit on the NGSolve host.
43
+
44
+ Deployment targets are 100 (build and RTX 5000 acceptance) and A100, excluding
45
+ 102. The 102 host tests `radia` and `radia-mcp` without installing `radia-gpu`.
46
+ A100 is optional and never blocks development or publication. It is not always running: record its acceptance as pending while offline,
47
+ then validate the same artifact hash when available. Do not treat an offline
48
+ target as a successful test.
49
+
50
+ Call `radia.gpu.csrPCG` with zero-based int32 CSR row pointers/columns and FP64
51
+ GPU values, RHS and positive inverse diagonal for a symmetric positive-definite
52
+ system. The caller owns FE assembly
53
+ and the GPU arrays. The solver verifies the true residual and raises on invalid
54
+ inputs, unsupported state, breakdown or nonconvergence.
55
+
56
+ `radia.simulink.buildCudaPCGBlock` builds a typed Level-2 MATLAB S-Function
57
+ block. Matrix upload occurs at Start; each RHS upload and solution download
58
+ is explicit in the block. Simulink is optional for standalone MEX use.
59
+
60
+ LTspice integration includes MATLAB `radia.ltspice`, Python
61
+ `radia_gpu.ltspice`, and the selected sampled-data
62
+ Simulink workflow. LTspice executes in its own installed runtime; it is not
63
+ a GPU circuit solver. LTspice, MATLAB, Simulink, CUDA Toolkit and NVIDIA
64
+ drivers are not redistributed. Install external products separately under
65
+ their own licenses. This distribution includes Radia integration code only.
66
+
67
+ ## Build and release
68
+
69
+ Build on 100 from a clean exact commit with `Build.ps1 -CudaMexOnly
70
+ -RequireNativeProvenance` and `Build.ps1 -AmsCudaOnly
71
+ -RequireNativeProvenance`, then run `python -m build --wheel` in this directory.
72
+ mexcuda compilation and GPU execution never use NGSolve `TaskManager`.
73
+ NGSolve preprocessing in this route does not use TaskManager. AMS setup may
74
+ use CUDA or OpenMP when validated for the workload; compare numerical parity,
75
+ transfer-inclusive timing and memory before selecting either backend. The
76
+ current snapshot adapter uses a serial reference. CUDA kernels and cuBLAS
77
+ provide GPU solve parallelism. Independent CPU Radia workflows retain their
78
+ own threading policy.
79
+
80
+ NGSolve's [device tutorial](https://docu.ngsolve.org/latest/i-tutorials/unit-5.5-cuda/poisson_cuda.html)
81
+ uses `TaskManager` around `ngsolve.gpu` calls, but device operators are provided
82
+ by `ngscuda`; [TaskManager itself](https://docu.ngsolve.org/latest/i-tutorials/appendix-taskmanager/taskmanager.html)
83
+ manages host threads. Reconsider it for this route only with a demonstrated
84
+ CUDA integration benefit and measured parity/performance, rather than assuming
85
+ host parallel loops execute on the GPU.
86
+
87
+ The wheel build requires the matching CUDA build receipt and binary hash.
88
+ The independent CPU Radia reference follows its own Python threading policy.
89
+ Canonical CUDA and MATLAB sources live in this package, under `native/` and
90
+ `matlab/`. Packaging stages those sources; it does not read a root MATLAB tree.
91
+ Use only the resulting verified wheel for deployment and PyPI publication.
92
+ The initial alpha requires independent review before a stable release.
93
+
94
+ `radia-gpu.yml` builds and accepts the installed wheel on the build host.
95
+ `radia-gpu-release.yml` publishes that successful main CI artifact without
96
+ rebuilding, requiring its exact SHA-256 and installed acceptance provenance.
97
+ Stable versions additionally require the exact-source independent review and
98
+ same-wheel 100 RTX 5000/CPU parity record described in
99
+ [`validation_test/radia_gpu/releases`](../../validation_test/radia_gpu/releases/README.md).
100
+ Configure PyPI Trusted Publishing for project `radia-gpu`, GitHub owner
101
+ `ksugahar`, repository `Radia`, workflow `radia-gpu-release.yml`, environment
102
+ `pypi`. A new project needs a pending publisher; checking availability does
103
+ not reserve its name. Publish only the Windows wheel, not a source archive
104
+ that would require an end user's proprietary build toolchain.
105
+
106
+ GPU AMS is developed separately. HDiv-MMM is a subsequent evaluation target,
107
+ after solver/preconditioner parity: preserve NGSolve's FE ownership and validate
108
+ the electromagnetic formulation, nonlinear convergence and optimization outcome
109
+ against the Python CPU route. Report transfer-inclusive timing and peak memory;
110
+ neither successful PCG nor AMS alone certifies HDiv-MMM support.
111
+
112
+ ## Experimental AMS and large numeric exchange
113
+
114
+ AMS CUDA and its snapshot adapter are package-owned native sources, built by
115
+ `tools/build_ams_cuda.py` through the root build dispatcher. The CPU setup
116
+ retains NGSolve and Radia ownership; the validation adapter is not installed
117
+ as a CPU solver in this wheel. `radia.gpu.amsPCG` accepts a checked numeric
118
+ hierarchy and RHS already uploaded to GPU memory, with no CPU fallback.
119
+
120
+ All AMS file exchange uses `radia.ams-hdf5.v1` plain HDF5. Install optional
121
+ `radia-gpu[exchange]` dependencies for the Python writer, and read the result
122
+ with `radia.gpu.readAMSExchange`. Values stay FP64 and CSR indices stay
123
+ zero-based int32. Shapes and array dimension order are explicit. HDF5 supports
124
+ the project's >2 GB exchange requirement; it does not bypass int32 kernel
125
+ capacity checks or the GPU working-memory budget. See
126
+ [AMS validation](../../validation_test/ams_cuda/README.md) for numerical gates,
127
+ transfer-inclusive timing and current limitations. Small-case A100 numerical
128
+ and timing evidence is recorded in that validation; it does not certify
129
+ A100 scaling or the exact artifact of a future release.
130
+
131
+ Python circuit converters use `radia-ltspice`; install `radia-gpu[ltspice]`
132
+ for the optional schemdraw route. MCP entry points, including
133
+ `mcp-server-radia-ltspice`, belong to `radia-mcp` and load the GPU distribution
134
+ only when circuit execution is requested. No circuit import alias is left in
135
+ the CPU Radia distribution.
136
+
137
+ The optional `coupling` extra requires Radia 5.3.1 or later with the CPU thermal-operator API. Existing Radia 5.3.0 wheels do not satisfy this contract; until that CPU release is available, use the standalone CUDA PCG, Simulink PCG and LTspice interfaces.
radia_gpu/__init__.py ADDED
@@ -0,0 +1,33 @@
1
+ """Locate and verify the independently installed MATLAB GPU payload."""
2
+ from __future__ import annotations
3
+
4
+ import hashlib
5
+ import json
6
+ from importlib.resources import files
7
+ from pathlib import Path
8
+
9
+ __version__ = "0.1.0"
10
+
11
+
12
+ def matlab_path() -> Path:
13
+ """Return installed resources only; never borrow an editable solver tree."""
14
+ return Path(str(files(__package__).joinpath("matlab")))
15
+
16
+
17
+ def verify() -> dict:
18
+ """Verify the installed payload without importing MATLAB, CUDA or Radia."""
19
+ root = Path(str(files(__package__)))
20
+ manifest_bytes = (root / "manifest.json").read_bytes()
21
+ manifest = json.loads(manifest_bytes)
22
+ if manifest.get("schema") != "radia.gpu.distribution.v1" or manifest.get("version") != __version__:
23
+ raise RuntimeError("Unsupported or mismatched radia-gpu manifest")
24
+ for relative, expected in manifest["files"].items():
25
+ path = (root / relative).resolve()
26
+ if not path.is_relative_to(root.resolve()) or not path.is_file():
27
+ raise RuntimeError(f"Missing or invalid payload path: {relative}")
28
+ if hashlib.sha256(path.read_bytes()).hexdigest() != expected:
29
+ raise RuntimeError(f"Payload hash mismatch: {relative}")
30
+ return dict(passed=True, runtime_checked=False, version=__version__, matlab_path=str(matlab_path()),
31
+ source_commit=manifest["source_commit"], capabilities=manifest["capabilities"],
32
+ manifest_sha256=hashlib.sha256(manifest_bytes).hexdigest(),
33
+ runtime_requirements=manifest["runtime_requirements"])
@@ -0,0 +1,9 @@
1
+ {
2
+ "schema": "radia.ams-cuda-build.v1",
3
+ "source_commit": "babc16d4a7f7d27bb8ce078c1af370c2fe5d9fb4",
4
+ "source_dirty": false,
5
+ "matlab": "26.1.0.3346908 (R2026a) Update 5",
6
+ "no_cpu_solver_fallback": true,
7
+ "binary_sha256": "45f0d3b13e185663b6d20cca658c27ff12700907a9b9b0ae3f2aad6c555f8cdd",
8
+ "source_sha256": "e800d46affc628dc53d6c600189ba527e3a03933e6af9bc282aecca5e263dd8d"
9
+ }
@@ -0,0 +1,101 @@
1
+ """Versioned plain-HDF5 numeric exchange for CPU-owned AMS snapshots.
2
+
3
+ This is HDF5, not MATLAB's proprietary MAT v7.3 struct encoding. The matching
4
+ MATLAB reader is radia.gpu.readAMSExchange. Arrays keep their NumPy shapes,
5
+ FP64 values and zero-based int32 indices; the reader restores dimension order.
6
+ All sizes use this format, including artifacts exceeding 2 GB.
7
+ """
8
+ from __future__ import annotations
9
+
10
+ import json
11
+ from pathlib import Path
12
+
13
+ SCHEMA = "radia.ams-hdf5.v1"
14
+
15
+
16
+ def write_exchange(path, payload):
17
+ """Write without collecting array data into a serialized in-memory blob."""
18
+ import h5py
19
+ import numpy as np
20
+
21
+ path = Path(path)
22
+ if path.suffix.lower() not in (".h5", ".hdf5"):
23
+ raise ValueError("AMS exchange requires an .h5 or .hdf5 file")
24
+ count = 0
25
+ numeric_bytes = 0
26
+ with h5py.File(path, "x") as handle:
27
+ arrays = handle.create_group("arrays")
28
+
29
+ def node(value):
30
+ nonlocal count, numeric_bytes
31
+ if isinstance(value, dict):
32
+ if any(not isinstance(k, str) or not k.isidentifier() for k in value):
33
+ raise ValueError("Exchange fields must be valid identifiers")
34
+ return {"kind": "struct", "fields": {k: node(v) for k, v in value.items()}}
35
+ if isinstance(value, (list, tuple)):
36
+ return {"kind": "cell", "items": [node(v) for v in value]}
37
+ if isinstance(value, np.ndarray):
38
+ if value.dtype not in (np.dtype("float64"), np.dtype("int32"), np.dtype("uint8")) or not 1 <= value.ndim <= 2:
39
+ raise ValueError("AMS exchange supports FP64/int32/uint8 vectors and matrices")
40
+ name = f"a{count:06d}"; count += 1
41
+ # h5py streams directly from contiguous native snapshot buffers.
42
+ # No compression, whole-payload copy, or MAT 2 GB length field.
43
+ arrays.create_dataset(name, data=value)
44
+ numeric_bytes += value.nbytes
45
+ return {"kind": "array", "path": "/arrays/" + name,
46
+ "shape": list(value.shape), "dtype": value.dtype.name}
47
+ if isinstance(value, (bool, np.bool_)):
48
+ return {"kind": "logical", "value": bool(value)}
49
+ if isinstance(value, (int, float, np.integer, np.floating)):
50
+ return {"kind": "number", "value": float(value)}
51
+ if isinstance(value, str):
52
+ return {"kind": "string", "value": value}
53
+ raise TypeError(f"Unsupported exchange type: {type(value).__name__}")
54
+
55
+ manifest = {"schema": SCHEMA, "index_base": 0, "precision": "FP64",
56
+ "array_order": "numpy", "units": "SI", "tree": node(payload)}
57
+ encoded = json.dumps(manifest, allow_nan=False, separators=(",", ":")).encode("utf-8")
58
+ handle.create_dataset("manifest", data=np.frombuffer(encoded, dtype=np.uint8))
59
+ return {"schema": SCHEMA, "format": "HDF5", "numeric_bytes": numeric_bytes,
60
+ "file_bytes": path.stat().st_size, "arrays": count}
61
+
62
+
63
+ def read_exchange(path):
64
+ """Read the same schema for diagnostics and paired timing input identity."""
65
+ import h5py
66
+ import numpy as np
67
+
68
+ with h5py.File(path, "r") as handle:
69
+ manifest = json.loads(handle["manifest"][...].tobytes().decode("utf-8"))
70
+ if (manifest.get("schema") != SCHEMA or manifest.get("index_base") != 0
71
+ or manifest.get("precision") != "FP64" or manifest.get("array_order") != "numpy"):
72
+ raise ValueError("Unsupported AMS HDF5 exchange contract")
73
+
74
+ def node(spec):
75
+ kind = spec["kind"]
76
+ if kind == "struct":
77
+ return {k: node(v) for k, v in spec["fields"].items()}
78
+ if kind == "cell":
79
+ return [node(v) for v in spec["items"]]
80
+ if kind == "array":
81
+ name = spec["path"]
82
+ if not name.startswith("/arrays/a") or not name[9:].isdigit():
83
+ raise ValueError("Invalid AMS dataset path")
84
+ dataset = handle[name]
85
+ if list(dataset.shape) != spec["shape"] or dataset.dtype != np.dtype(spec["dtype"]):
86
+ raise ValueError("AMS dataset shape/type mismatch")
87
+ return dataset[...]
88
+ if kind in ("number", "logical", "string"):
89
+ return spec["value"]
90
+ raise ValueError("Unsupported AMS HDF5 node")
91
+ return node(manifest["tree"])
92
+
93
+
94
+ def file_sha256(path):
95
+ """Hash even multi-GB inputs using bounded memory."""
96
+ import hashlib
97
+ digest = hashlib.sha256()
98
+ with open(path, "rb") as handle:
99
+ for block in iter(lambda: handle.read(8 * 1024 * 1024), b""):
100
+ digest.update(block)
101
+ return digest.hexdigest()
radia_gpu/build.json ADDED
@@ -0,0 +1,15 @@
1
+ {
2
+ "schema": "radia.cuda-mex-build.v1",
3
+ "source_commit": "babc16d4a7f7d27bb8ce078c1af370c2fe5d9fb4",
4
+ "source_dirty": false,
5
+ "source_sha256": "63cb771b2f998a0a02b22048a36fce7295d96e0b5181c7913fc0fdbd5c29d29d",
6
+ "binary_sha256": "57476f482bdacc9568de413cef405bd52e2ade5d513ff696944dd405c89f27ec",
7
+ "matlab": "26.1.0.3346908 (R2026a) Update 5",
8
+ "release": "2026a",
9
+ "no_cpu_solver_fallback": true,
10
+ "cuda_targets": [
11
+ "sm_75",
12
+ "sm_80",
13
+ "compute_80 PTX"
14
+ ]
15
+ }
radia_gpu/cli.py ADDED
@@ -0,0 +1,16 @@
1
+ """Small installation utilities; numerical execution stays in mexcuda."""
2
+ import argparse
3
+ import json
4
+ from . import matlab_path, verify
5
+
6
+
7
+ def path_main():
8
+ print(matlab_path())
9
+
10
+
11
+ def doctor_main():
12
+ parser = argparse.ArgumentParser(description=__doc__)
13
+ parser.add_argument("--json", action="store_true")
14
+ options = parser.parse_args()
15
+ report = verify()
16
+ print(json.dumps(report, indent=2) if options.json else f"radia-gpu {report['version']}: payload verified")
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 Mitsutoshi Sugahara
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
@@ -0,0 +1,82 @@
1
+ """Radia's circuit-aware SPICE and LTspice integration.
2
+
3
+ ``radia_gpu.ltspice`` is the canonical Python namespace. Circuit integration
4
+ is distributed independently from the CPU Radia solver.
5
+
6
+ Public API
7
+ ----------
8
+ - netlist_to_schemdraw(netlist, name) -> str
9
+ - schemdraw_to_netlist(script, title) -> str
10
+ - netlist_to_asc(netlist) -> str
11
+ - asc_to_netlist(asc_text, use_ltspice=None) -> str # None = auto (LTspice if installed)
12
+ - topology_signature(netlist) -> str (node-rename-invariant)
13
+ - topology_equivalent(netlist_a, netlist_b) -> (bool, info)
14
+ - circuit_knowledge(topic) -> dict
15
+ - buck_seed(vin_v, vout_v, iout_a, fsw_hz=...) -> BuckSeed
16
+ - patentability_search_plan(title, features, effects, domains) -> dict
17
+ - summarize_measure_log(log_text) -> dict
18
+ - summarize_stepped_measure_log(log_text) -> dict
19
+
20
+ CLI / MCP server
21
+ ----------------
22
+ - radia-ltspice (conversion and inspection CLI)
23
+ - mcp-server-radia-ltspice (FastMCP stdio server)
24
+ """
25
+ from __future__ import annotations
26
+
27
+ from .conversion import (
28
+ netlist_to_schemdraw,
29
+ schemdraw_to_netlist,
30
+ netlist_to_asc,
31
+ asc_to_netlist,
32
+ )
33
+ from .topology import topology_signature, topology_equivalent
34
+ from .knowledge import circuit_knowledge, buck_seed, BuckSeed
35
+ from .patentability import patentability_search_plan
36
+ from .measure import (
37
+ parse_ltspice_measure_lines,
38
+ parse_ltspice_stepped_measure_tables,
39
+ parse_ltspice_step_lines,
40
+ parse_spice_scalar,
41
+ summarize_measure_log,
42
+ summarize_stepped_measure_log,
43
+ )
44
+ from .voltage_multiplier_gate import cockcroft_walton_stage_gate
45
+ from .monte_carlo_gate import monte_carlo_tolerance_family_gate
46
+ from .bipolar_efficiency_gate import bipolar_converter_efficiency_gate
47
+ from .bipolar_rail_gate import bipolar_rail_power_quality_gate
48
+ from .series_rlc_gate import series_rlc_complex_impedance_gate
49
+ from .noise_gate import rc_thermal_noise_psd_gate
50
+ from .three_phase_delta_gate import balanced_three_phase_delta_rl_gate
51
+ from .ideal_transformer_gate import ideal_transformer_identity_gate
52
+ from .ltspice_v44_gates import validate_ltspice_v44_public_identity
53
+
54
+ __all__ = [
55
+ "netlist_to_schemdraw",
56
+ "schemdraw_to_netlist",
57
+ "netlist_to_asc",
58
+ "asc_to_netlist",
59
+ "topology_signature",
60
+ "topology_equivalent",
61
+ "circuit_knowledge",
62
+ "buck_seed",
63
+ "BuckSeed",
64
+ "patentability_search_plan",
65
+ "parse_spice_scalar",
66
+ "parse_ltspice_measure_lines",
67
+ "parse_ltspice_stepped_measure_tables",
68
+ "parse_ltspice_step_lines",
69
+ "summarize_measure_log",
70
+ "summarize_stepped_measure_log",
71
+ "cockcroft_walton_stage_gate",
72
+ "monte_carlo_tolerance_family_gate",
73
+ "bipolar_converter_efficiency_gate",
74
+ "bipolar_rail_power_quality_gate",
75
+ "series_rlc_complex_impedance_gate",
76
+ "rc_thermal_noise_psd_gate",
77
+ "balanced_three_phase_delta_rl_gate",
78
+ "ideal_transformer_identity_gate",
79
+ "validate_ltspice_v44_public_identity",
80
+ ]
81
+
82
+ from radia_gpu import __version__
@@ -0,0 +1,21 @@
1
+ """Shared artifact provenance predicates, independent of numbered gate APIs."""
2
+ from collections.abc import Mapping
3
+
4
+
5
+ def digest_is_sha256(value: object) -> bool:
6
+ """Require a hexadecimal string; accept either letter case."""
7
+ if not isinstance(value, str):
8
+ return False
9
+ text = value.lower()
10
+ return len(text) == 64 and all(char in "0123456789abcdef" for char in text)
11
+
12
+
13
+ def legacy_digest_is_sha256(value: object) -> bool:
14
+ """Preserve v43/v44 string coercion without weakening later contracts."""
15
+ return digest_is_sha256(str(value or ""))
16
+
17
+
18
+ def same_generation(contract: Mapping[str, object], *names: str) -> bool:
19
+ """Require every named field to equal the nonempty generation identifier."""
20
+ generation = str(contract.get("generation_id") or "")
21
+ return bool(generation) and all(contract.get(name) == generation for name in names)