fix(python): added temporary patch to let python bindings work on mac

Mirroring what was done in fourdst (see fourdst/tree/v0.8.5) we have added a temporary patch to let python bindings work on mac while the meson-python folks resolve the duplicate rpath issue in the shared object file
This commit is contained in:
2025-11-03 15:10:03 -05:00
parent 0adc340767
commit 3c80ccc77f
15 changed files with 1437 additions and 184 deletions

View File

@@ -22,9 +22,13 @@ namespace gridfire {
ELECTRON_CAPTURE = 1 << 3, // 8
POSITRON_CAPTURE = 1 << 4, // 16
WEAK = BETA_MINUS | BETA_PLUS | ELECTRON_CAPTURE | POSITRON_CAPTURE,
DEFAULT = STRONG,
ALL = STRONG | WEAK
REACLIB_WEAK = 1 << 5,
WRL_WEAK = BETA_MINUS | BETA_PLUS | ELECTRON_CAPTURE | POSITRON_CAPTURE,
REACLIB = STRONG | REACLIB_WEAK,
DEFAULT = REACLIB,
ALL = STRONG | WRL_WEAK
};
constexpr auto to_underlying(NetworkConstructionFlags f) noexcept {
@@ -45,12 +49,13 @@ namespace gridfire {
inline std::string NetworkConstructionFlagsToString(NetworkConstructionFlags flags) {
std::stringstream ss;
constexpr std::array<NetworkConstructionFlags, 5> bases_flags_array = {
constexpr std::array<NetworkConstructionFlags, 6> bases_flags_array = {
NetworkConstructionFlags::STRONG,
NetworkConstructionFlags::BETA_MINUS,
NetworkConstructionFlags::BETA_PLUS,
NetworkConstructionFlags::ELECTRON_CAPTURE,
NetworkConstructionFlags::POSITRON_CAPTURE
NetworkConstructionFlags::POSITRON_CAPTURE,
NetworkConstructionFlags::REACLIB_WEAK
};
const std::unordered_map<NetworkConstructionFlags, std::string> bases_string_map = {
@@ -58,7 +63,8 @@ namespace gridfire {
{NetworkConstructionFlags::BETA_MINUS, "BetaMinus"},
{NetworkConstructionFlags::BETA_PLUS, "BetaPlus"},
{NetworkConstructionFlags::ELECTRON_CAPTURE, "ElectronCapture"},
{NetworkConstructionFlags::POSITRON_CAPTURE, "PositronCapture"}
{NetworkConstructionFlags::POSITRON_CAPTURE, "PositronCapture"},
{NetworkConstructionFlags::REACLIB_WEAK, "ReaclibWeak"}
};
size_t i = 0;

View File

@@ -44,7 +44,7 @@ namespace {
const gridfire::NetworkConstructionFlags reactionTypes
) {
gridfire::reaction::ReactionSet weak_reaction_pool;
if (!has_flag(reactionTypes, gridfire::NetworkConstructionFlags::WEAK)) {
if (!has_flag(reactionTypes, gridfire::NetworkConstructionFlags::WRL_WEAK)) {
return weak_reaction_pool;
}
@@ -109,13 +109,38 @@ namespace {
if (has_flag(reaction_types, gridfire::NetworkConstructionFlags::STRONG)) {
const auto& allReaclibReactions = gridfire::reaclib::get_all_reaclib_reactions();
for (const auto& reaction : allReaclibReactions) {
if (!reaction->is_reverse() && !reaclib_reaction_is_weak(*reaction)) { // Only add reactions of the correct direction and which are not weak. Weak reactions are handled from the WRL separately which provides much higher quality weak reactions than reaclib does
const bool isWeakReaction = reaclib_reaction_is_weak(*reaction);
const bool okayToUseReaclibWeakReaction = has_flag(reaction_types, gridfire::NetworkConstructionFlags::REACLIB_WEAK);
const bool reaclibWeakOkay = !isWeakReaction || okayToUseReaclibWeakReaction;
if (!reaction->is_reverse() && reaclibWeakOkay) {
strong_reaction_pool.add_reaction(reaction->clone());
}
}
}
return strong_reaction_pool;
}
bool validate_unique_weak_set(gridfire::NetworkConstructionFlags flag) {
// This method ensures that weak reactions will only be fetched from either reaclib or the weak reaction library (WRL)
// but not both
std::array<gridfire::NetworkConstructionFlags, 4> WRL_Flags = {
gridfire::NetworkConstructionFlags::BETA_PLUS,
gridfire::NetworkConstructionFlags::ELECTRON_CAPTURE,
gridfire::NetworkConstructionFlags::POSITRON_CAPTURE,
gridfire::NetworkConstructionFlags::BETA_MINUS
};
if (!has_flag(flag, gridfire::NetworkConstructionFlags::REACLIB_WEAK)) {
return true;
}
for (const auto& WRLReactionType : WRL_Flags) {
if (has_flag(flag, WRLReactionType)) {
return false;
}
}
return true;
}
}
namespace gridfire {
@@ -131,6 +156,11 @@ namespace gridfire {
NetworkConstructionFlags ReactionTypes
) {
auto logger = fourdst::logging::LogManager::getInstance().getLogger("log");
if (!validate_unique_weak_set(ReactionTypes)) {
std::string msg = "Cannot construct network since weak reactions from both reaclib and WRL were requested. Only one weak rate source may be used. In network construction this likely means that the flag NetworkConstructionFlags::REACLIB_WEAK was used along with one of the weak flags (BETA_PLUS, BETA_MINUS, ELECTRON_CAPTURE, POSITRON_CAPTURE). These flags are for WRL rates and may not be used in conjunction with reaclib weak rates.";
LOG_ERROR(logger, "{}", msg);
throw std::logic_error(msg);
}
LOG_INFO(logger, "Constructing network topology from reaction types : {}", NetworkConstructionFlagsToString(ReactionTypes));
if (ReactionTypes == NetworkConstructionFlags::NONE) {

View File

@@ -23,30 +23,30 @@ PYBIND11_MODULE(gridfire, m) {
auto typeMod = m.def_submodule("type", "GridFire type bindings");
register_type_bindings(typeMod);
// auto partitionMod = m.def_submodule("partition", "GridFire partition function bindings");
// register_partition_bindings(partitionMod);
//
// auto expectationMod = m.def_submodule("expectations", "GridFire expectations bindings");
// register_expectation_bindings(expectationMod);
//
// auto reactionMod = m.def_submodule("reaction", "GridFire reaction bindings");
// register_reaction_bindings(reactionMod);
//
// auto screeningMod = m.def_submodule("screening", "GridFire plasma screening bindings");
// register_screening_bindings(screeningMod);
//
// auto ioMod = m.def_submodule("io", "GridFire io bindings");
// register_io_bindings(ioMod);
//
// auto exceptionMod = m.def_submodule("exceptions", "GridFire exceptions bindings");
// register_exception_bindings(exceptionMod);
//
// auto engineMod = m.def_submodule("engine", "Engine and Engine View bindings");
// register_engine_bindings(engineMod);
//
// auto solverMod = m.def_submodule("solver", "GridFire numerical solver bindings");
// register_solver_bindings(solverMod);
//
// auto utilsMod = m.def_submodule("utils", "GridFire utility method bindings");
// register_utils_bindings(utilsMod);
auto partitionMod = m.def_submodule("partition", "GridFire partition function bindings");
register_partition_bindings(partitionMod);
auto expectationMod = m.def_submodule("expectations", "GridFire expectations bindings");
register_expectation_bindings(expectationMod);
auto reactionMod = m.def_submodule("reaction", "GridFire reaction bindings");
register_reaction_bindings(reactionMod);
auto screeningMod = m.def_submodule("screening", "GridFire plasma screening bindings");
register_screening_bindings(screeningMod);
auto ioMod = m.def_submodule("io", "GridFire io bindings");
register_io_bindings(ioMod);
auto exceptionMod = m.def_submodule("exceptions", "GridFire exceptions bindings");
register_exception_bindings(exceptionMod);
auto engineMod = m.def_submodule("engine", "Engine and Engine View bindings");
register_engine_bindings(engineMod);
auto solverMod = m.def_submodule("solver", "GridFire numerical solver bindings");
register_solver_bindings(solverMod);
auto utilsMod = m.def_submodule("utils", "GridFire utility method bindings");
register_utils_bindings(utilsMod);
}

View File

@@ -197,11 +197,11 @@ namespace {
}
void register_engine_bindings(py::module &m) {
register_engine_type_bindings(m);
register_engine_procedural_bindings(m);
register_base_engine_bindings(m);
register_engine_view_bindings(m);
register_engine_diagnostic_bindings(m);
register_engine_procedural_bindings(m);
register_engine_type_bindings(m);
}
void register_base_engine_bindings(const pybind11::module &m) {

View File

@@ -45,14 +45,10 @@ void register_exception_bindings(const py::module &m) {
py::register_exception<gridfire::exceptions::JacobianError>(m, "JacobianError", m.attr("GridFireEngineError"));
py::register_exception<gridfire::exceptions::StaleJacobianError>(m, "StaleJacobianError", m.attr("JacobianEngineError"));
py::register_exception<gridfire::exceptions::UninitializedJacobianError>(m, "UninitializedJacobianError", m.attr("JacobianEngineError"));
py::register_exception<gridfire::exceptions::UnknownJacobianError>(m, "UnknownJacobianError", m.attr("JacobianEngineError"));
py::register_exception<gridfire::exceptions::StaleJacobianError>(m, "StaleJacobianError", m.attr("JacobianError"));
py::register_exception<gridfire::exceptions::UninitializedJacobianError>(m, "UninitializedJacobianError", m.attr("JacobianError"));
py::register_exception<gridfire::exceptions::UnknownJacobianError>(m, "UnknownJacobianError", m.attr("JacobianError"));
py::register_exception<gridfire::exceptions::UtilityError>(m, "UtilityError");
py::register_exception<gridfire::exceptions::HashingError>(m, "HashingError", m.attr("UtilityError"));
}

View File

@@ -1,10 +1,10 @@
subdir('types')
#subdir('utils')
#subdir('expectations')
#subdir('exceptions')
#subdir('io')
#subdir('partition')
#subdir('reaction')
#subdir('screening')
#subdir('engine')
#subdir('solver')
subdir('utils')
subdir('expectations')
subdir('exceptions')
subdir('io')
subdir('partition')
subdir('reaction')
subdir('screening')
subdir('engine')
subdir('solver')

View File

@@ -1,4 +1,5 @@
#include <pybind11/pybind11.h>
#include <pybind11/functional.h> // needed for std::function
#include <pybind11/stl.h> // Needed for vectors, maps, sets, strings
#include <pybind11/stl_bind.h> // Needed for binding std::vector, std::map etc. if needed directly
#include <pybind11/numpy.h>