MuPRO SDK Migration Plan Snapshot#

Last updated: 2026-05-26

This document records the accepted migration direction after the initial openmupro consolidation and platform baseline work. It is a stable internal snapshot; TASK.md remains the live task tracker.

Accepted Direction#

ID

Decision

Status

PLAN-MIG-001

Use a single private muprosdk repository as the primary engineering home.

Accepted

PLAN-MIG-002

Remove standalone openmupro as an active package and fold needed L0/L1 runtime code into library/.

Implemented for active build graph

PLAN-MIG-003

Do not migrate desktop/; desktop or GUI workflows will be redesigned in separate software later.

Accepted

PLAN-MIG-004

Keep app submodules unchanged for now; handle app repository consolidation during app refactors.

Accepted

PLAN-MIG-005

Do not rely on outside users contributing code. Users should provide requirements, issues, logs, examples, and feedback; MuPRO maintains and releases code.

Accepted

PLAN-MIG-006

Keep Fortran as the primary scientific implementation language, with a future C ABI boundary for multi-language hosts.

Accepted

PLAN-MIG-007

Use C/C++/CUDA/HIP selectively for solver hotspots or algebra kernels when GPU acceleration is justified.

Deferred

PLAN-MIG-008

Establish solver-level and scenario-level benchmark standards before risky solver refactors.

Standard skeleton implemented; reference outputs pending

PLAN-MIG-009

Adopt OpenUSD as the future high-level case input package while keeping large numerical data in scientific/native formats.

Accepted direction

PLAN-MIG-010

Keep MuPRO core CLI/TUI-first; leave full GUI, visual pre/post-processing, and broader workflow tooling to external SimViz-style software.

Accepted direction

PLAN-MIG-011

Own smoke/unit/MPI/integration/regression/benchmark tests inside each library/<module>/tests directory; equation-solving modules also own validation tests.

Accepted direction

PLAN-MIG-012

Keep root free of test source directories; library/ owns library-level tests and apps own their own benchmark/validation/regression checks.

Accepted direction

Current Build Baseline#

  • Linux and Windows remain the official oneAPI/oneMKL routes.

  • macOS is development-only and CPU-only, using Homebrew gfortran, OpenBLAS, FFTW, and OpenMPI.

  • FFTW is never bundled into SDK packages.

  • The repository root now has a migration CMake entrypoint that builds license, library, examples/demo1, and examples/c_api_tdgl together, but it owns no test source directory.

  • Root CTest aggregates child tests from library/; the current checks cover C ABI, runtime, status, L0 Base, L0 Log, all current L1 module directories, and a library-level configure smoke.

  • Current unit test source ownership is module-local under library/<module>/tests/unit, library/runtime/tests/unit, and library/c_api/tests/unit; root CTest aggregates registered tests.

  • Modules can now add smoke, mpi, integration, regression, benchmark, and validation categories without touching root CMake; benchmark and validation categories are opt-in through MUPRO_BUILD_BENCHMARKS and MUPRO_BUILD_VALIDATION.

  • The minimal C ABI skeleton is implemented with installed mupro.h, opaque runtime/TDGL handles, mupro_status_t, TDGL setup/solve signatures, and documented array layout.

  • The runtime context skeleton now lives under library/runtime; the C ABI bridge delegates size and MPI ownership to mod_mupro_runtime, which preserves legacy mod_base_size and mod_base_mpi compatibility.

  • FFT lifecycle is now an optional runtime capability: runtime_setup does not initialize FFT, and FFT-based solvers must request mupro_runtime_setup_fft or mupro_runtime_ensure_fft.

  • TDGL has a structured validation/status-return path, targeted macOS compile coverage, and an optional C adapter through MUPRO_BUILD_TDGL=ON.

  • library can build the L0/L1 macOS development route with MUPRO_BUILD_SOLVERS=OFF.

  • examples/demo1 is now a downstream SDK example under examples/demo1; the first C ABI example is under examples/c_api_tdgl.

  • Benchmark standards, catalogs, and result metadata templates are under benchmarks/.

  • OpenUSD case workflow direction is recorded in docs/internal/openusd-case-workflow.md.

  • Current build/test baseline and known blockers are recorded in docs/internal/baseline-build-test.md.

Current Repository State#

  • openmupro has been removed from the main repository index and .gitmodules.

  • Active build files no longer reference find_package(openmupro), openmupro_DIR, or mupro::openmupro.

  • apps/muFerro and apps/muPREDICT have local submodule edits from the cleanup. These are intentionally deferred until app refactoring.

Next Engineering Phases#

  1. Add explicit MPI smoke beyond single-process runtime initialization.

  2. Add concrete module-local benchmark, regression, integration, and validation cases using the standard category layout.

  3. Assign benchmark reference owners and confirm trusted outputs.

  4. Refactor solver/app code in narrow slices, using reference outputs from reference/ and benchmark cases.

Test Topology Direction#

The migration bootstrap used root-level tests/unit to quickly establish a non-empty CTest gate. That placement has now been replaced for current module/API/runtime checks.

