| Base 4e5abd | Head #31653 1b25b3 | ||||
|---|---|---|---|---|---|
| Total | Total | +/- | New | ||
| Rate | 85.99% | 85.93% | -0.05% | 100.00% | |
| Hits | 124384 | 124624 | +240 | 510 | |
| Misses | 20272 | 20400 | +128 | 0 | |
codecodecode+
62 63 64 65 + 66 67 68 |
* - Moose::Kokkos::ResidualObject in KokkosResidualObject.K * - Moose::Kokkos::MaterialBase in KokkosMaterialBase.K */ bool isKokkosObject() const { return parameters().isParamValid(MooseBase::kokkos_object_param); } #endif // To get warnings tracked in the SolutionInvalidityOutput |
160 161 162 163 + 164 165 + 166 167 168 169 170 + 171 172 + 173 174 + 175 + 176 177 178 + 179 180 181 |
#ifdef MOOSE_KOKKOS_ENABLED template <typename T> const T & FunctionInterface::getKokkosFunction(const std::string & name) const { return getKokkosFunctionByName<T>(_fni_params.get<FunctionName>(name)); } template <typename T> const T & FunctionInterface::getKokkosFunctionByName(const FunctionName & name) const { auto function = dynamic_cast<const T *>(getKokkosFunctionByNameHelper(name)); if (!function) _fni_object.mooseError( "Kokkos function '", name, "' is not of type '", MooseUtils::prettyCppType<T>(), "'"); return *function; } #endif |
25 26 27 28 + 29 30 31 |
protected: /// Returns whether the raw data has been loaded already bool isRawDataLoaded() const { return _raw_data_loaded; } /// Reads data from supplied CSV file. void buildFromFile(const libMesh::Parallel::Communicator & comm); |
19 20 21 22 + 23 24 + 25 26 27 |
KokkosFunctionAux(const InputParameters & parameters); KOKKOS_FUNCTION Real computeValue(const unsigned int qp, AssemblyDatum & datum) const { return _func.value(_t, datum.q_point(qp)); } protected: |
155 156 157 158 159 160 161 |
if (!isNodal()) reinitTransform(qp); else _xyz = _assembly.kokkosMesh().getNodePoint(_node); return _xyz; } |
20 21 22 23 + 24 25 26 |
class FunctorRegistryEntryBase { public: virtual ~FunctorRegistryEntryBase() {} /** * Build a host wrapper for this functor * @param object The pointer to the functor |
32 33 34 35 + 36 37 + 38 39 40 41 42 43 44 + 45 46 47 |
class FunctorRegistryEntry : public FunctorRegistryEntryBase { public: std::unique_ptr<FunctorWrapperHostBase> build(const void * object) const override final { return std::make_unique<FunctorWrapperHost<Object>>(object); } }; class FunctionRegistryEntryBase { public: virtual ~FunctionRegistryEntryBase() {} /** * Build a host wrapper for this function * @param object The pointer to the function |
53 54 55 56 + 57 58 + 59 60 61 62 63 64 + 65 66 67 |
class FunctionRegistryEntry : public FunctionRegistryEntryBase { public: std::unique_ptr<FunctionWrapperHostBase> build(const void * object) const override final { return std::make_unique<FunctionWrapperHost<Object>>(object); } }; class FunctorRegistry { public: FunctorRegistry() = default; FunctorRegistry(FunctorRegistry const &) = delete; FunctorRegistry & operator=(FunctorRegistry const &) = delete; |
75 76 77 78 + 79 80 + 81 82 + 83 84 85 |
* @param name The registered functor type name */ template <typename Object> static char addFunctor(const std::string & name) { getRegistry()._functors[name] = std::make_unique<FunctorRegistryEntry<Object>>(); return 0; } /** |
88 89 90 91 + 92 93 + 94 95 + 96 97 98 |
* @param name The registered function type name */ template <typename Object> static char addFunction(const std::string & name) { getRegistry()._functions[name] = std::make_unique<FunctionRegistryEntry<Object>>(); return 0; } /** |
119 120 121 122 + 123 124 125 + 126 + 127 + 128 129 130 131 + 132 133 134 |
* @param name The registered function type name * @returns The host wrapper */ static std::unique_ptr<FunctionWrapperHostBase> buildFunction(const void * object, const std::string & name) { auto it = getRegistry()._functions.find(name); if (it == getRegistry()._functions.end()) mooseError("Kokkos function not registered for type '", name, "'. Double check that you used Kokkos-specific registration macro."); return it->second->build(object); } private: |
22 23 24 25 + 26 + 27 28 29 |
class FunctorWrapperDeviceBase { public: KOKKOS_FUNCTION FunctorWrapperDeviceBase() {} KOKKOS_FUNCTION virtual ~FunctorWrapperDeviceBase() {} }; template <typename Object> |
32 33 34 35 + 36 37 38 |
friend class FunctorWrapperHost<Object>; public: KOKKOS_FUNCTION FunctorWrapperDevice() {} protected: /** |
44 45 46 47 + 48 49 50 |
class FunctorWrapperHostBase { public: virtual ~FunctorWrapperHostBase() {} /** * Allocate device functor and wrapper |
69 70 71 72 + 73 74 75 |
* Constructor * @param functor Pointer to the functor */ FunctorWrapperHost(const void * functor) : _functor_host(*static_cast<const Object *>(functor)) {} ~FunctorWrapperHost(); FunctorWrapperDeviceBase * allocate() final; |
93 94 95 96 + 97 98 99 + 100 + 101 102 103 + 104 + 105 106 107 + 108 + 109 110 111 + 112 + 113 114 + 115 116 117 118 119 + 120 121 122 + 123 124 125 + 126 + 127 + 128 129 130 131 + 132 133 + 134 + 135 136 137 + 138 139 + 140 + 141 142 143 |
template <typename Object> FunctorWrapperDeviceBase * FunctorWrapperHost<Object>::allocate() { // Allocate storage for device wrapper on device auto wrapper_device = static_cast<FunctorWrapperDevice<Object> *>( ::Kokkos::kokkos_malloc<ExecSpace::memory_space>(sizeof(FunctorWrapperDevice<Object>))); // Allocate device wrapper on device using placement new to populate vtable with device pointers ::Kokkos::parallel_for( 1, KOKKOS_LAMBDA(const int) { new (wrapper_device) FunctorWrapperDevice<Object>(); }); // Allocate storage for functor on device _functor_device = static_cast<Object *>(::Kokkos::kokkos_malloc<ExecSpace::memory_space>(sizeof(Object))); // Let device wrapper point to the copy ::Kokkos::Impl::DeepCopy<MemSpace, ::Kokkos::HostSpace>( &(wrapper_device->_functor), &_functor_device, sizeof(Object *)); return wrapper_device; } template <typename Object> void FunctorWrapperHost<Object>::copyFunctor() { // Make a copy of functor on host to trigger copy constructor _functor_copy = std::make_unique<Object>(_functor_host); // Copy functor to device ::Kokkos::Impl::DeepCopy<MemSpace, ::Kokkos::HostSpace>( _functor_device, _functor_copy.get(), sizeof(Object)); } template <typename Object> void FunctorWrapperHost<Object>::freeFunctor() { _functor_copy.reset(); } template <typename Object> FunctorWrapperHost<Object>::~FunctorWrapperHost() { ::Kokkos::kokkos_free<ExecSpace::memory_space>(_functor_device); } } // namespace Kokkos } // namespace Moose |
25 26 27 28 + 29 30 + 31 32 33 |
*/ template <typename T> KOKKOS_INLINE_FUNCTION T sign(T x) { return x >= 0.0 ? 1.0 : -1.0; } /** |
23 24 25 26 + 27 + 28 + 29 + 30 31 + 32 33 34 |
KokkosConstantFunction(const InputParameters & parameters); KOKKOS_FUNCTION Real value(Real /* t */, Real3 /* p */) const { return _value; } KOKKOS_FUNCTION Real timeDerivative(Real /* t */, Real3 /* p */) const { return 0; } KOKKOS_FUNCTION Real3 gradient(Real /* t */, Real3 /* p */) const { return Real3(0); } KOKKOS_FUNCTION Real timeIntegral(Real t1, Real t2, Real3 /* p */) const { return _value * (t2 - t1); } protected: |
45 46 47 48 + 49 50 51 + 52 53 54 55 56 + 57 58 59 + 60 61 62 63 64 + 65 66 67 + 68 69 70 |
/** * */ KOKKOS_FUNCTION Real3 gradient(Real /* t */, Real3 /* p */) const { KOKKOS_ASSERT(false); return Real3(0); } /** * */ KOKKOS_FUNCTION Real3 curl(Real /* t */, Real3 /* p */) const { KOKKOS_ASSERT(false); return Real3(0); } /** * */ KOKKOS_FUNCTION Real div(Real /* t */, Real3 /* p */) const { KOKKOS_ASSERT(false); return 0; } /** * |
77 78 79 80 + 81 82 83 + 84 85 86 87 88 + 89 90 91 + 92 93 94 95 96 + 97 98 99 + 100 101 102 |
/** * */ KOKKOS_FUNCTION Real timeIntegral(Real /* t1 */, Real /* t2 */, Real3 /* p */) const { KOKKOS_ASSERT(false); return 0; } /** * */ KOKKOS_FUNCTION Real integral() const { KOKKOS_ASSERT(false); return 0; } /** * */ KOKKOS_FUNCTION Real average() const { KOKKOS_ASSERT(false); return 0; } }; |
107 108 109 110 + 111 112 113 |
Function(const Function & function); ~Function(); KOKKOS_FUNCTION Real value(Real t, Real3 p) const { return _wrapper_device->value(t, p); } KOKKOS_FUNCTION Real3 gradient(Real t, Real3 p) const { return _wrapper_device->gradient(t, p); } KOKKOS_FUNCTION Real3 curl(Real t, Real3 p) const { return _wrapper_device->curl(t, p); } KOKKOS_FUNCTION Real div(Real t, Real3 p) const { return _wrapper_device->div(t, p); } |
22 23 24 25 + 26 + 27 28 29 |
class FunctionWrapperDeviceBase { public: KOKKOS_FUNCTION FunctionWrapperDeviceBase() {} KOKKOS_FUNCTION virtual ~FunctionWrapperDeviceBase() {} KOKKOS_FUNCTION virtual Real value(Real t, Real3 p) const = 0; KOKKOS_FUNCTION virtual Real3 gradient(Real t, Real3 p) const = 0; |
41 42 43 44 + 45 46 + 47 48 + 49 50 + 51 52 + 53 54 + 55 + 56 + 57 58 + 59 60 + 61 62 + 63 64 + 65 + 66 67 68 |
friend class FunctionWrapperHost<Object>; public: KOKKOS_FUNCTION FunctionWrapperDevice() {} KOKKOS_FUNCTION Real value(Real t, Real3 p) const override final { return _function->value(t, p); } KOKKOS_FUNCTION Real3 gradient(Real t, Real3 p) const override final { return _function->gradient(t, p); } KOKKOS_FUNCTION Real3 curl(Real t, Real3 p) const override final { return _function->curl(t, p); } KOKKOS_FUNCTION Real div(Real t, Real3 p) const override final { return _function->div(t, p); } KOKKOS_FUNCTION Real timeDerivative(Real t, Real3 p) const override final { return _function->timeDerivative(t, p); } KOKKOS_FUNCTION Real timeIntegral(Real t1, Real t2, Real3 p) const override final { return _function->timeIntegral(t1, t2, p); } KOKKOS_FUNCTION Real integral() const override final { return _function->integral(); } KOKKOS_FUNCTION Real average() const override final { return _function->average(); } protected: /** |
74 75 76 77 + 78 79 80 |
class FunctionWrapperHostBase { public: virtual ~FunctionWrapperHostBase() {} /** * Allocate device function and wrapper |
99 100 101 102 + 103 + 104 105 + 106 107 108 |
* Constructor * @param function Pointer to the function */ FunctionWrapperHost(const void * function) : _function_host(*static_cast<const Object *>(function)) { } ~FunctionWrapperHost(); FunctionWrapperDeviceBase * allocate() final; |
126 127 128 129 + 130 131 132 + 133 + 134 135 136 + 137 + 138 139 140 + 141 + 142 143 144 + 145 + 146 147 + 148 149 150 151 152 + 153 154 155 + 156 157 158 + 159 + 160 + 161 162 163 164 + 165 166 + 167 + 168 169 170 + 171 172 + 173 + 174 175 176 |
template <typename Object> FunctionWrapperDeviceBase * FunctionWrapperHost<Object>::allocate() { // Allocate storage for device wrapper on device auto wrapper_device = static_cast<FunctionWrapperDevice<Object> *>( ::Kokkos::kokkos_malloc<ExecSpace::memory_space>(sizeof(FunctionWrapperDevice<Object>))); // Allocate device wrapper on device using placement new to populate vtable with device pointers ::Kokkos::parallel_for( 1, KOKKOS_LAMBDA(const int) { new (wrapper_device) FunctionWrapperDevice<Object>(); }); // Allocate storage for function on device _function_device = static_cast<Object *>(::Kokkos::kokkos_malloc<ExecSpace::memory_space>(sizeof(Object))); // Let device wrapper point to the copy ::Kokkos::Impl::DeepCopy<MemSpace, ::Kokkos::HostSpace>( &(wrapper_device->_function), &_function_device, sizeof(Object *)); return wrapper_device; } template <typename Object> void FunctionWrapperHost<Object>::copyFunction() { // Make a copy of function on host to trigger copy constructor _function_copy = std::make_unique<Object>(_function_host); // Copy function to device ::Kokkos::Impl::DeepCopy<MemSpace, ::Kokkos::HostSpace>( _function_device, _function_copy.get(), sizeof(Object)); } template <typename Object> void FunctionWrapperHost<Object>::freeFunction() { _function_copy.reset(); } template <typename Object> FunctionWrapperHost<Object>::~FunctionWrapperHost() { ::Kokkos::kokkos_free<ExecSpace::memory_space>(_function_device); } } // namespace Kokkos } // namespace Moose |
23 24 25 26 + 27 + 28 + 29 30 31 |
KokkosPiecewiseBase(const InputParameters & parameters); KOKKOS_FUNCTION auto functionSize() const { return _raw_x.size(); } KOKKOS_FUNCTION Real domain(const unsigned int i) const { return _raw_x[i]; } KOKKOS_FUNCTION Real range(const unsigned int i) const { return _raw_y[i]; } /** * Provides a means for explicitly setting the x and y data. This must |
25 26 27 28 + 29 30 31 |
KokkosPiecewiseConstant(const InputParameters & parameters); KOKKOS_FUNCTION Real value(Real t, Real3 p) const; KOKKOS_FUNCTION Real timeDerivative(Real /* t */, Real3 /* p */) const { return 0; } KOKKOS_FUNCTION Real integral() const; KOKKOS_FUNCTION Real average() const; |
35 36 37 38 + 39 40 41 42 + 43 44 + 45 + 46 47 48 + 49 + 50 + 51 + 52 + 53 + 54 + 55 + 56 + 57 + 58 + 59 + 60 + 61 + 62 + 63 + 64 65 + 66 67 + 68 + 69 + 70 + 71 + 72 + 73 + 74 + 75 + 76 + 77 78 79 + 80 81 82 83 + 84 85 + 86 87 + 88 89 + 90 + 91 92 + 93 94 + 95 + 96 97 + 98 99 100 101 + 102 103 + 104 105 |
}; KOKKOS_FUNCTION inline Real KokkosPiecewiseConstant::value(Real t, Real3 p) const { using Moose::Kokkos::Utils::sign; const Real x = _has_axis ? p(_axis) : t; const auto len = functionSize(); const Real tolerance = 1.0e-14; // endpoint cases if ((_direction == Direction::LEFT && x < (1 + tolerance * sign(domain(0))) * domain(0)) || (_direction == Direction::RIGHT && x < (1 - tolerance * sign(domain(0))) * domain(0)) || (_direction == Direction::LEFT_INCLUSIVE && x < (1 - tolerance * sign(domain(0))) * domain(0)) || (_direction == Direction::RIGHT_INCLUSIVE && x < (1 + tolerance * sign(domain(0))) * domain(0))) return _scale_factor * range(0); else if ((_direction == Direction::LEFT && x > (1 + tolerance * sign(domain(len - 1))) * domain(len - 1)) || (_direction == Direction::RIGHT && x > (1 - tolerance * sign(domain(len - 1))) * domain(len - 1)) || (_direction == Direction::LEFT_INCLUSIVE && x > (1 - tolerance * sign(domain(len - 1))) * domain(len - 1)) || (_direction == Direction::RIGHT_INCLUSIVE && x > (1 + tolerance * sign(domain(len - 1))) * domain(len - 1))) return _scale_factor * range(len - 1); for (unsigned int i = 1; i < len; ++i) { if (_direction == Direction::LEFT && x < (1 + tolerance * sign(domain(i))) * domain(i)) return _scale_factor * range(i - 1); else if (_direction == Direction::LEFT_INCLUSIVE && x < (1 - tolerance * sign(domain(i))) * domain(i)) return _scale_factor * range(i - 1); else if ((_direction == Direction::RIGHT && x < (1 - tolerance * sign(domain(i))) * domain(i))) return _scale_factor * range(i); else if ((_direction == Direction::RIGHT_INCLUSIVE && x < (1 + tolerance * sign(domain(i))) * domain(i))) return _scale_factor * range(i); } return 0.0; } KOKKOS_FUNCTION inline Real KokkosPiecewiseConstant::integral() const { const auto len = functionSize(); unsigned int offset = 0; if (_direction == Direction::RIGHT || _direction == Direction::RIGHT_INCLUSIVE) offset = 1; Real sum = 0; for (unsigned int i = 0; i < len - 1; ++i) sum += range(i + offset) * (domain(i + 1) - domain(i)); return _scale_factor * sum; } KOKKOS_FUNCTION inline Real KokkosPiecewiseConstant::average() const { return integral() / (domain(functionSize() - 1) - domain(0)); } |
917 918 919 920 + 921 922 923 |
const unsigned int state) { if (_is_kokkos_object) _mi_moose_object.mooseError( "Attempted to retrieve a standard MOOSE material property from a Kokkos object."); if (_use_interpolated_state) |
980 981 982 983 + 984 985 986 |
MaterialPropertyInterface::getKokkosMaterialPropertyByName(const std::string & prop_name_in) { if (!_is_kokkos_object) _mi_moose_object.mooseError( "Attempted to retrieve a Kokkos material property from a standard MOOSE object."); if constexpr (std::is_same_v<T, Real>) |
3588 3589 3590 3591 + 3592 3593 + 3594 3595 3596 + 3597 3598 3599 3600 + 3601 3602 + 3603 + 3604 + 3605 + 3606 3607 3608 + 3609 + 3610 + 3611 3612 + 3613 + 3614 + 3615 3616 + 3617 3618 3619 |
#ifdef MOOSE_KOKKOS_ENABLED template <typename T> T & FEProblemBase::getKokkosFunction(const std::string & name) { if (!hasKokkosFunction(name)) { // If we didn't find a function, it might be a default function, attempt to construct one now std::istringstream ss(name); Real real_value; // First see if it's just a constant. If it is, build a ConstantFunction if (ss >> real_value && ss.eof()) { InputParameters params = _factory.getValidParams("KokkosConstantFunction"); params.set<Real>("value") = real_value; addKokkosFunction("KokkosConstantFunction", ss.str(), params); } // Try once more if (!hasKokkosFunction(name)) mooseError("Unable to find Kokkos function '" + name, "'"); } auto * const ret = dynamic_cast<T *>(_kokkos_functions.getActiveObject(name).get()); if (!ret) mooseError("No Kokkos function named '", name, "' of appropriate type"); return *ret; } #endif |
153 154 155 156 + 157 158 159 |
registerMooseObjectTask("add_function", Function, false); #ifdef MOOSE_KOKKOS_ENABLED appendMooseObjectTask ("add_function", KokkosFunction); #endif registerMooseObjectTask("add_distribution", Distribution, false); |
588 589 590 591 + 592 + 593 594 595 |
syntax.registerSyntaxType("Functions/*", "FunctionName"); #ifdef MOOSE_KOKKOS_ENABLED registerSyntax("AddKokkosFunctionAction", "KokkosFunctions/*"); syntax.registerSyntaxType("KokkosFunctions/*", "FunctionName"); #endif registerSyntax("AddMeshDivisionAction", "MeshDivisions/*"); |
15 16 17 18 + 19 20 21 22 23 24 25 + 26 27 28 |
InputParameters Function::validParams() { InputParameters params = FunctionBase::validParams(); params.registerBase("Function"); return params; } Function::Function(const InputParameters & parameters) : FunctionBase(parameters), Moose::FunctorBase<Real>(name()) { } |
13 14 15 16 + 17 18 + 19 + 20 21 22 + 23 24 + 25 + 26 27 + 28 29 30 |
{ InputParameters FunctionBase::validParams() { InputParameters params = MooseObject::validParams(); params += SetupInterface::validParams(); // Functions should be executed on the fly params.suppressParameter<ExecFlagEnum>("execute_on"); return params; } FunctionBase::FunctionBase(const InputParameters & parameters) : MooseObject(parameters), SetupInterface(this), TransientInterface(this), |
32 33 34 35 + 36 37 + 38 39 40 + 41 42 43 |
UserObjectInterface(this), Restartable(this, "Functions"), MeshChangedInterface(parameters), ScalarCoupleable(this) { } #ifdef MOOSE_KOKKOS_ENABLED FunctionBase::FunctionBase(const FunctionBase & object, const Moose::Kokkos::FunctorCopy & key) : MooseObject(object, key), SetupInterface(object, key), TransientInterface(object, key), |
45 46 47 48 + 49 50 + 51 52 53 + 54 55 56 |
UserObjectInterface(object, key), Restartable(object, key), MeshChangedInterface(object, key), ScalarCoupleable(object, key) { } #endif FunctionBase::~FunctionBase() {} } // namespace Moose |
20 21 22 23 + 24 + 25 26 27 |
} FunctionInterface::FunctionInterface(const MooseObject * moose_object) : _fni_object(*moose_object), _fni_params(moose_object->parameters()), _fni_feproblem(*_fni_params.getCheckedPointerParam<FEProblemBase *>("_fe_problem_base")), _fni_tid(_fni_params.have_parameter<THREAD_ID>("_tid") ? _fni_params.get<THREAD_ID>("_tid") : 0) { |
30 31 32 33 + 34 35 36 |
const Function & FunctionInterface::getFunction(const std::string & name) const { return getFunctionByName(_fni_params.get<FunctionName>(name)); } const Function & |
19 20 21 22 + 23 24 25 |
MooseEnum direction("LEFT RIGHT LEFT_INCLUSIVE RIGHT_INCLUSIVE", "LEFT"); params.addParam<MooseEnum>( "direction", direction, "Direction to look to find value: " + direction.getRawNames()); params.addClassDescription("Defines piece-wise constant data using a set of x-y data pairs"); return params; } |
14 15 16 17 + 18 19 20 21 22 23 24 25 26 27 + 28 + 29 30 31 32 + 33 34 35 |
PiecewiseTabularBase::validParams() { InputParameters params = PiecewiseBase::validParams(); params += PiecewiseTabularInterface::validParams(); params.addParam<Real>("scale_factor", 1.0, "Scale factor to be applied to the output values"); params.declareControllable("scale_factor"); return params; } PiecewiseTabularBase::PiecewiseTabularBase(const InputParameters & parameters) : PiecewiseBase(parameters), PiecewiseTabularInterface(*this, _raw_x, _raw_y), _scale_factor(getParam<Real>("scale_factor")) { // load the data if (isParamValid("data_file")) buildFromFile(_communicator); else if (isParamValid("x") && isParamValid("y")) buildFromXandY(); else if (isParamValid("xy_data")) |
46 47 48 49 + 50 51 |
if (!isParamValid("json_uo")) return; else buildFromJSON(getUserObject<JSONFileReader>("json_uo")); } |
14 15 16 17 + 18 19 + 20 21 22 + 23 + 24 25 26 27 + 28 29 + 30 + 31 32 33 + 34 + 35 + 36 + 37 38 + 39 40 + 41 + 42 + 43 + 44 45 46 47 + 48 + 49 50 + 51 52 53 + 54 + 55 56 57 + 58 59 + 60 + 61 62 + 63 64 + 65 + 66 + 67 + 68 + 69 + 70 71 72 + 73 + 74 75 76 + 77 + 78 + 79 80 + 81 82 83 + 84 + 85 86 + 87 + 88 + 89 + 90 + 91 + 92 93 94 95 + 96 + 97 + 98 99 100 101 + 102 103 104 + 105 106 107 + 108 + 109 110 111 112 113 + 114 + 115 116 + 117 + 118 119 120 121 + 122 123 124 125 + 126 + 127 + 128 + 129 130 + 131 + 132 133 + 134 + 135 + 136 137 138 139 140 141 + 142 143 144 + 145 + 146 + 147 148 + 149 150 + 151 + 152 + 153 + 154 155 + 156 + 157 158 159 160 161 162 + 163 164 + 165 166 + 167 + 168 169 170 |
#include "libmesh/int_range.h" InputParameters PiecewiseTabularInterface::validParams() { InputParameters params = emptyInputParameters(); // Parameters shared across all data input methods MooseEnum axis("x=0 y=1 z=2"); params.addParam<MooseEnum>( "axis", axis, "The axis used (x, y, or z) if this is to be a function of position"); // Data from input file parameters params.addParam<std::vector<Real>>("xy_data", "All function data, supplied in abscissa, ordinate pairs"); params.addParam<std::vector<Real>>("x", "The abscissa values"); params.addParam<std::vector<Real>>("y", "The ordinate values"); // Data from CSV file parameters params.addParam<FileName>("data_file", "File holding CSV data"); params.addParam<unsigned int>("x_index_in_file", 0, "The abscissa index in the data file"); params.addParam<unsigned int>("y_index_in_file", 1, "The ordinate index in the data file"); params.addParam<std::string>( "x_title", "The title of the column/row containing the x data in the data file"); params.addParam<std::string>( "y_title", "The title of the column/row containing the y data in the data file"); params.addParam<bool>( "xy_in_file_only", true, "If the data file only contains abscissa and ordinate data"); MooseEnum format("columns=0 rows=1", "rows"); params.addParam<MooseEnum>( "format", format, "Format of csv data file that is in either in columns or rows"); // Data from JSON parameters params.addParam<UserObjectName>("json_uo", "JSONFileReader holding the data"); params.addParam<std::vector<std::string>>( "x_keys", "Ordered vector of keys in the JSON tree to obtain the abscissa"); params.addParam<std::vector<std::string>>( "y_keys", "Ordered vector of keys in the JSON tree to obtain the ordinate"); params.addParamNamesToGroup("xy_data x y", "Data from input file"); params.addParamNamesToGroup( "data_file x_index_in_file y_index_in_file x_title y_title xy_in_file_only format", "Data from CSV file"); params.addParamNamesToGroup("json_uo x_keys y_keys", "Data from JSON"); return params; } PiecewiseTabularInterface::PiecewiseTabularInterface(const MooseObject & object, std::vector<Real> & data_x, std::vector<Real> & data_y) : _has_axis(object.isParamValid("axis")), _object(object), _parameters(object.parameters()), _data_x(data_x), _data_y(data_y) { // determine function argument if (_has_axis) _axis = _parameters.get<MooseEnum>("axis"); // Check all parameters for inconsistencies if (_parameters.isParamValid("data_file") + _parameters.isParamValid("json_uo") + (_parameters.isParamValid("x") || _parameters.isParamValid("y")) + _parameters.isParamValid("xy_data") > 1) _object.mooseError( "Either 'data_file' or 'json_uo' or 'x' and 'y' or 'xy_data' must be specified " "exclusively."); if ((_parameters.isParamValid("x") + _parameters.isParamValid("y")) % 2 != 0) _object.mooseError( "Both 'x' and 'y' parameters or neither (for another input method) must be specified"); if (!_parameters.isParamValid("data_file") && (_parameters.isParamSetByUser("x_index_in_file") || _parameters.isParamSetByUser("y_index_in_file") || _parameters.isParamValid("x_title") || _parameters.isParamValid("y_title") || _parameters.isParamSetByUser("xy_in_file_only") || _parameters.isParamSetByUser("format"))) _object.mooseError( "A parameter was passed for an option using data from a CSV file but the " "'data_file' parameter has not been set. This is not allowed. Please check the parameter " "groups in the documentation for the list of parameters for each data input method."); if (!_parameters.isParamValid("json_uo") && (_parameters.isParamValid("x_keys") || _parameters.isParamValid("y_keys"))) _object.mooseError( "A parameter was passed for a JSON input option but the 'json_uo' parameter has not " "been set. This is not allowed. Please check the parameter groups in the " "documentation for the list of parameters for each data input method."); } void PiecewiseTabularInterface::buildFromFile(const libMesh::Parallel::Communicator & comm) { // Input parameters const auto & data_file_name = _parameters.get<FileName>("data_file"); const MooseEnum format = _parameters.get<MooseEnum>("format"); // xy_in_file_only does not make sense here as it restricts the file to exactly // two cows/columns, which is not a likely scenario when looking up data by name. // A wrong 'format' parameter would be caught by the failing name resolution anyways. bool xy_only = _parameters.get<bool>("xy_in_file_only"); if (_parameters.isParamValid("x_title") || _parameters.isParamValid("y_title")) { if (_parameters.isParamSetByUser("xy_in_file_only") && xy_only) _parameters.paramError( "xy_in_file_only", "When accessing data through 'x_title' or 'y_title' this parameter should not be used"); else xy_only = false; } // Read the data from CSV file MooseUtils::DelimitedFileReader reader(data_file_name, &comm); reader.setFormatFlag(format.getEnum<MooseUtils::DelimitedFileReader::FormatFlag>()); reader.setComment("#"); reader.read(); const auto & columns = reader.getNames(); const auto & data = reader.getData(); if (data.size() > 2 && xy_only) _object.mooseError("In ", _object.name(), ": Read more than two ", format, " of data from file '", data_file_name, "'. Did you mean to use \"format = ", format == "columns" ? "rows" : "columns", "\" or set \"xy_in_file_only\" to false?"); unsigned int x_index = libMesh::invalid_uint; unsigned int y_index = libMesh::invalid_uint; const auto setIndex = [&](unsigned int & index, const std::string & prefix) { if (_parameters.isParamValid(prefix + "_title")) { const auto name = _parameters.get<std::string>(prefix + "_title"); for (const auto i : index_range(columns)) if (columns[i] == name) index = i; if (index == libMesh::invalid_uint) _parameters.paramError(prefix + "_title", "None of the ", format, " in the data file has the title '", name, "'."); } else index = _parameters.get<unsigned int>(prefix + "_index_in_file"); if (index >= data.size()) _parameters.paramError(prefix + "_index_in_file", "Index out-of-range of the available data in '", data_file_name, "', which contains ", |
172 173 174 175 + 176 177 + 178 + 179 180 + 181 + 182 + 183 184 185 186 + 187 + 188 189 190 + 191 + 192 193 + 194 + 195 196 197 + 198 199 + 200 + 201 + 202 + 203 + 204 + 205 + 206 207 208 + 209 + 210 + 211 + 212 213 214 + 215 216 + 217 + 218 + 219 + 220 221 222 + 223 224 + 225 + 226 + 227 + 228 + 229 230 + 231 + 232 + 233 + 234 235 + 236 + 237 238 + 239 + 240 |
" ", format, " of data."); }; setIndex(x_index, "x"); setIndex(y_index, "y"); if (x_index == y_index) _object.mooseError("In ", _object.name(), ": 'x_index_in_file' and 'y_index_in_file' are set to the same value."); // Update the input vectors to contained the desired data _data_x = reader.getData(x_index); _data_y = reader.getData(y_index); // Size mismatch error if (_data_x.size() != _data_y.size()) _object.mooseError("In ", _object.name(), ": Lengths of x and y data do not match."); _raw_data_loaded = true; } void PiecewiseTabularInterface::buildFromJSON(const JSONFileReader & json_uo) { if (!_parameters.isParamValid("x_keys")) _object.mooseError("Missing 'x_keys' parameters for loading data from JSON"); if (!_parameters.isParamValid("y_keys")) _object.mooseError("Missing 'y_keys' parameters for loading data from JSON"); json_uo.getVector<Real>(_parameters.get<std::vector<std::string>>("x_keys"), _data_x); json_uo.getVector<Real>(_parameters.get<std::vector<std::string>>("y_keys"), _data_y); _raw_data_loaded = true; // Size mismatch error if (_data_x.size() != _data_y.size()) _object.mooseError( "Lengths of x (", _data_x.size(), ") and y (", _data_y.size(), ") data do not match."); } void PiecewiseTabularInterface::buildFromXandY() { _data_x = _parameters.get<std::vector<Real>>("x"); _data_y = _parameters.get<std::vector<Real>>("y"); _raw_data_loaded = true; } void PiecewiseTabularInterface::buildFromXY() { const auto & xy = _parameters.get<std::vector<Real>>("xy_data"); const auto xy_size = xy.size(); if (xy_size % 2 != 0) _object.mooseError( "In ", _object.name(), ": Length of data provided in 'xy_data' must be a multiple of 2."); const auto data_size = xy_size / 2; _data_x.resize(data_size); _data_y.resize(data_size); for (const auto i : make_range(data_size)) { _data_x[i] = xy[2 * i]; _data_y[i] = xy[2 * i + 1]; } _raw_data_loaded = true; } |
88 89 90 91 + 92 93 94 |
if (_blk_feproblem != NULL) { #ifdef MOOSE_KOKKOS_ENABLED if (_moose_object->isKokkosObject()) _blk_material_data = &_blk_feproblem->getKokkosMaterialData(Moose::BLOCK_MATERIAL_DATA); else #endif |
187 188 189 190 + 191 192 193 |
_blk_dim = _blk_mesh->dimension(); #ifdef MOOSE_KOKKOS_ENABLED if (moose_object->isKokkosObject()) initializeKokkosBlockRestrictable(_blk_mesh->getKokkosMesh()); #endif } |
44 45 46 47 + 48 49 50 |
_bnd_tid(moose_object->isParamValid("_tid") ? moose_object->getParam<THREAD_ID>("_tid") : 0), _bnd_material_data( #ifdef MOOSE_KOKKOS_ENABLED moose_object->isKokkosObject() ? _bnd_feproblem->getKokkosMaterialData(Moose::BOUNDARY_MATERIAL_DATA) : #endif |
69 70 71 72 + 73 74 75 |
_bnd_tid(moose_object->isParamValid("_tid") ? moose_object->getParam<THREAD_ID>("_tid") : 0), _bnd_material_data( #ifdef MOOSE_KOKKOS_ENABLED moose_object->isKokkosObject() ? _bnd_feproblem->getKokkosMaterialData(Moose::BOUNDARY_MATERIAL_DATA) : #endif |
186 187 188 189 + 190 191 192 |
} #ifdef MOOSE_KOKKOS_ENABLED if (_moose_object.isKokkosObject()) initializeKokkosBoundaryRestrictable(_bnd_mesh); #endif } |
13 14 15 16 + 17 18 + 19 + 20 + 21 + 22 23 + 24 + 25 26 + 27 28 29 + 30 31 + 32 + 33 + 34 + 35 + 36 + 37 |
registerMooseAction("MooseApp", AddKokkosFunctionAction, "add_function"); InputParameters AddKokkosFunctionAction::validParams() { InputParameters params = KokkosObjectAction::validParams(); params.addClassDescription("Add a Kokkos Function object to the simulation."); return params; } AddKokkosFunctionAction::AddKokkosFunctionAction(const InputParameters & params) : KokkosObjectAction(params, "Function") { } void AddKokkosFunctionAction::act() { FunctionParserBase<Real> fp; std::string vars = "x,y,z,t,NaN,pi,e"; if (fp.Parse(_name, vars) == -1) // -1 for success mooseWarning("Function name '" + _name + "' could evaluate as a ParsedFunction"); _problem->addKokkosFunction(_type, _name, _moose_object_pars); } |
9 10 11 12 + 13 14 15 + 16 17 + 18 + 19 20 + 21 + 22 + 23 24 + 25 + 26 27 + 28 |
#include "KokkosFunctionAux.h" registerKokkosAuxKernel("MooseApp", KokkosFunctionAux); InputParameters KokkosFunctionAux::validParams() { InputParameters params = AuxKernel::validParams(); params.addClassDescription("Auxiliary Kernel that creates and updates a field variable by " "sampling a function through space and time."); params.addRequiredParam<FunctionName>("function", "The function to use as the value"); return params; } KokkosFunctionAux::KokkosFunctionAux(const InputParameters & parameters) : AuxKernel(parameters), _func(getKokkosFunction("function")) { } |
16 17 18 19 + 20 + 21 22 23 + 24 + 25 26 + 27 + 28 + 29 + 30 + 31 + 32 33 34 + 35 + 36 37 + 38 39 40 + 41 + 42 43 44 + 45 + 46 47 48 |
namespace Kokkos { Functor::Functor(FEProblemBase & problem, std::shared_ptr<FunctorWrapperHostBase> wrapper) : _wrapper_host(wrapper), _problem(problem), _t(problem.time()), _t_old(problem.timeOld()) { // Allocate device wrapper _wrapper_device = _wrapper_host->allocate(); } Functor::Functor(const Functor & functor) : _wrapper_host(functor._wrapper_host), _wrapper_device(functor._wrapper_device), _problem(functor._problem), _t(functor._t), _t_old(functor._t_old) { // Copy functor to device _wrapper_host->copyFunctor(); } Functor::~Functor() { // Free device wrapper if (_wrapper_host.use_count() == 1) ::Kokkos::kokkos_free<ExecSpace::memory_space>(_wrapper_device); // Free host copy of functor _wrapper_host->freeFunctor(); } } // namespace Kokkos } // namespace Moose |
15 16 17 18 + 19 20 21 + 22 + 23 + 24 25 26 |
{ FunctorRegistry & FunctorRegistry::getRegistry() { static FunctorRegistry * registry = nullptr; if (!registry) registry = new FunctorRegistry(); return *registry; } } // namespace Kokkos |
12 13 14 15 + 16 17 + 18 + 19 20 + 21 + 22 + 23 + 24 25 + 26 + 27 28 + 29 |
registerKokkosFunction("MooseApp", KokkosConstantFunction); InputParameters KokkosConstantFunction::validParams() { InputParameters params = FunctionBase::validParams(); params.addClassDescription( "A function that returns a constant value as defined by an input parameter."); params.addParam<Real>("value", 0.0, "The constant value"); params.declareControllable("value"); return params; } KokkosConstantFunction::KokkosConstantFunction(const InputParameters & parameters) : FunctionBase(parameters), _value(getParam<Real>("value")) { } |
15 16 17 18 + 19 20 + 21 + 22 23 + 24 + 25 26 + 27 28 + 29 30 + 31 32 33 + 34 + 35 36 + 37 + 38 39 40 + 41 + 42 43 + 44 45 46 + 47 + 48 49 50 + 51 + 52 53 54 |
{ InputParameters FunctionBase::validParams() { InputParameters params = Moose::FunctionBase::validParams(); params.registerBase("KokkosFunction"); return params; } FunctionBase::FunctionBase(const InputParameters & parameters) : Moose::FunctionBase(parameters) {} FunctionBase::FunctionBase(const FunctionBase & object) : Moose::FunctionBase(object, {}) {} Function::Function(std::shared_ptr<FunctionWrapperHostBase> wrapper) : _wrapper_host(wrapper) { // Allocate device wrapper _wrapper_device = _wrapper_host->allocate(); } Function::Function(const Function & function) : _wrapper_host(function._wrapper_host), _wrapper_device(function._wrapper_device) { // Copy function to device _wrapper_host->copyFunction(); } Function::~Function() { // Free device wrapper if (_wrapper_host.use_count() == 1) ::Kokkos::kokkos_free<ExecSpace::memory_space>(_wrapper_device); // Free host copy of function _wrapper_host->freeFunction(); } } // namespace Kokkos } // namespace Moose |
12 13 14 15 + 16 + 17 + 18 + 19 + 20 + 21 22 + 23 24 25 + 26 27 + 28 29 30 31 + 32 33 34 + 35 36 37 38 + 39 + 40 41 + 42 43 44 45 + 46 47 + 48 49 50 51 + 52 53 + 54 + 55 56 + 57 58 59 60 + 61 62 + 63 + 64 65 + 66 67 |
#include "FunctionInterface.h" #include "FEProblemBase.h" FunctionInterface::FunctionInterface(const FunctionInterface & object, const Moose::Kokkos::FunctorCopy &) : _fni_object(object._fni_object), _fni_params(object._fni_params), _fni_feproblem(object._fni_feproblem), _fni_tid(object._fni_tid) { } Moose::Kokkos::Function FunctionInterface::getKokkosFunction(const std::string & name) const { return getKokkosFunctionByName(_fni_params.get<FunctionName>(name)); } Moose::Kokkos::Function FunctionInterface::getKokkosFunctionByName(const FunctionName & name) const { #ifdef MOOSE_ENABLE_KOKKOS_GPU _fni_object.mooseError( "Retrieving a Kokkos function as abstract type is currently not supported for GPU."); #endif if (!_fni_object.isKokkosObject()) _fni_object.mooseError("Attempted to retrieve a Kokkos function from a non-Kokkos object."); return _fni_feproblem.getKokkosFunction(name); } bool FunctionInterface::hasKokkosFunction(const std::string & param_name) const { return hasKokkosFunctionByName(_fni_params.get<FunctionName>(param_name)); } bool FunctionInterface::hasKokkosFunctionByName(const FunctionName & name) const { if (!_fni_object.isKokkosObject()) _fni_object.mooseError("Attempted to retrieve a Kokkos function from a non-Kokkos object."); return _fni_feproblem.hasKokkosFunction(name); } const Moose::FunctionBase * FunctionInterface::getKokkosFunctionByNameHelper(const FunctionName & name) const { if (!_fni_object.isKokkosObject()) _fni_object.mooseError("Attempted to retrieve a Kokkos function from a non-Kokkos object."); return &_fni_feproblem.getKokkosFunction<Moose::FunctionBase>(name); } |
10 11 12 13 + 14 15 + 16 17 18 + 19 + 20 21 + 22 23 24 + 25 26 + 27 + 28 29 + 30 + 31 + 32 |
#include "KokkosPiecewiseBase.h" InputParameters KokkosPiecewiseBase::validParams() { return FunctionBase::validParams(); } KokkosPiecewiseBase::KokkosPiecewiseBase(const InputParameters & parameters) : FunctionBase(parameters) { } void KokkosPiecewiseBase::setData(const std::vector<Real> & x, const std::vector<Real> & y) { _raw_x = x; _raw_y = y; if (_raw_x.size() != _raw_y.size()) mooseError("In KokkosPiecewiseBase ", _name, ": Lengths of x and y data do not match."); } |
12 13 14 15 + 16 17 + 18 + 19 + 20 + 21 + 22 + 23 + 24 25 + 26 27 + 28 29 + 30 |
registerKokkosFunction("MooseApp", KokkosPiecewiseConstant); InputParameters KokkosPiecewiseConstant::validParams() { InputParameters params = KokkosPiecewiseTabularBase::validParams(); MooseEnum direction("LEFT RIGHT LEFT_INCLUSIVE RIGHT_INCLUSIVE", "LEFT"); params.addParam<MooseEnum>( "direction", direction, "Direction to look to find value: " + direction.getRawNames()); params.addClassDescription("Defines piece-wise constant data using a set of x-y data pairs"); return params; } KokkosPiecewiseConstant::KokkosPiecewiseConstant(const InputParameters & parameters) : KokkosPiecewiseTabularBase(parameters), _direction(getParam<MooseEnum>("direction").getEnum<Direction>()) { } |
12 13 14 15 + 16 17 + 18 + 19 20 + 21 + 22 23 + 24 + 25 26 + 27 28 + 29 + 30 31 32 + 33 + 34 + 35 + 36 + 37 + 38 + 39 + 40 41 + 42 43 44 + 45 46 47 + 48 + 49 50 51 + 52 + 53 + 54 |
#include "JSONFileReader.h" InputParameters KokkosPiecewiseTabularBase::validParams() { InputParameters params = KokkosPiecewiseBase::validParams(); params += PiecewiseTabularInterface::validParams(); params.addParam<Real>("scale_factor", 1.0, "Scale factor to be applied to the output values"); params.declareControllable("scale_factor"); return params; } KokkosPiecewiseTabularBase::KokkosPiecewiseTabularBase(const InputParameters & parameters) : KokkosPiecewiseBase(parameters), PiecewiseTabularInterface(*this, _data_x, _data_y), _scale_factor(getParam<Real>("scale_factor")) { // load the data if (isParamValid("data_file")) buildFromFile(_communicator); else if (isParamValid("x") && isParamValid("y")) buildFromXandY(); else if (isParamValid("xy_data")) buildFromXY(); else if (!isParamValid("json_uo")) mooseError("Unknown X-Y data source. Are you missing a parameter? Did you misspell one?"); // JSON data is not available at construction as we rely on a user object } void KokkosPiecewiseTabularBase::initialSetup() { // For JSON UO input, we need to wait for initialSetup to load the data if (isParamValid("json_uo")) buildFromJSON(getUserObject<JSONFileReader>("json_uo")); // Copy data to GPU _raw_x = _data_x; _raw_y = _data_y; } |
87 88 89 90 + 91 92 93 + 94 95 96 97 98 99 + 100 101 + 102 103 + 104 + 105 106 107 + 108 109 110 111 112 113 + 114 115 + 116 + 117 + 118 + 119 120 + 121 + 122 123 124 + 125 126 + 127 128 129 130 + 131 132 + 133 134 + 135 + 136 137 + 138 139 140 |
_has_kokkos_objects = true; _has_kokkos_residual_objects = true; } void FEProblemBase::addKokkosAuxKernel(const std::string & kernel_name, const std::string & name, InputParameters & parameters) { parallel_object_only(); setAuxKernelParamsAndLog(kernel_name, name, parameters, "KokkosAuxKernel"); _aux->addKokkosKernel(kernel_name, name, parameters); _has_kokkos_objects = true; } void FEProblemBase::addKokkosFunction(const std::string & type, const std::string & name, InputParameters & parameters) { parallel_object_only(); parameters.set<SubProblem *>("_subproblem") = this; std::shared_ptr<Moose::FunctionBase> func = _factory.create<Moose::FunctionBase>(type, name, parameters); logAdd("Function", name, type, parameters); _kokkos_functions.addObject(func); _has_kokkos_objects = true; } bool FEProblemBase::hasKokkosFunction(const std::string & name) { return _kokkos_functions.hasActiveObject(name); } Moose::Kokkos::Function FEProblemBase::getKokkosFunction(const std::string & name) { const auto & function = getKokkosFunction<Moose::FunctionBase>(name); std::shared_ptr<Moose::Kokkos::FunctionWrapperHostBase> wrapper = Moose::Kokkos::FunctorRegistry::buildFunction(&function, function.type()); return Moose::Kokkos::Function(wrapper); } void |
61 62 63 64 + 65 66 67 |
_mi_subproblem(*_mi_params.getCheckedPointerParam<SubProblem *>("_subproblem")), _mi_tid(_mi_params.get<THREAD_ID>("_tid")), #ifdef MOOSE_KOKKOS_ENABLED _is_kokkos_object(_mi_moose_object.isKokkosObject()), #else _is_kokkos_object(false), #endif |
1112 1113 1114 1115 + 1116 1117 1118 |
} #ifdef MOOSE_KOKKOS_ENABLED _kokkos_functions.initialSetup(); #endif } |
1612 1613 1614 1615 + 1616 1617 1618 |
} #ifdef MOOSE_KOKKOS_ENABLED _kokkos_functions.timestepSetup(); #endif _aux->timestepSetup(); |
4815 4816 4817 4818 + 4819 4820 4821 |
} #ifdef MOOSE_KOKKOS_ENABLED _kokkos_functions.customSetup(exec_type); #endif _aux->customSetup(exec_type); |
7245 7246 7247 7248 + 7249 7250 7251 |
} #ifdef MOOSE_KOKKOS_ENABLED _kokkos_functions.residualSetup(); #endif computeSystems(EXEC_LINEAR); |
7481 7482 7483 7484 + 7485 7486 7487 |
} #ifdef MOOSE_KOKKOS_ENABLED _kokkos_functions.residualSetup(); #endif computeSystems(EXEC_LINEAR); |
7631 7632 7633 7634 + 7635 7636 7637 |
} #ifdef MOOSE_KOKKOS_ENABLED _kokkos_functions.jacobianSetup(); #endif computeSystems(EXEC_NONLINEAR); |
7823 7824 7825 7826 + 7827 7828 7829 |
} #ifdef MOOSE_KOKKOS_ENABLED _kokkos_functions.jacobianSetup(); #endif try |