Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
27 changes: 19 additions & 8 deletions .gitlab-ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -175,21 +175,21 @@ openmpi_fortran_kokkos_static_openmp_clang:
SPACK_ENV_NAME: openmpi-fortran-kokkos-static-openmp-clang
SUBMIT_TO_CDASH: "${ENABLE_CDASH}"

openmpi_rocm_gcc:
openmpi_rocm_rocmcc:
extends: [.ascgit_job, .darwin_job, .darwin_regular_job, .build_and_test]
needs:
- prereq_offline_deps
variables:
SPACK_ENV_NAME: openmpi-rocm-gcc
SPACK_ENV_NAME: openmpi-rocm-rocmcc
SCHEDULER_PARAMETERS: "-n 1 --qos=debug -p shared-gpu-amd-mi250"
SUBMIT_TO_CDASH: "${ENABLE_CDASH}"

openmpi_fortran_rocm_gcc:
openmpi_fortran_rocm_rocmcc:
extends: [.ascgit_job, .darwin_job, .darwin_regular_job, .build_and_test]
needs:
- prereq_offline_deps
variables:
SPACK_ENV_NAME: openmpi-fortran-rocm-gcc
SPACK_ENV_NAME: openmpi-fortran-rocm-rocmcc
SCHEDULER_PARAMETERS: "-n 1 --qos=debug -p shared-gpu-amd-mi250"
SUBMIT_TO_CDASH: "${ENABLE_CDASH}"

Expand All @@ -204,6 +204,17 @@ rocinante_craympich_gcc:
SUBMIT_ON_ERROR: false # Compute nodes don't have network access, don't try to send from compute node
SUBMIT_AFTER: "${ENABLE_CDASH}" # after_script runs on a network connected system

venadito_craympich_cuda_gracehopper_gcc:
extends: [.ascgit_job, .venadito_job, .venadito_regular_job, .build_and_test]
needs:
- prereq_offline_deps
variables:
SPACK_ENV_NAME: craympich-cuda-gracehopper-gcc
SUBMIT_TO_CDASH: false
BUILD_WITH_CTEST: "${ENABLE_CDASH}"
SUBMIT_ON_ERROR: false # Compute nodes don't have network access, don't try to send from compute node
SUBMIT_AFTER: "${ENABLE_CDASH}" # after_script runs on a network connected system

rocinante_craympich_fortran_gcc:
extends: [.ascgit_job, .rocinante_job, .rocinante_regular_job, .build_and_test]
needs:
Expand All @@ -215,23 +226,23 @@ rocinante_craympich_fortran_gcc:
SUBMIT_ON_ERROR: false # Compute nodes don't have network access, don't try to send from compute node
SUBMIT_AFTER: "${ENABLE_CDASH}" # after_script runs on a network connected system

rzvernal_craympich_rocm_mi250_cce:
rzvernal_craympich_rocm_mi250_rocmcc:
extends: [.ascgit_job, .rzvernal_job, .rzvernal_regular_job, .build_and_test]
needs:
- prereq_offline_deps
variables:
SPACK_ENV_NAME: craympich-rocm-gfx90a-cce
SPACK_ENV_NAME: craympich-rocm-gfx90a-rocmcc
SUBMIT_TO_CDASH: false
BUILD_WITH_CTEST: "${ENABLE_CDASH}"
SUBMIT_ON_ERROR: false # Compute nodes don't have network access, don't try to send from compute node
SUBMIT_AFTER: "${ENABLE_CDASH}" # after_script runs on a network connected system

