Skip to content

Commit

Permalink
Add and use data space delimiting function #147
Browse files Browse the repository at this point in the history
  • Loading branch information
riftEmber committed Oct 13, 2021
1 parent 667c955 commit 2a455d4
Show file tree
Hide file tree
Showing 3 changed files with 288 additions and 172 deletions.
139 changes: 112 additions & 27 deletions src/computation/Computation.cc
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@
#include <string>
#include <unordered_set>
#include <utility>
#include <regex>
#include <vector>
#include <map>

Expand Down Expand Up @@ -87,7 +88,7 @@ bool Computation::operator==(const Computation& other) const {
this->parameters == other.parameters &&
this->returnValues == other.returnValues &&
this->transformationLists == other.transformationLists
);
);
}

std::string Computation::getName() const {
Expand Down Expand Up @@ -522,7 +523,7 @@ std::vector<std::string> Computation::getSetConstraints(Set* set) {
}

Set* Computation::trimISDataSpaces(Set* set) {
Set* s = new Set(stripDataSpaceDelimiterFromString(set->getString()));
Set* s = new Set(stripDataSpaceDelimiter(set->getString()));
return s;
}

Expand All @@ -549,28 +550,33 @@ Stmt* Computation::getStmt(unsigned int index) const { return stmts.at(index); }
unsigned int Computation::getNumStmts() const { return stmts.size(); }

void Computation::addDataSpace(std::string dataSpaceName, std::string dataSpaceType) {
assertValidDataSpaceName(dataSpaceName);
dataSpaces[dataSpaceName] = dataSpaceType;
bool alreadyDelimited = nameIsDelimited(dataSpaceName);
assertValidDataSpaceName(dataSpaceName, alreadyDelimited);
if (alreadyDelimited) {
originalDataSpaceNames.emplace(stripDataSpaceDelimiter(dataSpaceName));
dataSpaces[dataSpaceName] = dataSpaceType;
} else {
originalDataSpaceNames.emplace(dataSpaceName);
dataSpaces[delimitDataSpaceName(dataSpaceName)] = dataSpaceType;
}
}

std::map<std::string, std::string> Computation::getDataSpaces() const {
return dataSpaces;
}

std::string Computation::getDataSpaceType(std::string dataSpaceName) const{
if(isDataSpace(dataSpaceName)){
return dataSpaces.at(dataSpaceName);
}
return "";
return dataSpaces.at(dataSpaceName);
}

bool Computation::isDataSpace(std::string name) const {
return dataSpaces.find(name) != dataSpaces.end();
}

void Computation::addParameter(std::string paramName, std::string paramType) {
assertValidDataSpaceName(paramName);
parameters.push_back(paramName);
bool alreadyDelimited = nameIsDelimited(paramName);
assertValidDataSpaceName(paramName, alreadyDelimited);
parameters.push_back(alreadyDelimited ? paramName : delimitDataSpaceName(paramName));
// parameters are automatically available as data spaces to the Computation
addDataSpace(paramName, paramType);
}
Expand Down Expand Up @@ -1565,16 +1571,91 @@ bool Computation::consistentSetArity(const std::vector<Set*>& sets) {
return true;
}

std::string Computation::delimitDataSpacesInString(std::string originalString) {
std::ostringstream delimitedString;

static std::regex potentialVariableRegex("[a-zA-Z_][a-zA-Z_0-9]*");
static std::string quote = "\"";

std::vector<std::string> quoteSplitStringSegments;

std::size_t start = 0;
std::size_t end = originalString.find(quote);
std::size_t lastQuotePos = 0;
while (end != std::string::npos)
{
lastQuotePos = end;
// create a new segment on a non-escaped quote
if (end == 0 || originalString.at(end - 1) != '\\') {
quoteSplitStringSegments.emplace_back(originalString.substr(start, end - start));
start = end + quote.length();
}
end = originalString.find(quote, end + quote.length());
}
// add remainder of string after last quote
if (end != originalString.length() - 1) {
quoteSplitStringSegments.emplace_back(originalString.substr(lastQuotePos));
}

for (unsigned int i = 0; i < quoteSplitStringSegments.size(); ++i) {
// rewrite alternate sections, beginning from the first that is unquoted
if (i % 2 == 0) {
std::string& originalSegment = quoteSplitStringSegments[i];
std::ostringstream rewrittenSegment;
std::size_t currentPosInOriginalSegment = 0;
for (auto match_it = std::sregex_iterator(originalSegment.begin(), originalSegment.end(), potentialVariableRegex);
match_it != std::sregex_iterator(); ++match_it) {
// only replace potential identifiers that actually match existing data spaces
if (this->originalDataSpaceNames.count((*match_it).str())) {
// grab everything between the last match and the beginning of this one, then add the delimited version
// of this one
rewrittenSegment << originalSegment.substr(currentPosInOriginalSegment,
(*match_it).position() - currentPosInOriginalSegment)
<< delimitDataSpaceName((*match_it).str());
currentPosInOriginalSegment = (*match_it).position() + (*match_it).length();
}
}
// add the remainder of the original string
rewrittenSegment << originalSegment.substr(currentPosInOriginalSegment);

delimitedString << rewrittenSegment.str();
} else {
// quoted sections (string literals) are left as-is
delimitedString << quote << quoteSplitStringSegments[i];
}
}

return delimitedString.str();
}

std::string Computation::delimitDataSpaceName(std::string dataSpaceName) {
return DATA_SPACE_DELIMITER + dataSpaceName + DATA_SPACE_DELIMITER;
}

std::string Computation::stripDataSpaceDelimiterFromString(std::string delimitedStr) {
std::string Computation::stripDataSpaceDelimiter(std::string delimitedStr) {
static const std::string delimiterAsStr = std::string(1, DATA_SPACE_DELIMITER);
return iegenlib::replaceInString(delimitedStr, delimiterAsStr, "");
}

bool Computation::nameIsDelimited(std::string name) {
bool improperlyDelimited = false;
if (name.front() == DATA_SPACE_DELIMITER) {
if (name.back() == DATA_SPACE_DELIMITER) {
return true;
} else {
improperlyDelimited = true;
}
} else if (name.back() == DATA_SPACE_DELIMITER) {
improperlyDelimited = true;
}

if (improperlyDelimited) {
throw assert_exception("Data space name '" + name + "' is improperly delimited.");
} else {
return false;
}
}

void Computation::padExecutionSchedules() {
// Get the max arity
int maxArity = 0;
Expand Down Expand Up @@ -1954,7 +2035,7 @@ std::string Computation::codeGen(Set* knownConstraints) {

stmtMacroDefs << "#define s_" << stmtCount << "("
<< iterSpace->getTupleDecl().toString() << ") "
<< Computation::stripDataSpaceDelimiterFromString(stmt->getStmtSourceCode())
<< Computation::stripDataSpaceDelimiter(stmt->getStmtSourceCode())
<< " \n";

// Get the new iteration space set
Expand Down Expand Up @@ -2054,7 +2135,7 @@ std::string Computation::omegaCodeGenFromString(std::vector<int> relationArity,
for(int i=0; i<iterSpacesStr.size(); i++){
std::string omegaIterString = iterSpacesStr[i];
omega::Relation* omegaIterSpace =
omega::parser::ParseRelation(Computation::stripDataSpaceDelimiterFromString(omegaIterString));
omega::parser::ParseRelation(Computation::stripDataSpaceDelimiter(omegaIterString));

iterSpaces.push_back(omega::copy(*omegaIterSpace));
transforms.push_back(omega::Identity(relationArity[i]));
Expand Down Expand Up @@ -2115,13 +2196,17 @@ std::string Computation::toOmegaString() {
return omegaString.str();
}

bool Computation::assertValidDataSpaceName(const std::string& name) {
if (!(name.length() >= 3 && name.front() == DATA_SPACE_DELIMITER
&& name.back() == DATA_SPACE_DELIMITER)){// || name.find('.') != std::string::npos) {
std::stringstream msg;
msg << "Data space names must be nonempty, surrounded in " << DATA_SPACE_DELIMITER
<< ", and not contain '.'\nError triggered for data space: " << name;
throw assert_exception(msg.str());
bool Computation::assertValidDataSpaceName(const std::string &name, bool alreadyDelimited) {
std::string errorMsg;
if (name.empty() || (alreadyDelimited && name.length() < 3)) {
errorMsg = "Data space names must be nonempty.";
} else if (alreadyDelimited &&
(name.at(1) == DATA_SPACE_DELIMITER || name.at(name.length() - 2) == DATA_SPACE_DELIMITER)) {
errorMsg = "Data space appears to be delimited twice. This is a bug.";
}

if (!errorMsg.empty()) {
throw assert_exception(errorMsg + " Error triggered for data space '" + name + "'.");
}
return true;
}
Expand Down Expand Up @@ -2149,7 +2234,7 @@ void Computation::replaceDataSpaceName(std::string original, std::string newStri

std::string searchString;
std::string replacedString;
if(original.at(0) == DATA_SPACE_DELIMITER){
if(nameIsDelimited(original)){
searchString = original;
replacedString = newString;
}
Expand Down Expand Up @@ -2246,17 +2331,17 @@ Stmt::Stmt(std::string stmtSourceCode, std::string iterationSpaceStr,
std::string executionScheduleStr,
std::vector<std::pair<std::string, std::string>> dataReadsStrs,
std::vector<std::pair<std::string, std::string>> dataWritesStrs) {
setStmtSourceCode(stmtSourceCode);
setIterationSpace(iterationSpaceStr);
setExecutionSchedule(executionScheduleStr);
setStmtSourceCode(Computation::delimitDataSpacesInString(stmtSourceCode));
setIterationSpace(Computation::delimitDataSpacesInString(iterationSpaceStr));
setExecutionSchedule(Computation::delimitDataSpacesInString(executionScheduleStr));
for (const auto& readInfo : dataReadsStrs) {
dataReads.push_back(
{readInfo.first,
{Computation::delimitDataSpaceName(readInfo.first),
std::unique_ptr<Relation>(new Relation(readInfo.second))});
}
for (const auto& writeInfo : dataWritesStrs) {
dataWrites.push_back(
{writeInfo.first,
{Computation::delimitDataSpaceName(writeInfo.first),
std::unique_ptr<Relation>(new Relation(writeInfo.second))});
}
};
Expand Down Expand Up @@ -2292,7 +2377,7 @@ bool Stmt::operator==(const Stmt& other) const {
this->executionSchedule == other.executionSchedule &&
this->dataReads == other.dataReads &&
this->dataWrites == other.dataWrites
);
);
}

void Stmt::replaceRead(std::string searchStr, std::string replaceStr) {
Expand Down
20 changes: 15 additions & 5 deletions src/computation/Computation.h
Original file line number Diff line number Diff line change
Expand Up @@ -305,11 +305,16 @@ class Computation {
// S0: {[0,i,0,j,0] | stuff}; S1:{[0,i,1,j,0] | stuff}
void fuse (int s1, int s2, int fuseLevel);

std::string delimitDataSpacesInString(std::string originalString);

//! Wrap the given data space name in delimiters
static string delimitDataSpaceName(std::string dataSpaceName);
static std::string delimitDataSpaceName(std::string dataSpaceName);

//! Get a new string with all instances of the data space delimiter removed from the original string
static string stripDataSpaceDelimiterFromString(std::string delimitedStr);
static std::string stripDataSpaceDelimiter(std::string delimitedStr);

//! Check if a data space name is delimited, excepting if it is only delimited on one side.
static bool nameIsDelimited(std::string name);

private:

Expand Down Expand Up @@ -345,9 +350,13 @@ class Computation {

//! Data spaces available in the Computation, pairs of name : type
std::map<std::string, std::string> dataSpaces;
//! Non-delimited data space names
std::unordered_set<std::string> originalDataSpaceNames;

//! Parameters of the computation. All parameters should also be data spaces.
std::vector<std::string> parameters;
//! Non-delimited parameter names
std::vector<std::string> originalParameterNames;
//! Names of values that are returned if this Computation is called. May be
//! data space names or literals. This is an ordered list because some
//! languages allow multiple returns.
Expand All @@ -357,8 +366,8 @@ class Computation {
//! List of statement transformation lists
std::vector<std::vector<Relation*>> transformationLists;

//! Assert that a given string would be a valid data space name, that is, it is properly delimited by $'s
static bool assertValidDataSpaceName(const std::string& name);
//! Assert that a given string would be a valid data space name
static bool assertValidDataSpaceName(const std::string& name, bool alreadyDelimited);

//! Number of times *any* Computation has been appended into
//! others, for creating unique name prefixes.
Expand Down Expand Up @@ -396,7 +405,8 @@ class Stmt {
~Stmt();

//! Construct a complete Stmt, given strings that will be used to
//! construct each set/relation.
//! construct each set/relation. Data spaces in the incoming strings
//! will be delimited automatically.
Stmt(std::string stmtSourceCode, std::string iterationSpaceStr,
std::string executionScheduleStr,
std::vector<std::pair<std::string, std::string>> dataReadsStrs,
Expand Down
Loading

0 comments on commit 2a455d4

Please sign in to comment.