Target layout:

  • library/<module>/tests/unit: deterministic function-level and small API checks owned by the module.

  • library/<module>/tests/smoke: minimal build/run checks for module entrypoints.

  • library/<module>/tests/mpi: MPI-specific checks for modules with distributed behavior.

  • library/<module>/tests/integration: small examples that depend on a minimal set of neighboring modules.

  • library/<module>/tests/regression: historical behavior compatibility checks.

  • library/<module>/tests/benchmark: module performance and efficiency checks. These are opt-in through MUPRO_BUILD_BENCHMARKS.

  • library/<module>/tests/validation: accuracy checks for equation-solving modules with references, tolerances, and provenance. These are opt-in through MUPRO_BUILD_VALIDATION.

  • library/tests: assembled library-level checks, such as configure/install/export/package smoke or cross-module ABI/runtime behavior.

  • apps/<app>/benchmark: app-level performance and efficiency checks.

  • apps/<app>/validation: app-level accuracy or literature/reference checks.

  • apps/<app>/regression: app-level historical compatibility checks.

Root CTest remains useful, but only as an aggregator: it adds child targets from library/ and later apps rather than owning test source files. This keeps each module and app close to independently verifiable and makes future refactor safer.

L0/L1 Boundary Assessment#

The current L0/L1 split is usable for migration, but it is not the final architecture.

  • L0_Base is currently a compatibility container for precision/constants/status, MPI/global size, TOML, expression evaluation, and umbrella exports. This is acceptable during migration, but the long-term split should separate true base types, runtime ownership, and input parsing.

  • L0_Log is reasonably placed at L0, but fatal stop/finalize paths should gradually move behind structured status/runtime control instead of being called directly from utilities or solvers.

  • L0_FFT is a valid low-level runtime dependency today, but plan/size/wave-vector ownership should eventually move into runtime/backend context instead of global module state.

  • L1_Utilities is still broad. It mixes generic numerical helpers, ferroelectric/domain helpers, and legacy error handling. Keep it stable behind tests first, then split by responsibility.

  • L1_IO, L1_Transform, PostProcess, structure/material helpers, and Film now have module-local smoke or deterministic coverage. Their internal boundaries still need later cleanup.

The L0/L1 migration coverage gate is now in place. Broad L2 work should still remain narrow until runtime ownership and benchmark coverage are stronger.

Current L0/L1 Test Gate#

The root macOS development CTest gate currently passes with thirteen aggregated tests, where all test source files live under library/:

  • library.configure_smoke

  • unit.c_api

  • unit.runtime

  • unit.status

  • unit.l0_base

  • unit.l0_log

  • unit.l1_io

  • unit.l1_transform

  • unit.l1_utilities

  • unit.l1_post_process

  • unit.l1_structure_generator

  • unit.l1_material_generator

  • unit.l1_film

Coverage added in the L0/L1 stabilization slice:

  • L0 Log: scalar logging and time-dependent header/row output.

  • L1 Utilities: 1x21/6x6 conversion, LAPACK-backed matrix inverse, fixed-seed random helpers, and sumBox.

  • L1 Transform: zero-angle Euler identity and cubic tensor Voigt roundtrip.

  • L1 I/O: serial DAT/VTK output smoke, time-dependent CSV parsing, and single-process MPI-style 3D/4D/5D roundtrip.

  • L1 PostProcess: uniform domain classification over a tiny 3D box.

  • L1 StructureGenerator: round-pillar center-line generation on a 3x3x3 grid.

  • L1 MaterialGenerator: scalar and rank-2 property assignment from phase labels.

  • L1 Film: constant-field fitted derivative through runtime-owned FFT setup.

  • Runtime: context skeleton, size setup/query through legacy global compatibility, backend defaults, setup/finalize, MPI initialization/finalization, and optional FFT setup/finalize/re-setup.

With this gate in place, narrow L2 adapter work is no longer blocked by unfinished L1 migration coverage. Broad solver refactors still require benchmark-linked references.

The standalone library macOS development CTest gate also passes with the same thirteen library-owned tests.

Current C ABI Gate#

The first C ABI skeleton is in place:

  • Header: library/c_api/include/mupro.h

  • Implementation: library/c_api/src/mupro_c_api.c

  • Unit test: library/c_api/tests/unit

  • Example: examples/c_api_tdgl

  • Design note: docs/internal/c-api.md

The current C API can create/destroy runtime and TDGL handles, set runtime size through the Fortran mod_mupro_runtime bridge, initialize/query MPI rank/process through the runtime-owned mpi_setup path, store TDGL setup parameters, validate TDGL solve pointer/shape/stride metadata, and return structured status. In default L0/L1 builds, mupro_tdgl_solve returns MUPRO_STATUS_NOT_SETUP because TDGL is not present in that build. With MUPRO_BUILD_TDGL=ON, mupro_tdgl_setup/solve route through an optional Fortran TDGL adapter and request runtime FFT lazily. FFT is runtime-owned internally but is not exposed through the public C API yet.

Runtime limitation: mod_mupro_runtime still writes legacy Fortran global state. Treat the process as having one active MuPRO runtime until solver internals stop depending on global size, MPI, and FFT state.