rzadams_craympich_rocm_mi300_cce:
rzadams_craympich_rocm_mi300_rocmcc:
extends: [.ascgit_job, .rzadams_job, .rzadams_regular_job, .build_and_test]
needs:
- prereq_offline_deps
variables:
SPACK_ENV_NAME: craympich-rocm-gfx942-cce
SPACK_ENV_NAME: craympich-rocm-gfx942-rocmcc
SUBMIT_TO_CDASH: false
BUILD_WITH_CTEST: "${ENABLE_CDASH}"
SUBMIT_ON_ERROR: false # Compute nodes don't have network access, don't try to send from compute node
Expand Down
26 changes: 9 additions & 17 deletions .gitlab/common.yml
Original file line number Diff line number Diff line change
Expand Up @@ -74,30 +74,22 @@ default:
- if: $ENABLED_CLUSTERS =~ /rocinante/ && $CI_PIPELINE_SOURCE == "web"
- if: $ENABLED_CLUSTERS =~ /rocinante/ && $CI_PIPELINE_SOURCE == "push" && $CI_COMMIT_BRANCH == $CI_DEFAULT_BRANCH

.venado_job:
.venadito_job:
variables:
CLUSTER: venado
SCHEDULER_PARAMETERS: "-N 1 -A asc-ci_g -p ci_g --qos ci_g --reservation ci_g --time=02:00:00"
CLUSTER: venadito
SCHEDULER_PARAMETERS: "-N 1 -A vt-ci_g --reservation ci_g --time=02:00:00"
tags:
- venado
- venadito
- batch

.venado_shell_gpu_job:
variables:
CLUSTER: venado
tags:
- venado
- shell
- gpu

.venado_regular_job:
.venadito_regular_job:
variables:
CTEST_MODE: Continuous
rules:
- if: $ENABLED_CLUSTERS =~ /venado/ && $GITLAB_USER_LOGIN =~ $VENADO_USERS && $CI_PIPELINE_SOURCE == "merge_request_event"
- if: $ENABLED_CLUSTERS =~ /venado/ && $GITLAB_USER_LOGIN =~ $VENADO_USERS && $CI_PIPELINE_SOURCE == "schedule"
- if: $ENABLED_CLUSTERS =~ /venado/ && $GITLAB_USER_LOGIN =~ $VENADO_USERS && $CI_PIPELINE_SOURCE == "web"
- if: $ENABLED_CLUSTERS =~ /venado/ && $GITLAB_USER_LOGIN =~ $VENADO_USERS && $CI_PIPELINE_SOURCE == "push" && $CI_COMMIT_BRANCH == $CI_DEFAULT_BRANCH
- if: $ENABLED_CLUSTERS =~ /venadito/ && $CI_PIPELINE_SOURCE == "merge_request_event"
- if: $ENABLED_CLUSTERS =~ /venadito/ && $CI_PIPELINE_SOURCE == "schedule"
- if: $ENABLED_CLUSTERS =~ /venadito/ && $CI_PIPELINE_SOURCE == "web"
- if: $ENABLED_CLUSTERS =~ /venadito/ && $CI_PIPELINE_SOURCE == "push" && $CI_COMMIT_BRANCH == $CI_DEFAULT_BRANCH

.rzansel_job:
tags:
Expand Down
7 changes: 4 additions & 3 deletions .gitlab/kessel.sh
Original file line number Diff line number Diff line change
@@ -1,10 +1,11 @@
export DEPLOYMENT_VERSION_CURRENT_DEFAULT="2026-03-03"
export DEPLOYMENT_VERSION_CURRENT_DEFAULT="2026-07-07"
export DEPLOYMENT_VERSION_DEFAULT="${DEPLOYMENT_VERSION_DEFAULT:-$DEPLOYMENT_VERSION_CURRENT_DEFAULT}"
SCRIPT_PATH=${BASH_SOURCE[0]:-${(%):-%x}}
PARENT_DIR="$( cd "$( dirname "${SCRIPT_PATH}" )" &>/dev/null && pwd )"

if [ -n "$DEPLOYMENT_MR" ]; then
export DEPLOYMENT_VERSION=${DEPLOYMENT_VERSION:-mr/$DEPLOYMENT_MR/$DEPLOYMENT_VERSION_DEFAULT}
DEPLOYMENT_MR_ID=$(printf "%08d\n" "${DEPLOYMENT_MR}")
export DEPLOYMENT_VERSION=${DEPLOYMENT_VERSION:-mr/$DEPLOYMENT_MR_ID/$DEPLOYMENT_VERSION_DEFAULT}
else
export DEPLOYMENT_VERSION=${DEPLOYMENT_VERSION:-$DEPLOYMENT_VERSION_DEFAULT}
fi
Expand All @@ -26,7 +27,7 @@ fi
_KESSEL_WORKFLOW_DEPLOYMENT="$KESSEL_WORKFLOW_DEPLOYMENT"
export KESSEL_WORKFLOW_DEPLOYMENT="${KESSEL_WORKFLOW_DEPLOYMENT:-${TMPDIR:-/tmp}/$USER-ci-envs}"

