Nektar++
Public Member Functions | Private Types | Private Member Functions | Private Attributes | Static Private Attributes | List of all members
Nektar::Collections::CollectionOptimisation Class Reference

#include <CollectionOptimisation.h>

Public Member Functions

COLLECTIONS_EXPORT CollectionOptimisation (LibUtilities::SessionReaderSharedPtr pSession, const int shapedim, ImplementationType defaultType=eStdMat)
 
 ~CollectionOptimisation ()
 
ImplementationType GetDefaultImplementationType ()
 
unsigned int GetMaxCollectionSize ()
 
bool IsUsingAutotuning ()
 
COLLECTIONS_EXPORT OperatorImpMap GetOperatorImpMap (StdRegions::StdExpansionSharedPtr pExp)
 Get Operator Implementation Map from XMl or using default;. More...
 
COLLECTIONS_EXPORT OperatorImpMap SetWithTimings (std::vector< StdRegions::StdExpansionSharedPtr > pGeom, OperatorImpMap &impTypes, bool verbose=true)
 
COLLECTIONS_EXPORT void UpdateOptFile (std::string sessName, LibUtilities::CommSharedPtr &comm)
 

Private Types

typedef std::pair< LibUtilities::ShapeType, int > ElmtOrder
 
typedef std::map< OperatorType, std::map< ElmtOrder, ImplementationType > > GlobalOpMap
 

Private Member Functions

void ReadCollOps (TiXmlElement *xmlCol, GlobalOpMap &global, bool verbose)
 

Private Attributes

GlobalOpMap m_global
 
bool m_autotune
 
ImplementationType m_defaultType
 
unsigned int m_maxCollSize
 
unsigned int m_shapeDim
 

Static Private Attributes

static std::map< OpImpTimingKey, OperatorImpMapm_opImpMap
 

Detailed Description

Definition at line 123 of file CollectionOptimisation.h.

Member Typedef Documentation

◆ ElmtOrder

Definition at line 162 of file CollectionOptimisation.h.

◆ GlobalOpMap

Definition at line 164 of file CollectionOptimisation.h.

Constructor & Destructor Documentation

◆ CollectionOptimisation()

Nektar::Collections::CollectionOptimisation::CollectionOptimisation ( LibUtilities::SessionReaderSharedPtr  pSession,
const int  shapedim,
ImplementationType  defaultType = eStdMat 
)

Definition at line 57 of file CollectionOptimisation.cpp.

