mariepy 0.0.1__tar.gz
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.
- mariepy-0.0.1/.gitattributes +11 -0
- mariepy-0.0.1/.github/ISSUE_TEMPLATE/bug_report.yml +42 -0
- mariepy-0.0.1/.github/ISSUE_TEMPLATE/config.yml +8 -0
- mariepy-0.0.1/.github/ISSUE_TEMPLATE/feature_request.yml +31 -0
- mariepy-0.0.1/.github/PULL_REQUEST_TEMPLATE.md +24 -0
- mariepy-0.0.1/.github/dependabot.yml +39 -0
- mariepy-0.0.1/.github/workflows/codeql.yml +31 -0
- mariepy-0.0.1/.github/workflows/style.yml +42 -0
- mariepy-0.0.1/.github/workflows/tags-release.yml +58 -0
- mariepy-0.0.1/.github/workflows/test-ci.yml +56 -0
- mariepy-0.0.1/.github/workflows/wheels.yml +66 -0
- mariepy-0.0.1/.gitignore +28 -0
- mariepy-0.0.1/.pre-commit-config.yaml +27 -0
- mariepy-0.0.1/AGENTS.md +72 -0
- mariepy-0.0.1/CLAUDE.md +74 -0
- mariepy-0.0.1/CMakeLists.txt +72 -0
- mariepy-0.0.1/CODE_OF_CONDUCT.md +42 -0
- mariepy-0.0.1/CONTRIBUTING.md +45 -0
- mariepy-0.0.1/GEMINI.md +74 -0
- mariepy-0.0.1/LICENSE +674 -0
- mariepy-0.0.1/PKG-INFO +215 -0
- mariepy-0.0.1/PLAN.md +727 -0
- mariepy-0.0.1/README.md +179 -0
- mariepy-0.0.1/SECURITY.md +33 -0
- mariepy-0.0.1/THIRD_PARTY.md +54 -0
- mariepy-0.0.1/codecov.yml +24 -0
- mariepy-0.0.1/doc/milestone1.md +534 -0
- mariepy-0.0.1/examples/brainweb.py +303 -0
- mariepy-0.0.1/examples/brainweb_tissues.csv +10 -0
- mariepy-0.0.1/examples/multilayer_mie.py +104 -0
- mariepy-0.0.1/examples/tissue_gabriel.csv +4 -0
- mariepy-0.0.1/pyproject.toml +134 -0
- mariepy-0.0.1/scripts/format_and_lint.sh +21 -0
- mariepy-0.0.1/scripts/sync_agent_docs.sh +29 -0
- mariepy-0.0.1/setup.py +5 -0
- mariepy-0.0.1/src/cpp/convolution.cpp +294 -0
- mariepy-0.0.1/src/cpp/coupling.cpp +199 -0
- mariepy-0.0.1/src/cpp/green.hpp +65 -0
- mariepy-0.0.1/src/cpp/module.cpp +20 -0
- mariepy-0.0.1/src/cpp/volume.cpp +126 -0
- mariepy-0.0.1/src/cpp_lgpl/NOTICE.md +59 -0
- mariepy-0.0.1/src/cpp_lgpl/directfn_rwg/direct_ws_ea_rwg.cpp +2843 -0
- mariepy-0.0.1/src/cpp_lgpl/directfn_rwg/direct_ws_ea_rwg.h +141 -0
- mariepy-0.0.1/src/cpp_lgpl/directfn_rwg/direct_ws_st_rwg.cpp +1637 -0
- mariepy-0.0.1/src/cpp_lgpl/directfn_rwg/direct_ws_st_rwg.h +132 -0
- mariepy-0.0.1/src/cpp_lgpl/directfn_rwg/direct_ws_va_rwg.cpp +1054 -0
- mariepy-0.0.1/src/cpp_lgpl/directfn_rwg/direct_ws_va_rwg.h +129 -0
- mariepy-0.0.1/src/cpp_lgpl/directfn_vie/include/QUADRIC_WS_EA.h +36 -0
- mariepy-0.0.1/src/cpp_lgpl/directfn_vie/include/classes.h +420 -0
- mariepy-0.0.1/src/cpp_lgpl/directfn_vie/include/constants.h +67 -0
- mariepy-0.0.1/src/cpp_lgpl/directfn_vie/include/directfn.h +106 -0
- mariepy-0.0.1/src/cpp_lgpl/directfn_vie/include/directfn_ws_ea.h +44 -0
- mariepy-0.0.1/src/cpp_lgpl/directfn_vie/include/directfn_ws_st.h +46 -0
- mariepy-0.0.1/src/cpp_lgpl/directfn_vie/include/directfn_ws_va.h +36 -0
- mariepy-0.0.1/src/cpp_lgpl/directfn_vie/include/quadric_ws_st.h +29 -0
- mariepy-0.0.1/src/cpp_lgpl/directfn_vie/include/quadric_ws_va.h +24 -0
- mariepy-0.0.1/src/cpp_lgpl/directfn_vie/src_cpp/GL_1D.cpp +4075 -0
- mariepy-0.0.1/src/cpp_lgpl/directfn_vie/src_cpp/Kernels.cpp +517 -0
- mariepy-0.0.1/src/cpp_lgpl/directfn_vie/src_cpp/WS_EA/A_functions_ws_ea.cpp +64 -0
- mariepy-0.0.1/src/cpp_lgpl/directfn_vie/src_cpp/WS_EA/N_functions_ws_ea.cpp +331 -0
- mariepy-0.0.1/src/cpp_lgpl/directfn_vie/src_cpp/WS_EA/PSI_limits_ws_ea.cpp +50 -0
- mariepy-0.0.1/src/cpp_lgpl/directfn_vie/src_cpp/WS_EA/Simplex_ws_ea.cpp +28 -0
- mariepy-0.0.1/src/cpp_lgpl/directfn_vie/src_cpp/WS_EA/THETA_limits_ws_ea.cpp +51 -0
- mariepy-0.0.1/src/cpp_lgpl/directfn_vie/src_cpp/WS_EA/quadric_ws_ea.cpp +103 -0
- mariepy-0.0.1/src/cpp_lgpl/directfn_vie/src_cpp/WS_ST/a_functions_ws_st.cpp +69 -0
- mariepy-0.0.1/src/cpp_lgpl/directfn_vie/src_cpp/WS_ST/lambda_limits_ws_st.cpp +33 -0
- mariepy-0.0.1/src/cpp_lgpl/directfn_vie/src_cpp/WS_ST/n_functions_ws_st.cpp +47 -0
- mariepy-0.0.1/src/cpp_lgpl/directfn_vie/src_cpp/WS_ST/psi_limits_ws_st.cpp +37 -0
- mariepy-0.0.1/src/cpp_lgpl/directfn_vie/src_cpp/WS_ST/quadric_ws_st.cpp +94 -0
- mariepy-0.0.1/src/cpp_lgpl/directfn_vie/src_cpp/WS_ST/subtriangles_ws_st.cpp +29 -0
- mariepy-0.0.1/src/cpp_lgpl/directfn_vie/src_cpp/WS_ST/u_limits_ws_st.cpp +46 -0
- mariepy-0.0.1/src/cpp_lgpl/directfn_vie/src_cpp/WS_VA/quadric_ws_va.cpp +231 -0
- mariepy-0.0.1/src/cpp_lgpl/directfn_vie/src_cpp/WS_VA/rho_limits_ws_va.cpp +46 -0
- mariepy-0.0.1/src/cpp_lgpl/directfn_vie/src_cpp/WS_VA/theta_p_limits_ws_va.cpp +32 -0
- mariepy-0.0.1/src/cpp_lgpl/directfn_vie/src_cpp/WS_VA/theta_q_limits_ws_va.cpp +31 -0
- mariepy-0.0.1/src/cpp_lgpl/directfn_vie/src_cpp/classes.h +418 -0
- mariepy-0.0.1/src/cpp_lgpl/directfn_vie/src_cpp/create_EA.cpp +27 -0
- mariepy-0.0.1/src/cpp_lgpl/directfn_vie/src_cpp/create_ST.cpp +27 -0
- mariepy-0.0.1/src/cpp_lgpl/directfn_vie/src_cpp/create_VA.cpp +26 -0
- mariepy-0.0.1/src/cpp_lgpl/directfn_vie/src_cpp/directfn.h +106 -0
- mariepy-0.0.1/src/cpp_lgpl/module_directfn.cpp +316 -0
- mariepy-0.0.1/src/cpp_lgpl/rwg_namespace_ea.cpp +22 -0
- mariepy-0.0.1/src/cpp_lgpl/rwg_namespace_st.cpp +22 -0
- mariepy-0.0.1/src/cpp_lgpl/rwg_namespace_va.cpp +22 -0
- mariepy-0.0.1/src/mariepy/__init__.py +13 -0
- mariepy-0.0.1/src/mariepy/_accelerators.py +83 -0
- mariepy-0.0.1/src/mariepy/averaging.py +707 -0
- mariepy-0.0.1/src/mariepy/basis.py +1193 -0
- mariepy-0.0.1/src/mariepy/body.py +357 -0
- mariepy-0.0.1/src/mariepy/circuit.py +634 -0
- mariepy-0.0.1/src/mariepy/cli.py +321 -0
- mariepy-0.0.1/src/mariepy/coil.py +580 -0
- mariepy-0.0.1/src/mariepy/constants.py +133 -0
- mariepy-0.0.1/src/mariepy/cosim.py +1545 -0
- mariepy-0.0.1/src/mariepy/coupling.py +355 -0
- mariepy-0.0.1/src/mariepy/fields.py +387 -0
- mariepy-0.0.1/src/mariepy/gmres.py +307 -0
- mariepy-0.0.1/src/mariepy/implicit.py +829 -0
- mariepy-0.0.1/src/mariepy/incident.py +228 -0
- mariepy-0.0.1/src/mariepy/inputs.py +180 -0
- mariepy-0.0.1/src/mariepy/maps.py +198 -0
- mariepy-0.0.1/src/mariepy/mesh.py +547 -0
- mariepy-0.0.1/src/mariepy/metrics.py +291 -0
- mariepy-0.0.1/src/mariepy/network.py +107 -0
- mariepy-0.0.1/src/mariepy/pfft.py +1353 -0
- mariepy-0.0.1/src/mariepy/plot.py +599 -0
- mariepy-0.0.1/src/mariepy/preconditioner.py +50 -0
- mariepy-0.0.1/src/mariepy/quadrature.py +256 -0
- mariepy-0.0.1/src/mariepy/sar.py +179 -0
- mariepy-0.0.1/src/mariepy/shield.py +289 -0
- mariepy-0.0.1/src/mariepy/sie.py +789 -0
- mariepy-0.0.1/src/mariepy/solver.py +617 -0
- mariepy-0.0.1/src/mariepy/system.py +540 -0
- mariepy-0.0.1/src/mariepy/tissue.py +432 -0
- mariepy-0.0.1/src/mariepy/tt.py +455 -0
- mariepy-0.0.1/src/mariepy/tucker.py +337 -0
- mariepy-0.0.1/src/mariepy/vie.py +1664 -0
- mariepy-0.0.1/src/mariepy/vop.py +366 -0
- mariepy-0.0.1/src/mariepy/wire.py +1068 -0
- mariepy-0.0.1/tests/__init__.py +0 -0
- mariepy-0.0.1/tests/conftest.py +32 -0
- mariepy-0.0.1/tests/marie/Assemble_rwg_coupling_matrix_K_x.cpp +266 -0
- mariepy-0.0.1/tests/marie/Assemble_rwg_coupling_matrix_K_x1.cpp +267 -0
- mariepy-0.0.1/tests/marie/Assemble_rwg_coupling_matrix_K_x2.cpp +267 -0
- mariepy-0.0.1/tests/marie/Assemble_rwg_coupling_matrix_K_x3.cpp +267 -0
- mariepy-0.0.1/tests/marie/Assemble_rwg_coupling_matrix_K_y.cpp +267 -0
- mariepy-0.0.1/tests/marie/Assemble_rwg_coupling_matrix_K_y1.cpp +267 -0
- mariepy-0.0.1/tests/marie/Assemble_rwg_coupling_matrix_K_y2.cpp +267 -0
- mariepy-0.0.1/tests/marie/Assemble_rwg_coupling_matrix_K_y3.cpp +267 -0
- mariepy-0.0.1/tests/marie/Assemble_rwg_coupling_matrix_K_z.cpp +267 -0
- mariepy-0.0.1/tests/marie/Assemble_rwg_coupling_matrix_K_z1.cpp +267 -0
- mariepy-0.0.1/tests/marie/Assemble_rwg_coupling_matrix_K_z2.cpp +267 -0
- mariepy-0.0.1/tests/marie/Assemble_rwg_coupling_matrix_K_z3.cpp +267 -0
- mariepy-0.0.1/tests/marie/Assemble_rwg_coupling_matrix_N_x.cpp +267 -0
- mariepy-0.0.1/tests/marie/Assemble_rwg_coupling_matrix_N_x1.cpp +267 -0
- mariepy-0.0.1/tests/marie/Assemble_rwg_coupling_matrix_N_x2.cpp +267 -0
- mariepy-0.0.1/tests/marie/Assemble_rwg_coupling_matrix_N_x3.cpp +267 -0
- mariepy-0.0.1/tests/marie/Assemble_rwg_coupling_matrix_N_y.cpp +267 -0
- mariepy-0.0.1/tests/marie/Assemble_rwg_coupling_matrix_N_y1.cpp +267 -0
- mariepy-0.0.1/tests/marie/Assemble_rwg_coupling_matrix_N_y2.cpp +267 -0
- mariepy-0.0.1/tests/marie/Assemble_rwg_coupling_matrix_N_y3.cpp +267 -0
- mariepy-0.0.1/tests/marie/Assemble_rwg_coupling_matrix_N_z.cpp +267 -0
- mariepy-0.0.1/tests/marie/Assemble_rwg_coupling_matrix_N_z1.cpp +267 -0
- mariepy-0.0.1/tests/marie/Assemble_rwg_coupling_matrix_N_z2.cpp +267 -0
- mariepy-0.0.1/tests/marie/Assemble_rwg_coupling_matrix_N_z3.cpp +267 -0
- mariepy-0.0.1/tests/marie/wire/Assemble_tri_coupling_matrix_K_x.cpp +262 -0
- mariepy-0.0.1/tests/marie/wire/Assemble_tri_coupling_matrix_K_x1.cpp +262 -0
- mariepy-0.0.1/tests/marie/wire/Assemble_tri_coupling_matrix_K_x2.cpp +262 -0
- mariepy-0.0.1/tests/marie/wire/Assemble_tri_coupling_matrix_K_x3.cpp +262 -0
- mariepy-0.0.1/tests/marie/wire/Assemble_tri_coupling_matrix_K_y.cpp +262 -0
- mariepy-0.0.1/tests/marie/wire/Assemble_tri_coupling_matrix_K_y1.cpp +262 -0
- mariepy-0.0.1/tests/marie/wire/Assemble_tri_coupling_matrix_K_y2.cpp +262 -0
- mariepy-0.0.1/tests/marie/wire/Assemble_tri_coupling_matrix_K_y3.cpp +262 -0
- mariepy-0.0.1/tests/marie/wire/Assemble_tri_coupling_matrix_K_z.cpp +262 -0
- mariepy-0.0.1/tests/marie/wire/Assemble_tri_coupling_matrix_K_z1.cpp +262 -0
- mariepy-0.0.1/tests/marie/wire/Assemble_tri_coupling_matrix_K_z2.cpp +262 -0
- mariepy-0.0.1/tests/marie/wire/Assemble_tri_coupling_matrix_K_z3.cpp +262 -0
- mariepy-0.0.1/tests/marie/wire/Assemble_tri_coupling_matrix_N_x.cpp +262 -0
- mariepy-0.0.1/tests/marie/wire/Assemble_tri_coupling_matrix_N_x1.cpp +262 -0
- mariepy-0.0.1/tests/marie/wire/Assemble_tri_coupling_matrix_N_x2.cpp +262 -0
- mariepy-0.0.1/tests/marie/wire/Assemble_tri_coupling_matrix_N_x3.cpp +262 -0
- mariepy-0.0.1/tests/marie/wire/Assemble_tri_coupling_matrix_N_y.cpp +262 -0
- mariepy-0.0.1/tests/marie/wire/Assemble_tri_coupling_matrix_N_y1.cpp +262 -0
- mariepy-0.0.1/tests/marie/wire/Assemble_tri_coupling_matrix_N_y2.cpp +262 -0
- mariepy-0.0.1/tests/marie/wire/Assemble_tri_coupling_matrix_N_y3.cpp +262 -0
- mariepy-0.0.1/tests/marie/wire/Assemble_tri_coupling_matrix_N_z.cpp +262 -0
- mariepy-0.0.1/tests/marie/wire/Assemble_tri_coupling_matrix_N_z1.cpp +262 -0
- mariepy-0.0.1/tests/marie/wire/Assemble_tri_coupling_matrix_N_z2.cpp +262 -0
- mariepy-0.0.1/tests/marie/wire/Assemble_tri_coupling_matrix_N_z3.cpp +262 -0
- mariepy-0.0.1/tests/marie_files.py +126 -0
- mariepy-0.0.1/tests/mie.py +392 -0
- mariepy-0.0.1/tests/parity.py +310 -0
- mariepy-0.0.1/tests/pec.py +53 -0
- mariepy-0.0.1/tests/test_averaging.py +420 -0
- mariepy-0.0.1/tests/test_basis.py +676 -0
- mariepy-0.0.1/tests/test_body.py +248 -0
- mariepy-0.0.1/tests/test_circuit.py +248 -0
- mariepy-0.0.1/tests/test_cli.py +52 -0
- mariepy-0.0.1/tests/test_coil.py +381 -0
- mariepy-0.0.1/tests/test_constants.py +66 -0
- mariepy-0.0.1/tests/test_cosim.py +473 -0
- mariepy-0.0.1/tests/test_coupling.py +301 -0
- mariepy-0.0.1/tests/test_directfn.py +246 -0
- mariepy-0.0.1/tests/test_docstrings.py +30 -0
- mariepy-0.0.1/tests/test_fields.py +317 -0
- mariepy-0.0.1/tests/test_gmres.py +292 -0
- mariepy-0.0.1/tests/test_implicit.py +361 -0
- mariepy-0.0.1/tests/test_incident.py +84 -0
- mariepy-0.0.1/tests/test_inputs.py +214 -0
- mariepy-0.0.1/tests/test_linear.py +339 -0
- mariepy-0.0.1/tests/test_linear_coupled.py +156 -0
- mariepy-0.0.1/tests/test_maps.py +66 -0
- mariepy-0.0.1/tests/test_mesh.py +231 -0
- mariepy-0.0.1/tests/test_metrics.py +132 -0
- mariepy-0.0.1/tests/test_mie.py +283 -0
- mariepy-0.0.1/tests/test_near.py +341 -0
- mariepy-0.0.1/tests/test_network.py +69 -0
- mariepy-0.0.1/tests/test_pfft.py +393 -0
- mariepy-0.0.1/tests/test_plot.py +176 -0
- mariepy-0.0.1/tests/test_quadrature.py +158 -0
- mariepy-0.0.1/tests/test_sar.py +121 -0
- mariepy-0.0.1/tests/test_shield.py +266 -0
- mariepy-0.0.1/tests/test_sie.py +419 -0
- mariepy-0.0.1/tests/test_smoke.py +8 -0
- mariepy-0.0.1/tests/test_system.py +245 -0
- mariepy-0.0.1/tests/test_tissue.py +390 -0
- mariepy-0.0.1/tests/test_tt.py +155 -0
- mariepy-0.0.1/tests/test_tucker.py +156 -0
- mariepy-0.0.1/tests/test_vie.py +422 -0
- mariepy-0.0.1/tests/test_vop.py +317 -0
- mariepy-0.0.1/tests/test_wire.py +616 -0
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
name: Bug report
|
|
2
|
+
description: Something behaves differently from what it says it does.
|
|
3
|
+
labels: ["bug"]
|
|
4
|
+
body:
|
|
5
|
+
- type: textarea
|
|
6
|
+
id: what-happened
|
|
7
|
+
attributes:
|
|
8
|
+
label: What happened
|
|
9
|
+
description: What did you expect, and what did you get instead?
|
|
10
|
+
validations:
|
|
11
|
+
required: true
|
|
12
|
+
|
|
13
|
+
- type: textarea
|
|
14
|
+
id: reproduce
|
|
15
|
+
attributes:
|
|
16
|
+
label: Smallest reproduction
|
|
17
|
+
description: >
|
|
18
|
+
Code we can run. Prefer synthetic arrays over a data file; if the shape
|
|
19
|
+
of real data matters, give the shapes and dtypes.
|
|
20
|
+
render: python
|
|
21
|
+
validations:
|
|
22
|
+
required: true
|
|
23
|
+
|
|
24
|
+
- type: textarea
|
|
25
|
+
id: environment
|
|
26
|
+
attributes:
|
|
27
|
+
label: Environment
|
|
28
|
+
description: >
|
|
29
|
+
Output of `python -c "import mariepy, sys, torch;
|
|
30
|
+
print(mariepy.__version__, sys.version, torch.__version__,
|
|
31
|
+
torch.cuda.get_device_name(0) if torch.cuda.is_available() else 'cpu')"`
|
|
32
|
+
render: shell
|
|
33
|
+
validations:
|
|
34
|
+
required: true
|
|
35
|
+
|
|
36
|
+
- type: dropdown
|
|
37
|
+
id: device
|
|
38
|
+
attributes:
|
|
39
|
+
label: Where it happens
|
|
40
|
+
options: ["CPU only", "CUDA only", "Both"]
|
|
41
|
+
validations:
|
|
42
|
+
required: true
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
blank_issues_enabled: false
|
|
2
|
+
contact_links:
|
|
3
|
+
- name: Question or idea
|
|
4
|
+
url: https://github.com/pulserver/mariepy/discussions
|
|
5
|
+
about: Ask about usage, or propose something before it is a bug report.
|
|
6
|
+
- name: Security vulnerability
|
|
7
|
+
url: https://github.com/pulserver/mariepy/security/advisories/new
|
|
8
|
+
about: Report privately. Please do not open a public issue.
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
name: Feature request
|
|
2
|
+
description: Something this package should be able to do and cannot.
|
|
3
|
+
labels: ["enhancement"]
|
|
4
|
+
body:
|
|
5
|
+
- type: textarea
|
|
6
|
+
id: problem
|
|
7
|
+
attributes:
|
|
8
|
+
label: The problem
|
|
9
|
+
description: What are you trying to do, and where does it stop?
|
|
10
|
+
validations:
|
|
11
|
+
required: true
|
|
12
|
+
|
|
13
|
+
- type: textarea
|
|
14
|
+
id: proposal
|
|
15
|
+
attributes:
|
|
16
|
+
label: What you have in mind
|
|
17
|
+
description: >
|
|
18
|
+
A sketch of the API, if you have one. If there is a paper or another
|
|
19
|
+
implementation that does this, name it — that is usually the fastest
|
|
20
|
+
way to agree on what is wanted.
|
|
21
|
+
validations:
|
|
22
|
+
required: true
|
|
23
|
+
|
|
24
|
+
- type: textarea
|
|
25
|
+
id: layer
|
|
26
|
+
attributes:
|
|
27
|
+
label: Which layer this belongs to
|
|
28
|
+
description: >
|
|
29
|
+
This package is one of a family with a strict layering (`mrutils` at the
|
|
30
|
+
base, `deepmr` at the top). If the feature needs something from a
|
|
31
|
+
sibling package, say which — that usually means it belongs elsewhere.
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
## What this changes
|
|
2
|
+
|
|
3
|
+
<!-- One or two sentences. What behaviour is different afterwards? -->
|
|
4
|
+
|
|
5
|
+
## Why
|
|
6
|
+
|
|
7
|
+
<!-- The problem this solves. Link the issue if there is one. -->
|
|
8
|
+
|
|
9
|
+
## How it was verified
|
|
10
|
+
|
|
11
|
+
<!-- The commands you ran and what they said. Paste the output, don't
|
|
12
|
+
summarise it. "Tests pass" is not verification. -->
|
|
13
|
+
|
|
14
|
+
```
|
|
15
|
+
```
|
|
16
|
+
|
|
17
|
+
## Checklist
|
|
18
|
+
|
|
19
|
+
- [ ] `bash scripts/format_and_lint.sh` is clean
|
|
20
|
+
- [ ] `pytest -q` passes, and new behaviour has a test whose name states the
|
|
21
|
+
invariant it protects
|
|
22
|
+
- [ ] Anything numerical is exercised on CPU and CUDA, or the CUDA leg is
|
|
23
|
+
marked `@pytest.mark.cuda` and skips cleanly
|
|
24
|
+
- [ ] No comment or docstring describes the code's history
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
version: 2
|
|
2
|
+
updates:
|
|
3
|
+
# The Actions in .github/workflows pin third-party code that runs with
|
|
4
|
+
# repository credentials, so these are the updates worth having weekly.
|
|
5
|
+
- package-ecosystem: github-actions
|
|
6
|
+
directory: "/"
|
|
7
|
+
schedule:
|
|
8
|
+
interval: weekly
|
|
9
|
+
day: monday
|
|
10
|
+
labels: ["dependencies", "ci"]
|
|
11
|
+
commit-message:
|
|
12
|
+
prefix: "ci"
|
|
13
|
+
groups:
|
|
14
|
+
actions:
|
|
15
|
+
patterns: ["*"]
|
|
16
|
+
|
|
17
|
+
# Grouped so the numerical stack arrives as one pull request that can be
|
|
18
|
+
# tested together rather than as several that each need a full suite run.
|
|
19
|
+
- package-ecosystem: pip
|
|
20
|
+
directory: "/"
|
|
21
|
+
schedule:
|
|
22
|
+
interval: weekly
|
|
23
|
+
day: monday
|
|
24
|
+
open-pull-requests-limit: 5
|
|
25
|
+
labels: ["dependencies", "python"]
|
|
26
|
+
commit-message:
|
|
27
|
+
prefix: "deps"
|
|
28
|
+
groups:
|
|
29
|
+
numerical:
|
|
30
|
+
patterns: ["numpy", "scipy", "torch*", "triton", "mri-nufft", "finufft", "cufinufft"]
|
|
31
|
+
mr-stack:
|
|
32
|
+
patterns: ["mrutils", "mrtoeplitz", "mrllr", "mrmotion", "mrdistortion", "torchsolve", "deepinv", "SimpleITK"]
|
|
33
|
+
dev-tooling:
|
|
34
|
+
patterns: ["pytest*", "coverage", "ruff", "pre-commit", "build", "sphinx*"]
|
|
35
|
+
ignore:
|
|
36
|
+
# Torch major bumps move the CUDA runtime under the whole family, so they
|
|
37
|
+
# are a deliberate decision rather than a routine update.
|
|
38
|
+
- dependency-name: "torch"
|
|
39
|
+
update-types: ["version-update:semver-major"]
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
name: CodeQL
|
|
2
|
+
|
|
3
|
+
on:
|
|
4
|
+
push:
|
|
5
|
+
branches: [main]
|
|
6
|
+
pull_request:
|
|
7
|
+
branches: [main]
|
|
8
|
+
|
|
9
|
+
jobs:
|
|
10
|
+
analyze:
|
|
11
|
+
name: Analyze Python
|
|
12
|
+
runs-on: ubuntu-latest
|
|
13
|
+
# Code scanning on a private repository needs GitHub Advanced Security,
|
|
14
|
+
# and uploading results without it is a hard error rather than a warning.
|
|
15
|
+
# The job stands down while the repository is private and starts working
|
|
16
|
+
# on its own once it is made public.
|
|
17
|
+
if: github.event.repository.visibility == 'public'
|
|
18
|
+
permissions:
|
|
19
|
+
security-events: write
|
|
20
|
+
packages: read
|
|
21
|
+
actions: read
|
|
22
|
+
contents: read
|
|
23
|
+
steps:
|
|
24
|
+
- uses: actions/checkout@v7
|
|
25
|
+
- uses: github/codeql-action/init@v4
|
|
26
|
+
with:
|
|
27
|
+
languages: python
|
|
28
|
+
build-mode: none
|
|
29
|
+
- uses: github/codeql-action/analyze@v4
|
|
30
|
+
with:
|
|
31
|
+
category: "/language:python"
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
name: Style
|
|
2
|
+
|
|
3
|
+
# Runs the same script pre-commit runs, in --check mode: nothing is rewritten
|
|
4
|
+
# and any file that would change fails the job.
|
|
5
|
+
|
|
6
|
+
on:
|
|
7
|
+
# A branch is tested once, through its pull request.
|
|
8
|
+
push:
|
|
9
|
+
branches: [main]
|
|
10
|
+
pull_request:
|
|
11
|
+
workflow_dispatch:
|
|
12
|
+
|
|
13
|
+
concurrency:
|
|
14
|
+
group: ${{ github.workflow }}-${{ github.ref }}
|
|
15
|
+
cancel-in-progress: true
|
|
16
|
+
|
|
17
|
+
jobs:
|
|
18
|
+
format-and-lint:
|
|
19
|
+
runs-on: ubuntu-latest
|
|
20
|
+
steps:
|
|
21
|
+
- uses: actions/checkout@v7
|
|
22
|
+
- uses: actions/setup-python@v7
|
|
23
|
+
with:
|
|
24
|
+
python-version: "3.11"
|
|
25
|
+
|
|
26
|
+
# The linter only, taken from the same `dev` extra a contributor's
|
|
27
|
+
# pre-commit installs, so both apply one ruff. Installing the extra whole
|
|
28
|
+
# would download the runtime for a job that never imports it.
|
|
29
|
+
- name: Install ruff
|
|
30
|
+
run: |
|
|
31
|
+
python -m pip install --upgrade pip
|
|
32
|
+
python - <<'PY' > "$RUNNER_TEMP/lint-requirements.txt"
|
|
33
|
+
import tomllib
|
|
34
|
+
|
|
35
|
+
with open("pyproject.toml", "rb") as pyproject:
|
|
36
|
+
dev = tomllib.load(pyproject)["project"]["optional-dependencies"]["dev"]
|
|
37
|
+
print("\n".join(line for line in dev if line.startswith("ruff")))
|
|
38
|
+
PY
|
|
39
|
+
python -m pip install -r "$RUNNER_TEMP/lint-requirements.txt"
|
|
40
|
+
|
|
41
|
+
- name: Format and lint (check only)
|
|
42
|
+
run: bash scripts/format_and_lint.sh --check
|
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
name: Release
|
|
2
|
+
|
|
3
|
+
# Publishes a tagged version: the wheels and sdist from the reusable Wheels
|
|
4
|
+
# workflow, then PyPI and a signed GitHub release. The version comes from the
|
|
5
|
+
# tag via setuptools_scm.
|
|
6
|
+
|
|
7
|
+
on:
|
|
8
|
+
push:
|
|
9
|
+
tags:
|
|
10
|
+
- "v[0-9]+.[0-9]+.[0-9]+"
|
|
11
|
+
|
|
12
|
+
jobs:
|
|
13
|
+
build:
|
|
14
|
+
uses: ./.github/workflows/wheels.yml
|
|
15
|
+
with:
|
|
16
|
+
cibw-build: "cp310-* cp311-* cp312-* cp313-* cp314-*"
|
|
17
|
+
|
|
18
|
+
publish-to-pypi:
|
|
19
|
+
needs: [build]
|
|
20
|
+
runs-on: ubuntu-latest
|
|
21
|
+
environment:
|
|
22
|
+
name: pypi
|
|
23
|
+
url: https://pypi.org/p/mariepy
|
|
24
|
+
permissions:
|
|
25
|
+
id-token: write # trusted publishing (OIDC)
|
|
26
|
+
steps:
|
|
27
|
+
- uses: actions/download-artifact@v8
|
|
28
|
+
with:
|
|
29
|
+
pattern: "{wheels-*,sdist}"
|
|
30
|
+
path: dist
|
|
31
|
+
merge-multiple: true
|
|
32
|
+
- uses: pypa/gh-action-pypi-publish@release/v1
|
|
33
|
+
|
|
34
|
+
github-release:
|
|
35
|
+
needs: [publish-to-pypi]
|
|
36
|
+
runs-on: ubuntu-latest
|
|
37
|
+
permissions:
|
|
38
|
+
contents: write # create the release
|
|
39
|
+
id-token: write # sigstore
|
|
40
|
+
steps:
|
|
41
|
+
- uses: actions/download-artifact@v8
|
|
42
|
+
with:
|
|
43
|
+
pattern: "{wheels-*,sdist}"
|
|
44
|
+
path: dist
|
|
45
|
+
merge-multiple: true
|
|
46
|
+
- uses: sigstore/gh-action-sigstore-python@v3.5.0
|
|
47
|
+
with:
|
|
48
|
+
inputs: |
|
|
49
|
+
./dist/*.tar.gz
|
|
50
|
+
./dist/*.whl
|
|
51
|
+
- env:
|
|
52
|
+
GITHUB_TOKEN: ${{ github.token }}
|
|
53
|
+
run: |
|
|
54
|
+
gh release create '${{ github.ref_name }}' \
|
|
55
|
+
--repo '${{ github.repository }}' \
|
|
56
|
+
--title '${{ github.ref_name }}' \
|
|
57
|
+
--generate-notes
|
|
58
|
+
gh release upload '${{ github.ref_name }}' dist/** --repo '${{ github.repository }}'
|
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
name: Tests
|
|
2
|
+
|
|
3
|
+
on:
|
|
4
|
+
# A branch is tested once, through its pull request.
|
|
5
|
+
push:
|
|
6
|
+
branches: [main]
|
|
7
|
+
pull_request:
|
|
8
|
+
workflow_dispatch:
|
|
9
|
+
|
|
10
|
+
concurrency:
|
|
11
|
+
group: ${{ github.workflow }}-${{ github.ref }}
|
|
12
|
+
cancel-in-progress: true
|
|
13
|
+
|
|
14
|
+
jobs:
|
|
15
|
+
test:
|
|
16
|
+
name: Python ${{ matrix.python-version }}
|
|
17
|
+
runs-on: ubuntu-latest
|
|
18
|
+
strategy:
|
|
19
|
+
fail-fast: false
|
|
20
|
+
matrix:
|
|
21
|
+
# The floor and the ceiling of the supported band: an intermediate
|
|
22
|
+
# release that fails on neither is not a plausible failure.
|
|
23
|
+
python-version: ["3.10", "3.14"]
|
|
24
|
+
steps:
|
|
25
|
+
- uses: actions/checkout@v7
|
|
26
|
+
with:
|
|
27
|
+
fetch-depth: 0 # setuptools_scm reads the tags
|
|
28
|
+
|
|
29
|
+
- uses: actions/setup-python@v7
|
|
30
|
+
with:
|
|
31
|
+
python-version: ${{ matrix.python-version }}
|
|
32
|
+
cache: pip
|
|
33
|
+
|
|
34
|
+
# torch's CPU build: PyPI's carries the CUDA libraries, gigabytes this
|
|
35
|
+
# runner has no device for.
|
|
36
|
+
- name: Install
|
|
37
|
+
run: |
|
|
38
|
+
python -m pip install --upgrade pip
|
|
39
|
+
python -m pip install torch --index-url https://download.pytorch.org/whl/cpu
|
|
40
|
+
python -m pip install .[dev]
|
|
41
|
+
|
|
42
|
+
# No device here, so this run is also the check that every CUDA-marked
|
|
43
|
+
# test skips cleanly without one: -rs lists the skips. One worker per
|
|
44
|
+
# core, each held to one thread so the workers do not contend.
|
|
45
|
+
- name: Run the tests
|
|
46
|
+
env:
|
|
47
|
+
OMP_NUM_THREADS: 1
|
|
48
|
+
OPENBLAS_NUM_THREADS: 1
|
|
49
|
+
MKL_NUM_THREADS: 1
|
|
50
|
+
run: pytest -q -rs -n auto --cov --cov-report=xml
|
|
51
|
+
|
|
52
|
+
- uses: codecov/codecov-action@v7
|
|
53
|
+
with:
|
|
54
|
+
fail_ci_if_error: false
|
|
55
|
+
token: ${{ secrets.CODECOV_TOKEN }}
|
|
56
|
+
slug: pulserver/mariepy
|
|
@@ -0,0 +1,66 @@
|
|
|
1
|
+
name: Wheels
|
|
2
|
+
|
|
3
|
+
# Reusable: the release workflow calls this so what is published was built by
|
|
4
|
+
# the same job pull requests exercise.
|
|
5
|
+
|
|
6
|
+
on:
|
|
7
|
+
workflow_call:
|
|
8
|
+
inputs:
|
|
9
|
+
cibw-build:
|
|
10
|
+
description: Interpreters to build, as a CIBW_BUILD pattern.
|
|
11
|
+
type: string
|
|
12
|
+
required: true
|
|
13
|
+
workflow_dispatch:
|
|
14
|
+
inputs:
|
|
15
|
+
cibw-build:
|
|
16
|
+
description: Interpreters to build, as a CIBW_BUILD pattern.
|
|
17
|
+
type: string
|
|
18
|
+
default: "cp310-* cp311-* cp312-* cp313-* cp314-*"
|
|
19
|
+
|
|
20
|
+
jobs:
|
|
21
|
+
wheels:
|
|
22
|
+
name: ${{ matrix.os }}
|
|
23
|
+
runs-on: ${{ matrix.os }}
|
|
24
|
+
strategy:
|
|
25
|
+
fail-fast: false
|
|
26
|
+
matrix:
|
|
27
|
+
# Linux and macOS only. The kernels' SIMD paths are guarded on GCC and
|
|
28
|
+
# Clang, so a Windows build would take the scalar path; add it when
|
|
29
|
+
# someone needs it rather than paying for it on every release.
|
|
30
|
+
os: [ubuntu-latest, macos-14]
|
|
31
|
+
steps:
|
|
32
|
+
- uses: actions/checkout@v7
|
|
33
|
+
with:
|
|
34
|
+
fetch-depth: 0 # setuptools_scm reads the tags
|
|
35
|
+
|
|
36
|
+
- uses: pypa/cibuildwheel@v4.3.4
|
|
37
|
+
env:
|
|
38
|
+
CIBW_BUILD: ${{ inputs.cibw-build }}
|
|
39
|
+
CIBW_SKIP: "*-musllinux_*"
|
|
40
|
+
CIBW_ARCHS_LINUX: x86_64
|
|
41
|
+
CIBW_ARCHS_MACOS: arm64
|
|
42
|
+
CIBW_TEST_COMMAND: "python -c \"import mariepy; print(mariepy.__version__)\""
|
|
43
|
+
|
|
44
|
+
- uses: actions/upload-artifact@v7
|
|
45
|
+
with:
|
|
46
|
+
name: wheels-${{ matrix.os }}
|
|
47
|
+
path: wheelhouse/*.whl
|
|
48
|
+
if-no-files-found: error
|
|
49
|
+
|
|
50
|
+
sdist:
|
|
51
|
+
runs-on: ubuntu-latest
|
|
52
|
+
steps:
|
|
53
|
+
- uses: actions/checkout@v7
|
|
54
|
+
with:
|
|
55
|
+
fetch-depth: 0
|
|
56
|
+
- uses: actions/setup-python@v7
|
|
57
|
+
with:
|
|
58
|
+
python-version: "3.11"
|
|
59
|
+
- run: |
|
|
60
|
+
python -m pip install --upgrade pip build
|
|
61
|
+
python -m build --sdist
|
|
62
|
+
- uses: actions/upload-artifact@v7
|
|
63
|
+
with:
|
|
64
|
+
name: sdist
|
|
65
|
+
path: dist/*.tar.gz
|
|
66
|
+
if-no-files-found: error
|
mariepy-0.0.1/.gitignore
ADDED
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
__pycache__/
|
|
2
|
+
*.py[cod]
|
|
3
|
+
*.so
|
|
4
|
+
.Python
|
|
5
|
+
build/
|
|
6
|
+
dist/
|
|
7
|
+
wheelhouse/
|
|
8
|
+
*.egg-info/
|
|
9
|
+
.eggs/
|
|
10
|
+
|
|
11
|
+
.venv/
|
|
12
|
+
venv/
|
|
13
|
+
.env
|
|
14
|
+
|
|
15
|
+
.pytest_cache/
|
|
16
|
+
.ruff_cache/
|
|
17
|
+
.mypy_cache/
|
|
18
|
+
.coverage
|
|
19
|
+
.coverage.*
|
|
20
|
+
coverage.xml
|
|
21
|
+
htmlcov/
|
|
22
|
+
|
|
23
|
+
.idea/
|
|
24
|
+
.vscode/
|
|
25
|
+
.DS_Store
|
|
26
|
+
|
|
27
|
+
# Benchmark inputs are fetched, never committed.
|
|
28
|
+
data/
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
# The rules live in scripts/format_and_lint.sh, which the Style workflow also
|
|
2
|
+
# runs (there with --check). One entry point means a commit cannot pass locally
|
|
3
|
+
# and fail in CI on style.
|
|
4
|
+
repos:
|
|
5
|
+
- repo: local
|
|
6
|
+
hooks:
|
|
7
|
+
- id: format-and-lint
|
|
8
|
+
name: format and lint
|
|
9
|
+
entry: bash scripts/format_and_lint.sh
|
|
10
|
+
language: system
|
|
11
|
+
pass_filenames: false
|
|
12
|
+
types_or: [python, markdown]
|
|
13
|
+
|
|
14
|
+
- repo: https://github.com/pre-commit/pre-commit-hooks
|
|
15
|
+
rev: v6.0.0
|
|
16
|
+
hooks:
|
|
17
|
+
- id: check-merge-conflict
|
|
18
|
+
- id: end-of-file-fixer
|
|
19
|
+
- id: trailing-whitespace
|
|
20
|
+
- id: check-yaml
|
|
21
|
+
- id: check-toml
|
|
22
|
+
- id: check-added-large-files
|
|
23
|
+
args: [--maxkb=1024]
|
|
24
|
+
- id: check-symlinks
|
|
25
|
+
- id: destroyed-symlinks
|
|
26
|
+
- id: mixed-line-ending
|
|
27
|
+
args: [--fix=lf]
|
mariepy-0.0.1/AGENTS.md
ADDED
|
@@ -0,0 +1,72 @@
|
|
|
1
|
+
# mariepy — agent instructions
|
|
2
|
+
|
|
3
|
+
<!--
|
|
4
|
+
This file is the SOURCE. CLAUDE.md and GEMINI.md are generated from it by
|
|
5
|
+
scripts/sync_agent_docs.sh, which pre-commit runs. Edit this file, never those.
|
|
6
|
+
-->
|
|
7
|
+
|
|
8
|
+
## What this package is
|
|
9
|
+
|
|
10
|
+
Electromagnetic simulation of MRI transmit coils and virtual observation points
|
|
11
|
+
(VOPs) for SAR, ported from MARIE 3.0 (<https://github.com/cloudmrhub/marie-tools>,
|
|
12
|
+
MIT).
|
|
13
|
+
|
|
14
|
+
`PLAN.md` is the design brief: scope, the VOP file contract, the port's
|
|
15
|
+
milestones, validation, constraints and later stages. Read it before starting
|
|
16
|
+
work. When a decision it records changes, change `PLAN.md` in the same pull
|
|
17
|
+
request.
|
|
18
|
+
|
|
19
|
+
mariepy stands alone: it depends on torch and numpy, not on other MRI packages.
|
|
20
|
+
Its one external contract is the VOP file that pypulseqpp reads.
|
|
21
|
+
|
|
22
|
+
## Build and test
|
|
23
|
+
|
|
24
|
+
```bash
|
|
25
|
+
pip install -e .[dev]
|
|
26
|
+
bash scripts/format_and_lint.sh # rewrites in place; --check to verify only
|
|
27
|
+
pytest -q
|
|
28
|
+
```
|
|
29
|
+
|
|
30
|
+
Build and test steps are mandatory before reporting a change complete. Run them
|
|
31
|
+
and report the exact output; do not assume success.
|
|
32
|
+
|
|
33
|
+
## Tests
|
|
34
|
+
|
|
35
|
+
pytest with plain functions and fixtures — never `unittest.TestCase`. A test
|
|
36
|
+
name states the invariant it protects, so a failure reads as a sentence.
|
|
37
|
+
|
|
38
|
+
Anything numerical that can run on CPU and CUDA is parametrised over both, and
|
|
39
|
+
the CUDA leg skips when no device is present. A kernel-layout check that ran on
|
|
40
|
+
CPU only has passed in this codebase while CUDA was 100% wrong.
|
|
41
|
+
|
|
42
|
+
## Comments and docstrings
|
|
43
|
+
|
|
44
|
+
Write for someone reading the code as it is now, who has no memory of any
|
|
45
|
+
earlier version of it. **Never** write text whose subject is the history of the
|
|
46
|
+
code. Banned in comments, docstrings and prose alike:
|
|
47
|
+
|
|
48
|
+
- "used to", "was once", "no longer", "previously", "now that", "this replaces",
|
|
49
|
+
"the old X", "before the fix"
|
|
50
|
+
- justifying the present shape by contrast with a shape that is gone
|
|
51
|
+
- naming a bug that has been fixed, or the session that fixed it
|
|
52
|
+
- restating what the code plainly says
|
|
53
|
+
|
|
54
|
+
A docstring carries what a caller needs: one line of what, Parameters, Returns,
|
|
55
|
+
Raises. A comment earns its place only by explaining a non-obvious algorithm or
|
|
56
|
+
a choice a reader would otherwise undo — and even then, prefer a well-named
|
|
57
|
+
function or a test whose name states the invariant, because those cannot go
|
|
58
|
+
stale silently. When tempted to explain *why not the other way*, write a test.
|
|
59
|
+
|
|
60
|
+
Stale comments are actively harmful. Deleting an outdated comment is always
|
|
61
|
+
correct; rewriting one to describe the change is not.
|
|
62
|
+
|
|
63
|
+
## Documentation style
|
|
64
|
+
|
|
65
|
+
The audience is MR scientists. Write in the vocabulary of pulse sequences and
|
|
66
|
+
physics, not of software architecture. Never justify a design by describing the
|
|
67
|
+
design it replaced.
|
|
68
|
+
|
|
69
|
+
Do not print a measured constant that is not guaranteed across releases or
|
|
70
|
+
hardware. Name the symbol and where it comes from, and let the build supply the
|
|
71
|
+
number. Benchmark tables in the README are regenerated by the benchmark script,
|
|
72
|
+
not typed in.
|
mariepy-0.0.1/CLAUDE.md
ADDED
|
@@ -0,0 +1,74 @@
|
|
|
1
|
+
<!-- Generated from AGENTS.md by scripts/sync_agent_docs.sh. Do not edit. -->
|
|
2
|
+
|
|
3
|
+
# mariepy — agent instructions
|
|
4
|
+
|
|
5
|
+
<!--
|
|
6
|
+
This file is the SOURCE. CLAUDE.md and GEMINI.md are generated from it by
|
|
7
|
+
scripts/sync_agent_docs.sh, which pre-commit runs. Edit this file, never those.
|
|
8
|
+
-->
|
|
9
|
+
|
|
10
|
+
## What this package is
|
|
11
|
+
|
|
12
|
+
Electromagnetic simulation of MRI transmit coils and virtual observation points
|
|
13
|
+
(VOPs) for SAR, ported from MARIE 3.0 (<https://github.com/cloudmrhub/marie-tools>,
|
|
14
|
+
MIT).
|
|
15
|
+
|
|
16
|
+
`PLAN.md` is the design brief: scope, the VOP file contract, the port's
|
|
17
|
+
milestones, validation, constraints and later stages. Read it before starting
|
|
18
|
+
work. When a decision it records changes, change `PLAN.md` in the same pull
|
|
19
|
+
request.
|
|
20
|
+
|
|
21
|
+
mariepy stands alone: it depends on torch and numpy, not on other MRI packages.
|
|
22
|
+
Its one external contract is the VOP file that pypulseqpp reads.
|
|
23
|
+
|
|
24
|
+
## Build and test
|
|
25
|
+
|
|
26
|
+
```bash
|
|
27
|
+
pip install -e .[dev]
|
|
28
|
+
bash scripts/format_and_lint.sh # rewrites in place; --check to verify only
|
|
29
|
+
pytest -q
|
|
30
|
+
```
|
|
31
|
+
|
|
32
|
+
Build and test steps are mandatory before reporting a change complete. Run them
|
|
33
|
+
and report the exact output; do not assume success.
|
|
34
|
+
|
|
35
|
+
## Tests
|
|
36
|
+
|
|
37
|
+
pytest with plain functions and fixtures — never `unittest.TestCase`. A test
|
|
38
|
+
name states the invariant it protects, so a failure reads as a sentence.
|
|
39
|
+
|
|
40
|
+
Anything numerical that can run on CPU and CUDA is parametrised over both, and
|
|
41
|
+
the CUDA leg skips when no device is present. A kernel-layout check that ran on
|
|
42
|
+
CPU only has passed in this codebase while CUDA was 100% wrong.
|
|
43
|
+
|
|
44
|
+
## Comments and docstrings
|
|
45
|
+
|
|
46
|
+
Write for someone reading the code as it is now, who has no memory of any
|
|
47
|
+
earlier version of it. **Never** write text whose subject is the history of the
|
|
48
|
+
code. Banned in comments, docstrings and prose alike:
|
|
49
|
+
|
|
50
|
+
- "used to", "was once", "no longer", "previously", "now that", "this replaces",
|
|
51
|
+
"the old X", "before the fix"
|
|
52
|
+
- justifying the present shape by contrast with a shape that is gone
|
|
53
|
+
- naming a bug that has been fixed, or the session that fixed it
|
|
54
|
+
- restating what the code plainly says
|
|
55
|
+
|
|
56
|
+
A docstring carries what a caller needs: one line of what, Parameters, Returns,
|
|
57
|
+
Raises. A comment earns its place only by explaining a non-obvious algorithm or
|
|
58
|
+
a choice a reader would otherwise undo — and even then, prefer a well-named
|
|
59
|
+
function or a test whose name states the invariant, because those cannot go
|
|
60
|
+
stale silently. When tempted to explain *why not the other way*, write a test.
|
|
61
|
+
|
|
62
|
+
Stale comments are actively harmful. Deleting an outdated comment is always
|
|
63
|
+
correct; rewriting one to describe the change is not.
|
|
64
|
+
|
|
65
|
+
## Documentation style
|
|
66
|
+
|
|
67
|
+
The audience is MR scientists. Write in the vocabulary of pulse sequences and
|
|
68
|
+
physics, not of software architecture. Never justify a design by describing the
|
|
69
|
+
design it replaced.
|
|
70
|
+
|
|
71
|
+
Do not print a measured constant that is not guaranteed across releases or
|
|
72
|
+
hardware. Name the symbol and where it comes from, and let the build supply the
|
|
73
|
+
number. Benchmark tables in the README are regenerated by the benchmark script,
|
|
74
|
+
not typed in.
|