if [ "$SYSTEM_NAME" == "darwin" ] || [ "$SYSTEM_NAME" == "rocinante" ]; then
if [ "$SYSTEM_NAME" == "darwin" ] || [ "$SYSTEM_NAME" == "rocinante" ] || [ "$SYSTEM_NAME" == "venadito" ]; then
export KESSEL_DEPLOYMENT=${KESSEL_DEPLOYMENT:-/usr/projects/xcap/oss/deployments/$DEPLOYMENT_VERSION/$SYSTEM_NAME}
elif [ "$SYSTEM_NAME" == "rzadams" ] || [ "$SYSTEM_NAME" == "rzvernal" ] || [ "$SYSTEM_NAME" == "elcapitan" ] || [ "$SYSTEM_NAME" == "tuolumne" ]; then
export KESSEL_DEPLOYMENT=${KESSEL_DEPLOYMENT:-/usr/workspace/xcap/oss/deployments/$DEPLOYMENT_VERSION/$SYSTEM_NAME}
Expand Down
1 change: 1 addition & 0 deletions .kessel/workflows/cmake.py
Original file line number Diff line number Diff line change
Expand Up @@ -63,6 +63,7 @@ def test(self, args):
"""Testing"""
self.exec(f"""
pushd {self.build_dir}
source "$KESSEL_BUILD_ENV"
if [[ -f sesame2spiner/sesame2spiner ]]; then
echo "/usr/projects/data/eos/eos-developmental/Sn2162/v01/sn2162-v01.bin" > sesameFilesDir.txt
sesame2spiner/sesame2spiner -s materials.sp5 ../sesame2spiner/examples/unit_tests/mats.dat
Expand Down
4 changes: 3 additions & 1 deletion CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -13,8 +13,10 @@
### Fixed (Repair bugs, etc)
- [[PR645]](https://github.com/lanl/singularity-eos/pull/645) Fix internal energy from density and pressure for JWL
- [[PR63]](https://github.com/lanl/singularity-eos/pull/639) Fixed UnitSystem temperature bug. Temperature is now treated in the same as the time, mass, and length unit factors.

- [[PR637]](https://github.com/lanl/singularity-eos/pull/637) Fix is_normal

### Changed (changing behavior/API/variables/...)
- [[PR637]](https://github.com/lanl/singularity-eos/pull/637) For Kokkos 5/C++20, Python bindings now require context manager if run standalone
- [[PR641]](https://github.com/lanl/singularity-eos/pull/641) The location of some header files located in `<singularity-eos/base>` have moved to `<singularity-utils>`.

### Infrastructure (changes irrelevant to downstream codes)
Expand Down
27 changes: 25 additions & 2 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -247,6 +247,31 @@ if(SINGULARITY_BUILD_PYTHON)
set(CMAKE_POSITION_INDEPENDENT_CODE ON)
endif()

# require at least C++20, but allow newer versions to become a client requirement if
# explicitly set at build time (needed for building with newer Kokkos)
if(CMAKE_CXX_STANDARD)
target_compile_features(singularity-eos_Interface INTERFACE cxx_std_${CMAKE_CXX_STANDARD})
else()
target_compile_features(singularity-eos_Interface INTERFACE cxx_std_20)
endif()

# checks if this is our build, or we've been imported via `add_subdirectory` NB:
# this should make the `option(SINGULARITY_SUBMODULE_MODE ...)` unnecessary
if(CMAKE_PROJECT_NAME STREQUAL PROJECT_NAME)
set(CMAKE_CXX_EXTENSIONS OFF)
else()
message(
STATUS
"Detected that `singularity-eos` is a subproject, will configure build in submodule mode"
)
set(SINGULARITY_SUBMODULE_MODE ON)
endif()

if(SINGULARITY_FORCE_SUBMODULE_MODE)
message(STATUS "Building as though project was a submodule.")
set(SINGULARITY_SUBMODULE_MODE ON)
endif()

# Use to determine if Eigen is used or not
set(SINGULARITY_USE_EIGEN
OFF
Expand Down Expand Up @@ -625,8 +650,6 @@ target_compile_options(
# `-Wclass-memaccess now default with -Wall but we explicitly
# manage this ourselves in our serialization routines.
$<$<AND:$<CXX_COMPILER_ID:GNU>,$<COMPILE_LANGUAGE:CXX>>:-Wno-class-memaccess>
# Disable finite-math-only in Debug builds to allow NaN/Inf checks (Intel compilers)
$<$<AND:$<CONFIG:Debug>,$<OR:$<CXX_COMPILER_ID:IntelLLVM>,$<CXX_COMPILER_ID:Intel>>>:-fno-finite-math-only>
)
if (SINGULARITY_STRICT_WARNINGS)
target_compile_options(singularity-eos_Interface INTERFACE
Expand Down
76 changes: 64 additions & 12 deletions doc/sphinx/src/python.rst
Original file line number Diff line number Diff line change
Expand Up @@ -20,27 +20,70 @@ Example

::

from singularity_eos import IdealGas
import singularity_eos as eos

# Parameters for ideal gas
gm1 = 0.6
Cv = 2
eos = IdealGas(gm1, Cv)
rho = ...
sie = ...
P = eos.PressureFromDensityInternalEnergy(rho, sie)
eos.Finalize()
with eos.context():
# Parameters for ideal gas
gm1 = 0.6
Cv = 2
ideal_gas = eos.IdealGas(gm1, Cv)
rho = ...
sie = ...
P = ideal_gas.PressureFromDensityInternalEnergy(rho, sie)
ideal_gas.Finalize()

# Leaving the context does not finalize the shared runtime.
eos.finalize()

which should work for both scalar and vector (via numpy array)
calls. A more elaborate example can be found in
``examples/get_sound_speed_press.py``.
``example/get_sound_speed_press.py``.

Runtime Lifecycle
-----------------

The module owns a single runtime context, returned by :func:`context`. Entering
the context calls :func:`initialize`, but leaving the context does **not** call
:func:`finalize`. This lets EOS objects and work created in separate ``with``
blocks share the same runtime safely.

When the bindings are built with Kokkos support, :func:`initialize` first
checks whether Kokkos is already initialized. If another library initialized
Kokkos, Singularity EOS uses that runtime but does not take ownership of it;
in that case, :func:`finalize` does not shut Kokkos down. If Singularity EOS
starts Kokkos, it records ownership and :func:`finalize` shuts it down.

Calls to :func:`initialize` are idempotent while the runtime is active. Kokkos
cannot be initialized again after it has been finalized, so calling
:func:`initialize` after finalization raises an exception. When the bindings
are built without Kokkos, both lifecycle functions are no-ops.

The runtime may also be managed explicitly without a context manager:

::

import singularity_eos as eos

eos.initialize()
try:
ideal_gas = eos.IdealGas(0.6, 2.0)
# Use ideal_gas here.
ideal_gas.Finalize()
finally:
eos.finalize()

Call :func:`finalize` only after all Kokkos-dependent work and cleanup are
complete. An EOS object's ``Finalize()`` method releases resources owned by
that EOS object; it is separate from the module-level :func:`finalize`, which
manages the shared runtime.

.. currentmodule:: singularity_eos

Classes
-------
List may not be complete.

* :class:`SingularityContext`
* :class:`IdealGas`
* :class:`Gruneisen`
* :class:`JWL`
Expand Down Expand Up @@ -79,10 +122,18 @@ along with any modifier arguments.
``Scaled(Shifted(IdealGas(gm1, Cv), shift), scale)`` will return a Python object
that wraps the ``ScaledEOS<ShiftedEOS<IdealGas>>`` C++ type.

Class Reference
---------------
API Reference
-------------
List may not be complete.

.. autofunction:: initialize

.. autofunction:: finalize

.. autofunction:: context

.. autoclass:: SingularityContext

.. autoclass:: EOSState
:members:

Expand Down Expand Up @@ -115,3 +166,4 @@ List may not be complete.

.. autofunction:: UnitSystem

This file was made in part with generative AI.
11 changes: 10 additions & 1 deletion example/get_sound_speed_press.py
Original file line number Diff line number Diff line change
Expand Up @@ -12,12 +12,18 @@
# publicly and display publicly, and to permit others to do so.
#------------------------------------------------------------------------------

from singularity_eos import IdealGas, thermalqs
# This file was made in part with generative AI.

from singularity_eos import IdealGas, finalize, initialize, thermalqs
import numpy as np
import math

SMALL = 1e-20 # to avoid dividing by zero

# Initialize the shared runtime before making EOS calls. This is idempotent and
# does not take ownership of Kokkos if another component initialized it first.
initialize()

def PressureSoundSpeedFromDensityEnergyDensity(rho, uu, eos, # inputs
P, cs, Ncells # outputs
):
Expand Down Expand Up @@ -123,3 +129,6 @@ def print_results():
# This usually only does anything if you're on device, but for GPU-data it
# will call the appropriate destructor.
eos1.Finalize()

# Shut down the shared runtime if this module initialized it.
finalize()
50 changes: 49 additions & 1 deletion python/module.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -11,10 +11,58 @@
// prepare derivative works, distribute copies to the public, perform
// publicly and display publicly, and to permit others to do so.
//------------------------------------------------------------------------------

// This file was made in part with generative AI.

// clang-format off
#include "module.hpp"

PYBIND11_MODULE(singularity_eos, m) {
py::class_<SingularityContext>(
m, "SingularityContext",
"Module-owned context manager for the Singularity EOS runtime.\n\n"
"Use the singleton returned by ``singularity_eos.context()`` rather than "
"constructing this type directly. Entering the context initializes the "
"runtime, but leaving it does not finalize the runtime.")
.def("__enter__",
[](SingularityContext &self) -> SingularityContext & {
InitializeSingularity();
return self;
},
py::return_value_policy::reference_internal,
"Initialize the shared runtime and return this context."
)
.def("__exit__",
[](SingularityContext &self,
py::object,
py::object,
py::object) {
(void)self;
return false; // do not suppress exceptions
},
"Leave the context without finalizing the shared runtime."
);

m.def("context",
[]() -> SingularityContext & {
return SingularityContext::Instance();
},
py::return_value_policy::reference,
"Return the module-owned Singularity EOS runtime context.\n\n"
"The same context is returned on every call. Entering it initializes "
"the runtime; leaving it does not finalize the runtime.");
m.def("initialize", &InitializeSingularity,
"Initialize the Singularity EOS runtime if necessary.\n\n"
"When built with Kokkos, this starts Kokkos only if it is not already "
"initialized. Calls are idempotent while Kokkos remains active. If "
"another component initialized Kokkos first, Singularity EOS does not "
"take ownership of its lifetime.");
m.def("finalize", &FinalizeSingularity,
"Finalize the Singularity EOS runtime when owned by this module.\n\n"
"When built with Kokkos, this finalizes Kokkos only if "
"singularity_eos.initialize() or singularity_eos.context() originally "
"started it. Kokkos cannot be initialized again after finalization.");

py::class_<EOSState>(m, "EOSState")
.def(py::init())
.def_readwrite("density", &EOSState::density)
Expand Down Expand Up @@ -157,5 +205,5 @@ PYBIND11_MODULE(singularity_eos, m) {
eos_units.attr("ThermalUnits") = eos_units_init::thermal_units_init_tag;
eos_units.attr("LengthTimeUnits") = eos_units_init::length_time_units_init_tag;

m.doc() = "Singularity EOS Python Bindings";
m.doc() = "Python bindings for Singularity EOS.";
}
Loading
Loading