Nektar++
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Friends Macros Pages
Public Member Functions | Private Types | Private Attributes | Static Private Attributes | List of all members
Nektar::Collections::CollectionOptimisation Class Reference

#include <CollectionOptimisation.h>

Collaboration diagram for Nektar::Collections::CollectionOptimisation:
Collaboration graph
[legend]

Public Member Functions

COLLECTIONS_EXPORT CollectionOptimisation (LibUtilities::SessionReaderSharedPtr pSession, 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)
 
bool SetByXml (void)
 

Private Types

typedef std::pair
< LibUtilities::ShapeType, int > 
ElmtOrder
 

Private Attributes

std::map< OperatorType,
std::map< ElmtOrder,
ImplementationType > > 
m_global
 
bool m_setByXml
 
bool m_autotune
 
ImplementationType m_defaultType
 
unsigned int m_maxCollSize
 

Static Private Attributes

static std::map
< OpImpTimingKey,
OperatorImpMap
m_opImpMap
 

Detailed Description

Definition at line 114 of file CollectionOptimisation.h.

Member Typedef Documentation

Definition at line 155 of file CollectionOptimisation.h.

Constructor & Destructor Documentation

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

Definition at line 49 of file CollectionOptimisation.cpp.

References ASSERTL0, Nektar::LibUtilities::eHexahedron, Nektar::Collections::eIterPerExp, Nektar::Collections::eNoCollection, Nektar::Collections::eNoImpType, Nektar::Collections::ePhysDeriv, Nektar::LibUtilities::ePrism, Nektar::LibUtilities::ePyramid, Nektar::LibUtilities::eQuadrilateral, Nektar::LibUtilities::eSegment, Nektar::Collections::eStdMat, Nektar::Collections::eSumFac, Nektar::LibUtilities::eTetrahedron, Nektar::LibUtilities::eTriangle, Nektar::Collections::ImplementationTypeMap, Nektar::iterator, Nektar::Collections::OperatorTypeMap, Nektar::LibUtilities::ShapeTypeMap, Nektar::Collections::SIZE_ImplementationType, and Nektar::Collections::SIZE_OperatorType.

