Skip to content

Commit a14e06f

Browse files
committed
Merge branch 'fix/collections-autotuning' into 'master'
Fix/collections autotuning Contrary to its name, this MR actually sets the code to use Collections by default. Current policy is to use StdMat approach when P<5 and IterPerExp otherwise. This can still be overridden in the XML file and autotuning can optionally be turned on if desired. See merge request !476
2 parents 412eb07 + 6aa18d0 commit a14e06f

File tree

4 files changed

+94
-24
lines changed

4 files changed

+94
-24
lines changed

library/Collections/Collection.cpp

+10-9
Original file line numberDiff line numberDiff line change
@@ -57,19 +57,20 @@ Collection::Collection(
5757
OperatorType opType = (OperatorType)i;
5858
ImplementationType impType;
5959

60-
it = impTypes.find(opType);
61-
impType = it == impTypes.end() ? eIterPerExp : it->second;
60+
if ((it = impTypes.find(opType)) != impTypes.end())
61+
{
62+
impType = it->second;
63+
OperatorKey opKey(pCollExp[0]->DetShapeType(), opType, impType,
64+
pCollExp[0]->IsNodalNonTensorialExp());
6265

63-
OperatorKey opKey(pCollExp[0]->DetShapeType(), opType, impType,
64-
pCollExp[0]->IsNodalNonTensorialExp());
65-
66-
stringstream ss;
67-
ss << opKey;
68-
ASSERTL0(GetOperatorFactory().ModuleExists(opKey),
66+
stringstream ss;
67+
ss << opKey;
68+
ASSERTL0(GetOperatorFactory().ModuleExists(opKey),
6969
"Requested unknown operator "+ss.str());
7070

71-
m_ops[opType] = GetOperatorFactory().CreateInstance(
71+
m_ops[opType] = GetOperatorFactory().CreateInstance(
7272
opKey, pCollExp, m_geomData);
73+
}
7374
}
7475
}
7576

library/Collections/Collection.h

+7
Original file line numberDiff line numberDiff line change
@@ -77,6 +77,8 @@ class Collection
7777
Array<OneD, NekDouble> &output1,
7878
Array<OneD, NekDouble> &output2);
7979

80+
inline bool HasOperator(const OperatorType &op);
81+
8082
protected:
8183
StdRegions::StdExpansionSharedPtr m_stdExp;
8284
vector<SpatialDomains::GeometrySharedPtr> m_geom;
@@ -131,6 +133,11 @@ inline void Collection::ApplyOperator(
131133
(*m_ops[op])(inarray, output0, output1, output2, wsp);
132134
}
133135

136+
inline bool Collection::HasOperator(const OperatorType &op)
137+
{
138+
return (m_ops.find(op) != m_ops.end());
139+
}
140+
134141
}
135142
}
136143

library/Collections/CollectionOptimisation.cpp

