35 #include <boost/algorithm/string/predicate.hpp>
36 #include <boost/core/ignore_unused.hpp>
42 #include <boost/algorithm/string/classification.hpp>
43 #include <boost/algorithm/string/split.hpp>
55 map<OpImpTimingKey, OperatorImpMap> CollectionOptimisation::m_opImpMap;
57 CollectionOptimisation::CollectionOptimisation(
60 : m_shapeDim(shapedim)
62 map<ElmtOrder, ImplementationType> defaults, defaultsPhysDeriv,
64 bool verbose = (pSession.get()) &&
65 (pSession->DefinesCmdLineArgument(
"verbose")) &&
66 (pSession->GetComm()->GetRank() == 0);
72 map<string, LibUtilities::ShapeType> elTypes;
82 for (
auto &it2 : elTypes)
91 for (
auto &it2 : elTypes)
101 map<string, OperatorType> opTypes;
118 map<string, ImplementationType> impTypes;
126 if ((defaultType ==
eNoImpType) && (pSession.get()))
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;
134 TiXmlElement *xmlCol = master->FirstChildElement(
"COLLECTIONS");
140 const char *maxSize = xmlCol->Attribute(
"MAXSIZE");
143 const char *defaultImpl = xmlCol->Attribute(
"DEFAULT");
150 const std::string collinfo = string(defaultImpl);
151 m_autotune = boost::iequals(collinfo,
"auto");
155 bool collectionFound{
false};
164 collectionFound =
true;
170 "Unknown default collection scheme: " + collinfo);
174 for (
auto &it2 : elTypes)
185 const char *write = xmlCol->Attribute(
"WRITE");
186 if (write && boost::iequals(write,
"true"))
188 WriteFullCollections =
true;
197 if (WriteFullCollections)
204 for (
auto &eIt : mIt.second)
208 <<
" order " << eIt.first.second <<
" -> "
221 bool verboseHeader =
true;
222 map<string, LibUtilities::ShapeType> elTypes;
231 map<string, OperatorType> opTypes;
237 map<string, ImplementationType> impTypes;
243 TiXmlElement *elmt = xmlCol->FirstChildElement();
246 string tagname = elmt->ValueStr();
248 ASSERTL0(boost::iequals(tagname,
"OPERATOR"),
249 "Only OPERATOR tags are supported inside the "
252 const char *attr = elmt->Attribute(
"TYPE");
253 ASSERTL0(attr,
"Missing TYPE in OPERATOR tag.");
257 "Unknown OPERATOR type " + opType +
".");
261 TiXmlElement *elmt2 = elmt->FirstChildElement();
263 map<int, pair<int, std::string>> verboseWrite;
266 string tagname = elmt2->ValueStr();
267 ASSERTL0(boost::iequals(tagname,
"ELEMENT"),
268 "Only ELEMENT tags are supported inside the "
271 const char *attr = elmt2->Attribute(
"TYPE");
272 ASSERTL0(attr,
"Missing TYPE in ELEMENT tag.");
275 auto it2 = elTypes.find(elType);
276 ASSERTL0(it2 != elTypes.end(),
"Unknown element type " + elType +
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 +
".");
286 const char *attr3 = elmt2->Attribute(
"ORDER");
287 ASSERTL0(attr3,
"Missing ORDER in ELEMENT tag.");
295 global[ot][
ElmtOrder(it2->second, -1)] = impTypes[impType];
299 verboseWrite[it2->second] =
300 pair<int, std::string>(-1, impType);
305 vector<unsigned int> orders;
308 for (
int i = 0; i < orders.size(); ++i)
310 global[ot][
ElmtOrder(it2->second, orders[i])] =
315 verboseWrite[it2->second] =
316 pair<int, std::string>(orders[i], impType);
322 elmt2 = elmt2->NextSiblingElement();
325 if (verboseWrite.size())
329 cout <<
"Collection settings from file: " << endl;
330 verboseHeader =
false;
335 for (
auto &it : verboseWrite)
338 <<
" order " << it.second.first <<
" -> "
339 << it.second.second << endl;
343 elmt = elmt->NextSiblingElement();
351 ElmtOrder searchKey(pExp->DetShapeType(), pExp->GetBasisNumModes(0));
352 ElmtOrder defSearch(pExp->DetShapeType(), -1);
358 auto it2 = it.second.find(searchKey);
360 if (it2 == it.second.end())
362 it2 = it.second.find(defSearch);
363 if (it2 == it.second.end())
370 impType = it2->second;
375 impType = it2->second;
378 ret[it.first] = impType;
385 vector<StdRegions::StdExpansionSharedPtr> pCollExp,
388 boost::ignore_unused(impTypes);
403 pCollExp.size() * max(pExp->GetNcoeffs(), pExp->GetTotPoints());
413 cout <<
"Collection Implemenation for "
415 for (
int i = 0; i < pExp->GetNumBases(); ++i)
417 cout << pExp->GetBasis(i)->GetNumModes() <<
" ";
420 <<
" for ngeoms = " << pCollExp.size() << endl;
435 OperatorKey opKey(pCollExp[0]->DetShapeType(), opType, impType,
436 pCollExp[0]->IsNodalNonTensorialExp());
440 impTypes[opType] = impType;
449 coll.push_back(collLoc);
460 coll[0].ApplyOperator(OpType, inarray, outarray1, outarray2, outarray3);
465 Ntest[i] = max((
int)(0.25 / oneTest), 1);
476 <<
"\t (IterLocExp, IterStdExp, "
477 "StdMat, SumFac, MatrixFree)"
487 for (
int imp = 0; imp < coll.size(); ++imp)
489 if (coll[imp].HasOperator(OpType))
492 for (
int n = 0; n < Ntest[i]; ++n)
494 coll[imp].ApplyOperator(OpType, inarray, outarray1,
495 outarray2, outarray3);
502 timing[imp] = 1000.0;
507 int minImp =
Vmath::Imin(coll.size(), timing, 1) + 1;
513 for (
int j = 0; j < coll.size(); ++j)
515 if (timing[j] > 999.0)
523 if (j != coll.size() - 1)
545 if (comm->GetSize() != comm->GetSpaceComm()->GetSize())
550 std::string outname = sessName +
".opt";
554 TiXmlElement *xmlCol =
new TiXmlElement(
"COLLECTIONS");
556 int rank = comm->GetRank();
557 int nprocs = comm->GetSize();
560 if (!doc.LoadFile(outname))
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);
570 root = doc.FirstChildElement(
"NEKTAR");
571 xmlCol = root->FirstChildElement(
"COLLECTIONS");
573 bool verbose =
false;
579 map<LibUtilities::ShapeType, int> ShapeMaxSize;
582 bool updateShape =
true;
587 if (ShapeMaxSize.count(shape))
589 int ngeoms = opimp.first.GetNGeoms();
590 if (ngeoms > ShapeMaxSize[shape])
592 ShapeMaxSize[shape] = ngeoms;
602 for (
auto &op : opimp.second)
604 global[op.first][
ElmtOrder(shape, -1)] = op.second;
613 for (
auto &op : global)
618 for (
auto &el : op.second)
620 ElmtImp[el.first.first] = el.second;
621 ElmtDef[el.first.first] =
true;
631 if ((ElmtImp[i] != -1) && (ElmtDef[i] ==
false))
647 map<LibUtilities::ShapeType, string> ShapeLetMap = {
656 for (
auto &op : global)
658 TiXmlElement *ColOp =
new TiXmlElement(
"OPERATOR");
659 xmlCol->LinkEndChild(ColOp);
662 for (
auto &el : op.second)
664 TiXmlElement *ElmtOp =
new TiXmlElement(
"ELEMENT");
665 ColOp->LinkEndChild(ElmtOp);
667 ElmtOp->SetAttribute(
"TYPE", ShapeLetMap[el.first.first]);
668 ElmtOp->SetAttribute(
"ORDER",
"*");
669 ElmtOp->SetAttribute(
"IMPTYPE",
674 doc.SaveFile(outname);
#define ASSERTL0(condition, msg)
COLLECTIONS_EXPORT void Initialise(const OperatorType opType, StdRegions::FactorMap factors=StdRegions::NullFactorMap)
COLLECTIONS_EXPORT OperatorImpMap SetWithTimings(std::vector< StdRegions::StdExpansionSharedPtr > pGeom, OperatorImpMap &impTypes, bool verbose=true)
ImplementationType m_defaultType
COLLECTIONS_EXPORT void UpdateOptFile(std::string sessName, LibUtilities::CommSharedPtr &comm)
static std::map< OpImpTimingKey, OperatorImpMap > m_opImpMap
COLLECTIONS_EXPORT OperatorImpMap GetOperatorImpMap(StdRegions::StdExpansionSharedPtr pExp)
Get Operator Implementation Map from XMl or using default;.
std::map< OperatorType, std::map< ElmtOrder, ImplementationType > > GlobalOpMap
std::pair< LibUtilities::ShapeType, int > ElmtOrder
void ReadCollOps(TiXmlElement *xmlCol, GlobalOpMap &global, bool verbose)
unsigned int m_maxCollSize
NekDouble TimePerTest(unsigned int n)
Returns amount of seconds per iteration in a test with n iterations.
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.
std::map< OperatorType, ImplementationType > OperatorImpMap
const char *const ImplementationTypeMap[]
const char *const ImplementationTypeMap1[]
@ SIZE_ImplementationType
const char *const OperatorTypeMap[]
std::tuple< LibUtilities::ShapeType, OperatorType, ImplementationType, ExpansionIsNodal > OperatorKey
Key for describing an Operator.
OperatorFactory & GetOperatorFactory()
Returns the singleton Operator factory object.
const char *const OperatorTypeMap1[]
std::vector< Collection > CollectionVector
const char *const ShapeTypeMap[SIZE_ShapeType]
std::shared_ptr< SessionReader > SessionReaderSharedPtr
std::shared_ptr< Comm > CommSharedPtr
Pointer to a Communicator object.
constexpr unsigned int ShapeTypeDimMap[SIZE_ShapeType]
std::shared_ptr< StdExpansion > StdExpansionSharedPtr
std::map< ConstFactorType, NekDouble > ConstFactorMap
The above copyright notice and this permission notice shall be included.
int Imin(int n, const T *x, const int incx)
Return the index of the minimum element in x.