From 548b6d4dd5b83160f8591c636066c18d0045c1dc Mon Sep 17 00:00:00 2001 From: t Date: Sat, 24 Oct 2026 03:59:13 +0200 Subject: [PATCH 1/7] generic-parallel material properties: types of the generated functions Copies of the types of the functions generated by the `generic-parallel` interface of `MFront` for material properties (`TFEL` 5.2): data of a batch, fields, statistics, output status and pointers to the functions (`MGIS/MaterialProperty/BatchMaterialPropertyFctPtr.hxx`), version 1 of those functions. The execution policies are defined by `TFEL`: `MGIS` only declares their type (`MGIS/BackendExecutionPolicy.h`), so that it does not depend on `TFEL`. --- include/CMakeLists.txt | 2 + include/MGIS/BackendExecutionPolicy.h | 46 ++++ .../BatchMaterialPropertyFctPtr.hxx | 234 ++++++++++++++++++ 3 files changed, 282 insertions(+) create mode 100644 include/MGIS/BackendExecutionPolicy.h create mode 100644 include/MGIS/MaterialProperty/BatchMaterialPropertyFctPtr.hxx diff --git a/include/CMakeLists.txt b/include/CMakeLists.txt index 6a25f79fc..448d23e96 100644 --- a/include/CMakeLists.txt +++ b/include/CMakeLists.txt @@ -1,4 +1,5 @@ mgis_header(MGIS Config-c.h) +mgis_header(MGIS BackendExecutionPolicy.h) mgis_header(MGIS Config.hxx) mgis_header(MGIS LogStream.hxx) mgis_header(MGIS LogStream.ixx) @@ -32,6 +33,7 @@ mgis_header(MGIS LibrariesManager.hxx) mgis_header(MGIS/MaterialProperty OutputStatus.hxx) mgis_header(MGIS/MaterialProperty OutOfBoundsPolicy.hxx) mgis_header(MGIS/MaterialProperty MaterialPropertyFctPtr.hxx) +mgis_header(MGIS/MaterialProperty BatchMaterialPropertyFctPtr.hxx) mgis_header(MGIS/MaterialProperty MaterialProperty.hxx) mgis_header(MGIS/Behaviour Hypothesis.hxx) mgis_header(MGIS/Behaviour TimeStepStage.hxx) diff --git a/include/MGIS/BackendExecutionPolicy.h b/include/MGIS/BackendExecutionPolicy.h new file mode 100644 index 000000000..cdecd0427 --- /dev/null +++ b/include/MGIS/BackendExecutionPolicy.h @@ -0,0 +1,46 @@ +/*! + * \file include/MGIS/BackendExecutionPolicy.h + * \brief This file declares the type of the execution policies of the + * backends of the `generic-parallel` interfaces of `MFront`. Those policies + * are defined by `TFEL` (`MFront/GenericParallel/` headers, base class + * `mfront::generic_parallel::AbstractBackendExecutionPolicy`): `MGIS` only + * gives them to the generated functions, so that a declaration is enough and + * `MGIS` does not depend on `TFEL` at compile time. In `C`, the policies are + * opaque and can only be given as null pointers (default policy of the + * backend). + * \date 22/10/2026 + * \copyright Use, modification and distribution are subject + * to one of the following licences: + * - GNU Lesser General Public License (LGPL), Version 3.0. (See accompanying + * file LGPL-3.0.txt) + * - CECILL-C, Version 1.0 (See accompanying files + * CeCILL-C_V1-en.txt and CeCILL-C_V1-fr.txt). + */ + +#ifndef LIB_MGIS_BACKENDEXECUTIONPOLICY_H +#define LIB_MGIS_BACKENDEXECUTIONPOLICY_H + +// NOLINTBEGIN(modernize-use-using) +#ifdef __cplusplus + +namespace mfront::generic_parallel { + + //! \brief base class of the execution policies of the backends + struct AbstractBackendExecutionPolicy; + +} // end of namespace mfront::generic_parallel + +//! \brief a simple alias +typedef mfront::generic_parallel::AbstractBackendExecutionPolicy + mgis_gp_AbstractBackendExecutionPolicy; + +#else /* __cplusplus */ + +//! \brief opaque structure +typedef struct mgis_gp_AbstractBackendExecutionPolicy + mgis_gp_AbstractBackendExecutionPolicy; + +#endif /* __cplusplus */ +// NOLINTEND(modernize-use-using) + +#endif /* LIB_MGIS_BACKENDEXECUTIONPOLICY_H */ diff --git a/include/MGIS/MaterialProperty/BatchMaterialPropertyFctPtr.hxx b/include/MGIS/MaterialProperty/BatchMaterialPropertyFctPtr.hxx new file mode 100644 index 000000000..7134bed80 --- /dev/null +++ b/include/MGIS/MaterialProperty/BatchMaterialPropertyFctPtr.hxx @@ -0,0 +1,234 @@ +/*! + * \file include/MGIS/MaterialProperty/BatchMaterialPropertyFctPtr.hxx + * \brief This file declares the type of the functions generated by the + * `generic-parallel` interface of `MFront` for material properties. + * \date 08/10/2026 + * \copyright Use, modification and distribution are subject + * to one of the following licences: + * - GNU Lesser General Public License (LGPL), Version 3.0. (See accompanying + * file LGPL-3.0.txt) + * - CECILL-C, Version 1.0 (See accompanying files + * CeCILL-C_V1-en.txt and CeCILL-C_V1-fr.txt). + */ + +#ifndef LIB_MGIS_MATERIALPROPERTY_BATCHMATERIALPROPERTYFCTPTR_HXX +#define LIB_MGIS_MATERIALPROPERTY_BATCHMATERIALPROPERTYFCTPTR_HXX + +#include "MGIS/MaterialProperty/MaterialPropertyFctPtr.hxx" +#include "MGIS/BackendExecutionPolicy.h" + +/*! + * \brief version of the functions generated by the `generic-parallel` + * interface for material properties supported by MGIS. It is compared to + * the version exported by the libraries + * (`_generic_parallel_api_version` symbol) when a material property + * is loaded: any other version is refused. This version and the structures + * declared in this file are copies of the ones declared in the + * `MFront/GenericParallelMaterialProperty/MaterialProperty.h` header of + * `TFEL`, with the same members in the same order, so that `MGIS` does not + * depend on `TFEL` at compile time. + */ +#define MGIS_MP_GENERIC_PARALLEL_API_VERSION 1 + +#ifdef __cplusplus +extern "C" { +#endif /* __cplusplus */ + +/*! + * \brief statistics of the evaluation of a material property on a batch of + * points (copy of the `mfront_gpmp_Statistics` structure of `TFEL`). The + * device only updates them when an event occurs at a point (the `stlpar` + * backend merges the statuses of the points by a reduction on the host). They + * are initialized by `mgis_mp_initializeBatchStatistics` and analysed by the + * report function of the material property. + */ +typedef struct mgis_mp_BatchStatistics { + /*! + * \brief number of points where the evaluation failed (physical bound + * violated, bound violated with the strict policy, invalid result) + */ + unsigned long long number_of_failures; + /*! + * \brief opaque key of the first point where the evaluation failed, or + * `~0` if no point failed. Only the report function of the material + * property decodes it. + */ + unsigned long long first_failure; + //! \brief number of points where a bound is violated with the warning + //! policy + unsigned long long number_of_unreliable_results; + /*! + * \brief opaque key of the first point where the result is unreliable, or + * `~0` if no result is unreliable + */ + unsigned long long first_unreliable_result; +} mgis_mp_BatchStatistics; + +/*! + * \brief initialize the statistics of an evaluation (copy of the + * `mfront_gpmp_initializeStatistics` function of `TFEL`) + * \param[out] s: statistics + */ +static inline void mgis_mp_initializeBatchStatistics( + mgis_mp_BatchStatistics* const s) { + s->number_of_failures = 0; + s->first_failure = ~0ull; + s->number_of_unreliable_results = 0; + s->first_unreliable_result = ~0ull; +} /* end of mgis_mp_initializeBatchStatistics */ + +/*! + * \brief values of an argument on a batch of points (copy of the + * `mfront_gpmp_ConstField` structure of `TFEL`): the value at the `i`-th + * point is `values[i * point_stride]` + */ +typedef struct mgis_mp_BatchConstField { + //! \brief pointer to the first value + const mgis_real* values; + //! \brief stride between two points: a null stride denotes a uniform value + mgis_size_type point_stride; +} mgis_mp_BatchConstField; + +/*! + * \brief values of the output on a batch of points (copy of the + * `mfront_gpmp_Field` structure of `TFEL`) + */ +typedef struct mgis_mp_BatchField { + //! \brief pointer to the first value + mgis_real* values; + //! \brief stride between two points (null for a batch of one point only) + mgis_size_type point_stride; +} mgis_mp_BatchField; + +/*! + * \brief data of the evaluation of a material property on a batch of + * points (copy of the `mfront_gpmp_BatchData` structure of `TFEL`). The + * array of the arguments is read on the host. + */ +typedef struct mgis_mp_BatchData { + //! \brief number of points + mgis_size_type number_of_points; + //! \brief output values + mgis_mp_BatchField output; + //! \brief arguments, read on the host (null if there is no argument) + const mgis_mp_BatchConstField* arguments; + //! \brief number of arguments + mgis_size_type number_of_arguments; + //! \brief out of bounds policy + mgis_mp_OutOfBoundsPolicy out_of_bounds_policy; + //! \brief status of each point, or null + int* statuses; + /*! + * \brief statistics of the evaluation, or null. If given, the output + * status only reports the errors of the batch, and the report function + * gives the result once the computations are completed. Asynchronous + * evaluations require statistics. + */ + mgis_mp_BatchStatistics* statistics; + /*! + * \brief execution policy of the backend of the library, or null for the + * default policy of the backend (see `MGIS/BackendExecutionPolicy.h`) + */ + const mgis_gp_AbstractBackendExecutionPolicy* execution_policy; +} mgis_mp_BatchData; + +/*! + * \brief summary of the evaluation of a material property on a batch of + * points (copy of the `mfront_gpmp_OutputStatus` structure of `TFEL`). The + * `status` member is also the value returned by the functions: + * + * - `0`: the result has been evaluated at all points; + * - `1`: a bound is violated with the warning policy at some points; + * - `-1`: a physical bound, or a bound with the strict policy, is violated + * at some points (the output is `NaN` at those points); + * - `-4`: the result is not finite at some points; + * - `-5`: invalid arguments, nothing was computed; + * - `-6`: invalid parameters, nothing was computed; + * - `-7`: runtime error of the backend. + * + * The codes `0`, `1`, `-1` and `-4` are the codes of the `generic` + * interface at the reported point: the first point where the evaluation + * failed, otherwise the first point where the result is unreliable. + */ +typedef struct mgis_mp_BatchOutputStatus { + //! \brief status + int status; + //! \brief number of points where the evaluation failed + mgis_size_type number_of_failures; + /*! + * \brief index of the first point where the evaluation failed, or the + * maximal value of the type if no point failed + */ + mgis_size_type first_failure_index; + //! \brief number of points where a bound is violated with the warning + //! policy + mgis_size_type number_of_unreliable_results; + /*! + * \brief index of the first point where the result is unreliable, or the + * maximal value of the type if no result is unreliable + */ + mgis_size_type first_unreliable_result_index; + /*! + * \brief rank of the variable of the check retained at the reported point + * for the statuses `-1` and `1` (see `mgis_mp_OutputStatus`), zero + * otherwise + */ + int bounds_status; + //! \brief error message + char msg[512]; +} mgis_mp_BatchOutputStatus; + +/*! + * \brief type of a function evaluating a material property on a batch of + * points (`_generic_parallel` function) + */ +typedef int(MGIS_MATERIALPROPERTY_ADDCALL_PTR + mgis_mp_BatchMaterialPropertyFctPtr)( + mgis_mp_BatchOutputStatus* const, const mgis_mp_BatchData* const); + +/*! + * \brief type of the function analysing the statistics of an evaluation + * of a material property, once the evaluation is completed + * (`_generic_parallel_report` function), and reporting the result in + * an output status, as a synchronous evaluation does + */ +typedef int(MGIS_MATERIALPROPERTY_ADDCALL_PTR mgis_mp_BatchReportFctPtr)( + mgis_mp_BatchOutputStatus* const, const mgis_mp_BatchStatistics* const); + +#ifdef __cplusplus +} // end of extern "C" +#endif /* __cplusplus */ + +#ifdef __cplusplus + +namespace mgis::material_property { + + //! \brief a simple alias + using BatchStatistics = ::mgis_mp_BatchStatistics; + //! \brief a simple alias + using BatchConstField = ::mgis_mp_BatchConstField; + //! \brief a simple alias + using BatchField = ::mgis_mp_BatchField; + //! \brief a simple alias + using BatchData = ::mgis_mp_BatchData; + //! \brief a simple alias + using BatchOutputStatus = ::mgis_mp_BatchOutputStatus; + //! \brief a simple alias + using BatchMaterialPropertyFctPtr = ::mgis_mp_BatchMaterialPropertyFctPtr; + //! \brief a simple alias + using BatchReportFctPtr = ::mgis_mp_BatchReportFctPtr; + + /*! + * \brief initialize the statistics of an evaluation (see + * `mgis_mp_initializeBatchStatistics`) + * \param[out] s: statistics + */ + inline void initializeBatchStatistics(BatchStatistics& s) noexcept { + mgis_mp_initializeBatchStatistics(&s); + } // end of initializeBatchStatistics + +} // end of namespace mgis::material_property + +#endif /* __cplusplus */ + +#endif /* LIB_MGIS_MATERIALPROPERTY_BATCHMATERIALPROPERTYFCTPTR_HXX */ From 17a727b00295eeed6de979eea6e9b72f9de60e48 Mon Sep 17 00:00:00 2001 From: t Date: Sat, 24 Oct 2026 03:59:13 +0200 Subject: [PATCH 2/7] generic-parallel material properties: loading `load` recognizes the libraries generated by the `generic-parallel` interface by the version of their functions, checks this version and the memory space, and fills the new members of `MaterialProperty` (interface, version, backend, memory space, identifier of the expected execution policy, functions of batches of points). The libraries of the other interfaces are loaded as before. A library generated by a version of the `generic-parallel` interface which does not export the version of its functions is refused. --- include/MGIS/LibrariesManager.hxx | 75 +++++++++++++++- .../MaterialProperty/MaterialProperty.hxx | 61 ++++++++++++- src/LibrariesManager.cxx | 86 +++++++++++++++++++ src/MaterialProperty.cxx | 37 +++++++- 4 files changed, 255 insertions(+), 4 deletions(-) diff --git a/include/MGIS/LibrariesManager.hxx b/include/MGIS/LibrariesManager.hxx index fe9c3239e..24b44fe0b 100644 --- a/include/MGIS/LibrariesManager.hxx +++ b/include/MGIS/LibrariesManager.hxx @@ -27,7 +27,7 @@ #endif /* (defined _WIN32 || defined _WIN64) && (!defined __CYGWIN__) */ #include "MGIS/Config.hxx" -#include "MGIS/MaterialProperty/MaterialPropertyFctPtr.hxx" +#include "MGIS/MaterialProperty/BatchMaterialPropertyFctPtr.hxx" #include "MGIS/Behaviour/FiniteStrainBehaviourOptions.hxx" #include "MGIS/Behaviour/BehaviourFctPtr.hxx" #include "MGIS/Behaviour/Hypothesis.hxx" @@ -91,6 +91,49 @@ namespace mgis { * \param[in] n: entry point name */ std::string getInterface(const std::string &, const std::string &); + /*! + * \return true if the given entry point provides the functions of + * batches of points of the `generic-parallel` interface, i.e. if the + * library exports the version of those functions + * (`_generic_parallel_api_version` symbol) + * \param[in] l: library name + * \param[in] n: entry point name + */ + bool hasGenericParallelFunctions(const std::string &, const std::string &); + /*! + * \return the version of the functions of batches of points + * (`_generic_parallel_api_version` symbol) + * \param[in] l: library name + * \param[in] n: entry point name + */ + unsigned short getGenericParallelAPIVersion(const std::string &, + const std::string &); + /*! + * \return the backend of a library generated by the `generic-parallel` + * interface (`_generic_parallel_backend` symbol) + * \param[in] l: library name + * \param[in] n: entry point name + */ + std::string getGenericParallelBackend(const std::string &, + const std::string &); + /*! + * \return the memory space of the computations of a library generated by + * the `generic-parallel` interface: `host`, `device` or `any` + * (`_generic_parallel_memory_space` symbol) + * \param[in] l: library name + * \param[in] n: entry point name + */ + std::string getGenericParallelMemorySpace(const std::string &, + const std::string &); + /*! + * \return the identifier of the execution policy expected by a library + * generated by the `generic-parallel` interface + * (`_generic_parallel_execution_policy` symbol) + * \param[in] l: library name + * \param[in] n: entry point name + */ + std::string getGenericParallelExecutionPolicy(const std::string &, + const std::string &); /*! * \return the author of the `MFront` file * \param[in] l: library name @@ -129,6 +172,26 @@ namespace mgis { */ mgis::material_property::MaterialPropertyFctPtr getMaterialProperty( const std::string &, const std::string &); + /*! + * \return the function evaluating a material property on a batch of + * points (`_generic_parallel` symbol of a library generated by the + * `generic-parallel` interface) + * \param[in] l: library name + * \param[in] mp: material property name + */ + mgis::material_property::BatchMaterialPropertyFctPtr + getBatchMaterialProperty(const std::string &, const std::string &); + /*! + * \return the function analysing the statistics of an evaluation of a + * material property on a batch of points + * (`_generic_parallel_report` symbol of a library generated by the + * `generic-parallel` interface) + * \param[in] l: library name + * \param[in] mp: material property name + */ + mgis::material_property::BatchReportFctPtr + getBatchMaterialPropertyReportFunction(const std::string &, + const std::string &); /*! * \return the name of the output of the given material property * \param[in] l: library name @@ -832,6 +895,16 @@ namespace mgis { * \param[in] n: symbol name */ bool contains(const std::string &, const std::string &); + /*! + * \brief throw an exception if the given entry point does not provide + * the functions of batches of points of the `generic-parallel` interface + * \param[in] m: calling method + * \param[in] l: library name + * \param[in] n: entry point name + */ + void checkGenericParallelFunctions(const char *const, + const std::string &, + const std::string &); /*! * \return the adress of the given symbol. If no symbol is found, a * null pointer is returned. diff --git a/include/MGIS/MaterialProperty/MaterialProperty.hxx b/include/MGIS/MaterialProperty/MaterialProperty.hxx index 71c4cbb7e..5a36c1962 100644 --- a/include/MGIS/MaterialProperty/MaterialProperty.hxx +++ b/include/MGIS/MaterialProperty/MaterialProperty.hxx @@ -19,6 +19,7 @@ #include #include "MGIS/Config.hxx" #include "MGIS/MaterialProperty/MaterialPropertyFctPtr.hxx" +#include "MGIS/MaterialProperty/BatchMaterialPropertyFctPtr.hxx" namespace mgis::material_property { @@ -51,14 +52,72 @@ namespace mgis::material_property { std::string tfel_version; //! \brief unit system used by the material property std::string unit_system; - //! \brief pointer to the function implementing the material property + /*! + * \brief pointer to the function implementing the material property at + * one point, null if the library has no such function (material property + * generated by the `generic-parallel` interface) + */ MaterialPropertyFctPtr fct = nullptr; //! \brief output of the material property std::string output; //! \brief inputs of the material property std::vector inputs; + /*! + * \brief interface of `MFront` used to generate the material property + * (`_mfront_interface` symbol): `Generic`, `GenericParallel` or + * empty for the libraries which do not export it. This member is not + * named `interface`, which is a macro of the headers of Windows. + */ + std::string mfront_interface; + /*! + * \brief version of the functions of batches of points exported by the + * library (`_generic_parallel_api_version` symbol), zero if the + * library has no such functions + */ + unsigned short batch_api_version = 0; + /*! + * \brief backend of a library generated by the `generic-parallel` + * interface (for instance `cuda`, `hip`, `stlpar` or `sycl`), for + * information only (see `memory_space`), empty for the other interfaces + */ + std::string backend; + /*! + * \brief memory space of the computations of a library generated by the + * `generic-parallel` interface: `host`, `device` or `any`. The values, + * the statuses of the points and the statistics given to the functions of + * batches of points must be accessible in this memory space. Empty for + * the other interfaces, which compute on the host. + */ + std::string memory_space; + /*! + * \brief identifier of the execution policy expected by a library + * generated by the `generic-parallel` interface (for instance `cuda` or + * `sycl:oneapi`): a policy given to the functions of batches of points + * must have this identifier. Empty for the other interfaces. + */ + std::string execution_policy; + /*! + * \brief pointer to the function implementing the material property on + * a batch of points, null if the library has no such function + */ + BatchMaterialPropertyFctPtr batch_fct = nullptr; + /*! + * \brief pointer to the function analysing the statistics of an + * evaluation on a batch of points, null if the library has no such + * function + */ + BatchReportFctPtr batch_report_fct = nullptr; }; // end of struct MaterialProperty + /*! + * \return true if the library provides the functions evaluating the + * material property on batches of points (`generic-parallel` interface of + * `MFront`) + * \param[in] mp: material property + */ + MGIS_EXPORT bool isGenericParallelMaterialProperty( + const MaterialProperty &) noexcept; + /*! * \brief load the description of a material property from a library * diff --git a/src/LibrariesManager.cxx b/src/LibrariesManager.cxx index fb6184c11..b4ad5cb7b 100644 --- a/src/LibrariesManager.cxx +++ b/src/LibrariesManager.cxx @@ -199,6 +199,21 @@ namespace mgis { mgis::material_property::MaterialPropertyFctPtr LibrariesManager::getMaterialProperty(const std::string &l, const std::string &mp) { + if (this->getInterface(l, mp) == "GenericParallel") { + if (!this->hasGenericParallelFunctions(l, mp)) { + mgis::raise( + "LibrariesManager::getMaterialProperty: material property '" + mp + + "' in library '" + l + + "' has been generated by a version of the generic-parallel " + "interface which is not supported (no symbol '" + + mp + "_generic_parallel_api_version')"); + } + mgis::raise( + "LibrariesManager::getMaterialProperty: material property '" + mp + + "' in library '" + l + + "' has been generated by the generic-parallel interface, which " + "provides no function evaluating it at one point"); + } const auto p = this->getSymbolAddress(l, mp); if (p == nullptr) { mgis::raise( @@ -209,6 +224,37 @@ namespace mgis { return reinterpret_cast(p); } // end of getMaterialProperty + mgis::material_property::BatchMaterialPropertyFctPtr + LibrariesManager::getBatchMaterialProperty(const std::string &l, + const std::string &mp) { + this->checkGenericParallelFunctions( + "LibrariesManager::getBatchMaterialProperty", l, mp); + const auto p = this->getSymbolAddress(l, mp + "_generic_parallel"); + if (p == nullptr) { + mgis::raise( + "LibrariesManager::getBatchMaterialProperty: can't load material " + "property '" + + mp + "' in library '" + l + "'"); + } + return reinterpret_cast< + mgis::material_property::BatchMaterialPropertyFctPtr>(p); + } // end of getBatchMaterialProperty + + mgis::material_property::BatchReportFctPtr + LibrariesManager::getBatchMaterialPropertyReportFunction( + const std::string &l, const std::string &mp) { + this->checkGenericParallelFunctions( + "LibrariesManager::getBatchMaterialPropertyReportFunction", l, mp); + const auto p = this->getSymbolAddress(l, mp + "_generic_parallel_report"); + if (p == nullptr) { + mgis::raise( + "LibrariesManager::getBatchMaterialPropertyReportFunction: can't " + "load the report function of material property '" + + mp + "' in library '" + l + "'"); + } + return reinterpret_cast(p); + } // end of getBatchMaterialPropertyReportFunction + std::vector LibrariesManager::getMaterialPropertyInputsNames( const std::string &l, const std::string &mp) { return this->getNames(l, mp, "args"); @@ -661,6 +707,46 @@ namespace mgis { return *(static_cast(p)); } // end of getInterface + bool LibrariesManager::hasGenericParallelFunctions(const std::string &l, + const std::string &n) { + return this->contains(l, n + "_generic_parallel_api_version"); + } // end of hasGenericParallelFunctions + + void LibrariesManager::checkGenericParallelFunctions(const char *const m, + const std::string &l, + const std::string &n) { + if (!this->hasGenericParallelFunctions(l, n)) { + mgis::raise(std::string{m} + ": entry point '" + n + "' in library '" + + l + + "' has not been generated by the generic-parallel " + "interface (no symbol '" + + n + "_generic_parallel_api_version')"); + } + } // end of checkGenericParallelFunctions + + unsigned short LibrariesManager::getGenericParallelAPIVersion( + const std::string &l, const std::string &n) { + return *( + this->extract(l, n + "_generic_parallel_api_version")); + } // end of getGenericParallelAPIVersion + + std::string LibrariesManager::getGenericParallelBackend( + const std::string &l, const std::string &n) { + return *(this->extract(l, n + "_generic_parallel_backend")); + } // end of getGenericParallelBackend + + std::string LibrariesManager::getGenericParallelMemorySpace( + const std::string &l, const std::string &n) { + return *( + this->extract(l, n + "_generic_parallel_memory_space")); + } // end of getGenericParallelMemorySpace + + std::string LibrariesManager::getGenericParallelExecutionPolicy( + const std::string &l, const std::string &n) { + return *(this->extract( + l, n + "_generic_parallel_execution_policy")); + } // end of getGenericParallelExecutionPolicy + unsigned short LibrariesManager::getBehaviourType(const std::string &l, const std::string &b) { return *(this->extract(l, b + "_BehaviourType")); diff --git a/src/MaterialProperty.cxx b/src/MaterialProperty.cxx index 3740e1014..2a0c8a872 100644 --- a/src/MaterialProperty.cxx +++ b/src/MaterialProperty.cxx @@ -12,6 +12,8 @@ * CeCILL-C_V1-en.txt and CeCILL-C_V1-fr.txt). */ +#include +#include "MGIS/Raise.hxx" #include "MGIS/LibrariesManager.hxx" #include "MGIS/MaterialProperty/MaterialProperty.hxx" @@ -27,16 +29,47 @@ namespace mgis::material_property { MaterialProperty load(const std::string &l, const std::string &mp) { auto &lm = mgis::LibrariesManager::get(); + auto raise_if = [&l, &mp](const bool c, const std::string &msg) { + if (c) { + mgis::raise("load: " + msg + + ".\nError while trying to load material property '" + mp + + "' in library '" + l + "'\n"); + } + }; auto d = MaterialProperty{}; d.library = l; d.material_property = mp; d.tfel_version = lm.getTFELVersion(l, mp); d.unit_system = lm.getUnitSystem(l, mp); d.source = lm.getSource(l, mp); - d.fct = lm.getMaterialProperty(l, mp); + d.mfront_interface = lm.getInterface(l, mp); + if (lm.hasGenericParallelFunctions(l, mp)) { + // functions of batches of points (`generic-parallel` interface) + d.batch_api_version = lm.getGenericParallelAPIVersion(l, mp); + raise_if(d.batch_api_version != MGIS_MP_GENERIC_PARALLEL_API_VERSION, + "unmatched version of the functions of the generic-parallel " + "interface (the material property uses version " + + std::to_string(d.batch_api_version) + + ", mgis uses version " + + std::to_string(MGIS_MP_GENERIC_PARALLEL_API_VERSION) + ")"); + d.backend = lm.getGenericParallelBackend(l, mp); + d.memory_space = lm.getGenericParallelMemorySpace(l, mp); + raise_if((d.memory_space != "host") && (d.memory_space != "device") && + (d.memory_space != "any"), + "invalid memory space '" + d.memory_space + "'"); + d.execution_policy = lm.getGenericParallelExecutionPolicy(l, mp); + d.batch_fct = lm.getBatchMaterialProperty(l, mp); + d.batch_report_fct = lm.getBatchMaterialPropertyReportFunction(l, mp); + } else { + d.fct = lm.getMaterialProperty(l, mp); + } d.output = lm.getMaterialPropertyOutputName(l, mp); d.inputs = lm.getMaterialPropertyInputsNames(l, mp); return d; - } // end of load_behaviour + } // end of load + + bool isGenericParallelMaterialProperty(const MaterialProperty &mp) noexcept { + return mp.batch_fct != nullptr; + } // end of isGenericParallelMaterialProperty } // end of namespace mgis::material_property From 352dc634ad98a64f4c835abb8b7141c9ea36a3a7 Mon Sep 17 00:00:00 2001 From: t Date: Sat, 24 Oct 2026 03:59:13 +0200 Subject: [PATCH 3/7] generic-parallel material properties: tests With `TFEL` 5.2 or later: copies of the types of `TFEL` (sizes and offsets of the members), loading of a library generated with the `stlpar` backend, values and statuses compared to the `generic` interface, report of an evaluation with statistics, refused libraries. --- CMakeLists.txt | 1 + cmake/modules/generic-parallel.cmake | 53 +++++ tests/CMakeLists.txt | 35 ++++ ...nericParallelInvalidMaterialProperties.cxx | 49 +++++ ...oadGenericParallelMaterialPropertyTest.cxx | 188 ++++++++++++++++++ 5 files changed, 326 insertions(+) create mode 100644 cmake/modules/generic-parallel.cmake create mode 100644 tests/GenericParallelInvalidMaterialProperties.cxx create mode 100644 tests/LoadGenericParallelMaterialPropertyTest.cxx diff --git a/CMakeLists.txt b/CMakeLists.txt index f79bd74bd..e45a3e2b4 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -219,6 +219,7 @@ if(NOT disable-tfel) if(TFEL_FOUND) include(tfel) include(material-properties) + include(generic-parallel) include(behaviours) endif(TFEL_FOUND) endif(NOT disable-tfel) diff --git a/cmake/modules/generic-parallel.cmake b/cmake/modules/generic-parallel.cmake new file mode 100644 index 000000000..1224a4c81 --- /dev/null +++ b/cmake/modules/generic-parallel.cmake @@ -0,0 +1,53 @@ +# Libraries of material properties generated by the `generic-parallel` +# interface of `MFront` (`TFEL` 5.2 or later), compiled by the C++ compiler +# of `MGIS`. Only the backends whose sources are standard C++ sources are +# supported (`stlpar`). The sources are generated in a directory of their +# own. +# +# usage: mfront_generic_parallel_material_properties_check_library(name +# backend properties...) +function(mfront_generic_parallel_material_properties_check_library name + backend) + set(_directory + "${CMAKE_CURRENT_BINARY_DIR}/generic-parallel-material-properties-${backend}") + file(MAKE_DIRECTORY "${_directory}") + set(_configuration "${_directory}/configuration.json") + file(WRITE "${_configuration}" + "interfaces_options: {\n" + " generic-parallel: {\n" + " backend: \"${backend}\"\n" + " }\n" + "}\n") + set(_sources) + foreach(source ${ARGN}) + set(_file "${CMAKE_CURRENT_SOURCE_DIR}/${source}.mfront") + set(_output "${_directory}/src/${source}-generic-parallel-${backend}.cxx") + add_custom_command( + OUTPUT "${_output}" + COMMAND "${MFRONT}" + ARGS "--interface=generic-parallel" + ARGS "--configuration-file=${_configuration}" + ARGS "${_file}" + DEPENDS "${_file}" "${MFRONT}" "${_configuration}" + WORKING_DIRECTORY "${_directory}" + COMMENT "mfront source ${_file} (generic-parallel interface)") + list(APPEND _sources "${_output}") + endforeach(source ${ARGN}) + add_library(${name} SHARED EXCLUDE_FROM_ALL ${_sources}) + add_dependencies(check ${name}) + target_include_directories(${name} + PRIVATE "${_directory}/include" + PRIVATE "${TFEL_INCLUDE_PATH}") + target_compile_definitions(${name} PRIVATE MFRONT_COMPILING) + if(backend STREQUAL "stlpar") + # libraries required by the parallel algorithms of the standard library + # (see the `enable-parallel-stl-algorithms` option) + target_link_libraries(${name} PRIVATE ${MGIS_ADDITIONAL_LIBRARIES}) + if(UNIX AND NOT APPLE) + # the library stays loaded until the end of the process: the threads + # of TBB may still run when the libraries are unloaded at exit (as in + # the configuration files of the stlpar backend of TFEL) + target_link_libraries(${name} PRIVATE "-Wl,-z,nodelete") + endif(UNIX AND NOT APPLE) + endif(backend STREQUAL "stlpar") +endfunction(mfront_generic_parallel_material_properties_check_library) diff --git a/tests/CMakeLists.txt b/tests/CMakeLists.txt index 64ffc2572..236b2a776 100644 --- a/tests/CMakeLists.txt +++ b/tests/CMakeLists.txt @@ -118,6 +118,22 @@ if(MGIS_HAVE_MFRONT_SUPPORT) MaterialPropertyErrnoCheck2 Inconel600_YoungModulus) + # material properties generated by the `generic-parallel` interface + # (TFEL 5.2 or later) with the `stlpar` backend, which requires the + # parallel algorithms of the standard library + if(enable-parallel-stl-algorithms AND + EXISTS "${TFEL_INCLUDE_PATH}/MFront/GenericParallelMaterialProperty/MaterialProperty.h") + set(MGIS_HAVE_GENERIC_PARALLEL_MATERIAL_PROPERTIES ON) + mfront_generic_parallel_material_properties_check_library( + GenericParallelMaterialPropertyTest stlpar + MaterialPropertyBoundCheck) + add_library(GenericParallelInvalidMaterialProperties SHARED EXCLUDE_FROM_ALL + GenericParallelInvalidMaterialProperties.cxx) + target_link_libraries(GenericParallelInvalidMaterialProperties + PRIVATE MFrontGenericInterface) + add_dependencies(check GenericParallelInvalidMaterialProperties) + endif() + mfront_behaviours_check_library( BehaviourTest Elasticity @@ -140,6 +156,25 @@ if(MGIS_HAVE_MFRONT_SUPPORT) # Tests that depend on behaviour libraries add_library_test_with_tfel_version(LoadMaterialPropertyTest LoadMaterialPropertyTest.cxx MaterialPropertyTest) + if(MGIS_HAVE_GENERIC_PARALLEL_MATERIAL_PROPERTIES) + add_executable(LoadGenericParallelMaterialPropertyTest EXCLUDE_FROM_ALL + LoadGenericParallelMaterialPropertyTest.cxx) + target_link_libraries(LoadGenericParallelMaterialPropertyTest + PRIVATE MFrontGenericInterface) + # the headers of TFEL are only used to check the copies of its types + target_include_directories(LoadGenericParallelMaterialPropertyTest + PRIVATE "${TFEL_INCLUDE_PATH}") + add_test(NAME LoadGenericParallelMaterialPropertyTest + COMMAND LoadGenericParallelMaterialPropertyTest + "$" + "$" + "$") + add_dependencies(build-tests LoadGenericParallelMaterialPropertyTest) + set_property(TEST LoadGenericParallelMaterialPropertyTest + PROPERTY DEPENDS GenericParallelMaterialPropertyTest MaterialPropertyTest + GenericParallelInvalidMaterialProperties) + set_test_environment(LoadGenericParallelMaterialPropertyTest) + endif() # Tests with TFEL_VERSION add_tfel_version_test(MFrontGenericBehaviourInterfaceTest diff --git a/tests/GenericParallelInvalidMaterialProperties.cxx b/tests/GenericParallelInvalidMaterialProperties.cxx new file mode 100644 index 000000000..6a9311c02 --- /dev/null +++ b/tests/GenericParallelInvalidMaterialProperties.cxx @@ -0,0 +1,49 @@ +/*! + * \file tests/GenericParallelInvalidMaterialProperties.cxx + * \brief This file exports the symbols of material properties of the + * `generic-parallel` interface which `MGIS` must refuse: functions of a + * version which is not supported, invalid memory space, library generated + * by a version of the interface which does not export the version of its + * functions. No function is defined: those material properties are refused + * before any function is loaded. + * \date 24/10/2026 + * \copyright Use, modification and distribution are subject + * to one of the following licences: + * - GNU Lesser General Public License (LGPL), Version 3.0. (See accompanying + * file LGPL-3.0.txt) + * - CECILL-C, Version 1.0 (See accompanying files + * CeCILL-C_V1-en.txt and CeCILL-C_V1-fr.txt). + */ + +#include "MGIS/Config-c.h" +#include "MGIS/MaterialProperty/BatchMaterialPropertyFctPtr.hxx" + +extern "C" { + +//! \brief version of the functions which is not supported +MGIS_VISIBILITY_EXPORT const char* UnsupportedVersion_mfront_interface = + "GenericParallel"; +MGIS_VISIBILITY_EXPORT unsigned short + UnsupportedVersion_generic_parallel_api_version = + MGIS_MP_GENERIC_PARALLEL_API_VERSION + 1; +MGIS_VISIBILITY_EXPORT const char* UnsupportedVersion_generic_parallel_backend = + "stlpar"; +MGIS_VISIBILITY_EXPORT const char* + UnsupportedVersion_generic_parallel_memory_space = "host"; + +//! \brief invalid memory space +MGIS_VISIBILITY_EXPORT const char* InvalidMemorySpace_mfront_interface = + "GenericParallel"; +MGIS_VISIBILITY_EXPORT unsigned short + InvalidMemorySpace_generic_parallel_api_version = + MGIS_MP_GENERIC_PARALLEL_API_VERSION; +MGIS_VISIBILITY_EXPORT const char* InvalidMemorySpace_generic_parallel_backend = + "stlpar"; +MGIS_VISIBILITY_EXPORT const char* + InvalidMemorySpace_generic_parallel_memory_space = "nowhere"; + +//! \brief no symbol giving the version of the functions +MGIS_VISIBILITY_EXPORT const char* NoVersion_mfront_interface = + "GenericParallel"; + +} // end of extern "C" diff --git a/tests/LoadGenericParallelMaterialPropertyTest.cxx b/tests/LoadGenericParallelMaterialPropertyTest.cxx new file mode 100644 index 000000000..8f0e0f14d --- /dev/null +++ b/tests/LoadGenericParallelMaterialPropertyTest.cxx @@ -0,0 +1,188 @@ +/*! + * \file tests/LoadGenericParallelMaterialPropertyTest.cxx + * \brief This file tests the loading of material properties generated by + * the `generic-parallel` interface of `MFront`, and checks that the types + * declared by `MGIS` are copies of the ones declared by `TFEL`. + * + * usage: LoadGenericParallelMaterialPropertyTest generic_parallel_library + * generic_library invalid_library + * \date 24/10/2026 + * \copyright Use, modification and distribution are subject + * to one of the following licences: + * - GNU Lesser General Public License (LGPL), Version 3.0. (See accompanying + * file LGPL-3.0.txt) + * - CECILL-C, Version 1.0 (See accompanying files + * CeCILL-C_V1-en.txt and CeCILL-C_V1-fr.txt). + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "MGIS/MaterialProperty/MaterialProperty.hxx" +#include "MFront/GenericParallelMaterialProperty/MaterialProperty.h" + +// copies of the types of `TFEL`: same version, same sizes, same members at +// the same offsets +static_assert(MGIS_MP_GENERIC_PARALLEL_API_VERSION == MFRONT_GPMP_API_VERSION); +static_assert(std::is_same_v); +static_assert(sizeof(mgis_size_type) == sizeof(mfront_gmp_size_type)); +static_assert(std::is_same_v); +static_assert(static_cast(MGIS_MATERIALPROPERTY_NONE_POLICY) == + static_cast(GENERIC_MATERIALPROPERTY_NONE_POLICY)); +static_assert(static_cast(MGIS_MATERIALPROPERTY_WARNING_POLICY) == + static_cast(GENERIC_MATERIALPROPERTY_WARNING_POLICY)); +static_assert(static_cast(MGIS_MATERIALPROPERTY_STRICT_POLICY) == + static_cast(GENERIC_MATERIALPROPERTY_STRICT_POLICY)); +#define MGIS_CHECK_SIZE(T1, T2) \ + static_assert(sizeof(mgis_mp_##T1) == sizeof(mfront_gpmp_##T2)) +#define MGIS_CHECK_MEMBER(T1, T2, m) \ + static_assert(offsetof(mgis_mp_##T1, m) == offsetof(mfront_gpmp_##T2, m)) +MGIS_CHECK_SIZE(BatchStatistics, Statistics); +MGIS_CHECK_MEMBER(BatchStatistics, Statistics, number_of_failures); +MGIS_CHECK_MEMBER(BatchStatistics, Statistics, first_failure); +MGIS_CHECK_MEMBER(BatchStatistics, Statistics, number_of_unreliable_results); +MGIS_CHECK_MEMBER(BatchStatistics, Statistics, first_unreliable_result); +MGIS_CHECK_SIZE(BatchConstField, ConstField); +MGIS_CHECK_MEMBER(BatchConstField, ConstField, values); +MGIS_CHECK_MEMBER(BatchConstField, ConstField, point_stride); +MGIS_CHECK_SIZE(BatchField, Field); +MGIS_CHECK_MEMBER(BatchField, Field, values); +MGIS_CHECK_MEMBER(BatchField, Field, point_stride); +MGIS_CHECK_SIZE(BatchData, BatchData); +MGIS_CHECK_MEMBER(BatchData, BatchData, number_of_points); +MGIS_CHECK_MEMBER(BatchData, BatchData, output); +MGIS_CHECK_MEMBER(BatchData, BatchData, arguments); +MGIS_CHECK_MEMBER(BatchData, BatchData, number_of_arguments); +MGIS_CHECK_MEMBER(BatchData, BatchData, out_of_bounds_policy); +MGIS_CHECK_MEMBER(BatchData, BatchData, statuses); +MGIS_CHECK_MEMBER(BatchData, BatchData, statistics); +MGIS_CHECK_MEMBER(BatchData, BatchData, execution_policy); +MGIS_CHECK_SIZE(BatchOutputStatus, OutputStatus); +MGIS_CHECK_MEMBER(BatchOutputStatus, OutputStatus, status); +MGIS_CHECK_MEMBER(BatchOutputStatus, OutputStatus, number_of_failures); +MGIS_CHECK_MEMBER(BatchOutputStatus, OutputStatus, first_failure_index); +MGIS_CHECK_MEMBER(BatchOutputStatus, + OutputStatus, + number_of_unreliable_results); +MGIS_CHECK_MEMBER(BatchOutputStatus, + OutputStatus, + first_unreliable_result_index); +MGIS_CHECK_MEMBER(BatchOutputStatus, OutputStatus, bounds_status); +MGIS_CHECK_MEMBER(BatchOutputStatus, OutputStatus, msg); + +static bool success = true; + +static bool check(const bool b, const std::string_view msg) { + if (!b) { + success = false; + std::cerr << msg << '\n'; + } + return b; +} + +//! \brief description and evaluation of a material property on a batch +static void test1(const std::string& gp_library, + const std::string& generic_library) { + using namespace mgis; + using namespace mgis::material_property; + const auto mp = load(gp_library, "MaterialPropertyBoundCheck"); + check(isGenericParallelMaterialProperty(mp), "batch functions expected"); + check(mp.fct == nullptr, "no function of a point expected"); + check(mp.batch_report_fct != nullptr, "report function expected"); + check(mp.mfront_interface == "GenericParallel", "invalid interface"); + check(mp.batch_api_version == MGIS_MP_GENERIC_PARALLEL_API_VERSION, + "invalid version"); + check(mp.backend == "stlpar", "invalid backend"); + check(mp.memory_space == "host", "invalid memory space"); + check(mp.execution_policy == "stlpar", "invalid execution policy"); + check(mp.output == "YoungModulus", "invalid output"); + check((mp.inputs.size() == 1) && (mp.inputs[0] == "Temperature"), + "invalid inputs"); + // the third temperature is out of the bounds [200:300] + const auto T = std::array{250, 280, 100, 300}; + auto E = std::array{}; + auto statuses = std::array{12, 12, 12, 12}; + const auto args = std::array{ + BatchConstField{.values = T.data(), .point_stride = 1}}; + auto d = + BatchData{.number_of_points = 4, + .output = BatchField{.values = E.data(), .point_stride = 1}, + .arguments = args.data(), + .number_of_arguments = 1, + .out_of_bounds_policy = MGIS_MATERIALPROPERTY_NONE_POLICY, + .statuses = statuses.data(), + .statistics = nullptr, + .execution_policy = nullptr}; + // same values as the function of the `generic` interface + const auto g = load(generic_library, "MaterialPropertyBoundCheck"); + check(!isGenericParallelMaterialProperty(g), "no batch functions expected"); + check((g.fct != nullptr) && (g.batch_api_version == 0) && g.backend.empty(), + "invalid description of a material property of the generic interface"); + auto s = BatchOutputStatus{}; + check(mp.batch_fct(&s, &d) == 0, "evaluation failed"); + check(s.status == 0, "invalid output status"); + for (std::size_t i = 0; i != T.size(); ++i) { + auto gs = OutputStatus{}; + const auto Eg = g.fct(&gs, &T[i], 1, MGIS_MATERIALPROPERTY_NONE_POLICY); + check(std::abs(E[i] - Eg) <= 1e-14 * std::abs(Eg), + "invalid value at point " + std::to_string(i)); + check(statuses[i] == gs.status, + "invalid status at point " + std::to_string(i)); + } + // strict policy, statistics given by the calling code: the evaluation + // only reports the errors of the batch and the report function gives the + // result + auto statistics = BatchStatistics{}; + initializeBatchStatistics(statistics); + d.out_of_bounds_policy = MGIS_MATERIALPROPERTY_STRICT_POLICY; + d.statistics = &statistics; + check(mp.batch_fct(&s, &d) == 0, "invalid status of the batch"); + const auto r = mp.batch_report_fct(&s, &statistics); + check(r < 0, "the evaluation shall fail at the third point"); + check((s.number_of_failures == 1) && (s.first_failure_index == 2), + "invalid report"); + check((statuses[0] == 0) && (statuses[1] == 0) && (statuses[2] < 0) && + (statuses[3] == 0), + "invalid statuses of the points"); +} + +//! \brief material properties which must be refused +static void test2(const std::string& library) { + using namespace mgis::material_property; + auto check_refused = [&library](const std::string& n, + const std::string_view expected) { + try { + load(library, n); + check(false, "material property '" + n + "' shall be refused"); + } catch (std::exception& e) { + check(std::string_view{e.what()}.find(expected) != std::string_view::npos, + "unexpected message for '" + n + "': " + e.what()); + } + }; + check_refused("UnsupportedVersion", "unmatched version"); + check_refused("InvalidMemorySpace", "invalid memory space 'nowhere'"); + check_refused("NoVersion", "is not supported"); +} + +int main(const int argc, const char* const* argv) { + if (argc != 4) { + std::cerr << "usage: " << argv[0] + << " generic_parallel_library generic_library invalid_library\n"; + return EXIT_FAILURE; + } + try { + test1(argv[1], argv[2]); + test2(argv[3]); + } catch (std::exception& e) { + std::cerr << e.what() << '\n'; + return EXIT_FAILURE; + } + return success ? EXIT_SUCCESS : EXIT_FAILURE; +} // end of main From 28fa2dadef7814021797d208a1f20f5dd2662258 Mon Sep 17 00:00:00 2001 From: t Date: Sat, 24 Oct 2026 03:59:13 +0200 Subject: [PATCH 4/7] generic-parallel material properties: release notes --- docs/web/release-notes-3.2.md | 61 +++++++++++++++++++++++++++++++++++ 1 file changed, 61 insertions(+) diff --git a/docs/web/release-notes-3.2.md b/docs/web/release-notes-3.2.md index 3839baffb..53d46d52a 100644 --- a/docs/web/release-notes-3.2.md +++ b/docs/web/release-notes-3.2.md @@ -132,6 +132,63 @@ setExternalStateVariable(m.s1, "Temperature", T1, MaterialStateManager::UPDATE); ~~~~ +# New features of the `MGIS/MaterialProperty` library + +## Material properties generated by the `generic-parallel` interface + +The `generic-parallel` interface of `MFront` (`TFEL` 5.2 or later) +generates functions evaluating a material property on a batch of points, +on CPUs or on GPUs. The `load` function recognizes those libraries by the +version of their functions (`_generic_parallel_api_version` +symbol) and fills the new members of the `MaterialProperty` structure: + +- `mfront_interface`: interface of `MFront` used to generate the + material property; +- `batch_api_version`: version of the functions of batches of points; +- `backend`: backend of the library (`cuda`, `hip`, `stlpar` or `sycl`); +- `memory_space`: memory space of the computations (`host`, `device` or + `any`); +- `execution_policy`: identifier of the execution policy expected by the + library; +- `batch_fct` and `batch_report_fct`: functions evaluating the material + property on a batch of points and analysing the statistics of an + evaluation. + +A library exporting another version of those functions, an invalid memory +space, or generated by a version of the `generic-parallel` interface which +does not export the version of its functions, is refused. The +`isGenericParallelMaterialProperty` function tells if a material property +provides the functions of batches of points. + +The types of those functions (`mgis_mp_BatchData`, +`mgis_mp_BatchStatistics`, `mgis_mp_BatchOutputStatus`, etc.), declared in +`MGIS/MaterialProperty/BatchMaterialPropertyFctPtr.hxx`, are copies of the +ones of `TFEL`: `MGIS` does not depend on `TFEL`. The execution policies of +the backends are defined by `TFEL`: `MGIS` only declares their type +(`MGIS/BackendExecutionPolicy.h`), and a code creating a policy includes the +headers of `TFEL` and links the `MFrontGenericParallelRuntime` library. + +### Example of usage + +~~~~{.cxx} +using namespace mgis::material_property; +const auto mp = load("libGenericParallelMaterial-stlpar.so", "YoungModulus"); +const auto T = std::array{300, 400, 500, 600}; +auto E = std::array{}; +const auto args = std::array{ + BatchConstField{.values = T.data(), .point_stride = 1}}; +const auto d = BatchData{.number_of_points = 4, + .output = BatchField{.values = E.data(), .point_stride = 1}, + .arguments = args.data(), + .number_of_arguments = 1, + .out_of_bounds_policy = MGIS_MATERIALPROPERTY_NONE_POLICY, + .statuses = nullptr, + .statistics = nullptr, + .execution_policy = nullptr}; +auto s = BatchOutputStatus{}; +const auto r = mp.batch_fct(&s, &d); +~~~~ + # New features of the `MGIS/Function` library ## Support for quantities @@ -264,6 +321,10 @@ assign(ctx, f | as_scalar, f2 | as_scalar); # Issues fixed +## Issue 320: generic-parallel material properties: the libraries generated by TFEL 5.2 can't be loaded nor checked + +For more details, see + ## Issue 255: Fix `InvokeTest` on `MacOS` For more details, see From 657866c31533e305de750fe5a7a20f6879118d81 Mon Sep 17 00:00:00 2001 From: t Date: Tue, 27 Oct 2026 03:58:21 +0100 Subject: [PATCH 5/7] generic-parallel material properties: statistics accessible by the host and by the device The statistics are read on the host by the report function (and written on the host by the stlpar backend): as in TFEL, they must be accessible by the host and by the device, not only in the memory space of the library. Review item: M-008 --- .../MGIS/MaterialProperty/BatchMaterialPropertyFctPtr.hxx | 8 ++++++-- include/MGIS/MaterialProperty/MaterialProperty.hxx | 7 ++++--- 2 files changed, 10 insertions(+), 5 deletions(-) diff --git a/include/MGIS/MaterialProperty/BatchMaterialPropertyFctPtr.hxx b/include/MGIS/MaterialProperty/BatchMaterialPropertyFctPtr.hxx index 7134bed80..5e851a6c3 100644 --- a/include/MGIS/MaterialProperty/BatchMaterialPropertyFctPtr.hxx +++ b/include/MGIS/MaterialProperty/BatchMaterialPropertyFctPtr.hxx @@ -40,7 +40,8 @@ extern "C" { * device only updates them when an event occurs at a point (the `stlpar` * backend merges the statuses of the points by a reduction on the host). They * are initialized by `mgis_mp_initializeBatchStatistics` and analysed by the - * report function of the material property. + * report function of the material property, on the host: they must be + * accessible by the host and by the device (see `mgis_mp_BatchData`). */ typedef struct mgis_mp_BatchStatistics { /*! @@ -122,7 +123,10 @@ typedef struct mgis_mp_BatchData { * \brief statistics of the evaluation, or null. If given, the output * status only reports the errors of the batch, and the report function * gives the result once the computations are completed. Asynchronous - * evaluations require statistics. + * evaluations require statistics. The statistics must be accessible by + * the host and by the device where the computations are performed + * (managed or shared memory if the memory space of the library is + * `device`). */ mgis_mp_BatchStatistics* statistics; /*! diff --git a/include/MGIS/MaterialProperty/MaterialProperty.hxx b/include/MGIS/MaterialProperty/MaterialProperty.hxx index 5a36c1962..900a56440 100644 --- a/include/MGIS/MaterialProperty/MaterialProperty.hxx +++ b/include/MGIS/MaterialProperty/MaterialProperty.hxx @@ -83,9 +83,10 @@ namespace mgis::material_property { std::string backend; /*! * \brief memory space of the computations of a library generated by the - * `generic-parallel` interface: `host`, `device` or `any`. The values, - * the statuses of the points and the statistics given to the functions of - * batches of points must be accessible in this memory space. Empty for + * `generic-parallel` interface: `host`, `device` or `any`. The values + * and the statuses of the points given to the functions of batches of + * points must be accessible in this memory space, and the statistics by + * the host and in this memory space (see `mgis_mp_BatchData`). Empty for * the other interfaces, which compute on the host. */ std::string memory_space; From 86084cf98f00b2059af3dae0295b9c034044555c Mon Sep 17 00:00:00 2001 From: t Date: Sun, 1 Nov 2026 21:48:49 +0100 Subject: [PATCH 6/7] Build system: generic-parallel test libraries built by build-tests The generic-parallel material property libraries of the tests were only built by check, so that make build-tests followed by ctest ran with missing or stale libraries; they now depend on build-tests, as the other test targets. Review item: M-116 --- cmake/modules/generic-parallel.cmake | 2 +- tests/CMakeLists.txt | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/cmake/modules/generic-parallel.cmake b/cmake/modules/generic-parallel.cmake index 1224a4c81..72abe7f0a 100644 --- a/cmake/modules/generic-parallel.cmake +++ b/cmake/modules/generic-parallel.cmake @@ -34,7 +34,7 @@ function(mfront_generic_parallel_material_properties_check_library name list(APPEND _sources "${_output}") endforeach(source ${ARGN}) add_library(${name} SHARED EXCLUDE_FROM_ALL ${_sources}) - add_dependencies(check ${name}) + add_dependencies(build-tests ${name}) target_include_directories(${name} PRIVATE "${_directory}/include" PRIVATE "${TFEL_INCLUDE_PATH}") diff --git a/tests/CMakeLists.txt b/tests/CMakeLists.txt index 89acbcf17..2c2727557 100644 --- a/tests/CMakeLists.txt +++ b/tests/CMakeLists.txt @@ -126,7 +126,7 @@ if(MGIS_HAVE_MFRONT_SUPPORT) GenericParallelInvalidMaterialProperties.cxx) target_link_libraries(GenericParallelInvalidMaterialProperties PRIVATE MFrontGenericInterface) - add_dependencies(check GenericParallelInvalidMaterialProperties) + add_dependencies(build-tests GenericParallelInvalidMaterialProperties) endif() mfront_behaviours_check_library( From 59cc074b3b9d2432329790f80e9794337616a0cf Mon Sep 17 00:00:00 2001 From: t Date: Tue, 3 Nov 2026 13:21:08 +0100 Subject: [PATCH 7/7] Tests: no DEPENDS property on LoadGenericParallelMaterialPropertyTest The DEPENDS property of a test names other tests, which must have run before it. LoadGenericParallelMaterialPropertyTest named three library targets, which are not tests: the property had no effect. The fix of M-153 (1f97fdf, on master) removed the other occurrences; this one, added by this pull request (352dc63) before that fix, was kept by the merge of master (cd8a6d1). The libraries are built by the build-tests target, as the other test libraries. Review item: M-192 --- tests/CMakeLists.txt | 3 --- 1 file changed, 3 deletions(-) diff --git a/tests/CMakeLists.txt b/tests/CMakeLists.txt index 2c2727557..644e8a949 100644 --- a/tests/CMakeLists.txt +++ b/tests/CMakeLists.txt @@ -165,9 +165,6 @@ if(MGIS_HAVE_MFRONT_SUPPORT) "$" "$") add_dependencies(build-tests LoadGenericParallelMaterialPropertyTest) - set_property(TEST LoadGenericParallelMaterialPropertyTest - PROPERTY DEPENDS GenericParallelMaterialPropertyTest MaterialPropertyTest - GenericParallelInvalidMaterialProperties) set_test_environment(LoadGenericParallelMaterialPropertyTest) endif()