+73-11
Original file line numberDiff line numberDiff line change
@@ -50,6 +50,7 @@ CollectionOptimisation::CollectionOptimisation(
5050
{
5151
int i;
5252
map<ElmtOrder, ImplementationType> defaults;
53+
map<ElmtOrder, ImplementationType> defaultsPhysDeriv;
5354
map<ElmtOrder, ImplementationType>::iterator it;
5455
bool verbose = (pSession.get()) &&
5556
(pSession->DefinesCmdLineArgument("verbose")) &&
@@ -58,7 +59,7 @@ CollectionOptimisation::CollectionOptimisation(
5859
m_setByXml = false;
5960
m_autotune = false;
6061
m_maxCollSize = 0;
61-
m_defaultType = defaultType == eNoImpType ? eNoCollection : defaultType;
62+
m_defaultType = defaultType == eNoImpType ? eIterPerExp : defaultType;
6263

6364
map<string, LibUtilities::ShapeType> elTypes;
6465
map<string, LibUtilities::ShapeType>::iterator it2;
@@ -73,14 +74,38 @@ CollectionOptimisation::CollectionOptimisation(
7374
// Set defaults for all element types.
7475
for (it2 = elTypes.begin(); it2 != elTypes.end(); ++it2)
7576
{
76-
defaults[ElmtOrder(it2->second, -1)] = m_defaultType;
77+
defaults [ElmtOrder(it2->second, -1)] = m_defaultType;
78+
defaultsPhysDeriv [ElmtOrder(it2->second, -1)] = m_defaultType;
79+
}
80+
81+
if (defaultType == eNoImpType)
82+
{
83+
for (it2 = elTypes.begin(); it2 != elTypes.end(); ++it2)
84+
{
85+
defaultsPhysDeriv [ElmtOrder(it2->second, -1)] = eNoCollection;
86+
for (int i = 1; i < 5; ++i)
87+
{
88+
defaults[ElmtOrder(it2->second, i)] = eStdMat;
89+
}
90+
for (int i = 1; i < 3; ++i)
91+
{
92+
defaultsPhysDeriv[ElmtOrder(it2->second, i)] = eSumFac;
93+
}
94+
}
7795
}
7896

7997
map<string, OperatorType> opTypes;
8098
for (i = 0; i < SIZE_OperatorType; ++i)
8199
{
82100
opTypes[OperatorTypeMap[i]] = (OperatorType)i;
83-
m_global[(OperatorType)i] = defaults;
101+
switch ((OperatorType)i)
102+
{
103+
case ePhysDeriv:
104+
m_global[(OperatorType)i] = defaultsPhysDeriv;
105+
break;
106+
default:
107+
m_global[(OperatorType)i] = defaults;
108+
}
84109
}
85110

86111
map<string, ImplementationType> impTypes;
@@ -98,17 +123,23 @@ CollectionOptimisation::CollectionOptimisation(
98123

99124
TiXmlElement *xmlCol = master->FirstChildElement("COLLECTIONS");
100125

126+
// Check if user has specified some options
101127
if (xmlCol)
102128
{
129+
// Set the maxsize and default implementation type if provided
103130
const char *maxSize = xmlCol->Attribute("MAXSIZE");
104131
m_maxCollSize = (maxSize ? atoi(maxSize) : 0);
105132

106133
const char *defaultImpl = xmlCol->Attribute("DEFAULT");
107134
m_defaultType = defaultType;
135+
136+
// If user has specified a default impl type, autotuning
137+
// and set this default across all operators.
108138
if (defaultType == eNoImpType && defaultImpl)
109139
{
110140
const std::string collinfo = string(defaultImpl);
111141
m_autotune = boost::iequals(collinfo, "auto");
142+
112143
if (!m_autotune)
113144
{
114145
for(i = 1; i < Collections::SIZE_ImplementationType; ++i)
@@ -122,7 +153,7 @@ CollectionOptimisation::CollectionOptimisation(
122153
}
123154

124155
ASSERTL0(i != Collections::SIZE_ImplementationType,
125-
"Unknown default collection scheme: "+collinfo);
156+
"Unknown default collection scheme: "+collinfo);
126157

127158
// Override default types
128159
for (it2 = elTypes.begin(); it2 != elTypes.end(); ++it2)
@@ -137,6 +168,7 @@ CollectionOptimisation::CollectionOptimisation(
137168
}
138169
}
139170

171+
// Now process operator-specific implementation selections
140172
TiXmlElement *elmt = xmlCol->FirstChildElement();
141173
while (elmt)
142174
{
@@ -323,7 +355,23 @@ OperatorImpMap CollectionOptimisation::SetWithTimings(
323355
CollectionVector coll;
324356
for(int imp = 1; imp < SIZE_ImplementationType; ++imp)
325357
{
326-
OperatorImpMap impTypes = SetFixedImpType((ImplementationType) imp);
358+
ImplementationType impType = (ImplementationType)imp;
359+
OperatorImpMap impTypes;
360+
for (int i = 0; i < SIZE_OperatorType; ++i)
361+
{
362+
OperatorType opType = (OperatorType)i;
363+
OperatorKey opKey(pCollExp[0]->DetShapeType(), opType, impType,
364+
pCollExp[0]->IsNodalNonTensorialExp());
365+
366+
if (GetOperatorFactory().ModuleExists(opKey))
367+
{
368+
impTypes[opType] = impType;
369+
}
370+
else
371+
{
372+
cout << "Note: Implementation does not exist: " << opKey << endl;
373+
}
374+
}
327375

328376
Collection collloc(pCollExp,impTypes);
329377
coll.push_back(collloc);
@@ -357,17 +405,24 @@ OperatorImpMap CollectionOptimisation::SetWithTimings(
357405
// call collection implementation in thorugh ExpList.
358406
for (int imp = 0; imp < coll.size(); ++imp)
359407
{
360-
t.Start();
361-
for(int n = 0; n < Ntest[i]; ++n)
408+
if (coll[imp].HasOperator(OpType))
362409
{
363-
coll[imp].ApplyOperator(OpType,
410+
t.Start();
411+
for(int n = 0; n < Ntest[i]; ++n)
412+
{
413+
coll[imp].ApplyOperator(OpType,
364414
inarray,
365415
outarray1,
366416
outarray2,
367417
outarray3);
418+
}
419+
t.Stop();
420+
timing[imp] = t.TimePerTest(Ntest[i]);
421+
}
422+
else
423+
{
424+
timing[imp] = 1000.0;
368425
}
369-
t.Stop();
370-
timing[imp] = t.TimePerTest(Ntest[i]);
371426
}
372427
// determine optimal implementation. Note +1 to
373428
// remove NoImplementationType flag
@@ -379,7 +434,14 @@ OperatorImpMap CollectionOptimisation::SetWithTimings(
379434
<< ImplementationTypeMap[minImp] << "\t (";
380435
for(int j = 0; j < coll.size(); ++j)
381436
{
382-
cout << timing[j] ;
437+
if (timing[j] > 999.0)
438+
{
439+
cout << "-";
440+
}
441+
else
442+
{
443+
cout << timing[j] ;
444+
}
383445
if(j != coll.size()-1)
384446
{
385447
cout <<", ";

library/Collections/Operator.cpp

+4-4
Original file line numberDiff line numberDiff line change
@@ -88,10 +88,10 @@ bool operator< (OperatorKey const &p1, OperatorKey const &p2)
8888
*/
8989
std::ostream &operator<<(std::ostream &os, OperatorKey const &p)
9090
{
91-
os << boost::get<0>(p) << " "
92-
<< OperatorTypeMap [boost::get<1>(p)] << " "
93-
<< ImplementationTypeMap[boost::get<2>(p)] << " "
94-
<< ImplementationTypeMap[boost::get<3>(p)];
91+
os << LibUtilities::ShapeTypeMap[boost::get<0>(p)] << ", "
92+
<< OperatorTypeMap [boost::get<1>(p)] << ", "
93+
<< ImplementationTypeMap [boost::get<2>(p)] << ", "
94+
<< (boost::get<3>(p) ? "Nodal" : "Modal");
9595
return os;
9696
}
9797

0 commit comments

Comments
 (0)