60  : m_shapeDim(shapedim)
61 {
62  map<ElmtOrder, ImplementationType> defaults, defaultsPhysDeriv,
63  defaultsHelmholtz;
64  bool verbose = (pSession.get()) &&
65  (pSession->DefinesCmdLineArgument("verbose")) &&
66  (pSession->GetComm()->GetRank() == 0);
67 
68  m_autotune = false;
69  m_maxCollSize = 0;
70  m_defaultType = defaultType == eNoImpType ? eIterPerExp : defaultType;
71 
72  map<string, LibUtilities::ShapeType> elTypes;
73  elTypes["S"] = LibUtilities::eSegment;
74  elTypes["T"] = LibUtilities::eTriangle;
75  elTypes["Q"] = LibUtilities::eQuadrilateral;
76  elTypes["A"] = LibUtilities::eTetrahedron;
77  elTypes["P"] = LibUtilities::ePyramid;
78  elTypes["R"] = LibUtilities::ePrism;
79  elTypes["H"] = LibUtilities::eHexahedron;
80 
81  // Set defaults for all element types.
82  for (auto &it2 : elTypes)
83  {
84  defaults[ElmtOrder(it2.second, -1)] = m_defaultType;
85  defaultsPhysDeriv[ElmtOrder(it2.second, -1)] = m_defaultType;
86  defaultsHelmholtz[ElmtOrder(it2.second, -1)] = m_defaultType;
87  }
88 
89  if (defaultType == eNoImpType)
90  {
91  for (auto &it2 : elTypes)
92  {
93  // use Nocollection for Phys Deriv
94  defaultsPhysDeriv[ElmtOrder(it2.second, -1)] = eNoCollection;
95 
96  // Use IterPerExp
97  defaultsHelmholtz[ElmtOrder(it2.second, -1)] = eMatrixFree;
98  }
99  }
100 
101  map<string, OperatorType> opTypes;
102  for (int i = 0; i < SIZE_OperatorType; ++i)
103  {
104  opTypes[OperatorTypeMap[i]] = (OperatorType)i;
105  switch ((OperatorType)i)
106  {
107  case eHelmholtz:
108  m_global[(OperatorType)i] = defaultsHelmholtz;
109  break;
110  case ePhysDeriv:
111  m_global[(OperatorType)i] = defaultsPhysDeriv;
112  break;
113  default:
114  m_global[(OperatorType)i] = defaults;
115  }
116  }
117 
118  map<string, ImplementationType> impTypes;
119  for (int i = 0; i < SIZE_ImplementationType; ++i)
120  {
121  impTypes[ImplementationTypeMap[i]] = (ImplementationType)i;
122  }
123 
124  // turn off file reader if dummy pointer is given or if default
125  // option is passed and by default calling argument.
126  if ((defaultType == eNoImpType) && (pSession.get()))
127  {
128  TiXmlDocument &doc = pSession->GetDocument();
129  TiXmlHandle docHandle(&doc);
130  TiXmlElement *master = docHandle.FirstChildElement("NEKTAR").Element();
131  ASSERTL0(master, "Unable to find NEKTAR tag in file.");
132  bool WriteFullCollections = false;
133 
134  TiXmlElement *xmlCol = master->FirstChildElement("COLLECTIONS");
135 
136  // Check if user has specified some options
137  if (xmlCol)
138  {
139  // Set the maxsize and default implementation type if provided
140  const char *maxSize = xmlCol->Attribute("MAXSIZE");
141  m_maxCollSize = (maxSize ? atoi(maxSize) : 0);
142 
143  const char *defaultImpl = xmlCol->Attribute("DEFAULT");
144  m_defaultType = defaultType;
145 
146  // If user has specified a default impl type or autotuning
147  // and set this default across all operators.
148  if (defaultImpl)
149  {
150  const std::string collinfo = string(defaultImpl);
151  m_autotune = boost::iequals(collinfo, "auto");
152 
153  if (!m_autotune)
154  {
155  bool collectionFound{false};
156  for (int i = 1; i < Collections::SIZE_ImplementationType;
157  ++i)
158  {
159  if (boost::iequals(
160  collinfo,
162  {
164  collectionFound = true;
165  break;
166  }
167  }
168 
169  ASSERTL0(collectionFound,
170  "Unknown default collection scheme: " + collinfo);
171 
172  defaults.clear();
173  // Override default types
174  for (auto &it2 : elTypes)
175  {
176  defaults[ElmtOrder(it2.second, -1)] = m_defaultType;
177  }
178 
179  for (int i = 0; i < SIZE_OperatorType; ++i)
180  {
181  m_global[(OperatorType)i] = defaults;
182  }
183  }
184  }
185  const char *write = xmlCol->Attribute("WRITE");
186  if (write && boost::iequals(write, "true"))
187  {
188  WriteFullCollections = true;
189  }
190 
191  // Now process operator-specific implementation selections
192  ReadCollOps(xmlCol, m_global, verbose);
193 
194  // Print out operator map
195  if (verbose)
196  {
197  if (WriteFullCollections)
198  {
199  for (auto &mIt : m_global)
200  {
201  cout << "Operator " << OperatorTypeMap[mIt.first] << ":"
202  << endl;
203 
204  for (auto &eIt : mIt.second)
205  {
206  cout << "- "
207  << LibUtilities::ShapeTypeMap[eIt.first.first]
208  << " order " << eIt.first.second << " -> "
209  << ImplementationTypeMap[eIt.second] << endl;
210  }
211  }
212  }
213  }
214  }
215  }
216 }
#define ASSERTL0(condition, msg)
Definition: ErrorUtil.hpp:215
std::pair< LibUtilities::ShapeType, int > ElmtOrder
void ReadCollOps(TiXmlElement *xmlCol, GlobalOpMap &global, bool verbose)
const char *const ImplementationTypeMap[]
Definition: Operator.h:94
const char *const OperatorTypeMap[]
Definition: Operator.h:76
const char *const ShapeTypeMap[SIZE_ShapeType]
Definition: ShapeType.hpp:79

References ASSERTL0, Nektar::Collections::eHelmholtz, Nektar::LibUtilities::eHexahedron, Nektar::Collections::eIterPerExp, Nektar::Collections::eMatrixFree, Nektar::Collections::eNoCollection, Nektar::Collections::eNoImpType, Nektar::Collections::ePhysDeriv, Nektar::LibUtilities::ePrism, Nektar::LibUtilities::ePyramid, Nektar::LibUtilities::eQuadrilateral, Nektar::LibUtilities::eSegment, Nektar::LibUtilities::eTetrahedron, Nektar::LibUtilities::eTriangle, Nektar::Collections::ImplementationTypeMap, m_autotune, m_defaultType, m_global, m_maxCollSize, Nektar::Collections::OperatorTypeMap, ReadCollOps(), Nektar::LibUtilities::ShapeTypeMap, Nektar::Collections::SIZE_ImplementationType, and Nektar::Collections::SIZE_OperatorType.

◆ ~CollectionOptimisation()

Nektar::Collections::CollectionOptimisation::~CollectionOptimisation ( )
inline

Definition at line 131 of file CollectionOptimisation.h.

131 {};

Member Function Documentation

◆ GetDefaultImplementationType()

ImplementationType Nektar::Collections::CollectionOptimisation::GetDefaultImplementationType ( )
inline

Definition at line 133 of file CollectionOptimisation.h.

134  {
135  return m_defaultType;
136  }

References m_defaultType.

◆ GetMaxCollectionSize()

unsigned int Nektar::Collections::CollectionOptimisation::GetMaxCollectionSize ( )
inline

Definition at line 138 of file CollectionOptimisation.h.

139  {
140  return m_maxCollSize;
141  }

References m_maxCollSize.

Referenced by Nektar::MultiRegions::ExpList::CreateCollections().

◆ GetOperatorImpMap()

OperatorImpMap Nektar::Collections::CollectionOptimisation::GetOperatorImpMap ( StdRegions::StdExpansionSharedPtr  pExp)

Get Operator Implementation Map from XMl or using default;.

Definition at line 347 of file CollectionOptimisation.cpp.

349 {
350  OperatorImpMap ret;
351  ElmtOrder searchKey(pExp->DetShapeType(), pExp->GetBasisNumModes(0));
352  ElmtOrder defSearch(pExp->DetShapeType(), -1);
353 
354  for (auto &it : m_global)
355  {
356  ImplementationType impType;
357 
358  auto it2 = it.second.find(searchKey);
359 
360  if (it2 == it.second.end())
361  {
362  it2 = it.second.find(defSearch);
363  if (it2 == it.second.end())
364  {
365  // Shouldn't be able to reach here.
366  impType = eNoCollection;
367  }
368  else
369  {
370  impType = it2->second;
371  }
372  }
373  else
374  {
375  impType = it2->second;
376  }
377 
378  ret[it.first] = impType;
379  }
380 
381  return ret;
382 }
std::map< OperatorType, ImplementationType > OperatorImpMap
Definition: Operator.h:112

References Nektar::Collections::eNoCollection, and m_global.

Referenced by Nektar::MultiRegions::ExpList::CreateCollections().

◆ IsUsingAutotuning()

bool Nektar::Collections::CollectionOptimisation::IsUsingAutotuning ( )
inline

Definition at line 143 of file CollectionOptimisation.h.

144  {
145  return m_autotune;
146  }

References m_autotune.

Referenced by Nektar::MultiRegions::ExpList::CreateCollections().

◆ ReadCollOps()

void Nektar::Collections::CollectionOptimisation::ReadCollOps ( TiXmlElement *  xmlCol,
GlobalOpMap global,
bool  verbose 
)
private

Definition at line 218 of file CollectionOptimisation.cpp.

220 {
221  bool verboseHeader = true;
222  map<string, LibUtilities::ShapeType> elTypes;
223  elTypes["S"] = LibUtilities::eSegment;
224  elTypes["T"] = LibUtilities::eTriangle;
225  elTypes["Q"] = LibUtilities::eQuadrilateral;
226  elTypes["A"] = LibUtilities::eTetrahedron;
227  elTypes["P"] = LibUtilities::ePyramid;
228  elTypes["R"] = LibUtilities::ePrism;
229  elTypes["H"] = LibUtilities::eHexahedron;
230 
231  map<string, OperatorType> opTypes;
232  for (int i = 0; i < SIZE_OperatorType; ++i)
233  {
234  opTypes[OperatorTypeMap[i]] = (OperatorType)i;
235  }
236 
237  map<string, ImplementationType> impTypes;
238  for (int i = 0; i < SIZE_ImplementationType; ++i)
239  {
240  impTypes[ImplementationTypeMap[i]] = (ImplementationType)i;
241  }
242 
243  TiXmlElement *elmt = xmlCol->FirstChildElement();
244  while (elmt)
245  {
246  string tagname = elmt->ValueStr();
247 
248  ASSERTL0(boost::iequals(tagname, "OPERATOR"),
249  "Only OPERATOR tags are supported inside the "
250  "COLLECTIONS tag.");
251 
252  const char *attr = elmt->Attribute("TYPE");
253  ASSERTL0(attr, "Missing TYPE in OPERATOR tag.");
254  string opType(attr);
255 
256  ASSERTL0(opTypes.count(opType) > 0,
257  "Unknown OPERATOR type " + opType + ".");
258 
259  OperatorType ot = opTypes[opType];
260 
261  TiXmlElement *elmt2 = elmt->FirstChildElement();
262 
263  map<int, pair<int, std::string>> verboseWrite;
264  while (elmt2)
265  {
266  string tagname = elmt2->ValueStr();
267  ASSERTL0(boost::iequals(tagname, "ELEMENT"),
268  "Only ELEMENT tags are supported inside the "
269  "OPERATOR tag.");
270 
271  const char *attr = elmt2->Attribute("TYPE");
272  ASSERTL0(attr, "Missing TYPE in ELEMENT tag.");
273 
274  string elType(attr);
275  auto it2 = elTypes.find(elType);
276  ASSERTL0(it2 != elTypes.end(), "Unknown element type " + elType +
277  " in ELEMENT "
278  "tag");
279 
280  const char *attr2 = elmt2->Attribute("IMPTYPE");
281  ASSERTL0(attr2, "Missing IMPTYPE in ELEMENT tag.");
282  string impType(attr2);
283  ASSERTL0(impTypes.count(impType) > 0,
284  "Unknown IMPTYPE type " + impType + ".");
285 
286  const char *attr3 = elmt2->Attribute("ORDER");
287  ASSERTL0(attr3, "Missing ORDER in ELEMENT tag.");
288  string order(attr3);
289 
290  // load details relevant to this shape dimension.
291  if (LibUtilities::ShapeTypeDimMap[it2->second] == m_shapeDim)
292  {
293  if (order == "*")
294  {
295  global[ot][ElmtOrder(it2->second, -1)] = impTypes[impType];
296 
297  if (verbose)
298  {
299  verboseWrite[it2->second] =
300  pair<int, std::string>(-1, impType);
301  }
302  }
303  else
304  {
305  vector<unsigned int> orders;
306  ParseUtils::GenerateSeqVector(order, orders);
307 
308  for (int i = 0; i < orders.size(); ++i)
309  {
310  global[ot][ElmtOrder(it2->second, orders[i])] =
311  impTypes[impType];
312 
313  if (verbose)
314  {
315  verboseWrite[it2->second] =
316  pair<int, std::string>(orders[i], impType);
317  }
318  }
319  }
320  }
321 
322  elmt2 = elmt2->NextSiblingElement();
323  }
324 
325  if (verboseWrite.size())
326  {
327  if (verboseHeader)
328  {
329  cout << "Collection settings from file: " << endl;
330  verboseHeader = false;
331  }
332 
333  cout << "\t Operator " << OperatorTypeMap[ot] << ":" << endl;
334 
335  for (auto &it : verboseWrite)
336  {
337  cout << "\t - " << LibUtilities::ShapeTypeMap[it.first]
338  << " order " << it.second.first << " -> "
339  << it.second.second << endl;
340  }
341  }
342 
343  elmt = elmt->NextSiblingElement();
344  }
345 }
static bool GenerateSeqVector(const std::string &str, std::vector< unsigned int > &out)
Takes a comma-separated compressed string and converts it to entries in a vector.
Definition: ParseUtils.cpp:105
constexpr unsigned int ShapeTypeDimMap[SIZE_ShapeType]
Definition: ShapeType.hpp:85

References ASSERTL0, Nektar::LibUtilities::eHexahedron, Nektar::LibUtilities::ePrism, Nektar::LibUtilities::ePyramid, Nektar::LibUtilities::eQuadrilateral, Nektar::LibUtilities::eSegment, Nektar::LibUtilities::eTetrahedron, Nektar::LibUtilities::eTriangle, Nektar::ParseUtils::GenerateSeqVector(), Nektar::Collections::ImplementationTypeMap, m_shapeDim, Nektar::Collections::OperatorTypeMap, Nektar::LibUtilities::ShapeTypeDimMap, Nektar::LibUtilities::ShapeTypeMap, Nektar::Collections::SIZE_ImplementationType, and Nektar::Collections::SIZE_OperatorType.

Referenced by CollectionOptimisation(), and UpdateOptFile().

◆ SetWithTimings()

OperatorImpMap Nektar::Collections::CollectionOptimisation::SetWithTimings ( std::vector< StdRegions::StdExpansionSharedPtr pGeom,
OperatorImpMap impTypes,
bool  verbose = true 
)

Definition at line 384 of file CollectionOptimisation.cpp.

387 {
388  boost::ignore_unused(impTypes);
389 
390  OperatorImpMap ret;
391 
392  StdRegions::StdExpansionSharedPtr pExp = pCollExp[0];
393 
394  // check to see if already defined for this expansion
395  OpImpTimingKey OpKey(pExp, pCollExp.size(), pExp->GetNumBases());
396  if (m_opImpMap.count(OpKey) != 0)
397  {
398  ret = m_opImpMap[OpKey];
399  return ret;
400  }
401 
402  int maxsize =
403  pCollExp.size() * max(pExp->GetNcoeffs(), pExp->GetTotPoints());
404  Array<OneD, NekDouble> inarray(maxsize, 1.0);
405  Array<OneD, NekDouble> outarray1(maxsize);
406  Array<OneD, NekDouble> outarray2(maxsize);
407  Array<OneD, NekDouble> outarray3(maxsize);
408 
409  LibUtilities::Timer t;
410 
411  if (verbose)
412  {
413  cout << "Collection Implemenation for "
414  << LibUtilities::ShapeTypeMap[pExp->DetShapeType()] << " ( ";
415  for (int i = 0; i < pExp->GetNumBases(); ++i)
416  {
417  cout << pExp->GetBasis(i)->GetNumModes() << " ";
418  }
419  cout << ")"
420  << " for ngeoms = " << pCollExp.size() << endl;
421  }
422  // set up an array of collections
423  CollectionVector coll;
424 
425  StdRegions::ConstFactorMap factors; // required for helmholtz operator
426  factors[StdRegions::eFactorLambda] = 1.5;
427 
428  for (int imp = 1; imp < SIZE_ImplementationType; ++imp)
429  {
430  ImplementationType impType = (ImplementationType)imp;
431  OperatorImpMap impTypes;
432  for (int i = 0; i < SIZE_OperatorType; ++i)
433  {
434  OperatorType opType = (OperatorType)i;
435  OperatorKey opKey(pCollExp[0]->DetShapeType(), opType, impType,
436  pCollExp[0]->IsNodalNonTensorialExp());
437 
438  if (GetOperatorFactory().ModuleExists(opKey))
439  {
440  impTypes[opType] = impType;
441  }
442  }
443 
444  Collection collLoc(pCollExp, impTypes);
445  for (int i = 0; i < SIZE_OperatorType; ++i)
446  {
447  collLoc.Initialise((OperatorType)i, factors);
448  }
449  coll.push_back(collLoc);
450  }
451 
452  // Determine the number of tests to do in one second
453  Array<OneD, int> Ntest(SIZE_OperatorType);
454  for (int i = 0; i < SIZE_OperatorType; ++i)
455  {
456  OperatorType OpType = (OperatorType)i;
457 
458  t.Start();
459 
460  coll[0].ApplyOperator(OpType, inarray, outarray1, outarray2, outarray3);
461  t.Stop();
462 
463  NekDouble oneTest = t.TimePerTest(1);
464 
465  Ntest[i] = max((int)(0.25 / oneTest), 1);
466  }
467 
468  Array<OneD, NekDouble> timing(SIZE_ImplementationType);
469 
470  if (verbose)
471  {
472  cout << "\t "
473  << " Op. "
474  << ":\t"
475  << "opt. Impl."
476  << "\t (IterLocExp, IterStdExp, "
477  "StdMat, SumFac, MatrixFree)"
478  << endl;
479  }
480 
481  // loop over all operators and determine fastest implementation
482  for (int i = 0; i < SIZE_OperatorType; ++i)
483  {
484  OperatorType OpType = (OperatorType)i;
485 
486  // call collection implementation in thorugh ExpList.
487  for (int imp = 0; imp < coll.size(); ++imp)
488  {
489  if (coll[imp].HasOperator(OpType))
490  {
491  t.Start();
492  for (int n = 0; n < Ntest[i]; ++n)
493  {
494  coll[imp].ApplyOperator(OpType, inarray, outarray1,
495  outarray2, outarray3);
496  }
497  t.Stop();
498  timing[imp] = t.TimePerTest(Ntest[i]);
499  }
500  else
501  {
502  timing[imp] = 1000.0;
503  }
504  }
505  // determine optimal implementation. Note +1 to
506  // remove NoImplementationType flag
507  int minImp = Vmath::Imin(coll.size(), timing, 1) + 1;
508 
509  if (verbose)
510  {
511  cout << "\t " << OperatorTypeMap1[i] << ": \t"
512  << ImplementationTypeMap1[minImp] << "\t (";
513  for (int j = 0; j < coll.size(); ++j)
514  {
515  if (timing[j] > 999.0)
516  {
517  cout << " -- ";
518  }
519  else
520  {
521  cout << timing[j];
522  }
523  if (j != coll.size() - 1)
524  {
525  cout << ", ";
526  }
527  }
528  cout << ")" << endl;
529  }
530 
531  // could reset global map if reusing method?
532  // m_global[OpType][pExp->DetShapeType()] = (ImplementationType)minImp;
533  // set up new map
534  ret[OpType] = (ImplementationType)minImp;
535  }
536 
537  // store map for use by another expansion.
538  m_opImpMap[OpKey] = ret;
539  return ret;
540 }
static std::map< OpImpTimingKey, OperatorImpMap > m_opImpMap
const char *const ImplementationTypeMap1[]
Definition: Operator.h:101
std::tuple< LibUtilities::ShapeType, OperatorType, ImplementationType, ExpansionIsNodal > OperatorKey
Key for describing an Operator.
Definition: Operator.h:177
OperatorFactory & GetOperatorFactory()
Returns the singleton Operator factory object.
Definition: Operator.cpp:117
const char *const OperatorTypeMap1[]
Definition: Operator.h:80
std::vector< Collection > CollectionVector
Definition: Collection.h:110
std::shared_ptr< StdExpansion > StdExpansionSharedPtr
std::map< ConstFactorType, NekDouble > ConstFactorMap
Definition: StdRegions.hpp:399
double NekDouble
int Imin(int n, const T *x, const int incx)
Return the index of the minimum element in x.
Definition: Vmath.cpp:1023

References Nektar::StdRegions::eFactorLambda, Nektar::Collections::GetOperatorFactory(), Vmath::Imin(), Nektar::Collections::ImplementationTypeMap1, Nektar::Collections::Collection::Initialise(), m_opImpMap, Nektar::Collections::OperatorTypeMap1, Nektar::LibUtilities::ShapeTypeMap, Nektar::Collections::SIZE_ImplementationType, Nektar::Collections::SIZE_OperatorType, Nektar::LibUtilities::Timer::Start(), Nektar::LibUtilities::Timer::Stop(), and Nektar::LibUtilities::Timer::TimePerTest().

Referenced by Nektar::MultiRegions::ExpList::CreateCollections().

◆ UpdateOptFile()

void Nektar::Collections::CollectionOptimisation::UpdateOptFile ( std::string  sessName,
LibUtilities::CommSharedPtr comm 
)

Definition at line 542 of file CollectionOptimisation.cpp.

544 {
545  if (comm->GetSize() != comm->GetSpaceComm()->GetSize())
546  {
547  return; // FIXME: Parareal
548  }
549 
550  std::string outname = sessName + ".opt";
551 
552  TiXmlDocument doc;
553  TiXmlElement *root;
554  TiXmlElement *xmlCol = new TiXmlElement("COLLECTIONS");
555  GlobalOpMap global;
556  int rank = comm->GetRank();
557  int nprocs = comm->GetSize();
558  if (rank == 0)
559  {
560  if (!doc.LoadFile(outname)) // set up new file
561  {
562  TiXmlDeclaration *decl = new TiXmlDeclaration("1.0", "utf-8", "");
563  doc.LinkEndChild(decl);
564  root = new TiXmlElement("NEKTAR");
565  doc.LinkEndChild(root);
566  root->LinkEndChild(xmlCol);
567  }
568  else // load file and read operator information
569  {
570  root = doc.FirstChildElement("NEKTAR");
571  xmlCol = root->FirstChildElement("COLLECTIONS");
572 
573  bool verbose = false;
574  ReadCollOps(xmlCol, global, verbose);
575  }
576  }
577 
578  // update global with m_opImpMap info
579  map<LibUtilities::ShapeType, int> ShapeMaxSize;
580  for (auto &opimp : m_opImpMap)
581  {
582  bool updateShape = true;
583  LibUtilities::ShapeType shape = opimp.first.GetShapeType();
584 
585  // check to see if already added this shapes details but with
586  // a larger collection and if so do not update.
587  if (ShapeMaxSize.count(shape))
588  {
589  int ngeoms = opimp.first.GetNGeoms();
590  if (ngeoms > ShapeMaxSize[shape])
591  {
592  ShapeMaxSize[shape] = ngeoms;
593  }
594  else
595  {
596  updateShape = false;
597  }
598  }
599 
600  if (updateShape)
601  {
602  for (auto &op : opimp.second)
603  {
604  global[op.first][ElmtOrder(shape, -1)] = op.second;
605  }
606  }
607  }
608 
609  // share
610  if (nprocs)
611  {
612  // loop over operators
613  for (auto &op : global)
614  {
615  // check to see which shapes are defined in this proc
616  Array<OneD, int> ElmtImp(LibUtilities::SIZE_ShapeType, -1);
617  Array<OneD, bool> ElmtDef(LibUtilities::SIZE_ShapeType, false);
618  for (auto &el : op.second)
619  {
620  ElmtImp[el.first.first] = el.second;
621  ElmtDef[el.first.first] = true;
622  }
623 
624  comm->AllReduce(ElmtImp, LibUtilities::ReduceMax);
625 
626  // loop over elements and update if not already defined
627  if (rank == 0)
628  {
629  for (int i = 1; i < LibUtilities::SIZE_ShapeType; ++i)
630  {
631  if ((ElmtImp[i] != -1) && (ElmtDef[i] == false))
632  {
633  global[op.first]
635  (ImplementationType)ElmtImp[i];
636  }
637  }
638  }
639  }
640  }
641 
642  // Update Collection section with global data on root
643  if (rank == 0)
644  {
645  xmlCol->Clear();
646 
647  map<LibUtilities::ShapeType, string> ShapeLetMap = {
648  {LibUtilities::eSegment, "S"},
652  {LibUtilities::ePyramid, "P"},
653  {LibUtilities::ePrism, "R"},
655 
656  for (auto &op : global)
657  {
658  TiXmlElement *ColOp = new TiXmlElement("OPERATOR");
659  xmlCol->LinkEndChild(ColOp);
660  ColOp->SetAttribute("TYPE", OperatorTypeMap[op.first]);
661 
662  for (auto &el : op.second)
663  {
664  TiXmlElement *ElmtOp = new TiXmlElement("ELEMENT");
665  ColOp->LinkEndChild(ElmtOp);
666 
667  ElmtOp->SetAttribute("TYPE", ShapeLetMap[el.first.first]);
668  ElmtOp->SetAttribute("ORDER", "*");
669  ElmtOp->SetAttribute("IMPTYPE",
670  ImplementationTypeMap[el.second]);
671  }
672  }
673 
674  doc.SaveFile(outname);
675  }
676 }
std::map< OperatorType, std::map< ElmtOrder, ImplementationType > > GlobalOpMap

References Nektar::LibUtilities::eHexahedron, Nektar::LibUtilities::ePrism, Nektar::LibUtilities::ePyramid, Nektar::LibUtilities::eQuadrilateral, Nektar::LibUtilities::eSegment, Nektar::LibUtilities::eTetrahedron, Nektar::LibUtilities::eTriangle, Nektar::Collections::ImplementationTypeMap, m_opImpMap, Nektar::Collections::OperatorTypeMap, ReadCollOps(), Nektar::LibUtilities::ReduceMax, and Nektar::LibUtilities::SIZE_ShapeType.

Referenced by Nektar::MultiRegions::ExpList::CreateCollections().

Member Data Documentation

◆ m_autotune

bool Nektar::Collections::CollectionOptimisation::m_autotune
private

Definition at line 167 of file CollectionOptimisation.h.

Referenced by CollectionOptimisation(), and IsUsingAutotuning().

◆ m_defaultType

ImplementationType Nektar::Collections::CollectionOptimisation::m_defaultType
private

◆ m_global

GlobalOpMap Nektar::Collections::CollectionOptimisation::m_global
private

Definition at line 166 of file CollectionOptimisation.h.

Referenced by CollectionOptimisation(), and GetOperatorImpMap().

◆ m_maxCollSize

unsigned int Nektar::Collections::CollectionOptimisation::m_maxCollSize
private

Definition at line 169 of file CollectionOptimisation.h.

Referenced by CollectionOptimisation(), and GetMaxCollectionSize().

◆ m_opImpMap

map< OpImpTimingKey, OperatorImpMap > Nektar::Collections::CollectionOptimisation::m_opImpMap
staticprivate

Definition at line 165 of file CollectionOptimisation.h.

Referenced by SetWithTimings(), and UpdateOptFile().

◆ m_shapeDim

unsigned int Nektar::Collections::CollectionOptimisation::m_shapeDim
private

Definition at line 170 of file CollectionOptimisation.h.

Referenced by ReadCollOps().