47 map<OpImpTimingKey,OperatorImpMap> CollectionOptimisation::m_opImpMap;
49 CollectionOptimisation::CollectionOptimisation(
54 map<ElmtOrder, ImplementationType> defaults;
55 map<ElmtOrder, ImplementationType> defaultsPhysDeriv;
57 bool verbose = (pSession.get()) &&
58 (pSession->DefinesCmdLineArgument(
"verbose")) &&
59 (pSession->GetComm()->GetRank() == 0);
66 map<string, LibUtilities::ShapeType> elTypes;
77 for (it2 = elTypes.begin(); it2 != elTypes.end(); ++it2)
79 defaults [
ElmtOrder(it2->second, -1)] = m_defaultType;
80 defaultsPhysDeriv [
ElmtOrder(it2->second, -1)] = m_defaultType;
85 for (it2 = elTypes.begin(); it2 != elTypes.end(); ++it2)
88 for (
int i = 1; i < 5; ++i)
97 for (
int i = 1; i < 3; ++i)
104 map<string, OperatorType> opTypes;
118 map<string, ImplementationType> impTypes;
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.");
131 TiXmlElement *xmlCol = master->FirstChildElement(
"COLLECTIONS");
137 const char *maxSize = xmlCol->Attribute(
"MAXSIZE");
138 m_maxCollSize = (maxSize ? atoi(maxSize) : 0);
140 const char *defaultImpl = xmlCol->Attribute(
"DEFAULT");
141 m_defaultType = defaultType;
147 const std::string collinfo = string(defaultImpl);
148 m_autotune = boost::iequals(collinfo,
"auto");
154 if(boost::iequals(collinfo,
162 ASSERTL0(i != Collections::SIZE_ImplementationType,
163 "Unknown default collection scheme: "+collinfo);
167 for (it2 = elTypes.begin(); it2 != elTypes.end(); ++it2)
169 defaults[
ElmtOrder(it2->second, -1)] = m_defaultType;
180 TiXmlElement *elmt = xmlCol->FirstChildElement();
185 string tagname = elmt->ValueStr();
187 ASSERTL0(boost::iequals(tagname,
"OPERATOR"),
188 "Only OPERATOR tags are supported inside the "
191 const char *attr = elmt->Attribute(
"TYPE");
192 ASSERTL0(attr,
"Missing TYPE in OPERATOR tag.");
196 "Unknown OPERATOR type " + opType +
".");
200 TiXmlElement *elmt2 = elmt->FirstChildElement();
204 string tagname = elmt2->ValueStr();
205 ASSERTL0(boost::iequals(tagname,
"ELEMENT"),
206 "Only ELEMENT tags are supported inside the "
209 const char *attr = elmt2->Attribute(
"TYPE");
210 ASSERTL0(attr,
"Missing TYPE in ELEMENT tag.");
213 it2 = elTypes.find(elType);
215 "Unknown element type "+elType+
" in ELEMENT "
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 +
".");
224 const char *attr3 = elmt2->Attribute(
"ORDER");
225 ASSERTL0(attr3,
"Missing ORDER in ELEMENT tag.");
235 vector<unsigned int> orders;
236 ParseUtils::GenerateSeqVector(order.c_str(), orders);
238 for (
int i = 0; i < orders.size(); ++i)
240 m_global[ot][
ElmtOrder(it2->second, orders[i])]
245 elmt2 = elmt2->NextSiblingElement();
248 elmt = elmt->NextSiblingElement();
254 if (!m_setByXml && !m_autotune)
256 cout <<
"Setting Collection optimisation using: "
266 for (mIt = m_global.begin(); mIt != m_global.end(); mIt++)
271 for (eIt = mIt->second.begin();
272 eIt != mIt->second.end(); eIt++)
276 <<
" order " << eIt->first.second <<
" -> "
289 map<OperatorType, map<ElmtOrder, ImplementationType> >
::iterator it;
293 ElmtOrder searchKey(pExp->DetShapeType(),
294 pExp->GetBasisNumModes(0));
295 ElmtOrder defSearch(pExp->DetShapeType(), -1);
297 for (it = m_global.begin(); it != m_global.end(); ++it)
301 it2 = it->second.find(searchKey);
303 if (it2 == it->second.end())
305 it2 = it->second.find(defSearch);
306 if (it2 == it->second.end())
313 impType = it2->second;
318 impType = it2->second;
321 ret[it->first] = impType;
328 vector<StdRegions::StdExpansionSharedPtr> pCollExp,
338 if(m_opImpMap.count(OpKey) != 0)
340 ret = m_opImpMap[OpKey];
344 int maxsize = pCollExp.size()*max(pExp->GetNcoeffs(),pExp->GetTotPoints());
354 cout <<
"Collection Implemenation for "
356 for(
int i = 0; i < pExp->GetNumBases(); ++i)
358 cout << pExp->GetBasis(i)->GetNumModes() <<
" ";
360 cout <<
")" <<
" for ngeoms = " << pCollExp.size() << endl;
371 OperatorKey opKey(pCollExp[0]->DetShapeType(), opType, impType,
372 pCollExp[0]->IsNodalNonTensorialExp());
376 impTypes[opType] = impType;
380 cout <<
"Note: Implementation does not exist: " << opKey << endl;
385 coll.push_back(collloc);
395 coll[0].ApplyOperator(OpType,
404 Ntest[i] = max((
int)(0.25/oneTest),1);
414 for (
int imp = 0; imp < coll.size(); ++imp)
416 if (coll[imp].HasOperator(OpType))
419 for(
int n = 0; n < Ntest[i]; ++n)
421 coll[imp].ApplyOperator(OpType,
432 timing[imp] = 1000.0;
443 for(
int j = 0; j < coll.size(); ++j)
445 if (timing[j] > 999.0)
453 if(j != coll.size()-1)
467 m_opImpMap[OpKey] = ret;
#define ASSERTL0(condition, msg)
const char *const ImplementationTypeMap[]
boost::tuple< LibUtilities::ShapeType, OperatorType, ImplementationType, ExpansionIsNodal > OperatorKey
Key for describing an Operator.
std::vector< Collection > CollectionVector
int Imin(int n, const T *x, const int incx)
Return the index of the minimum element in x.
boost::shared_ptr< SessionReader > SessionReaderSharedPtr
const char *const OperatorTypeMap[]
const char *const ShapeTypeMap[]
std::map< OperatorType, ImplementationType > OperatorImpMap
OperatorFactory & GetOperatorFactory()
Returns the singleton Operator factory object.
StandardMatrixTag boost::call_traits< LhsDataType >::const_reference rhs typedef NekMatrix< LhsDataType, StandardMatrixTag >::iterator iterator
boost::shared_ptr< StdExpansion > StdExpansionSharedPtr
std::pair< LibUtilities::ShapeType, int > ElmtOrder
NekDouble TimePerTest(unsigned int n)
Returns amount of seconds per iteration in a test with n iterations.