https://mooseframework.inl.gov
KokkosResidualObject.h
Go to the documentation of this file.
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 #pragma once
11 
12 #include "KokkosDispatcher.h"
13 #include "KokkosVariableValue.h"
15 
16 #include "MooseVariableBase.h"
17 #include "ResidualObject.h"
18 
19 namespace Moose::Kokkos
20 {
21 
26  public MeshHolder,
27  public AssemblyHolder,
28  public SystemHolder
29 {
30 public:
32 
39  Moose::VarFieldType field_type,
40  bool nodal = false);
44  ResidualObject(const ResidualObject & object);
45 
49  struct ResidualLoop
51  {
52  };
53  struct JacobianLoop
54  {
55  };
57  {
58  };
60 
61  virtual const MooseVariableBase & variable() const override { return _var; }
62 
63  virtual void computeOffDiagJacobian(unsigned int) override final
64  {
65  mooseError("computeOffDiagJacobian() is not used for Kokkos residual objects.");
66  }
67  virtual void computeResidualAndJacobian() override
68  {
71  }
72 
73 protected:
89  std::unique_ptr<DispatcherBase> _residual_dispatcher;
91  std::unique_ptr<DispatcherBase> _jacobian_dispatcher;
92  std::unique_ptr<DispatcherBase> _offdiag_jacobian_dispatcher;
94 
98 
120 
128  KOKKOS_FUNCTION void accumulateTaggedElementalResidual(const Real local_re,
129  const ContiguousElementID elem,
130  const unsigned int i,
131  const unsigned int comp = 0) const;
139  KOKKOS_FUNCTION void accumulateTaggedNodalResidual(const bool add,
140  const Real local_re,
141  const ContiguousNodeID node,
142  const unsigned int comp = 0) const;
152  KOKKOS_FUNCTION void accumulateTaggedElementalMatrix(const Real local_ke,
153  const ContiguousElementID elem,
154  const unsigned int i,
155  const unsigned int j,
156  const unsigned int jvar,
157  const unsigned int comp = 0) const;
166  KOKKOS_FUNCTION void accumulateTaggedElementalMatrix(const DNDerivativeType & local_ke,
167  const AssemblyDatum & datum,
168  const unsigned int i,
169  const unsigned int comp = 0) const;
178  KOKKOS_FUNCTION void accumulateTaggedNodalMatrix(const bool add,
179  const Real local_ke,
180  const ContiguousNodeID node,
181  const unsigned int jvar,
182  const unsigned int comp = 0) const;
191  KOKKOS_FUNCTION void accumulateTaggedNodalMatrix(const bool add,
192  const DNDerivativeType & local_ke,
193  const ContiguousNodeID node,
194  const unsigned int comp = 0) const;
195 
201  template <typename function>
202  KOKKOS_FUNCTION void computeResidualInternal(AssemblyDatum & datum, function body) const;
208  template <typename function>
209  KOKKOS_FUNCTION void computeJacobianInternal(AssemblyDatum & datum, function body) const;
210 
211 private:
219 };
220 
221 KOKKOS_FUNCTION inline void
223  const ContiguousElementID elem,
224  const unsigned int i,
225  const unsigned int comp) const
226 {
227  if (!local_re)
228  return;
229 
230  auto & sys = kokkosSystem(_kokkos_var.sys(comp));
231  auto dof = sys.getElemLocalDofIndex(elem, i, _kokkos_var.var(comp));
232 
233  for (unsigned int t = 0; t < _vector_tags.size(); ++t)
234  {
235  auto tag = _vector_tags[t];
236 
237  if (sys.isResidualTagActive(tag))
238  ::Kokkos::atomic_add(&sys.getVectorDofValue(dof, tag), local_re);
239  }
240 }
241 
242 KOKKOS_FUNCTION inline void
244  const Real local_re,
245  const ContiguousNodeID node,
246  const unsigned int comp) const
247 {
248  if (!local_re && add)
249  return;
250 
251  auto & sys = kokkosSystem(_kokkos_var.sys(comp));
252  auto dof = sys.getNodeLocalDofIndex(node, 0, _kokkos_var.var(comp));
253 
254  for (unsigned int t = 0; t < _vector_tags.size(); ++t)
255  {
256  auto tag = _vector_tags[t];
257 
258  if (sys.isResidualTagActive(tag))
259  {
260  if (add)
261  sys.getVectorDofValue(dof, tag) += local_re;
262  else
263  sys.getVectorDofValue(dof, tag) = local_re;
264  }
265  }
266 }
267 
268 KOKKOS_FUNCTION inline void
270  const ContiguousElementID elem,
271  const unsigned int i,
272  const unsigned int j,
273  const unsigned int jvar,
274  const unsigned int comp) const
275 {
276  if (!local_ke)
277  return;
278 
279  auto & sys = kokkosSystem(_kokkos_var.sys(comp));
280  auto row = sys.getElemLocalDofIndex(elem, i, _kokkos_var.var(comp));
281  auto col = sys.getElemGlobalDofIndex(elem, j, jvar);
282 
283  for (unsigned int t = 0; t < _matrix_tags.size(); ++t)
284  {
285  auto tag = _matrix_tags[t];
286 
287  if (sys.isMatrixTagActive(tag) && !sys.hasNodalBCMatrixTag(row, tag))
288  ::Kokkos::atomic_add(&sys.getMatrixValue(row, col, tag), local_ke);
289  }
290 }
291 
292 KOKKOS_FUNCTION inline void
294  const AssemblyDatum & datum,
295  const unsigned int i,
296  const unsigned int comp) const
297 {
298  auto & sys = kokkosSystem(_kokkos_var.sys(comp));
299  auto row = sys.getElemLocalDofIndex(datum.elem().id, i, _kokkos_var.var(comp));
300 
301  for (unsigned int t = 0; t < _matrix_tags.size(); ++t)
302  {
303  auto tag = _matrix_tags[t];
304 
305  if (sys.isMatrixTagActive(tag) && !sys.hasNodalBCMatrixTag(row, tag))
306  for (unsigned int j = 0; j < local_ke.size(); ++j)
307  {
308  auto col = local_ke.raw_index(j);
309 
310  ::Kokkos::atomic_add(&sys.getMatrixValue(row, col, tag), local_ke.raw_at(j));
311  }
312  }
313 }
314 
315 KOKKOS_FUNCTION inline void
317  const Real local_ke,
318  const ContiguousNodeID node,
319  const unsigned int jvar,
320  const unsigned int comp) const
321 {
322  if (!local_ke && add)
323  return;
324 
325  auto & sys = kokkosSystem(_kokkos_var.sys(comp));
326  auto row = sys.getNodeLocalDofIndex(node, 0, _kokkos_var.var(comp));
327  auto col = sys.getNodeGlobalDofIndex(node, jvar);
328 
329  for (unsigned int t = 0; t < _matrix_tags.size(); ++t)
330  {
331  auto tag = _matrix_tags[t];
332 
333  if (sys.isMatrixTagActive(tag))
334  {
335  auto & matrix = sys.getMatrix(tag);
336 
337  if (add)
338  matrix(row, col) += local_ke;
339  else
340  {
341  matrix.zero(row);
342  matrix(row, col) = local_ke;
343  }
344  }
345  }
346 }
347 
348 KOKKOS_FUNCTION inline void
350  const DNDerivativeType & local_ke,
351  const ContiguousNodeID node,
352  const unsigned int comp) const
353 {
354  auto & sys = kokkosSystem(_kokkos_var.sys(comp));
355  auto row = sys.getNodeLocalDofIndex(node, 0, _kokkos_var.var(comp));
356 
357  for (unsigned int t = 0; t < _matrix_tags.size(); ++t)
358  {
359  auto tag = _matrix_tags[t];
360  auto & matrix = sys.getMatrix(tag);
361 
362  if (sys.isMatrixTagActive(tag))
363  {
364  if (!add)
365  matrix.zero(row);
366 
367  for (unsigned int j = 0; j < local_ke.size(); ++j)
368  {
369  auto col = local_ke.raw_index(j);
370 
371  if (add)
372  matrix(row, col) += local_ke.raw_at(j);
373  else
374  matrix(row, col) = local_ke.raw_at(j);
375  }
376  }
377  }
378 }
379 
380 template <typename function>
381 KOKKOS_FUNCTION void
383 {
384  Real local_re[MAX_CACHED_DOF];
385 
386  unsigned int stride = MAX_CACHED_DOF * datum.num_local_threads();
387  unsigned int num_batches = datum.n_dofs() / stride;
388 
389  if (datum.n_dofs() % stride)
390  ++num_batches;
391 
392  for (unsigned int batch = 0; batch < num_batches; ++batch)
393  {
394  unsigned int ib = batch * stride;
395  unsigned int ie = ::Kokkos::min(ib + stride, datum.n_dofs());
396 
397  const unsigned int n = ie - ib;
398  const unsigned int d = n / datum.num_local_threads();
399  const unsigned int m = n % datum.num_local_threads();
400  const unsigned int t = datum.local_thread_id();
401 
402  ib += t * d + (t < m ? t : m);
403  ie = ib + d + (t < m ? 1 : 0);
404 
405  for (unsigned int i = ib; i < ie; ++i)
406  local_re[i - ib] = 0;
407 
408  body(local_re - ib, ib, ie);
409 
410  for (unsigned int i = ib; i < ie; ++i)
411  accumulateTaggedElementalResidual(local_re[i - ib], datum.elem().id, i);
412  }
413 }
414 
415 template <typename function>
416 KOKKOS_FUNCTION void
418 {
419  Real local_ke[MAX_CACHED_DOF];
420 
421  for (unsigned int j = datum.local_thread_id(); j < datum.n_jdofs();
422  j += datum.num_local_threads())
423  {
424  unsigned int num_batches = datum.n_idofs() / MAX_CACHED_DOF;
425 
426  if (datum.n_idofs() % MAX_CACHED_DOF)
427  ++num_batches;
428 
429  for (unsigned int batch = 0; batch < num_batches; ++batch)
430  {
431  unsigned int ib = batch * MAX_CACHED_DOF;
432  unsigned int ie = ::Kokkos::min(ib + MAX_CACHED_DOF, datum.n_idofs());
433 
434  for (unsigned int i = ib; i < ie; ++i)
435  local_ke[i - ib] = 0;
436 
437  body(local_ke - ib, ib, ie, j);
438 
439  for (unsigned int i = ib; i < ie; ++i)
440  accumulateTaggedElementalMatrix(local_ke[i - ib], datum.elem().id, i, j, datum.jvar());
441  }
442  }
443 }
444 
445 } // namespace Moose::Kokkos
VarFieldType
Definition: MooseTypes.h:770
KOKKOS_FUNCTION dof_id_type getElemLocalDofIndex(ContiguousElementID elem, unsigned int i, unsigned int var) const
Get the local DOF index of a variable for an element.
Definition: KokkosSystem.h:212
Scalar< Real > _dt_old
Size of the old time step.
KOKKOS_FUNCTION dof_id_type getNodeLocalDofIndex(ContiguousNodeID node, unsigned int i, unsigned int var) const
Get the local DOF index of a variable for a node.
Definition: KokkosSystem.h:225
std::unique_ptr< DispatcherBase > _jacobian_dispatcher
KOKKOS_FUNCTION unsigned int sys(unsigned int comp=0) const
Get the system number of a component.
KOKKOS_FUNCTION void computeJacobianInternal(AssemblyDatum &datum, function body) const
The common loop structure template for computing elemental Jacobian.
Scalar< Real > _t
TODO: Move to TransientInterface.
dof_id_type ContiguousElementID
Definition: KokkosMesh.h:20
KOKKOS_FUNCTION unsigned int num_local_threads() const
Get the number of local threads.
Definition: KokkosDatum.h:202
const InputParameters & parameters() const
Get the parameters of the object.
Definition: MooseBase.h:131
ResidualObject(const InputParameters &parameters, Moose::VarFieldType field_type, bool nodal=false)
Constructor.
KOKKOS_FUNCTION void accumulateTaggedNodalResidual(const bool add, const Real local_re, const ContiguousNodeID node, const unsigned int comp=0) const
Accumulate or set local nodal residual contribution to tagged vectors.
virtual void computeOffDiagJacobian(unsigned int) override final
Computes this object&#39;s contribution to off-diagonal blocks of the system Jacobian matrix...
The main MOOSE class responsible for handling user-defined parameters in almost every MOOSE system...
The base class for Kokkos residual objects.
Thread _thread
Kokkos thread object.
KOKKOS_FUNCTION unsigned int jvar() const
Get the coupled variable number.
Definition: KokkosDatum.h:456
MooseVariableFieldBase & _var
Reference of the MOOSE variable.
This class provides an interface for common operations on field variables of both FE and FV types wit...
The Kokkos interface that holds the host reference of the Kokkos systems and copies it to device duri...
Definition: KokkosSystem.h:753
KOKKOS_FUNCTION unsigned int n_jdofs() const
Get the number of local DOFs for the coupled variable.
Definition: KokkosDatum.h:436
The Kokkos interface that holds the host reference of the Kokkos mesh and copies it to device during ...
Definition: KokkosMesh.h:430
KOKKOS_FUNCTION void accumulateTaggedElementalMatrix(const Real local_ke, const ContiguousElementID elem, const unsigned int i, const unsigned int j, const unsigned int jvar, const unsigned int comp=0) const
Accumulate local elemental Jacobian contribution to tagged matrices.
dof_id_type ContiguousNodeID
Definition: KokkosMesh.h:21
KOKKOS_FUNCTION unsigned int n_idofs() const
Get the number of local DOFs.
Definition: KokkosDatum.h:431
virtual void computeResidual()=0
Compute this object&#39;s contribution to the residual.
KOKKOS_FUNCTION const System & kokkosSystem(unsigned int sys) const
Get the const reference of a Kokkos system.
Definition: KokkosSystem.h:792
The Kokkos interface that holds the host reference of the Kokkos assembly and copies it to device dur...
KOKKOS_FUNCTION unsigned int local_thread_id() const
Get the current local thread ID.
Definition: KokkosDatum.h:197
virtual void computeJacobian()=0
Compute this object&#39;s contribution to the diagonal Jacobian entries.
KOKKOS_FUNCTION index_type size() const
Get the total array size.
Definition: KokkosArray.h:205
Scalar< const Real > _t_old
Old time.
KokkosSemiDynamicSparseNumberArray< Real, libMesh::dof_id_type, NWrapper< MOOSE_AD_MAX_DOFS_PER_ELEM > > DNDerivativeType
Definition: KokkosADReal.h:22
Scalar< int > _t_step
The number of the time step.
std::unique_ptr< DispatcherBase > _offdiag_jacobian_dispatcher
constexpr unsigned int MAX_CACHED_DOF
Maximum number of DOFs to cache during residual and Jacobian computation.
Definition: KokkosHeader.h:77
DIE A HORRIBLE DEATH HERE typedef LIBMESH_DEFAULT_SCALAR_TYPE Real
The Kokkos variable object that carries the coupled variable and tag information. ...
KOKKOS_FUNCTION void accumulateTaggedElementalResidual(const Real local_re, const ContiguousElementID elem, const unsigned int i, const unsigned int comp=0) const
Accumulate local elemental residual contribution to tagged vectors.
KOKKOS_FUNCTION const ElementInfo & elem() const
Get the element information object.
Definition: KokkosDatum.h:84
void mooseError(Args &&... args) const
Emits an error prefixed with object name and type and optionally a file path to the top-level block p...
Definition: MooseBase.h:281
The Kokkos object that holds thread-private data in the parallel operations of Kokkos kernels...
Definition: KokkosDatum.h:364
Scalar< Real > _dt
Time step size.
Variable _kokkos_var
Kokkos variable.
KOKKOS_FUNCTION unsigned int var(unsigned int comp=0) const
Get the variable number of a component.
std::unique_ptr< DispatcherBase > _residual_dispatcher
Kokkos functor dispatchers.
KOKKOS_FUNCTION unsigned int n_dofs() const
Get the number of local DOFs.
Definition: KokkosDatum.h:426
auto min(const L &left, const R &right)
static InputParameters validParams()
Array< TagID > _vector_tags
Tags this object operates on.
KOKKOS_FUNCTION void computeResidualInternal(AssemblyDatum &datum, function body) const
The common loop structure template for computing elemental residual.
KOKKOS_FUNCTION void accumulateTaggedNodalMatrix(const bool add, const Real local_ke, const ContiguousNodeID node, const unsigned int jvar, const unsigned int comp=0) const
Accumulate or set local nodal Jacobian contribution to tagged matrices.
The Kokkos thread object that aids in converting the one-dimensional thread index into multi-dimensio...
Definition: KokkosThread.h:29
virtual void computeResidualAndJacobian() override
Compute this object&#39;s contribution to the residual and Jacobian simultaneously.
virtual const MooseVariableBase & variable() const override
Returns the variable that this object operates on.
ContiguousElementID id
Contiguous element ID.
Definition: KokkosMesh.h:42
Base variable class.