Line data Source code
1 : //* This file is part of the MOOSE framework
2 : //* https://www.mooseframework.org
3 : //*
4 : //* All rights reserved, see COPYRIGHT for full restrictions
5 : //* https://github.com/idaholab/moose/blob/master/COPYRIGHT
6 : //*
7 : //* Licensed under LGPL 2.1, please see LICENSE for details
8 : //* https://www.gnu.org/licenses/lgpl-2.1.html
9 :
10 : #include "KokkosTypes.h"
11 : #include "KokkosFunction.h"
12 :
13 : #include "FEProblemBase.h"
14 : #include "DisplacedProblem.h"
15 : #include "NonlinearSystemBase.h"
16 : #include "AuxiliarySystem.h"
17 : #include "MaterialBase.h"
18 :
19 : Moose::Kokkos::System &
20 0 : FEProblemBase::getKokkosSystem(const unsigned int sys_num)
21 : {
22 0 : return _kokkos_systems[sys_num];
23 : }
24 :
25 : const Moose::Kokkos::System &
26 0 : FEProblemBase::getKokkosSystem(const unsigned int sys_num) const
27 : {
28 0 : return _kokkos_systems[sys_num];
29 : }
30 :
31 : void
32 1469 : FEProblemBase::addKokkosKernel(const std::string & kernel_name,
33 : const std::string & name,
34 : InputParameters & parameters)
35 : {
36 : parallel_object_only();
37 :
38 2938 : const auto nl_sys_num = determineSolverSystem(parameters.varName("variable", name), true).second;
39 1469 : if (!isSolverSystemNonlinear(nl_sys_num))
40 0 : mooseError("You are trying to add a Kernel to a linear variable/system, which is not "
41 : "supported at the moment!");
42 :
43 1789 : setResidualObjectParamsAndLog(
44 1149 : kernel_name, name, parameters, nl_sys_num, "KokkosKernel", _reinit_displaced_elem);
45 :
46 1469 : _nl[nl_sys_num]->addKokkosKernel(kernel_name, name, parameters);
47 :
48 1467 : _has_kokkos_objects = true;
49 1467 : _has_kokkos_residual_objects = true;
50 1467 : }
51 :
52 : void
53 272 : FEProblemBase::addKokkosNodalKernel(const std::string & kernel_name,
54 : const std::string & name,
55 : InputParameters & parameters)
56 : {
57 : parallel_object_only();
58 :
59 544 : const auto nl_sys_num = determineSolverSystem(parameters.varName("variable", name), true).second;
60 :
61 329 : setResidualObjectParamsAndLog(
62 215 : kernel_name, name, parameters, nl_sys_num, "KokkosNodalKernel", _reinit_displaced_elem);
63 :
64 272 : _nl[nl_sys_num]->addKokkosNodalKernel(kernel_name, name, parameters);
65 :
66 272 : _has_kokkos_objects = true;
67 272 : _has_kokkos_residual_objects = true;
68 272 : }
69 :
70 : void
71 1562 : FEProblemBase::addKokkosBoundaryCondition(const std::string & bc_name,
72 : const std::string & name,
73 : InputParameters & parameters)
74 : {
75 : parallel_object_only();
76 :
77 3124 : const auto nl_sys_num = determineSolverSystem(parameters.varName("variable", name), true).second;
78 1562 : if (!isSolverSystemNonlinear(nl_sys_num))
79 0 : mooseError(
80 : "You are trying to add a BoundaryCondition to a linear variable/system, which is not "
81 : "supported at the moment!");
82 :
83 1907 : setResidualObjectParamsAndLog(
84 1217 : bc_name, name, parameters, nl_sys_num, "KokkosBoundaryCondition", _reinit_displaced_face);
85 :
86 1562 : _nl[nl_sys_num]->addKokkosBoundaryCondition(bc_name, name, parameters);
87 :
88 1562 : _has_kokkos_objects = true;
89 1562 : _has_kokkos_residual_objects = true;
90 1562 : }
91 :
92 : void
93 316 : FEProblemBase::addKokkosAuxKernel(const std::string & kernel_name,
94 : const std::string & name,
95 : InputParameters & parameters)
96 : {
97 : parallel_object_only();
98 :
99 316 : setAuxKernelParamsAndLog(kernel_name, name, parameters, "KokkosAuxKernel");
100 :
101 316 : _aux->addKokkosKernel(kernel_name, name, parameters);
102 :
103 316 : _has_kokkos_objects = true;
104 316 : }
105 :
106 : void
107 190 : FEProblemBase::addKokkosFunction(const std::string & type,
108 : const std::string & name,
109 : InputParameters & parameters)
110 : {
111 : parallel_object_only();
112 :
113 380 : parameters.set<SubProblem *>("_subproblem") = this;
114 :
115 6 : std::shared_ptr<Moose::FunctionBase> func =
116 184 : _factory.create<Moose::FunctionBase>(type, name, parameters);
117 190 : logAdd("Function", name, type, parameters);
118 190 : _kokkos_functions.addObject(func);
119 :
120 190 : _has_kokkos_objects = true;
121 190 : }
122 :
123 : bool
124 113 : FEProblemBase::hasKokkosFunction(const std::string & name)
125 : {
126 113 : return _kokkos_functions.hasActiveObject(name);
127 : }
128 :
129 : Moose::Kokkos::Function
130 90 : FEProblemBase::getKokkosFunction(const std::string & name)
131 : {
132 90 : const auto & function = getKokkosFunction<Moose::FunctionBase>(name);
133 :
134 0 : std::shared_ptr<Moose::Kokkos::FunctionWrapperHostBase> wrapper =
135 90 : Moose::Kokkos::FunctorRegistry::buildFunction(&function, function.type());
136 :
137 180 : return Moose::Kokkos::Function(wrapper);
138 90 : }
139 :
140 : void
141 294 : FEProblemBase::addKokkosMaterial(const std::string & mat_name,
142 : const std::string & name,
143 : InputParameters & parameters)
144 : {
145 588 : addMaterialHelper({&_kokkos_materials}, mat_name, name, parameters);
146 :
147 288 : _has_kokkos_objects = true;
148 288 : }
149 :
150 : MaterialData &
151 9117 : FEProblemBase::getKokkosMaterialData(Moose::MaterialDataType type, const MooseObject * object) const
152 : {
153 9117 : switch (type)
154 : {
155 5099 : case Moose::BLOCK_MATERIAL_DATA:
156 5099 : if (object)
157 2090 : _kokkos_material_props.addConsumer(type, object);
158 5099 : return _kokkos_material_props.getMaterialData(0);
159 311 : case Moose::NEIGHBOR_MATERIAL_DATA:
160 311 : if (object)
161 311 : _kokkos_neighbor_material_props.addConsumer(type, object);
162 311 : return _kokkos_neighbor_material_props.getMaterialData(0);
163 3707 : case Moose::BOUNDARY_MATERIAL_DATA:
164 : case Moose::FACE_MATERIAL_DATA:
165 : case Moose::INTERFACE_MATERIAL_DATA:
166 3707 : if (object)
167 605 : _kokkos_bnd_material_props.addConsumer(type, object);
168 3707 : return _kokkos_bnd_material_props.getMaterialData(0);
169 : }
170 :
171 0 : mooseError("FEProblemBase::getKokkosMaterialData(): Invalid MaterialDataType ", type);
172 : }
173 :
174 : const std::set<const MooseObject *> &
175 807 : FEProblemBase::getKokkosMaterialPropertyStorageConsumers(Moose::MaterialDataType type) const
176 : {
177 807 : switch (type)
178 : {
179 0 : case Moose::BLOCK_MATERIAL_DATA:
180 0 : return _kokkos_material_props.getConsumers(type);
181 0 : case Moose::NEIGHBOR_MATERIAL_DATA:
182 0 : return _kokkos_neighbor_material_props.getConsumers(type);
183 807 : case Moose::BOUNDARY_MATERIAL_DATA:
184 : case Moose::FACE_MATERIAL_DATA:
185 : case Moose::INTERFACE_MATERIAL_DATA:
186 807 : return _kokkos_bnd_material_props.getConsumers(type);
187 : }
188 :
189 0 : mooseError(
190 : "FEProblemBase::getKokkosMaterialPropertyStorageConsumers(): Invalid MaterialDataType ",
191 : type);
192 : }
193 :
194 : void
195 807 : FEProblemBase::initKokkos()
196 : {
197 : // Error on unsupported options
198 :
199 807 : if (haveDisplaced())
200 0 : mooseError("Kokkos does not support displaced mesh yet.");
201 :
202 807 : if (adaptivity().isOn())
203 0 : mooseError("Kokkos does not support adaptivity yet.");
204 :
205 : // Initialize Kokkos assembly
206 :
207 807 : _kokkos_assembly.init();
208 :
209 : // Initialize Kokkos systems
210 :
211 807 : unsigned int max_system_number = 0;
212 :
213 1614 : for (unsigned int s = 0; s < numNonlinearSystems(); ++s)
214 807 : max_system_number = std::max(max_system_number, getNonlinearSystemBase(s).number());
215 :
216 807 : max_system_number = std::max(max_system_number, getAuxiliarySystem().number());
217 :
218 : // Kokkos system does not have a default constructor, so this simply allocates buffer to which we
219 : // should do placement new later
220 807 : _kokkos_systems.create(max_system_number + 1);
221 :
222 1614 : for (unsigned int s = 0; s < numNonlinearSystems(); ++s)
223 : {
224 807 : auto & nl = getNonlinearSystemBase(s);
225 807 : new (&_kokkos_systems[nl.number()]) Moose::Kokkos::System(nl);
226 : }
227 :
228 807 : auto & aux = getAuxiliarySystem();
229 807 : new (&_kokkos_systems[aux.number()]) Moose::Kokkos::System(aux);
230 :
231 : // Initialize Kokkos material properties
232 :
233 807 : _kokkos_material_props.allocateKokkosProperties();
234 807 : _kokkos_bnd_material_props.allocateKokkosProperties();
235 807 : _kokkos_neighbor_material_props.allocateKokkosProperties();
236 807 : }
237 :
238 : void
239 310 : FEProblemBase::initKokkosStatefulProps()
240 : {
241 : // Resolve dependencies
242 :
243 310 : std::set<MooseVariableFieldBase *> needed_moose_vars;
244 310 : std::set<TagID> needed_fe_var_vector_tags;
245 :
246 632 : for (auto block : _mesh.meshSubdomains())
247 : {
248 322 : _kokkos_materials.updateBlockVariableDependency(block, needed_moose_vars);
249 322 : _kokkos_materials.updateBlockFEVariableCoupledVectorTagDependency(block,
250 : needed_fe_var_vector_tags);
251 : }
252 :
253 1484 : for (auto boundary : _mesh.meshBoundaryIds())
254 : {
255 1174 : _kokkos_materials.updateBoundaryVariableDependency(boundary, needed_moose_vars);
256 1174 : _kokkos_materials.updateBoundaryFEVariableCoupledVectorTagDependency(boundary,
257 : needed_fe_var_vector_tags);
258 : }
259 :
260 : // Copy data and preallocate quadature point solution vectors
261 :
262 930 : for (auto & system : _kokkos_systems)
263 : {
264 620 : system.setActiveVariables(needed_moose_vars);
265 620 : system.setActiveSolutionTags(needed_fe_var_vector_tags);
266 :
267 620 : system.sync(Moose::Kokkos::MemcpyKind::HOST_TO_DEVICE);
268 620 : system.reinit();
269 : }
270 :
271 310 : _kokkos_systems.copyToDevice();
272 :
273 : // Initialize stateful properties
274 :
275 720 : for (auto & material : _kokkos_materials.getActiveObjects())
276 410 : if (!material->hasRestoredProperties() && !material->boundaryRestricted())
277 356 : material->initStatefulProperties(0);
278 :
279 698 : for (auto & material : _kokkos_materials[Moose::FACE_MATERIAL_DATA].getActiveObjects())
280 388 : if (!material->hasRestoredProperties())
281 354 : material->initStatefulProperties(0);
282 :
283 698 : for (auto & material : _kokkos_materials[Moose::NEIGHBOR_MATERIAL_DATA].getActiveObjects())
284 388 : if (!material->hasRestoredProperties())
285 356 : material->initStatefulProperties(0);
286 :
287 720 : for (auto & material : _kokkos_materials.getActiveObjects())
288 410 : if (!material->hasRestoredProperties() && material->boundaryRestricted())
289 20 : material->initStatefulProperties(0);
290 :
291 : // Copy to old and older states
292 :
293 310 : _kokkos_material_props.copy();
294 310 : _kokkos_bnd_material_props.copy();
295 310 : _kokkos_neighbor_material_props.copy();
296 :
297 : // Clear
298 :
299 930 : for (auto & system : _kokkos_systems)
300 : {
301 620 : system.sync(Moose::Kokkos::MemcpyKind::DEVICE_TO_HOST);
302 :
303 620 : system.clearActiveVariables();
304 620 : system.clearActiveSolutionTags();
305 : }
306 310 : }
307 :
308 : void
309 51694 : FEProblemBase::prepareKokkosMaterials(
310 : const std::unordered_set<unsigned int> & consumer_needed_mat_props)
311 : {
312 51694 : std::unordered_set<unsigned int> needed_mat_props;
313 :
314 105278 : for (auto block : mesh().meshSubdomains())
315 53584 : _kokkos_materials.updateBlockMatPropDependency(block, needed_mat_props);
316 :
317 244095 : for (auto boundary : mesh().meshBoundaryIds())
318 192401 : _kokkos_materials.updateBoundaryMatPropDependency(boundary, needed_mat_props);
319 :
320 51694 : needed_mat_props.insert(consumer_needed_mat_props.begin(), consumer_needed_mat_props.end());
321 :
322 51694 : setActiveMaterialProperties(needed_mat_props, 0);
323 51694 : }
324 :
325 : void
326 51694 : FEProblemBase::reinitKokkosMaterials()
327 : {
328 51694 : if (hasActiveMaterialProperties(0))
329 : {
330 29815 : for (auto & material : _kokkos_materials.getActiveObjects())
331 16579 : if (!material->boundaryRestricted())
332 15708 : material->computeProperties();
333 :
334 28944 : for (auto & material : _kokkos_materials[Moose::FACE_MATERIAL_DATA].getActiveObjects())
335 15708 : material->computeProperties();
336 :
337 28944 : for (auto & material : _kokkos_materials[Moose::NEIGHBOR_MATERIAL_DATA].getActiveObjects())
338 15708 : material->computeProperties();
339 :
340 29815 : for (auto & material : _kokkos_materials.getActiveObjects())
341 16579 : if (material->boundaryRestricted())
342 871 : material->computeProperties();
343 : }
344 :
345 51694 : Kokkos::fence();
346 51694 : }
|