openPMD Transport
HASEonGPU uses openPMD as the transport boundary between the Python frontend and
the C++ calcPhiASE backend. Users normally work with Python objects such
as GainMedium and PhiASE; the transport converts those objects into the
records and attributes consumed by the backend.
Storage Backends
The openPMD storage backend is independent from the Alpaka compute backend.
auto is the default: it chooses the first backend supported by both the
compiled and Python openPMD providers in this order: adios-sst, adios,
then hdf5. Explicit runtime values are:
adios-sstADIOS2 SST streaming series. This is the default when supported.
adiosADIOS2 file-backed
.bpseries.hdf5HDF5
.h5series. Requires HDF5 support in the selected openPMD-api provider.
Select it in Python or YAML:
phi_ase = PhiASE(..., openpmdBackend="auto")
compute:
backend: Host_Cpu_CpuSerial # Alpaka compute backend
openpmd_backend: auto # choose a compatible backend
Set PhiASE.openpmdBackend or the YAML openpmd_backend value to override
automatic selection for a particular run.
Streaming Sessions
PhiASE.run(...) defaults to one open/write/read/close cycle per call. For
repeated adios-sst calls, keep a stream open:
session = phi_ase.openStream()
try:
for _ in range(steps):
phi_ase.run(gainMedium=medium, crossSections=spectra, openpmdSession=session)
result = phi_ase.getResults()
finally:
phi_ase.closeStream()
Use openpmdSession="persistent" to let PhiASE own a reusable stream, or
openpmdSession="interval" to force one-shot behavior. Simulation uses a
persistent stream automatically for adios-sst unless another mode or session
is supplied.
Provider Compatibility
The Python openpmd_api module and the C++ openPMD::openPMD provider
must be compatible and must both support the selected runtime backend. The
guided setup checks this for common installs:
python3 utils/configure_hase.py
For manual checks against an existing provider:
python3 utils/check_openpmd_compatibility.py \
--backend adios-sst \
--cmake-prefix-path /path/to/openpmd/prefix
Then point installation or CMake configuration at the same provider, for
example with CMAKE_PREFIX_PATH or openPMD_DIR. If the matching Python
package is not on the normal Python path, set HASE_OPENPMD_PYTHON_PACKAGE_DIR
at build time or HASE_OPENPMD_PYTHONPATH before importing HASEonGPU.
The HASEonGPU wheel does not vendor openPMD runtime libraries or generated
openpmd_api bindings. The runtime environment must provide compatible
openPMD libraries and Python bindings.
Record Layout
All array data is written as openPMD Mesh records below each iteration’s
meshes group. Scalar simulation settings such as number_of_points,
backend, openpmd_backend, and parallel_mode are iteration
attributes, not mesh records.
Topology records use a VTK-compatible unstructured wedge layout inside openPMD:
core_pointsstores point coordinates asx,y, andzcomponents.core_cells_connectivitystores VTK wedge point ids.core_cells_offsetsstores offsets into the connectivity array.core_cells_typesstores the VTK cell type id; wedge cells use type13.
Main input field records are:
core_beta_volumeandcore_point_betafor dynamic excited-state datacore_cladding_cell_type,core_refractive_index, andcore_reflectivityfor static material/surface datacore_lambda_absorption,core_lambda_emission,core_sigma_absorption, andcore_sigma_emissionfor spectra
The backend writes result records named core_result_phi_ase,
core_result_mse, core_result_total_rays, and
core_result_dndt_ase.
Custom fields declared with GainMedium.defineField(...) or
PrimitiveFieldSpec are serialized as additional openPMD mesh records with
their unit metadata. They are available to downstream readers; the current ASE
backend ignores them unless a future backend explicitly consumes them.
Iteration Updates
The first Python-written iteration contains the full static context: topology,
material records, spectra, compute attributes, and dynamic beta fields. Later
iterations normally contain only core_beta_volume and core_point_beta
and reuse the cached static context from iteration 0.
Changing topology, spectra, material constants, or compute settings requires a new input series whose first iteration carries a complete static update. This keeps repeated ASE evaluations and streaming runs small while preserving a stable backend contract.
MPI Launching
The standalone binary reads the same transport layout under MPI:
mpiexec -npernode 4 ./build/calcPhiASE \
--input-path=input.sst \
--output-path=output.sst
The high-level Python frontend launches the binary automatically when MPI mode is selected:
import HASEonGPU
phi_ase = HASEonGPU.PhiASE(
parallelMode="mpi",
nPerNode=4,
openpmdBackend="adios-sst",
)
phi_ase.run(gainMedium=medium, crossSections=spectra)
The scheduler controls the node allocation, while nPerNode controls the
number of ranks launched on each allocated node. File-based transport data is
created below ./IO/phiase_mpi so the launch directory must be shared for a
multi-node run.
Artifact Retention
Temporary transport artifacts are normally removed when a session exits. These environment variables help with debugging:
HASE_OPENPMD_KEEP_ARTIFACTS=1Keep artifacts below
./hase-openpmd-artifacts.HASE_OPENPMD_ARTIFACT_DIR=/pathWrite artifacts to an explicit directory.
HASE_OPENPMD_ARTIFACT_PREFIX=namePrefix generated artifact names.
HASE_OPENPMD_ARTIFACT_RUN_ID=idUse a stable run id instead of a timestamped id.
HASE_OPENPMD_WATCHDOG_INTERVAL=30Watchdog interval while the result receiver waits. Use
0ornoneto disable the watchdog.HASE_OPENPMD_THREAD_JOIN_TIMEOUT=10Time allowed for streaming helper threads to stop during session close.
HASE_CALCPHIASE=/path/to/calcPhiASEForce the Python transport to use a specific binary.