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.
- radia_gpu/LICENSE +165 -0
- radia_gpu/README.md +137 -0
- radia_gpu/__init__.py +33 -0
- radia_gpu/ams-build.json +9 -0
- radia_gpu/ams_exchange.py +101 -0
- radia_gpu/build.json +15 -0
- radia_gpu/cli.py +16 -0
- radia_gpu/ltspice/LICENSE +21 -0
- radia_gpu/ltspice/__init__.py +82 -0
- radia_gpu/ltspice/_artifact_identity.py +21 -0
- radia_gpu/ltspice/_identity_circuit.py +1295 -0
- radia_gpu/ltspice/_identity_common.py +36 -0
- radia_gpu/ltspice/_identity_dynamic.py +1514 -0
- radia_gpu/ltspice/_identity_signal.py +1393 -0
- radia_gpu/ltspice/_identity_topology.py +771 -0
- radia_gpu/ltspice/_shared.py +68 -0
- radia_gpu/ltspice/allpass_gate.py +139 -0
- radia_gpu/ltspice/bandwidth_gate.py +125 -0
- radia_gpu/ltspice/bipolar_efficiency_gate.py +87 -0
- radia_gpu/ltspice/bipolar_rail_gate.py +161 -0
- radia_gpu/ltspice/bipolar_startup_gate.py +183 -0
- radia_gpu/ltspice/boost_gate.py +11 -0
- radia_gpu/ltspice/bridge_rectifier_gate.py +136 -0
- radia_gpu/ltspice/cli.py +1009 -0
- radia_gpu/ltspice/complex_zero_gate.py +227 -0
- radia_gpu/ltspice/conversion.py +110 -0
- radia_gpu/ltspice/distributed_line_gate.py +133 -0
- radia_gpu/ltspice/filter_gates.py +104 -0
- radia_gpu/ltspice/hysteresis_gate.py +138 -0
- radia_gpu/ltspice/ideal_transformer_gate.py +629 -0
- radia_gpu/ltspice/knowledge.py +171 -0
- radia_gpu/ltspice/learning_quality.py +68 -0
- radia_gpu/ltspice/ltspice_v43_gates.py +162 -0
- radia_gpu/ltspice/ltspice_v44_gates.py +82 -0
- radia_gpu/ltspice/ltspice_v45_gates.py +42 -0
- radia_gpu/ltspice/ltspice_v46_gates.py +90 -0
- radia_gpu/ltspice/ltspice_v47_gates.py +87 -0
- radia_gpu/ltspice/ltspice_v48_gates.py +95 -0
- radia_gpu/ltspice/ltspice_v49_gates.py +67 -0
- radia_gpu/ltspice/ltspice_v50_gates.py +173 -0
- radia_gpu/ltspice/ltspice_v51_gates.py +167 -0
- radia_gpu/ltspice/ltspice_v52_gates.py +87 -0
- radia_gpu/ltspice/ltspice_v53_gates.py +112 -0
- radia_gpu/ltspice/ltspice_v54_gates.py +120 -0
- radia_gpu/ltspice/ltspice_v55_gates.py +103 -0
- radia_gpu/ltspice/measure.py +372 -0
- radia_gpu/ltspice/monte_carlo_gate.py +170 -0
- radia_gpu/ltspice/noise_gate.py +132 -0
- radia_gpu/ltspice/parser/__init__.py +5 -0
- radia_gpu/ltspice/parser/asc_parser.py +1835 -0
- radia_gpu/ltspice/parser/asc_to_schemdraw.py +499 -0
- radia_gpu/ltspice/parser/cir_to_schemdraw.py +613 -0
- radia_gpu/ltspice/parser/netlist_to_asc.py +1929 -0
- radia_gpu/ltspice/parser/schemdraw_to_cir.py +822 -0
- radia_gpu/ltspice/parser/schemdraw_to_ltspice.py +460 -0
- radia_gpu/ltspice/patentability.py +189 -0
- radia_gpu/ltspice/psrr_gate.py +12 -0
- radia_gpu/ltspice/py.typed +1 -0
- radia_gpu/ltspice/rectifier_gate.py +7 -0
- radia_gpu/ltspice/series_rlc_gate.py +122 -0
- radia_gpu/ltspice/three_phase_delta_gate.py +331 -0
- radia_gpu/ltspice/topology.py +162 -0
- radia_gpu/ltspice/voltage_multiplier_gate.py +86 -0
- radia_gpu/maglev.py +52 -0
- radia_gpu/manifest.json +142 -0
- radia_gpu/matlab/+radia/+gpu/+internal/systemStore.m +23 -0
- radia_gpu/matlab/+radia/+gpu/amsPCG.m +13 -0
- radia_gpu/matlab/+radia/+gpu/csrPCG.m +11 -0
- radia_gpu/matlab/+radia/+gpu/readAMSExchange.m +49 -0
- radia_gpu/matlab/+radia/+gpu/requireRuntime.m +13 -0
- radia_gpu/matlab/+radia/+ltspice/+internal/terminateProcessTree.m +15 -0
- radia_gpu/matlab/+radia/+ltspice/AscEditor.m +8 -0
- radia_gpu/matlab/+radia/+ltspice/LTSpiceLogReader.m +8 -0
- radia_gpu/matlab/+radia/+ltspice/LTspice.m +72 -0
- radia_gpu/matlab/+radia/+ltspice/LogReader.m +68 -0
- radia_gpu/matlab/+radia/+ltspice/RawRead.m +229 -0
- radia_gpu/matlab/+radia/+ltspice/RawWrite.m +52 -0
- radia_gpu/matlab/+radia/+ltspice/RunTask.m +27 -0
- radia_gpu/matlab/+radia/+ltspice/SchematicEditor.m +136 -0
- radia_gpu/matlab/+radia/+ltspice/SimCommander.m +12 -0
- radia_gpu/matlab/+radia/+ltspice/SimRunner.m +132 -0
- radia_gpu/matlab/+radia/+ltspice/SpiceCircuit.m +8 -0
- radia_gpu/matlab/+radia/+ltspice/SpiceEditor.m +217 -0
- radia_gpu/matlab/+radia/+ltspice/Trace.m +15 -0
- radia_gpu/matlab/+radia/+ltspice/analyzeFFT.m +21 -0
- radia_gpu/matlab/+radia/+ltspice/applyTransientState.m +26 -0
- radia_gpu/matlab/+radia/+ltspice/collectDependencies.m +29 -0
- radia_gpu/matlab/+radia/+ltspice/collectSchematicDependencies.m +33 -0
- radia_gpu/matlab/+radia/+ltspice/extractTransientState.m +98 -0
- radia_gpu/matlab/+radia/+ltspice/findExecutable.m +35 -0
- radia_gpu/matlab/+radia/+ltspice/measureSeriesResonance.m +96 -0
- radia_gpu/matlab/+radia/+ltspice/netlistToSchematic.m +39 -0
- radia_gpu/matlab/+radia/+ltspice/readRaw.m +47 -0
- radia_gpu/matlab/+radia/+ltspice/readRawAscii.m +120 -0
- radia_gpu/matlab/+radia/+ltspice/readRawBinary.m +88 -0
- radia_gpu/matlab/+radia/+ltspice/run.m +175 -0
- radia_gpu/matlab/+radia/+ltspice/runIntervals.m +28 -0
- radia_gpu/matlab/+radia/+ltspice/runNoise.m +12 -0
- radia_gpu/matlab/+radia/+ltspice/schematicToNetlist.m +39 -0
- radia_gpu/matlab/+radia/+ltspice/writePwl.m +40 -0
- radia_gpu/matlab/+radia/+simulink/+internal/runArtifacts.m +65 -0
- radia_gpu/matlab/+radia/+simulink/buildCudaPCGBlock.m +21 -0
- radia_gpu/matlab/+radia/+simulink/buildLTspiceBlock.m +18 -0
- radia_gpu/matlab/+radia/+simulink/cudaPCGSFunction.m +96 -0
- radia_gpu/matlab/+radia/+simulink/ltspiceSFunction.m +82 -0
- radia_gpu/matlab/+radia/+simulink/runLTspice.m +64 -0
- radia_gpu/matlab/+radia/+simulink/runLTspiceClosedLoop.m +22 -0
- radia_gpu/matlab/+radia/+simulink/runLTspiceInterval.m +26 -0
- radia_gpu/matlab/radia_cuda_ams.mexw64 +0 -0
- radia_gpu/matlab/radia_cuda_csr_pcg.mexw64 +0 -0
- radia_gpu/matlab/radia_gpu_pcg_sfun.m +4 -0
- radia_gpu/matlab/radia_ltspice_sfun.m +4 -0
- radia_gpu/motor_rom_export.py +235 -0
- radia_gpu/ports.py +148 -0
- radia_gpu/simulink/__init__.py +16 -0
- radia_gpu/simulink/application.py +430 -0
- radia_gpu/simulink/contracts/ih_coil_bema_v1.json +13 -0
- radia_gpu/simulink/contracts/ih_thermal_axisym_v1.json +7 -0
- radia_gpu/simulink/contracts/ih_workpiece_v1.json +13 -0
- radia_gpu/simulink/ih_operator_assembly.py +1171 -0
- radia_gpu/vim.py +199 -0
- radia_gpu-0.1.0.dist-info/METADATA +166 -0
- radia_gpu-0.1.0.dist-info/RECORD +126 -0
- radia_gpu-0.1.0.dist-info/WHEEL +5 -0
- radia_gpu-0.1.0.dist-info/entry_points.txt +8 -0
- 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"])
|
radia_gpu/ams-build.json
ADDED
|
@@ -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)
|