Nalu
Nalu: a generalized unstructured massively parallel low Mach flow code designed to support a variety of energy applications of interest (most notably Wind ECP) built on the Sierra Toolkit and Trilinos solver Tpetra/Epetra stack. The open source BSD, clause 3 license model has been chosen for the code base. See LICENSE for more information. http://NaluCFD.org
UnitTestKokkosME.h
Go to the documentation of this file.
1 /*------------------------------------------------------------------------*/
2 /* Copyright 2014 National Renewable Energy Laboratory. */
3 /* This software is released under the license detailed */
4 /* in the file, LICENSE, which is located in the top-level Nalu */
5 /* directory structure */
6 /*------------------------------------------------------------------------*/
7 
8 #ifndef UNITTESTKOKKOSME_H
9 #define UNITTESTKOKKOSME_H
10 
11 #include "gtest/gtest.h"
12 #include "UnitTestUtils.h"
13 
14 #include "ScratchViews.h"
15 #include "CopyAndInterleave.h"
16 #include "ElemDataRequests.h"
17 #include "AlgTraits.h"
18 #include "KokkosInterface.h"
19 #include "SimdInterface.h"
20 
21 namespace unit_test_utils {
22 
23 template<typename AlgTraits>
25 {
26 public:
27  KokkosMEViews(bool doInit=true)
28  : comm_(MPI_COMM_WORLD),
29  meta_(AlgTraits::nDim_),
30  bulk_(meta_, comm_)
31  {
32  if (doInit)
34  }
35 
36  virtual ~KokkosMEViews() {}
37 
40  void fill_mesh_and_init_data(bool doPerturb=false)
41  {
42  fill_mesh(doPerturb);
43  init_me_data();
44  }
45 
46  void fill_mesh(bool doPerturb=false)
47  {
48  if (doPerturb)
50  else
52 
53  partVec_ = {meta_.get_part("block_1")};
54  coordinates_ = static_cast<const VectorFieldType*>(
55  meta_.coordinate_field());
56 
57  EXPECT_TRUE(coordinates_ != nullptr);
60  }
61 
62  void init_me_data()
63  {
64  // Initialize both surface and volume elements
67 
68  // Register them to ElemDataRequests
71 
72  // Initialize shape function views
73  double scs_data[AlgTraits::numScsIp_*AlgTraits::nodesPerElement_];
74  meSCS_->shape_fcn(scs_data);
75  DoubleType* v_scs_data = &scs_shape_fcn_(0,0);
76  for (int i=0; i < (AlgTraits::numScsIp_*AlgTraits::nodesPerElement_); ++i) {
77  v_scs_data[i] = scs_data[i];
78  }
79 
80  double scv_data[AlgTraits::numScvIp_*AlgTraits::nodesPerElement_];
81  meSCV_->shape_fcn(scv_data);
82  DoubleType* v_scv_data = &scv_shape_fcn_(0,0);
83  for (int i=0; i < (AlgTraits::numScvIp_*AlgTraits::nodesPerElement_); ++i) {
84  v_scv_data[i] = scv_data[i];
85  }
86  }
87 
88  template<typename LambdaFunction>
89  void execute(LambdaFunction func)
90  {
91  constexpr int simdLen = stk::simd::ndoubles;
92  // Do not copy and interleave ME views
93  const bool alsoProcessMEViews = false;
94 
95  stk::mesh::Selector sel = (
96  meta_.locally_owned_part() & stk::mesh::selectUnion(partVec_));
97 
98  const int bytes_per_team = 0;
99  int bytes_per_thread = sierra::nalu::get_num_bytes_pre_req_data<double>(
100  dataNeeded_, AlgTraits::nDim_);
101  bytes_per_thread *= 3 * stk::simd::ndoubles;
102 
103  const auto& buckets = bulk_.get_buckets(stk::topology::ELEM_RANK, sel);
104 
105  auto team_exec = sierra::nalu::get_team_policy(
106  buckets.size(), bytes_per_team, bytes_per_thread);
107 
108  Kokkos::parallel_for(team_exec, [&](const sierra::nalu::TeamHandleType& team) {
109  auto& b = *buckets[team.league_rank()];
110  const auto length = b.size();
111 
112  std::vector<sierra::nalu::ScratchViews<double>*> prereqData(simdLen, nullptr);
113 
114  for (int simdIndex=0; simdIndex < simdLen; ++simdIndex) {
115  prereqData[simdIndex] = new sierra::nalu::ScratchViews<double>(
116  team, bulk_, AlgTraits::topo_, dataNeeded_);
117  }
119  team, bulk_, AlgTraits::topo_, dataNeeded_);
120 
121  const stk::mesh::Entity* elemNodes[simdLen];
122  stk::mesh::Bucket::size_type simdBucketLen = length / simdLen;
123  const stk::mesh::Bucket::size_type remainder = length % simdLen;
124  if (remainder > 0) simdBucketLen++;
125 
126  Kokkos::parallel_for(Kokkos::TeamThreadRange(team, simdBucketLen), [&](const size_t& bktIndex){
127  int simdElems = simdLen;
128  if (length - bktIndex*simdLen < simdLen) {
129  simdElems = length - bktIndex*simdLen;
130  }
131 
132  stk::mesh::Entity element;
133  for (int simdIndex=0; simdIndex < simdElems; ++simdIndex) {
134  element = b[bktIndex*simdLen + simdIndex];
135  elemNodes[simdIndex] = bulk_.begin_nodes(element);
136  fill_pre_req_data(dataNeeded_, bulk_, AlgTraits::topo_, element,
137  *prereqData[simdIndex], alsoProcessMEViews);
138  }
139 
140  copy_and_interleave(prereqData, simdElems, simdPrereqData,
141  alsoProcessMEViews);
142  fill_master_element_views(dataNeeded_, bulk_, AlgTraits::topo_,
143  element, simdPrereqData);
144 
145  func(simdPrereqData);
146  });
147  });
148  }
149 
150  stk::ParallelMachine comm_;
151  stk::mesh::MetaData meta_;
152  stk::mesh::BulkData bulk_;
154  const VectorFieldType* coordinates_{nullptr};
155 
159 
160  Kokkos::View<DoubleType[AlgTraits::numScvIp_][AlgTraits::nodesPerElement_]> scv_shape_fcn_ {"scv_shape_function"};
161  Kokkos::View<DoubleType[AlgTraits::numScsIp_][AlgTraits::nodesPerElement_]> scs_shape_fcn_ {"scs_shape_function"};
162 };
163 
164 } // namespace unit_test_utils
165 
166 #endif /* UNITTESTKOKKOSME_H */
std::vector< Part * > PartVector
Definition: Algorithm.h:16
Definition: MasterElement.h:53
sierra::nalu::DoubleType DoubleType
Definition: SimdInterface.h:37
void add_coordinates_field(const stk::mesh::FieldBase &field, unsigned scalarsPerNode, COORDS_TYPES cType)
Definition: ElemDataRequests.C:69
void fill_master_element_views(ElemDataRequests &dataNeeded, const stk::mesh::BulkData &bulkData, stk::topology topo, stk::mesh::Entity elem, ScratchViews< DoubleType > &prereqData)
Definition: ScratchViews.C:257
static MasterElement * get_surface_master_element(const stk::topology &theTopo, int dimension=0, std::string quadType="GaussLegendre")
Definition: MasterElementFactory.C:208
void add_cvfem_volume_me(MasterElement *meSCV)
Definition: ElemDataRequests.h:103
Definition: ElemDataRequests.h:66
virtual void shape_fcn(SharedMemView< DoubleType ** > &shpfc)
Definition: MasterElement.h:60
void copy_and_interleave(const std::vector< ScratchViews< double > * > &data, int simdElems, ScratchViews< DoubleType > &simdData, bool copyMEViews=true)
Definition: CopyAndInterleave.h:152
stk::mesh::MetaData meta_
Definition: UnitTestKokkosME.h:151
Definition: UnitTestKokkosME.h:24
STK SIMD Interface.
void add_cvfem_surface_me(MasterElement *meSCS)
Definition: ElemDataRequests.h:108
Definition: UnitTestFieldUtils.C:10
stk::mesh::Field< double, stk::mesh::Cartesian > VectorFieldType
Definition: PromotedElementIO.h:40
sierra::nalu::MasterElement * meSCV_
Definition: UnitTestKokkosME.h:157
sierra::nalu::ElemDataRequests dataNeeded_
Definition: UnitTestKokkosME.h:156
Definition: ElemDataRequests.h:35
stk::ParallelMachine comm_
Definition: UnitTestKokkosME.h:150
KokkosMEViews(bool doInit=true)
Definition: UnitTestKokkosME.h:27
stk::mesh::Entity create_one_reference_element(stk::mesh::BulkData &bulk, stk::topology topo)
Definition: UnitTestUtils.C:295
virtual ~KokkosMEViews()
Definition: UnitTestKokkosME.h:36
void fill_mesh_and_init_data(bool doPerturb=false)
Create a 1-element STK mesh and initialize MasterElement data structures.
Definition: UnitTestKokkosME.h:40
DeviceTeamPolicy get_team_policy(const size_t sz, const size_t bytes_per_team, const size_t bytes_per_thread)
Definition: KokkosInterface.h:30
sierra::nalu::MasterElement * meSCS_
Definition: UnitTestKokkosME.h:158
stk::mesh::Entity create_one_perturbed_element(stk::mesh::BulkData &bulk, stk::topology topo)
Definition: UnitTestUtils.C:330
Kokkos::View< DoubleType[AlgTraits::numScsIp_][AlgTraits::nodesPerElement_]> scs_shape_fcn_
Definition: UnitTestKokkosME.h:161
void execute(LambdaFunction func)
Definition: UnitTestKokkosME.h:89
void fill_mesh(bool doPerturb=false)
Definition: UnitTestKokkosME.h:46
Kokkos::View< DoubleType[AlgTraits::numScvIp_][AlgTraits::nodesPerElement_]> scv_shape_fcn_
Definition: UnitTestKokkosME.h:160
void init_me_data()
Definition: UnitTestKokkosME.h:62
stk::mesh::PartVector partVec_
Definition: UnitTestKokkosME.h:153
Kokkos::TeamPolicy< DeviceSpace, DynamicScheduleType >::member_type TeamHandleType
Definition: KokkosInterface.h:22
static MasterElement * get_volume_master_element(const stk::topology &theTopo, int dimension=0, std::string quadType="GaussLegendre")
Definition: MasterElementFactory.C:228
const VectorFieldType * coordinates_
Definition: UnitTestKokkosME.h:154
void fill_pre_req_data(ElemDataRequests &dataNeeded, const stk::mesh::BulkData &bulkData, stk::topology topo, stk::mesh::Entity elem, ScratchViews< double > &prereqData, bool fillMEViews)
Definition: ScratchViews.C:180
Definition: ScratchViews.h:82
stk::mesh::BulkData bulk_
Definition: UnitTestKokkosME.h:152