From 98fad7cc2a54e63ca50bf74cc4992f94fb5b401f Mon Sep 17 00:00:00 2001 From: Jessica Shi Date: Mon, 6 Jul 2020 04:25:34 -0400 Subject: [PATCH 01/12] add scheduling commands to command line tool --- tools/taco.cpp | 153 ++++++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 152 insertions(+), 1 deletion(-) diff --git a/tools/taco.cpp b/tools/taco.cpp index 16ded8406..ac1928597 100644 --- a/tools/taco.cpp +++ b/tools/taco.cpp @@ -201,6 +201,134 @@ static void printCommandLine(ostream& os, int argc, char* argv[]) { } } +static void setSchedulingCommands(istream& in, ostream& out, parser::Parser& parser, IndexStmt& stmt) { + map addedVars; + auto findVar = [&parser, &addedVars](string name) { + if (parser.hasIndexVar(name)) { + return parser.getIndexVar(name); + } else if (util::contains(addedVars, name)) { + return addedVars.at(name); + } + + throw "Index variable not defined in statement."; + }; + + auto getInput = [&in, &out](string prompt, auto &var) { + out << prompt; + in >> var; + }; + + out << endl << "To exit, input 'q'." << endl << endl; + while (true) { + string command; + getInput("Enter a command: ", command); + + if (command == "split") { + string i, i1, i2; + getInput("Enter the index variable to split: ", i); + getInput("Enter the split outer index variable: ", i1); + getInput("Enter the split inner index variable: ", i2); + + size_t splitFactor; + getInput("Enter the split factor: ", splitFactor); + + try { + IndexVar split1(i1); + IndexVar split2(i2); + addedVars.insert({i1, split1}); + addedVars.insert({i2, split2}); + stmt = stmt.split(findVar(i), split1, split2, splitFactor); + } catch (const char* msg) { + out << msg << endl; + } + } else if (command == "fuse") { + string i, j, f; + getInput("Enter the outer index variable to fuse: ", i); + getInput("Enter the inner index variable to fuse: ", j); + getInput("Enter the fused index variable: ", f); + + try { + IndexVar fused(f); + addedVars.insert({f, fused}); + stmt = stmt.fuse(findVar(i), findVar(j), fused); + } catch (const char* msg) { + out << msg << endl; + } + } else if (command == "pos") { + string i, ipos; + getInput("Enter the index variable to transform: ", i); + getInput("Enter the derived position index variable: ", ipos); + + string tensor; + getInput("Enter the tensor to perform the position cut on: ", tensor); + + for (auto a : getArgumentAccesses(stmt)) { + if (a.getTensorVar().getName() == tensor) { + try { + IndexVar derived(ipos); + addedVars.insert({ipos, derived}); + stmt = stmt.pos(findVar(i), derived, a); + goto end; + } catch (const char* msg) { + out << msg << endl; + } + } + } + out << "Tensor access not defined in statement." << endl; + } else if (command == "parallelize") { + string i, unit, strategy; + getInput("Enter the index variable to parallelize: ", i); + getInput("Enter the type of parallel hardware: ", unit); + getInput("Enter the race strategy: ", strategy); + + ParallelUnit parallel_unit; + if (unit == "NotParallel") { + parallel_unit = ParallelUnit::NotParallel; + } else if (unit == "DefaultUnit") { + parallel_unit = ParallelUnit::DefaultUnit; + } else if (unit == "CPUThread") { + parallel_unit = ParallelUnit::CPUThread; + } else if (unit == "CPUVector") { + parallel_unit = ParallelUnit::CPUVector; + } else { + out << "Parallel hardware not defined." << endl; + goto end; + } + + OutputRaceStrategy output_race_strategy; + if (strategy == "IgnoreRaces") { + output_race_strategy = OutputRaceStrategy::IgnoreRaces; + } else if (strategy == "NoRaces") { + output_race_strategy = OutputRaceStrategy::NoRaces; + } else if (strategy == "Atomics") { + output_race_strategy = OutputRaceStrategy::Atomics; + } else if (strategy == "Temporary") { + output_race_strategy = OutputRaceStrategy::Temporary; + } else if (strategy == "ParallelReduction") { + output_race_strategy = OutputRaceStrategy::ParallelReduction; + } else { + out << "Race strategy not defined." << endl; + goto end; + } + + try { + stmt = stmt.parallelize(findVar(i), parallel_unit, output_race_strategy); + } catch (const char* msg) { + out << msg << endl; + } + } else if (command == "q") { + break; + } else { + out << "Not a valid command"; + break; + } + + end: out << endl; + } + + out << endl << endl; +} + int main(int argc, char* argv[]) { if (argc < 2) { printUsageInfo(); @@ -228,6 +356,9 @@ int main(int argc, char* argv[]) { bool readKernels = false; bool cuda = false; + bool setScheduleInteractive = false; + bool setScheduleManual = false; + ParallelSchedule sched = ParallelSchedule::Static; int chunkSize = 0; int nthreads = 0; @@ -256,6 +387,8 @@ int main(int argc, char* argv[]) { vector kernelFilenames; + stringstream scheduleStream; + for (int i = 1; i < argc; i++) { string arg = argv[i]; vector argparts = util::split(arg, "="); @@ -542,6 +675,16 @@ int main(int argc, char* argv[]) { else if ("-print-kernels" == argName) { printKernels = true; } + else if ("-set-schedule" == argName) { + if (argValue.empty()) { + setScheduleInteractive = true; + } else { + setScheduleManual = true; + replace(argValue.begin(), argValue.end(), '-', ' '); + scheduleStream << argValue; + scheduleStream << " q"; + } + } else { if (exprStr.size() != 0) { printUsageInfo(); @@ -644,6 +787,14 @@ int main(int argc, char* argv[]) { stmt = reorderLoopsTopologically(stmt); stmt = insertTemporaries(stmt); stmt = parallelizeOuterLoop(stmt); + + if (setScheduleInteractive) { + setSchedulingCommands(cin, cout, parser, stmt); + } else if (setScheduleManual) { + stringstream throwaway; + setSchedulingCommands(scheduleStream, throwaway, parser, stmt); + } + if (printConcrete) { cout << stmt << endl; } @@ -747,7 +898,7 @@ int main(int argc, char* argv[]) { " * For both, the `_COO_pos` arrays contain two elements, where the first is 0\n" " * and the second is the number of nonzeros in the tensor.\n" " */"; - + vector packs; for (auto a : getArgumentAccesses(stmt)) { TensorVar tensor = a.getTensorVar(); From d15a7e1b26d2edd8c58c2be04677b28d2bde54a7 Mon Sep 17 00:00:00 2001 From: Jessica Shi Date: Tue, 14 Jul 2020 11:36:47 -0400 Subject: [PATCH 02/12] replace try-catch with taco_uerror, add bound --- tools/taco.cpp | 116 ++++++++++++++++++++++++++++++++++++------------- 1 file changed, 85 insertions(+), 31 deletions(-) diff --git a/tools/taco.cpp b/tools/taco.cpp index ac1928597..51bad0044 100644 --- a/tools/taco.cpp +++ b/tools/taco.cpp @@ -210,7 +210,7 @@ static void setSchedulingCommands(istream& in, ostream& out, parser::Parser& par return addedVars.at(name); } - throw "Index variable not defined in statement."; + taco_uerror << "Index variable not defined in statement."; }; auto getInput = [&in, &out](string prompt, auto &var) { @@ -232,28 +232,44 @@ static void setSchedulingCommands(istream& in, ostream& out, parser::Parser& par size_t splitFactor; getInput("Enter the split factor: ", splitFactor); - try { - IndexVar split1(i1); - IndexVar split2(i2); - addedVars.insert({i1, split1}); - addedVars.insert({i2, split2}); - stmt = stmt.split(findVar(i), split1, split2, splitFactor); - } catch (const char* msg) { - out << msg << endl; - } + IndexVar split1(i1); + IndexVar split2(i2); + addedVars.insert({i1, split1}); + addedVars.insert({i2, split2}); + stmt = stmt.split(findVar(i), split1, split2, splitFactor); + + } else if (command == "divide") { + string i, i1, i2; + getInput("Enter the index variable to divide: ", i); + getInput("Enter the divided outer index variable: ", i1); + getInput("Enter the divided inner index variable: ", i2); + + size_t divideFactor; + getInput("Enter the divide factor: ", divideFactor); + + IndexVar divide1(i1); + IndexVar divide2(i2); + addedVars.insert({i1, divide1}); + addedVars.insert({i2, divide2}); + stmt = stmt.divide(findVar(i), divide1, divide2, divideFactor); + + } else if (command == "reorder") { + string i, j; + getInput("Enter an index variable to reorder: ", i); + getInput("Enter an index variable to reorder: ", j); + + stmt = stmt.reorder(findVar(i), findVar(j)); + } else if (command == "fuse") { string i, j, f; getInput("Enter the outer index variable to fuse: ", i); getInput("Enter the inner index variable to fuse: ", j); getInput("Enter the fused index variable: ", f); - try { - IndexVar fused(f); - addedVars.insert({f, fused}); - stmt = stmt.fuse(findVar(i), findVar(j), fused); - } catch (const char* msg) { - out << msg << endl; - } + IndexVar fused(f); + addedVars.insert({f, fused}); + stmt = stmt.fuse(findVar(i), findVar(j), fused); + } else if (command == "pos") { string i, ipos; getInput("Enter the index variable to transform: ", i); @@ -264,17 +280,14 @@ static void setSchedulingCommands(istream& in, ostream& out, parser::Parser& par for (auto a : getArgumentAccesses(stmt)) { if (a.getTensorVar().getName() == tensor) { - try { - IndexVar derived(ipos); - addedVars.insert({ipos, derived}); - stmt = stmt.pos(findVar(i), derived, a); - goto end; - } catch (const char* msg) { - out << msg << endl; - } + IndexVar derived(ipos); + addedVars.insert({ipos, derived}); + stmt = stmt.pos(findVar(i), derived, a); + goto end; } } out << "Tensor access not defined in statement." << endl; + } else if (command == "parallelize") { string i, unit, strategy; getInput("Enter the index variable to parallelize: ", i); @@ -311,11 +324,46 @@ static void setSchedulingCommands(istream& in, ostream& out, parser::Parser& par goto end; } - try { - stmt = stmt.parallelize(findVar(i), parallel_unit, output_race_strategy); - } catch (const char* msg) { - out << msg << endl; + stmt = stmt.parallelize(findVar(i), parallel_unit, output_race_strategy); + + } else if (command == "bound") { + string i, i1; + getInput("Enter the index variable to bound: ", i); + getInput("Enter the bounded index variable: ", i1); + + size_t bound; + getInput("Enter the value to bound by: ", bound); + + string type; + getInput("Enter the bound type: ", type); + + BoundType bound_type; + if (type == "MinExact") { + bound_type = BoundType::MinExact; + } else if (type == "MinConstraint") { + bound_type = BoundType::MinConstraint; + } else if (type == "MaxExact") { + bound_type = BoundType::MaxExact; + } else if (type == "MaxConstraint") { + bound_type = BoundType::MaxConstraint; + } else { + out << "Bound type not defined." << endl; + goto end; } + + IndexVar bound1(i1); + addedVars.insert({i1, bound1}); + stmt = stmt.bound(findVar(i), bound1, bound, bound_type); + + } else if (command == "unroll") { + string i; + getInput("Enter the index variable to unroll: ", i); + + size_t unrollFactor; + getInput("Enter the unroll factor: ", unrollFactor); + + stmt = stmt.unroll(findVar(i), unrollFactor); + } else if (command == "q") { break; } else { @@ -790,9 +838,15 @@ int main(int argc, char* argv[]) { if (setScheduleInteractive) { setSchedulingCommands(cin, cout, parser, stmt); - } else if (setScheduleManual) { + } else if (setScheduleManual) { // TEMPORARY FIX TODO stringstream throwaway; - setSchedulingCommands(scheduleStream, throwaway, parser, stmt); + try { + setSchedulingCommands(scheduleStream, throwaway, parser, stmt); + } catch (TacoException e) { + string msg = string(e.what()); + msg = msg.insert(msg.find(":\n") + 3, "Cannot implement schedule: "); + throw TacoException(msg); + } } if (printConcrete) { From c179d51c44bc2db6593858fda10d66f2e58578b8 Mon Sep 17 00:00:00 2001 From: Jessica Shi Date: Tue, 21 Jul 2020 21:31:13 -0400 Subject: [PATCH 03/12] reorder ifelseifs --- tools/taco.cpp | 171 ++++++++++++++++++++++++++++++------------------- 1 file changed, 104 insertions(+), 67 deletions(-) diff --git a/tools/taco.cpp b/tools/taco.cpp index 51bad0044..05eef4e02 100644 --- a/tools/taco.cpp +++ b/tools/taco.cpp @@ -27,7 +27,8 @@ #include "taco/util/env.h" #include "taco/util/collections.h" #include "taco/cuda.h" -#include +#include "taco/index_notation/transformations.h" +#include "taco/index_notation/index_notation_visitor.h" using namespace std; using namespace taco; @@ -223,7 +224,35 @@ static void setSchedulingCommands(istream& in, ostream& out, parser::Parser& par string command; getInput("Enter a command: ", command); - if (command == "split") { + if (command == "pos") { + string i, ipos; + getInput("Enter the index variable to transform: ", i); + getInput("Enter the derived position index variable: ", ipos); + + string tensor; + getInput("Enter the tensor to perform the position cut on: ", tensor); + + for (auto a : getArgumentAccesses(stmt)) { + if (a.getTensorVar().getName() == tensor) { + IndexVar derived(ipos); + addedVars.insert({ipos, derived}); + stmt = stmt.pos(findVar(i), derived, a); + goto end; + } + } + out << "Tensor access not defined in statement." << endl; + + } else if (command == "fuse") { + string i, j, f; + getInput("Enter the outer index variable to fuse: ", i); + getInput("Enter the inner index variable to fuse: ", j); + getInput("Enter the fused index variable: ", f); + + IndexVar fused(f); + addedVars.insert({f, fused}); + stmt = stmt.fuse(findVar(i), findVar(j), fused); + + } else if (command == "split") { string i, i1, i2; getInput("Enter the index variable to split: ", i); getInput("Enter the split outer index variable: ", i1); @@ -253,78 +282,48 @@ static void setSchedulingCommands(istream& in, ostream& out, parser::Parser& par addedVars.insert({i2, divide2}); stmt = stmt.divide(findVar(i), divide1, divide2, divideFactor); - } else if (command == "reorder") { - string i, j; - getInput("Enter an index variable to reorder: ", i); - getInput("Enter an index variable to reorder: ", j); - - stmt = stmt.reorder(findVar(i), findVar(j)); - - } else if (command == "fuse") { - string i, j, f; - getInput("Enter the outer index variable to fuse: ", i); - getInput("Enter the inner index variable to fuse: ", j); - getInput("Enter the fused index variable: ", f); + } else if (command == "precompute") { + string i, iw; + getInput("Enter the index variable to precompute over: ", i); + getInput("Enter the index variable to precompute with: ", iw); // FIX TODO? - IndexVar fused(f); - addedVars.insert({f, fused}); - stmt = stmt.fuse(findVar(i), findVar(j), fused); + IndexVar orig = findVar(i); + IndexVar pre; + try { + pre = findVar(iw); + } catch (exception& e) { + pre = IndexVar(iw); + addedVars.insert({iw, pre}); + } - } else if (command == "pos") { - string i, ipos; - getInput("Enter the index variable to transform: ", i); - getInput("Enter the derived position index variable: ", ipos); + struct GetRhs : public IndexNotationVisitor { + using IndexNotationVisitor::visit; + IndexExpr rhs; - string tensor; - getInput("Enter the tensor to perform the position cut on: ", tensor); + void visit(const AssignmentNode* node) { + rhs = Assignment(node).getRhs(); + } + }; - for (auto a : getArgumentAccesses(stmt)) { - if (a.getTensorVar().getName() == tensor) { - IndexVar derived(ipos); - addedVars.insert({ipos, derived}); - stmt = stmt.pos(findVar(i), derived, a); - goto end; - } - } - out << "Tensor access not defined in statement." << endl; + GetRhs visitor; + stmt.accept(&visitor); + IndexExpr rhs = visitor.rhs; - } else if (command == "parallelize") { - string i, unit, strategy; - getInput("Enter the index variable to parallelize: ", i); - getInput("Enter the type of parallel hardware: ", unit); - getInput("Enter the race strategy: ", strategy); + TensorVar workspace("workspacce", Type(Float64, {Dimension(42)}), Dense); + stmt = stmt.precompute(rhs, orig, pre, workspace); - ParallelUnit parallel_unit; - if (unit == "NotParallel") { - parallel_unit = ParallelUnit::NotParallel; - } else if (unit == "DefaultUnit") { - parallel_unit = ParallelUnit::DefaultUnit; - } else if (unit == "CPUThread") { - parallel_unit = ParallelUnit::CPUThread; - } else if (unit == "CPUVector") { - parallel_unit = ParallelUnit::CPUVector; - } else { - out << "Parallel hardware not defined." << endl; - goto end; - } - - OutputRaceStrategy output_race_strategy; - if (strategy == "IgnoreRaces") { - output_race_strategy = OutputRaceStrategy::IgnoreRaces; - } else if (strategy == "NoRaces") { - output_race_strategy = OutputRaceStrategy::NoRaces; - } else if (strategy == "Atomics") { - output_race_strategy = OutputRaceStrategy::Atomics; - } else if (strategy == "Temporary") { - output_race_strategy = OutputRaceStrategy::Temporary; - } else if (strategy == "ParallelReduction") { - output_race_strategy = OutputRaceStrategy::ParallelReduction; - } else { - out << "Race strategy not defined." << endl; - goto end; + } else if (command == "reorder") { + int n; + getInput("Enter the number of index variables to reorder: ", n); + + vector reorderedVars; + for (int i = 0; i < n; i++) { + string var; + getInput("Enter an index variable to reorder: ", var); + reorderedVars.push_back(findVar(var)); } - stmt = stmt.parallelize(findVar(i), parallel_unit, output_race_strategy); + stmt = stmt.reorder(reorderedVars); } else if (command == "bound") { string i, i1; @@ -364,6 +363,44 @@ static void setSchedulingCommands(istream& in, ostream& out, parser::Parser& par stmt = stmt.unroll(findVar(i), unrollFactor); + } else if (command == "parallelize") { + string i, unit, strategy; + getInput("Enter the index variable to parallelize: ", i); + getInput("Enter the type of parallel hardware: ", unit); + getInput("Enter the race strategy: ", strategy); + + ParallelUnit parallel_unit; + if (unit == "NotParallel") { + parallel_unit = ParallelUnit::NotParallel; + } else if (unit == "DefaultUnit") { + parallel_unit = ParallelUnit::DefaultUnit; + } else if (unit == "CPUThread") { + parallel_unit = ParallelUnit::CPUThread; + } else if (unit == "CPUVector") { + parallel_unit = ParallelUnit::CPUVector; + } else { + out << "Parallel hardware not defined." << endl; + goto end; + } + + OutputRaceStrategy output_race_strategy; + if (strategy == "IgnoreRaces") { + output_race_strategy = OutputRaceStrategy::IgnoreRaces; + } else if (strategy == "NoRaces") { + output_race_strategy = OutputRaceStrategy::NoRaces; + } else if (strategy == "Atomics") { + output_race_strategy = OutputRaceStrategy::Atomics; + } else if (strategy == "Temporary") { + output_race_strategy = OutputRaceStrategy::Temporary; + } else if (strategy == "ParallelReduction") { + output_race_strategy = OutputRaceStrategy::ParallelReduction; + } else { + out << "Race strategy not defined." << endl; + goto end; + } + + stmt = stmt.parallelize(findVar(i), parallel_unit, output_race_strategy); + } else if (command == "q") { break; } else { @@ -844,7 +881,7 @@ int main(int argc, char* argv[]) { setSchedulingCommands(scheduleStream, throwaway, parser, stmt); } catch (TacoException e) { string msg = string(e.what()); - msg = msg.insert(msg.find(":\n") + 3, "Cannot implement schedule: "); + msg = msg.insert(msg.find(":\n") + 3, "Error with provided schedule: "); throw TacoException(msg); } } From 460bb2f9339d3308bc2f5cfc9cbf84318c3c0cb3 Mon Sep 17 00:00:00 2001 From: Jessica Shi Date: Tue, 28 Jul 2020 23:45:57 -0400 Subject: [PATCH 04/12] change precompute to parse arbitrary expression --- tools/taco.cpp | 69 ++++++++++++++++++++++++++++++++++++++++++-------- 1 file changed, 58 insertions(+), 11 deletions(-) diff --git a/tools/taco.cpp b/tools/taco.cpp index 05eef4e02..cc7d4bf79 100644 --- a/tools/taco.cpp +++ b/tools/taco.cpp @@ -29,6 +29,7 @@ #include "taco/cuda.h" #include "taco/index_notation/transformations.h" #include "taco/index_notation/index_notation_visitor.h" +#include "taco/index_notation/index_notation_nodes.h" using namespace std; using namespace taco; @@ -283,9 +284,9 @@ static void setSchedulingCommands(istream& in, ostream& out, parser::Parser& par stmt = stmt.divide(findVar(i), divide1, divide2, divideFactor); } else if (command == "precompute") { - string i, iw; + string i, iw, exprStr; getInput("Enter the index variable to precompute over: ", i); - getInput("Enter the index variable to precompute with: ", iw); // FIX TODO? + getInput("Enter the index variable to precompute with: ", iw); IndexVar orig = findVar(i); IndexVar pre; @@ -296,21 +297,67 @@ static void setSchedulingCommands(istream& in, ostream& out, parser::Parser& par addedVars.insert({iw, pre}); } - struct GetRhs : public IndexNotationVisitor { + out << "Enter the expression to precompute: "; + in.ignore(); + getline(in, exprStr); + + struct GetExpr : public IndexNotationVisitor { using IndexNotationVisitor::visit; - IndexExpr rhs; + + string exprStr; + IndexExpr expr; + + void setExprStr(string input) { + exprStr = input; + exprStr.erase(remove(exprStr.begin(), exprStr.end(), ' ')); + } + + string toString(IndexExpr e) { + stringstream tempStream; + tempStream << e; + string tempStr = tempStream.str(); + tempStr.erase(remove(tempStr.begin(), tempStr.end(), ' ')); + return tempStr; + } + + void visit(const AccessNode* node) { + IndexExpr currentExpr(node); + if (toString(currentExpr) == exprStr) { + expr = currentExpr; + } + else { + IndexNotationVisitor::visit(node); + } + } - void visit(const AssignmentNode* node) { - rhs = Assignment(node).getRhs(); - } + void visit(const UnaryExprNode* node) { + IndexExpr currentExpr(node); + if (toString(currentExpr) == exprStr) { + expr = currentExpr; + } + else { + IndexNotationVisitor::visit(node); + } + } + + void visit(const BinaryExprNode* node) { + IndexExpr currentExpr(node); + if (toString(currentExpr) == exprStr) { + expr = currentExpr; + } + else { + IndexNotationVisitor::visit(node); + } + } }; - GetRhs visitor; + GetExpr visitor; + visitor.setExprStr(exprStr); stmt.accept(&visitor); - IndexExpr rhs = visitor.rhs; - TensorVar workspace("workspacce", Type(Float64, {Dimension(42)}), Dense); - stmt = stmt.precompute(rhs, orig, pre, workspace); + Dimension dim = stmt.getIndexVarDomains().at(orig); + TensorVar workspace("workspace", Type(Float64, {dim}), Dense); + stmt = stmt.precompute(visitor.expr, orig, pre, workspace); } else if (command == "reorder") { int n; From b70a96441b23b98ad2387c867dc53daf7c0ea8a5 Mon Sep 17 00:00:00 2001 From: Jessica Shi Date: Wed, 29 Jul 2020 00:28:11 -0400 Subject: [PATCH 05/12] fix str.erase bug --- tools/taco.cpp | 11 ++++------- 1 file changed, 4 insertions(+), 7 deletions(-) diff --git a/tools/taco.cpp b/tools/taco.cpp index cc7d4bf79..88b9adc44 100644 --- a/tools/taco.cpp +++ b/tools/taco.cpp @@ -287,6 +287,7 @@ static void setSchedulingCommands(istream& in, ostream& out, parser::Parser& par string i, iw, exprStr; getInput("Enter the index variable to precompute over: ", i); getInput("Enter the index variable to precompute with: ", iw); + getInput("Enter (without spaces) the expression to precompute: ", exprStr); IndexVar orig = findVar(i); IndexVar pre; @@ -297,10 +298,6 @@ static void setSchedulingCommands(istream& in, ostream& out, parser::Parser& par addedVars.insert({iw, pre}); } - out << "Enter the expression to precompute: "; - in.ignore(); - getline(in, exprStr); - struct GetExpr : public IndexNotationVisitor { using IndexNotationVisitor::visit; @@ -309,14 +306,14 @@ static void setSchedulingCommands(istream& in, ostream& out, parser::Parser& par void setExprStr(string input) { exprStr = input; - exprStr.erase(remove(exprStr.begin(), exprStr.end(), ' ')); + exprStr.erase(remove(exprStr.begin(), exprStr.end(), ' '), exprStr.end()); } string toString(IndexExpr e) { stringstream tempStream; tempStream << e; string tempStr = tempStream.str(); - tempStr.erase(remove(tempStr.begin(), tempStr.end(), ' ')); + tempStr.erase(remove(tempStr.begin(), tempStr.end(), ' '), tempStr.end()); return tempStr; } @@ -341,7 +338,7 @@ static void setSchedulingCommands(istream& in, ostream& out, parser::Parser& par } void visit(const BinaryExprNode* node) { - IndexExpr currentExpr(node); + IndexExpr currentExpr(node); if (toString(currentExpr) == exprStr) { expr = currentExpr; } From 8976d0bfd199811630f08ce5c6aa9d45f23f1565 Mon Sep 17 00:00:00 2001 From: Jessica Shi Date: Sun, 2 Aug 2020 23:56:19 -0400 Subject: [PATCH 06/12] refactor some things --- include/taco/error.h | 8 +++---- tools/taco.cpp | 55 +++++++++++++++++++++++++++----------------- 2 files changed, 38 insertions(+), 25 deletions(-) diff --git a/include/taco/error.h b/include/taco/error.h index 8920c7b6b..e6edafc39 100644 --- a/include/taco/error.h +++ b/include/taco/error.h @@ -57,11 +57,11 @@ struct ErrorReport { if (condition) { return; } -#ifdef PYTHON +// #ifdef PYTHON explodeWithException(); -#else - explode(); -#endif +// #else +// explode(); +// #endif } void explode(); diff --git a/tools/taco.cpp b/tools/taco.cpp index 88b9adc44..c14dc7333 100644 --- a/tools/taco.cpp +++ b/tools/taco.cpp @@ -203,13 +203,13 @@ static void printCommandLine(ostream& os, int argc, char* argv[]) { } } -static void setSchedulingCommands(istream& in, ostream& out, parser::Parser& parser, IndexStmt& stmt) { - map addedVars; - auto findVar = [&parser, &addedVars](string name) { - if (parser.hasIndexVar(name)) { - return parser.getIndexVar(name); - } else if (util::contains(addedVars, name)) { - return addedVars.at(name); +static void setSchedulingCommands(istream& in, ostream& out, parser::Parser& parser, IndexStmt& stmt) { + auto findVar = [&stmt](string name) { + ProvenanceGraph graph(stmt); + for (auto v : graph.getAllIndexVars()) { + if (v.getName() == name) { + return v; + } } taco_uerror << "Index variable not defined in statement."; @@ -236,7 +236,6 @@ static void setSchedulingCommands(istream& in, ostream& out, parser::Parser& par for (auto a : getArgumentAccesses(stmt)) { if (a.getTensorVar().getName() == tensor) { IndexVar derived(ipos); - addedVars.insert({ipos, derived}); stmt = stmt.pos(findVar(i), derived, a); goto end; } @@ -250,7 +249,6 @@ static void setSchedulingCommands(istream& in, ostream& out, parser::Parser& par getInput("Enter the fused index variable: ", f); IndexVar fused(f); - addedVars.insert({f, fused}); stmt = stmt.fuse(findVar(i), findVar(j), fused); } else if (command == "split") { @@ -264,8 +262,6 @@ static void setSchedulingCommands(istream& in, ostream& out, parser::Parser& par IndexVar split1(i1); IndexVar split2(i2); - addedVars.insert({i1, split1}); - addedVars.insert({i2, split2}); stmt = stmt.split(findVar(i), split1, split2, splitFactor); } else if (command == "divide") { @@ -279,8 +275,6 @@ static void setSchedulingCommands(istream& in, ostream& out, parser::Parser& par IndexVar divide1(i1); IndexVar divide2(i2); - addedVars.insert({i1, divide1}); - addedVars.insert({i2, divide2}); stmt = stmt.divide(findVar(i), divide1, divide2, divideFactor); } else if (command == "precompute") { @@ -295,7 +289,6 @@ static void setSchedulingCommands(istream& in, ostream& out, parser::Parser& par pre = findVar(iw); } catch (exception& e) { pre = IndexVar(iw); - addedVars.insert({iw, pre}); } struct GetExpr : public IndexNotationVisitor { @@ -395,7 +388,6 @@ static void setSchedulingCommands(istream& in, ostream& out, parser::Parser& par } IndexVar bound1(i1); - addedVars.insert({i1, bound1}); stmt = stmt.bound(findVar(i), bound1, bound, bound_type); } else if (command == "unroll") { @@ -418,10 +410,22 @@ static void setSchedulingCommands(istream& in, ostream& out, parser::Parser& par parallel_unit = ParallelUnit::NotParallel; } else if (unit == "DefaultUnit") { parallel_unit = ParallelUnit::DefaultUnit; + } else if (unit == "GPUBlock") { + parallel_unit = ParallelUnit::GPUBlock; + } else if (unit == "GPUWarp") { + parallel_unit = ParallelUnit::GPUWarp; + } else if (unit == "GPUThread") { + parallel_unit = ParallelUnit::GPUThread; } else if (unit == "CPUThread") { parallel_unit = ParallelUnit::CPUThread; } else if (unit == "CPUVector") { parallel_unit = ParallelUnit::CPUVector; + } else if (unit == "CPUThreadGroupReduction") { + parallel_unit = ParallelUnit::CPUThreadGroupReduction; + } else if (unit == "CPUThreadGroupReduction") { + parallel_unit = ParallelUnit::CPUThreadGroupReduction; + } else if (unit == "GPUWarpReduction") { + parallel_unit = ParallelUnit::GPUWarpReduction; } else { out << "Parallel hardware not defined." << endl; goto end; @@ -516,7 +520,7 @@ int main(int argc, char* argv[]) { vector kernelFilenames; - stringstream scheduleStream; + vector scheduleCommands; for (int i = 1; i < argc; i++) { string arg = argv[i]; @@ -804,14 +808,18 @@ int main(int argc, char* argv[]) { else if ("-print-kernels" == argName) { printKernels = true; } - else if ("-set-schedule" == argName) { + else if ("-s" == argName) { if (argValue.empty()) { setScheduleInteractive = true; } else { setScheduleManual = true; - replace(argValue.begin(), argValue.end(), '-', ' '); - scheduleStream << argValue; - scheduleStream << " q"; + std::replace_if(argValue.begin(), argValue.end(), [](char c) { + if (c == '(' || c == ')' || c == ',') { + return true; + } + return false; + }, ' '); + scheduleCommands.push_back(argValue); } } else { @@ -919,7 +927,12 @@ int main(int argc, char* argv[]) { if (setScheduleInteractive) { setSchedulingCommands(cin, cout, parser, stmt); - } else if (setScheduleManual) { // TEMPORARY FIX TODO + } else if (setScheduleManual) { + stringstream scheduleStream; + for (string command : scheduleCommands) { + scheduleStream << command; + } + stringstream throwaway; try { setSchedulingCommands(scheduleStream, throwaway, parser, stmt); From 49ddc0bcd44b4c76a2dbd90274dd6ee7e51a9102 Mon Sep 17 00:00:00 2001 From: Jessica Shi Date: Mon, 3 Aug 2020 11:26:08 -0400 Subject: [PATCH 07/12] fix precompute bug --- tools/taco.cpp | 21 ++++++++++++++++++--- 1 file changed, 18 insertions(+), 3 deletions(-) diff --git a/tools/taco.cpp b/tools/taco.cpp index c14dc7333..dd7c914b8 100644 --- a/tools/taco.cpp +++ b/tools/taco.cpp @@ -813,9 +813,24 @@ int main(int argc, char* argv[]) { setScheduleInteractive = true; } else { setScheduleManual = true; - std::replace_if(argValue.begin(), argValue.end(), [](char c) { - if (c == '(' || c == ')' || c == ',') { - return true; + + bool insideCall = false; + bool parsingExpr = false; + + std::replace_if(argValue.begin(), argValue.end(), [&insideCall, &parsingExpr](char c) { + if (c == '(') { + if (insideCall) { + parsingExpr = true; // need to handle precompute case specially + } else { + insideCall = true; + return true; + } + } else if (c == ',') { + return !parsingExpr; + } else if (c == ')') { + bool previous = parsingExpr; + parsingExpr = false; + return !previous; } return false; }, ' '); From 44ee8e5dd88bbd2eb41bd3f5924655664c4a748f Mon Sep 17 00:00:00 2001 From: Jessica Shi Date: Tue, 11 Aug 2020 01:43:59 -0400 Subject: [PATCH 08/12] remove interactive, fix GPU, refactor --- tools/taco.cpp | 181 +++++++++++++++++++++++-------------------------- 1 file changed, 84 insertions(+), 97 deletions(-) diff --git a/tools/taco.cpp b/tools/taco.cpp index dd7c914b8..1786d6b7d 100644 --- a/tools/taco.cpp +++ b/tools/taco.cpp @@ -203,7 +203,7 @@ static void printCommandLine(ostream& os, int argc, char* argv[]) { } } -static void setSchedulingCommands(istream& in, ostream& out, parser::Parser& parser, IndexStmt& stmt) { +static bool setSchedulingCommands(istream& in, parser::Parser& parser, IndexStmt& stmt) { auto findVar = [&stmt](string name) { ProvenanceGraph graph(stmt); for (auto v : graph.getAllIndexVars()) { @@ -213,25 +213,22 @@ static void setSchedulingCommands(istream& in, ostream& out, parser::Parser& par } taco_uerror << "Index variable not defined in statement."; + return IndexVar(); }; - auto getInput = [&in, &out](string prompt, auto &var) { - out << prompt; - in >> var; - }; + bool isGPU = false; - out << endl << "To exit, input 'q'." << endl << endl; while (true) { string command; - getInput("Enter a command: ", command); + in >> command; if (command == "pos") { string i, ipos; - getInput("Enter the index variable to transform: ", i); - getInput("Enter the derived position index variable: ", ipos); + in >> i; + in >> ipos; string tensor; - getInput("Enter the tensor to perform the position cut on: ", tensor); + in >> tensor; for (auto a : getArgumentAccesses(stmt)) { if (a.getTensorVar().getName() == tensor) { @@ -240,25 +237,24 @@ static void setSchedulingCommands(istream& in, ostream& out, parser::Parser& par goto end; } } - out << "Tensor access not defined in statement." << endl; } else if (command == "fuse") { string i, j, f; - getInput("Enter the outer index variable to fuse: ", i); - getInput("Enter the inner index variable to fuse: ", j); - getInput("Enter the fused index variable: ", f); + in >> i; + in >> j; + in >> f; IndexVar fused(f); stmt = stmt.fuse(findVar(i), findVar(j), fused); } else if (command == "split") { string i, i1, i2; - getInput("Enter the index variable to split: ", i); - getInput("Enter the split outer index variable: ", i1); - getInput("Enter the split inner index variable: ", i2); + in >> i; + in >> i1; + in >> i2; size_t splitFactor; - getInput("Enter the split factor: ", splitFactor); + in >> splitFactor; IndexVar split1(i1); IndexVar split2(i2); @@ -266,12 +262,12 @@ static void setSchedulingCommands(istream& in, ostream& out, parser::Parser& par } else if (command == "divide") { string i, i1, i2; - getInput("Enter the index variable to divide: ", i); - getInput("Enter the divided outer index variable: ", i1); - getInput("Enter the divided inner index variable: ", i2); + in >> i; + in >> i1; + in >> i2; size_t divideFactor; - getInput("Enter the divide factor: ", divideFactor); + in >> divideFactor; IndexVar divide1(i1); IndexVar divide2(i2); @@ -279,9 +275,9 @@ static void setSchedulingCommands(istream& in, ostream& out, parser::Parser& par } else if (command == "precompute") { string i, iw, exprStr; - getInput("Enter the index variable to precompute over: ", i); - getInput("Enter the index variable to precompute with: ", iw); - getInput("Enter (without spaces) the expression to precompute: ", exprStr); + in >> i; + in >> iw; + in >> exprStr; IndexVar orig = findVar(i); IndexVar pre; @@ -345,18 +341,26 @@ static void setSchedulingCommands(istream& in, ostream& out, parser::Parser& par visitor.setExprStr(exprStr); stmt.accept(&visitor); - Dimension dim = stmt.getIndexVarDomains().at(orig); + Dimension dim; + auto domains = stmt.getIndexVarDomains(); + auto it = domains.find(orig); + if (it != domains.end()) { + dim = it->second; + } else { + dim = Dimension(orig); + } + TensorVar workspace("workspace", Type(Float64, {dim}), Dense); stmt = stmt.precompute(visitor.expr, orig, pre, workspace); } else if (command == "reorder") { int n; - getInput("Enter the number of index variables to reorder: ", n); + in >> n; vector reorderedVars; for (int i = 0; i < n; i++) { string var; - getInput("Enter an index variable to reorder: ", var); + in >> var; reorderedVars.push_back(findVar(var)); } @@ -364,14 +368,14 @@ static void setSchedulingCommands(istream& in, ostream& out, parser::Parser& par } else if (command == "bound") { string i, i1; - getInput("Enter the index variable to bound: ", i); - getInput("Enter the bounded index variable: ", i1); + in >> i; + in >> i1; size_t bound; - getInput("Enter the value to bound by: ", bound); + in >> bound; string type; - getInput("Enter the bound type: ", type); + in >> type; BoundType bound_type; if (type == "MinExact") { @@ -383,7 +387,7 @@ static void setSchedulingCommands(istream& in, ostream& out, parser::Parser& par } else if (type == "MaxConstraint") { bound_type = BoundType::MaxConstraint; } else { - out << "Bound type not defined." << endl; + taco_uerror << "Bound type not defined."; goto end; } @@ -392,42 +396,37 @@ static void setSchedulingCommands(istream& in, ostream& out, parser::Parser& par } else if (command == "unroll") { string i; - getInput("Enter the index variable to unroll: ", i); + in >> i; size_t unrollFactor; - getInput("Enter the unroll factor: ", unrollFactor); + in >> unrollFactor; stmt = stmt.unroll(findVar(i), unrollFactor); } else if (command == "parallelize") { string i, unit, strategy; - getInput("Enter the index variable to parallelize: ", i); - getInput("Enter the type of parallel hardware: ", unit); - getInput("Enter the race strategy: ", strategy); + in >> i; + in >> unit; + in >> strategy; ParallelUnit parallel_unit; if (unit == "NotParallel") { parallel_unit = ParallelUnit::NotParallel; - } else if (unit == "DefaultUnit") { - parallel_unit = ParallelUnit::DefaultUnit; } else if (unit == "GPUBlock") { parallel_unit = ParallelUnit::GPUBlock; + isGPU = true; } else if (unit == "GPUWarp") { parallel_unit = ParallelUnit::GPUWarp; + isGPU = true; } else if (unit == "GPUThread") { parallel_unit = ParallelUnit::GPUThread; + isGPU = true; } else if (unit == "CPUThread") { parallel_unit = ParallelUnit::CPUThread; } else if (unit == "CPUVector") { parallel_unit = ParallelUnit::CPUVector; - } else if (unit == "CPUThreadGroupReduction") { - parallel_unit = ParallelUnit::CPUThreadGroupReduction; - } else if (unit == "CPUThreadGroupReduction") { - parallel_unit = ParallelUnit::CPUThreadGroupReduction; - } else if (unit == "GPUWarpReduction") { - parallel_unit = ParallelUnit::GPUWarpReduction; } else { - out << "Parallel hardware not defined." << endl; + taco_uerror << "Parallel hardware not defined."; goto end; } @@ -443,23 +442,20 @@ static void setSchedulingCommands(istream& in, ostream& out, parser::Parser& par } else if (strategy == "ParallelReduction") { output_race_strategy = OutputRaceStrategy::ParallelReduction; } else { - out << "Race strategy not defined." << endl; + taco_uerror << "Race strategy not defined."; goto end; } stmt = stmt.parallelize(findVar(i), parallel_unit, output_race_strategy); - } else if (command == "q") { - break; } else { - out << "Not a valid command"; break; } - end: out << endl; + end:; } - out << endl << endl; + return isGPU; } int main(int argc, char* argv[]) { @@ -489,8 +485,7 @@ int main(int argc, char* argv[]) { bool readKernels = false; bool cuda = false; - bool setScheduleInteractive = false; - bool setScheduleManual = false; + bool setSchedule = false; ParallelSchedule sched = ParallelSchedule::Static; int chunkSize = 0; @@ -808,34 +803,29 @@ int main(int argc, char* argv[]) { else if ("-print-kernels" == argName) { printKernels = true; } - else if ("-s" == argName) { - if (argValue.empty()) { - setScheduleInteractive = true; - } else { - setScheduleManual = true; - - bool insideCall = false; - bool parsingExpr = false; - - std::replace_if(argValue.begin(), argValue.end(), [&insideCall, &parsingExpr](char c) { - if (c == '(') { - if (insideCall) { - parsingExpr = true; // need to handle precompute case specially - } else { - insideCall = true; - return true; - } - } else if (c == ',') { - return !parsingExpr; - } else if (c == ')') { - bool previous = parsingExpr; - parsingExpr = false; - return !previous; + else if ("-s" == argName) { + setSchedule = true; + bool insideCall = false; + bool parsingExpr = false; + + std::replace_if(argValue.begin(), argValue.end(), [&insideCall, &parsingExpr](char c) { + if (c == '(') { + if (insideCall) { + parsingExpr = true; // need to handle precompute case specially + } else { + insideCall = true; + return true; } - return false; - }, ' '); - scheduleCommands.push_back(argValue); - } + } else if (c == ',') { + return !parsingExpr; + } else if (c == ')') { + bool previous = parsingExpr; + parsingExpr = false; + return !previous; + } + return false; + }, ' '); + scheduleCommands.push_back(argValue); } else { if (exprStr.size() != 0) { @@ -917,16 +907,6 @@ int main(int argc, char* argv[]) { } } - if (cuda) { - if (!CUDA_BUILT && benchmark) { - return reportError("TACO must be built for CUDA (cmake -DCUDA=ON ..) to benchmark", 2); - } - set_CUDA_codegen_enabled(true); - } - else { - set_CUDA_codegen_enabled(false); - } - ir::Stmt assemble; ir::Stmt compute; ir::Stmt evaluate; @@ -940,17 +920,14 @@ int main(int argc, char* argv[]) { stmt = insertTemporaries(stmt); stmt = parallelizeOuterLoop(stmt); - if (setScheduleInteractive) { - setSchedulingCommands(cin, cout, parser, stmt); - } else if (setScheduleManual) { + if (setSchedule) { stringstream scheduleStream; for (string command : scheduleCommands) { scheduleStream << command; } - stringstream throwaway; try { - setSchedulingCommands(scheduleStream, throwaway, parser, stmt); + cuda |= setSchedulingCommands(scheduleStream, parser, stmt); } catch (TacoException e) { string msg = string(e.what()); msg = msg.insert(msg.find(":\n") + 3, "Error with provided schedule: "); @@ -958,6 +935,16 @@ int main(int argc, char* argv[]) { } } + if (cuda) { + if (!CUDA_BUILT && benchmark) { + return reportError("TACO must be built for CUDA (cmake -DCUDA=ON ..) to benchmark", 2); + } + set_CUDA_codegen_enabled(true); + } + else { + set_CUDA_codegen_enabled(false); + } + if (printConcrete) { cout << stmt << endl; } From a9d361595a2ac111b6d219fccedc74177a78a5b9 Mon Sep 17 00:00:00 2001 From: Jessica Shi Date: Mon, 17 Aug 2020 02:50:39 -0400 Subject: [PATCH 09/12] tweak parameters, add flag description --- tools/taco.cpp | 23 +++++++++++++++-------- 1 file changed, 15 insertions(+), 8 deletions(-) diff --git a/tools/taco.cpp b/tools/taco.cpp index 1786d6b7d..ddc4a79ef 100644 --- a/tools/taco.cpp +++ b/tools/taco.cpp @@ -114,6 +114,11 @@ static void printUsageInfo() { "float, double, complexfloat, complexdouble" "Examples: A:uint16, b:long and D:complexfloat."); cout << endl; + printFlag("s=\"()\"", + "Specify a scheduling command to apply to the generated code. " + "Parameters take the form of a comma-delimited list. " + "Examples: split(i,i0,i1,16), precompute(A(i,j)*x(j),i,i)."); + cout << endl; printFlag("c", "Generate compute kernel that simultaneously does assembly."); cout << endl; @@ -274,10 +279,11 @@ static bool setSchedulingCommands(istream& in, parser::Parser& parser, IndexStmt stmt = stmt.divide(findVar(i), divide1, divide2, divideFactor); } else if (command == "precompute") { - string i, iw, exprStr; + string exprStr, i, iw; + in >> exprStr; in >> i; in >> iw; - in >> exprStr; + IndexVar orig = findVar(i); IndexVar pre; @@ -354,13 +360,14 @@ static bool setSchedulingCommands(istream& in, parser::Parser& parser, IndexStmt stmt = stmt.precompute(visitor.expr, orig, pre, workspace); } else if (command == "reorder") { - int n; - in >> n; + string line; + getline(in, line); + stringstream temp; + temp << line; vector reorderedVars; - for (int i = 0; i < n; i++) { - string var; - in >> var; + string var; + while (temp >> var) { reorderedVars.push_back(findVar(var)); } @@ -923,7 +930,7 @@ int main(int argc, char* argv[]) { if (setSchedule) { stringstream scheduleStream; for (string command : scheduleCommands) { - scheduleStream << command; + scheduleStream << command << endl; } try { From 8abe130eb075790b50491edf376c27acd4e11214 Mon Sep 17 00:00:00 2001 From: Jessica Shi Date: Tue, 18 Aug 2020 01:24:13 -0400 Subject: [PATCH 10/12] revert error to explosion --- include/taco/error.h | 8 ++++---- tools/taco.cpp | 8 +------- 2 files changed, 5 insertions(+), 11 deletions(-) diff --git a/include/taco/error.h b/include/taco/error.h index e6edafc39..8920c7b6b 100644 --- a/include/taco/error.h +++ b/include/taco/error.h @@ -57,11 +57,11 @@ struct ErrorReport { if (condition) { return; } -// #ifdef PYTHON +#ifdef PYTHON explodeWithException(); -// #else -// explode(); -// #endif +#else + explode(); +#endif } void explode(); diff --git a/tools/taco.cpp b/tools/taco.cpp index 76d50b596..008a935a8 100644 --- a/tools/taco.cpp +++ b/tools/taco.cpp @@ -934,13 +934,7 @@ int main(int argc, char* argv[]) { scheduleStream << command << endl; } - try { - cuda |= setSchedulingCommands(scheduleStream, parser, stmt); - } catch (TacoException e) { - string msg = string(e.what()); - msg = msg.insert(msg.find(":\n") + 3, "Error with provided schedule: "); - throw TacoException(msg); - } + cuda |= setSchedulingCommands(scheduleStream, parser, stmt); } if (cuda) { From ddd6af24390d03fe0da26d32b90afb2abf4c1291 Mon Sep 17 00:00:00 2001 From: Jessica Shi Date: Tue, 18 Aug 2020 01:28:35 -0400 Subject: [PATCH 11/12] comment out divide --- tools/taco.cpp | 21 ++++++++++----------- 1 file changed, 10 insertions(+), 11 deletions(-) diff --git a/tools/taco.cpp b/tools/taco.cpp index 008a935a8..62682a387 100644 --- a/tools/taco.cpp +++ b/tools/taco.cpp @@ -265,25 +265,24 @@ static bool setSchedulingCommands(istream& in, parser::Parser& parser, IndexStmt IndexVar split2(i2); stmt = stmt.split(findVar(i), split1, split2, splitFactor); - } else if (command == "divide") { - string i, i1, i2; - in >> i; - in >> i1; - in >> i2; + // } else if (command == "divide") { + // string i, i1, i2; + // in >> i; + // in >> i1; + // in >> i2; - size_t divideFactor; - in >> divideFactor; + // size_t divideFactor; + // in >> divideFactor; - IndexVar divide1(i1); - IndexVar divide2(i2); - stmt = stmt.divide(findVar(i), divide1, divide2, divideFactor); + // IndexVar divide1(i1); + // IndexVar divide2(i2); + // stmt = stmt.divide(findVar(i), divide1, divide2, divideFactor); } else if (command == "precompute") { string exprStr, i, iw; in >> exprStr; in >> i; in >> iw; - IndexVar orig = findVar(i); IndexVar pre; From 61d136fe7028ba094bf28926a0cb509e75672260 Mon Sep 17 00:00:00 2001 From: Jessica Shi Date: Tue, 18 Aug 2020 01:48:51 -0400 Subject: [PATCH 12/12] change error handling for precompute --- tools/taco.cpp | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/tools/taco.cpp b/tools/taco.cpp index 62682a387..d2d2a02c6 100644 --- a/tools/taco.cpp +++ b/tools/taco.cpp @@ -217,8 +217,7 @@ static bool setSchedulingCommands(istream& in, parser::Parser& parser, IndexStmt } } - taco_uerror << "Index variable not defined in statement."; - return IndexVar(); + throw "Index variable not defined in statement."; }; bool isGPU = false; @@ -288,7 +287,7 @@ static bool setSchedulingCommands(istream& in, parser::Parser& parser, IndexStmt IndexVar pre; try { pre = findVar(iw); - } catch (exception& e) { + } catch (const char* e) { pre = IndexVar(iw); }