52 {
53  int i;
54  map<ElmtOrder, ImplementationType> defaults;
55  map<ElmtOrder, ImplementationType> defaultsPhysDeriv;
57  bool verbose = (pSession.get()) &&
58  (pSession->DefinesCmdLineArgument("verbose")) &&
59  (pSession->GetComm()->GetRank() == 0);
60 
61  m_setByXml = false;
62  m_autotune = false;
63  m_maxCollSize = 0;
64  m_defaultType = defaultType == eNoImpType ? eIterPerExp : defaultType;
65 
66  map<string, LibUtilities::ShapeType> elTypes;
68  elTypes["S"] = LibUtilities::eSegment;
69  elTypes["T"] = LibUtilities::eTriangle;
70  elTypes["Q"] = LibUtilities::eQuadrilateral;
71  elTypes["A"] = LibUtilities::eTetrahedron;
72  elTypes["P"] = LibUtilities::ePyramid;
73  elTypes["R"] = LibUtilities::ePrism;
74  elTypes["H"] = LibUtilities::eHexahedron;
75 
76  // Set defaults for all element types.
77  for (it2 = elTypes.begin(); it2 != elTypes.end(); ++it2)
78  {
79  defaults [ElmtOrder(it2->second, -1)] = m_defaultType;
80  defaultsPhysDeriv [ElmtOrder(it2->second, -1)] = m_defaultType;
81  }
82 
83  if (defaultType == eNoImpType)
84  {
85  for (it2 = elTypes.begin(); it2 != elTypes.end(); ++it2)
86  {
87  // For 1<=N<=5 use StdMat otherwise IterPerExp or given default type
88  for (int i = 1; i < 5; ++i)
89  {
90  defaults[ElmtOrder(it2->second, i)] = eStdMat;
91  }
92 
93  // For 1<=N<=3 use SumFac otherwise NoCollection. Note that
94  // default is not currently overwritten by given default
95  // type
96  defaultsPhysDeriv [ElmtOrder(it2->second, -1)] = eNoCollection;
97  for (int i = 1; i < 3; ++i)
98  {
99  defaultsPhysDeriv[ElmtOrder(it2->second, i)] = eSumFac;
100  }
101  }
102  }
103 
104  map<string, OperatorType> opTypes;
105  for (i = 0; i < SIZE_OperatorType; ++i)
106  {
107  opTypes[OperatorTypeMap[i]] = (OperatorType)i;
108  switch ((OperatorType)i)
109  {
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 (i = 0; i < SIZE_ImplementationType; ++i)
120  {
121  impTypes[ImplementationTypeMap[i]] = (ImplementationType)i;
122  }
123 
124  if(pSession.get()) // turn off file reader if dummy pointer is given
125  {
126  TiXmlDocument &doc = pSession->GetDocument();
127  TiXmlHandle docHandle(&doc);
128  TiXmlElement *master = docHandle.FirstChildElement("NEKTAR").Element();
129  ASSERTL0(master, "Unable to find NEKTAR tag in file.");
130 
131  TiXmlElement *xmlCol = master->FirstChildElement("COLLECTIONS");
132 
133  // Check if user has specified some options
134  if (xmlCol)
135  {
136  // Set the maxsize and default implementation type if provided
137  const char *maxSize = xmlCol->Attribute("MAXSIZE");
138  m_maxCollSize = (maxSize ? atoi(maxSize) : 0);
139 
140  const char *defaultImpl = xmlCol->Attribute("DEFAULT");
141  m_defaultType = defaultType;
142 
143  // If user has specified a default impl type, autotuning
144  // and set this default across all operators.
145  if (defaultType == eNoImpType && defaultImpl)
146  {
147  const std::string collinfo = string(defaultImpl);
148  m_autotune = boost::iequals(collinfo, "auto");
149 
150  if (!m_autotune)
151  {
152  for(i = 1; i < Collections::SIZE_ImplementationType; ++i)
153  {
154  if(boost::iequals(collinfo,
156  {
158  break;
159  }
160  }
161 
162  ASSERTL0(i != Collections::SIZE_ImplementationType,
163  "Unknown default collection scheme: "+collinfo);
164 
165  defaults.clear();
166  // Override default types
167  for (it2 = elTypes.begin(); it2 != elTypes.end(); ++it2)
168  {
169  defaults[ElmtOrder(it2->second, -1)] = m_defaultType;
170  }
171 
172  for (i = 0; i < SIZE_OperatorType; ++i)
173  {
174  m_global[(OperatorType)i] = defaults;
175  }
176  }
177  }
178 
179  // Now process operator-specific implementation selections
180  TiXmlElement *elmt = xmlCol->FirstChildElement();
181  while (elmt)
182  {
183  m_setByXml = true;
184 
185  string tagname = elmt->ValueStr();
186 
187  ASSERTL0(boost::iequals(tagname, "OPERATOR"),
188  "Only OPERATOR tags are supported inside the "
189  "COLLECTIONS tag.");
190 
191  const char *attr = elmt->Attribute("TYPE");
192  ASSERTL0(attr, "Missing TYPE in OPERATOR tag.");
193  string opType(attr);
194 
195  ASSERTL0(opTypes.count(opType) > 0,
196  "Unknown OPERATOR type " + opType + ".");
197 
198  OperatorType ot = opTypes[opType];
199 
200  TiXmlElement *elmt2 = elmt->FirstChildElement();
201 
202  while (elmt2)
203  {
204  string tagname = elmt2->ValueStr();
205  ASSERTL0(boost::iequals(tagname, "ELEMENT"),
206  "Only ELEMENT tags are supported inside the "
207  "OPERATOR tag.");
208 
209  const char *attr = elmt2->Attribute("TYPE");
210  ASSERTL0(attr, "Missing TYPE in ELEMENT tag.");
211 
212  string elType(attr);
213  it2 = elTypes.find(elType);
214  ASSERTL0(it2 != elTypes.end(),
215  "Unknown element type "+elType+" in ELEMENT "
216  "tag");
217 
218  const char *attr2 = elmt2->Attribute("IMPTYPE");
219  ASSERTL0(attr2, "Missing IMPTYPE in ELEMENT tag.");
220  string impType(attr2);
221  ASSERTL0(impTypes.count(impType) > 0,
222  "Unknown IMPTYPE type " + impType + ".");
223 
224  const char *attr3 = elmt2->Attribute("ORDER");
225  ASSERTL0(attr3, "Missing ORDER in ELEMENT tag.");
226  string order(attr3);
227 
228  if (order == "*")
229  {
230  m_global[ot][ElmtOrder(it2->second, -1)]
231  = impTypes[impType];
232  }
233  else
234  {
235  vector<unsigned int> orders;
236  ParseUtils::GenerateSeqVector(order.c_str(), orders);
237 
238  for (int i = 0; i < orders.size(); ++i)
239  {
240  m_global[ot][ElmtOrder(it2->second, orders[i])]
241  = impTypes[impType];
242  }
243  }
244 
245  elmt2 = elmt2->NextSiblingElement();
246  }
247 
248  elmt = elmt->NextSiblingElement();
249  }
250 
251  // Print out operator map
252  if (verbose)
253  {
254  if (!m_setByXml && !m_autotune)
255  {
256  cout << "Setting Collection optimisation using: "
258  << endl;
259  }
260 
261  if (m_setByXml)
262  {
263  map<OperatorType, map<ElmtOrder,
266  for (mIt = m_global.begin(); mIt != m_global.end(); mIt++)
267  {
268  cout << "Operator " << OperatorTypeMap[mIt->first]
269  << ":" << endl;
270 
271  for (eIt = mIt->second.begin();
272  eIt != mIt->second.end(); eIt++)
273  {
274  cout << "- "
275  << LibUtilities::ShapeTypeMap[eIt->first.first]
276  << " order " << eIt->first.second << " -> "
277  << ImplementationTypeMap[eIt->second] << endl;
278  }
279  }
280  }
281  }
282  }
283  }
284 }
#define ASSERTL0(condition, msg)
Definition: ErrorUtil.hpp:198
const char *const ImplementationTypeMap[]
Definition: Operator.h:91
std::map< OperatorType, std::map< ElmtOrder, ImplementationType > > m_global
static bool GenerateSeqVector(const char *const str, std::vector< unsigned int > &vec)
Definition: ParseUtils.hpp:79
const char *const OperatorTypeMap[]
Definition: Operator.h:73
const char *const ShapeTypeMap[]
Definition: ShapeType.hpp:66
StandardMatrixTag boost::call_traits< LhsDataType >::const_reference rhs typedef NekMatrix< LhsDataType, StandardMatrixTag >::iterator iterator
std::pair< LibUtilities::ShapeType, int > ElmtOrder
Nektar::Collections::CollectionOptimisation::~CollectionOptimisation ( )
inline

Definition at line 122 of file CollectionOptimisation.h.

122 {};

Member Function Documentation

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

Definition at line 124 of file CollectionOptimisation.h.

References m_defaultType.

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

125  {
126  return m_defaultType;
127  }
unsigned int Nektar::Collections::CollectionOptimisation::GetMaxCollectionSize ( )
inline

Definition at line 129 of file CollectionOptimisation.h.

References m_maxCollSize.

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

130  {
131  return m_maxCollSize;
132  }
OperatorImpMap Nektar::Collections::CollectionOptimisation::GetOperatorImpMap ( StdRegions::StdExpansionSharedPtr  pExp)

Get Operator Implementation Map from XMl or using default;.

Definition at line 286 of file CollectionOptimisation.cpp.

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

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

288 {
289  map<OperatorType, map<ElmtOrder, ImplementationType> >::iterator it;
291 
292  OperatorImpMap ret;
293  ElmtOrder searchKey(pExp->DetShapeType(),
294  pExp->GetBasisNumModes(0));
295  ElmtOrder defSearch(pExp->DetShapeType(), -1);
296 
297  for (it = m_global.begin(); it != m_global.end(); ++it)
298  {
299  ImplementationType impType;
300 
301  it2 = it->second.find(searchKey);
302 
303  if (it2 == it->second.end())
304  {
305  it2 = it->second.find(defSearch);
306  if (it2 == it->second.end())
307  {
308  // Shouldn't be able to reach here.
309  impType = eNoCollection;
310  }
311  else
312  {
313  impType = it2->second;
314  }
315  }
316  else
317  {
318  impType = it2->second;
319  }
320 
321  ret[it->first] = impType;
322  }
323 
324  return ret;
325 }
std::map< OperatorType, std::map< ElmtOrder, ImplementationType > > m_global
std::map< OperatorType, ImplementationType > OperatorImpMap
Definition: Operator.h:102
StandardMatrixTag boost::call_traits< LhsDataType >::const_reference rhs typedef NekMatrix< LhsDataType, StandardMatrixTag >::iterator iterator
std::pair< LibUtilities::ShapeType, int > ElmtOrder
bool Nektar::Collections::CollectionOptimisation::IsUsingAutotuning ( )
inline
bool Nektar::Collections::CollectionOptimisation::SetByXml ( void  )
inline

Definition at line 149 of file CollectionOptimisation.h.

References m_setByXml.

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

Definition at line 327 of file CollectionOptimisation.cpp.

References Nektar::Collections::GetOperatorFactory(), Vmath::Imin(), Nektar::Collections::ImplementationTypeMap, Nektar::Collections::OperatorTypeMap, Nektar::LibUtilities::ShapeTypeMap, Nektar::Collections::SIZE_ImplementationType, Nektar::Collections::SIZE_OperatorType, Nektar::Timer::Start(), Nektar::Timer::Stop(), and Nektar::Timer::TimePerTest().

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

331 {
332  OperatorImpMap ret;
333 
334  StdRegions::StdExpansionSharedPtr pExp = pCollExp[0];
335 
336  // check to see if already defined for this expansion
337  OpImpTimingKey OpKey(pExp,pCollExp.size(),pExp->GetNumBases());
338  if(m_opImpMap.count(OpKey) != 0)
339  {
340  ret = m_opImpMap[OpKey];
341  return ret;
342  }
343 
344  int maxsize = pCollExp.size()*max(pExp->GetNcoeffs(),pExp->GetTotPoints());
345  Array<OneD, NekDouble> inarray(maxsize,1.0);
346  Array<OneD, NekDouble> outarray1(maxsize);
347  Array<OneD, NekDouble> outarray2(maxsize);
348  Array<OneD, NekDouble> outarray3(maxsize);
349 
350  Timer t;
351 
352  if(verbose)
353  {
354  cout << "Collection Implemenation for "
355  << LibUtilities::ShapeTypeMap[pExp->DetShapeType()] << " ( ";
356  for(int i = 0; i < pExp->GetNumBases(); ++i)
357  {
358  cout << pExp->GetBasis(i)->GetNumModes() <<" ";
359  }
360  cout << ")" << " for ngeoms = " << pCollExp.size() << endl;
361  }
362  // set up an array of collections
363  CollectionVector coll;
364  for(int imp = 1; imp < SIZE_ImplementationType; ++imp)
365  {
366  ImplementationType impType = (ImplementationType)imp;
367  OperatorImpMap impTypes;
368  for (int i = 0; i < SIZE_OperatorType; ++i)
369  {
370  OperatorType opType = (OperatorType)i;
371  OperatorKey opKey(pCollExp[0]->DetShapeType(), opType, impType,
372  pCollExp[0]->IsNodalNonTensorialExp());
373 
374  if (GetOperatorFactory().ModuleExists(opKey))
375  {
376  impTypes[opType] = impType;
377  }
378  else
379  {
380  cout << "Note: Implementation does not exist: " << opKey << endl;
381  }
382  }
383 
384  Collection collloc(pCollExp,impTypes);
385  coll.push_back(collloc);
386  }
387 
388  // Determine the number of tests to do in one second
389  Array<OneD, int> Ntest(SIZE_OperatorType);
390  for(int i = 0; i < SIZE_OperatorType; ++i)
391  {
392  OperatorType OpType = (OperatorType)i;
393 
394  t.Start();
395  coll[0].ApplyOperator(OpType,
396  inarray,
397  outarray1,
398  outarray2,
399  outarray3);
400  t.Stop();
401 
402  NekDouble oneTest = t.TimePerTest(1);
403 
404  Ntest[i] = max((int)(0.25/oneTest),1);
405  }
406 
407  Array<OneD, NekDouble> timing(SIZE_ImplementationType);
408  // loop over all operators and determine fastest implementation
409  for(int i = 0; i < SIZE_OperatorType; ++i)
410  {
411  OperatorType OpType = (OperatorType)i;
412 
413  // call collection implementation in thorugh ExpList.
414  for (int imp = 0; imp < coll.size(); ++imp)
415  {
416  if (coll[imp].HasOperator(OpType))
417  {
418  t.Start();
419  for(int n = 0; n < Ntest[i]; ++n)
420  {
421  coll[imp].ApplyOperator(OpType,
422  inarray,
423  outarray1,
424  outarray2,
425  outarray3);
426  }
427  t.Stop();
428  timing[imp] = t.TimePerTest(Ntest[i]);
429  }
430  else
431  {
432  timing[imp] = 1000.0;
433  }
434  }
435  // determine optimal implementation. Note +1 to
436  // remove NoImplementationType flag
437  int minImp = Vmath::Imin(coll.size(),timing,1)+1;
438 
439  if(verbose)
440  {
441  cout << "\t " << OperatorTypeMap[i] << ": "
442  << ImplementationTypeMap[minImp] << "\t (";
443  for(int j = 0; j < coll.size(); ++j)
444  {
445  if (timing[j] > 999.0)
446  {
447  cout << "-";
448  }
449  else
450  {
451  cout << timing[j] ;
452  }
453  if(j != coll.size()-1)
454  {
455  cout <<", ";
456  }
457  }
458  cout << ")" <<endl;
459  }
460  // could reset global map if reusing method?
461  //m_global[OpType][pExp->DetShapeType()] = (ImplementationType)minImp;
462  // set up new map
463  ret[OpType] = (ImplementationType)minImp;
464  }
465 
466  // store map for use by another expansion.
467  m_opImpMap[OpKey] = ret;
468  return ret;
469 }
const char *const ImplementationTypeMap[]
Definition: Operator.h:91
boost::tuple< LibUtilities::ShapeType, OperatorType, ImplementationType, ExpansionIsNodal > OperatorKey
Key for describing an Operator.
Definition: Operator.h:159
std::vector< Collection > CollectionVector
Definition: Collection.h:98
int Imin(int n, const T *x, const int incx)
Return the index of the minimum element in x.
Definition: Vmath.cpp:847
static std::map< OpImpTimingKey, OperatorImpMap > m_opImpMap
const char *const OperatorTypeMap[]
Definition: Operator.h:73
const char *const ShapeTypeMap[]
Definition: ShapeType.hpp:66
std::map< OperatorType, ImplementationType > OperatorImpMap
Definition: Operator.h:102
double NekDouble
OperatorFactory & GetOperatorFactory()
Returns the singleton Operator factory object.
Definition: Operator.cpp:110
boost::shared_ptr< StdExpansion > StdExpansionSharedPtr

Member Data Documentation

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

Definition at line 160 of file CollectionOptimisation.h.

Referenced by IsUsingAutotuning().

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

Definition at line 161 of file CollectionOptimisation.h.

Referenced by GetDefaultImplementationType().

std::map<OperatorType, std::map<ElmtOrder, ImplementationType> > Nektar::Collections::CollectionOptimisation::m_global
private

Definition at line 158 of file CollectionOptimisation.h.

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

Definition at line 162 of file CollectionOptimisation.h.

Referenced by GetMaxCollectionSize().

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

Definition at line 157 of file CollectionOptimisation.h.

bool Nektar::Collections::CollectionOptimisation::m_setByXml
private

Definition at line 159 of file CollectionOptimisation.h.

Referenced by SetByXml().