Skip to content

Commit

Permalink
Lat norm not complete
Browse files Browse the repository at this point in the history
  • Loading branch information
QXG2 committed Jan 17, 2020
1 parent 642b0d1 commit 27c98c0
Show file tree
Hide file tree
Showing 7 changed files with 261 additions and 139 deletions.
6 changes: 3 additions & 3 deletions src/AstTranslator.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -352,9 +352,9 @@ std::unique_ptr<RamValue> AstTranslator::translateValue(const AstArgument* arg,
assert(index.isDefined(var) && "variable not grounded");
if (index.isArgEnum(index.getDefinitionPoint(var),
translator.typeEnv)) {
std::cout << "Enum type detected! all loc size:"
<< index.getVariableReferences().at(var.getName()).size()
<< "\n";
// std::cout << "Enum type detected! all loc size:"
// << index.getVariableReferences().at(var.getName()).size()
// << "\n";
if (index.getVariableReferences().at(var.getName()).size() == 1)
return makeRamElementAccess(index.getDefinitionPoint(var));
else
Expand Down
214 changes: 158 additions & 56 deletions src/Interpreter.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -332,7 +332,8 @@ RamDomain Interpreter::evalVal(const RamValue& value,
}
}

std::cerr << "Failed to find a match for a lattice unary functor!" << std::endl;
std::cerr << "Failed to find a match for a lattice unary functor!"
<< std::endl;
exit(1);
}

Expand All @@ -358,7 +359,8 @@ RamDomain Interpreter::evalVal(const RamValue& value,
}
}

std::cerr << "Failed to find a match for a lattice binary functor!" << std::endl;
std::cerr << "Failed to find a match for a lattice binary functor!"
<< std::endl;
exit(1);
}

Expand Down Expand Up @@ -925,7 +927,7 @@ void Interpreter::evalStmt(const RamStatement& stmt) {

bool visitStratum(const RamStratum& stratum) override {
// TODO (lyndonhenry): should enable strata as subprograms for interpreter here
std::cout<<"visitStratum!\n";
std::cout << "visitStratum!\n";
// Record relations created in each stratum
if (Global::config().has("profile")) {
std::map<std::string, size_t> relNames;
Expand Down Expand Up @@ -978,7 +980,8 @@ void Interpreter::evalStmt(const RamStatement& stmt) {
InterpreterRelation& relation = interpreter.getRelation(
load.getRelation());
IOSystem::getInstance().getReader(
load.getRelation().getSymbolMask(), load.getRelation().getEnumTypeMask(),
load.getRelation().getSymbolMask(),
load.getRelation().getEnumTypeMask(),
interpreter.getSymbolTable(), ioDirectives,
Global::config().has("provenance"))->readAll(
relation);
Expand All @@ -999,7 +1002,8 @@ void Interpreter::evalStmt(const RamStatement& stmt) {
for (IODirectives ioDirectives : store.getIODirectives()) {
try {
IOSystem::getInstance().getWriter(
store.getRelation().getSymbolMask(), store.getRelation().getEnumTypeMask(),
store.getRelation().getSymbolMask(),
store.getRelation().getEnumTypeMask(),
interpreter.getSymbolTable(), ioDirectives,
Global::config().has("provenance"))->writeAll(
interpreter.getRelation(store.getRelation()));
Expand Down Expand Up @@ -1058,83 +1062,181 @@ void Interpreter::evalStmt(const RamStatement& stmt) {
return true;
}

// TODO
//
bool visitLatNorm(const RamLatNorm& latnorm) override {
std::cout << "visit LatNorm here!\n";
// get involved relation
InterpreterRelation& fst = interpreter.getRelation(
latnorm.getRelation_IN_New());
InterpreterRelation& scd = interpreter.getRelation(
InterpreterRelation& IN_Origin = interpreter.getRelation(
latnorm.getRelation_IN_Origin());
size_t arity = fst.getArity();
assert(
arity == scd.getArity()
&& "Two relations must have the same arity!");

// insert biggest lattice element into both relations
// auto latticeAssoc =
// interpreter.getTranslationUnit().getProgram()->getLattice();
// std::cout << "visitLatNorm now.\n";
// for partial we search for lower and upper boundaries
InterpreterRelation& IN_New = interpreter.getRelation(
latnorm.getRelation_IN_New());
InterpreterRelation& OUT_Origin = interpreter.getRelation(
latnorm.getRelation_OUT_Origin());
InterpreterRelation& OUT_New = interpreter.getRelation(
latnorm.getRelation_OUT_New());

size_t arity = IN_Origin.getArity();

// Require: there is only one element for each cell in in_origin lattice relation!
// Find biggest lattice element in the same cell, and
// put it into out_origin. If the biggest element does not
// exist in in_origin, also put it in out_new
RamDomain low[arity];
RamDomain high[arity];
for (size_t i = 0; i < arity; i++) {
low[i] = MIN_RAM_DOMAIN;
high[i] = MAX_RAM_DOMAIN;
}

// obtain index
auto totalIndex = fst.getTotalIndex();
// auto iitt = totalIndex->begin();
auto range = totalIndex->lowerUpperBound(low, high);

InterpreterContext ctxt_temp;
const RamLatticeBinaryFunction& lub_func =
interpreter.getTranslationUnit().getProgram()->getLattice()->getLUB();

auto it = range.first;
auto itend = range.second;
// obtain index
auto org_totalIndex = IN_Origin.getTotalIndex();
auto new_totalIndex = IN_New.getTotalIndex();

// Traverse the whole relation
while (it != itend) {
const RamDomain* data = *(it);
auto org_range = org_totalIndex->lowerUpperBound(low, high);
auto org_it = org_range.first;
auto org_itend = org_range.second;

// Step 1: Traverse the whole original relation, require that only 1 element in 1 cell!
for (; org_it != org_itend; ++org_it) {
const RamDomain* data = *org_it;
for (size_t i = 0; i < arity - 1; i++) {
low[i] = data[i];
high[i] = data[i];
}
low[arity - 1] = MIN_RAM_DOMAIN;
high[arity - 1] = MAX_RAM_DOMAIN; // must keep this

// get iterator range
auto range_end = totalIndex->UpperBound(high);
// RamDomain biggestLat = latAssoc->getBot();
RamDomain biggestLat = data[arity - 1];
++it;
for (; it != range_end; ++it) {
// const RamDomain* data = *(it);
// auto curlat = data[arity-1];
// TODO
RamDomain curlat = (*it)[arity - 1];
// set 2 input variables
std::vector<RamDomain> args = { biggestLat, curlat };
ctxt_temp.setArguments(args);

// evaluate binary constraint
for (const auto& cas : lub_func.getLatCase()) {
if (cas.match == nullptr
|| interpreter.evalCond(*cas.match,
ctxt_temp)) {
// get output if match
biggestLat = interpreter.evalVal(*cas.output,
ctxt_temp);
break;
auto new_range = new_totalIndex->lowerUpperBound(low, high);
auto new_it = new_range.first;
auto new_itend = new_range.second;

if (new_it != new_itend) {
// the cell exists in the new lattice relation
RamDomain Org_Lat = data[arity - 1];
RamDomain biggestLat = Org_Lat;

// search the cell in new lattice relation
for (++new_it; new_it != new_itend; ++new_it) {
RamDomain curlat = (*new_it)[arity - 1];
// set 2 input variables
ctxt_temp.setArguments( { biggestLat, curlat });
// evaluate binary constraint
for (const auto& cas : lub_func.getLatCase()) {
if (cas.match == nullptr
|| interpreter.evalCond(*cas.match,
ctxt_temp)) {
// get output if match
biggestLat = interpreter.evalVal(*cas.output,
ctxt_temp);
break;
}
}
}
// biggestLat = latAssoc->applyLub(biggestLat, curlat);
high[arity - 1] = biggestLat;

OUT_Origin.insert(high);
if (biggestLat != Org_Lat) {
OUT_New.insert(high);
}

} else {
// the cell does not exist in the new lattice relation
OUT_Origin.insert(high);
}

}

// Step 2: Traverse the whole new lattice relation
for (size_t i = 0; i < arity; i++) {
low[i] = MIN_RAM_DOMAIN;
high[i] = MAX_RAM_DOMAIN;
}
auto new_range = new_totalIndex->lowerUpperBound(low, high);
auto new_it = new_range.first;
auto new_itend = new_range.second;
while (new_it != new_itend) {
const RamDomain* data = *new_it;
for (size_t i = 0; i < arity - 1; i++) {
low[i] = data[i];
high[i] = data[i];
}
high[arity - 1] = biggestLat;
low[arity - 1] = MIN_RAM_DOMAIN;
high[arity - 1] = MAX_RAM_DOMAIN; // must keep this
auto range_end = new_totalIndex->UpperBound(high);

if (org_totalIndex->LowerBound(low) == org_itend) {
// the cell does not exist in original lattice relation, need to handle
RamDomain biggestLat = data[arity - 1];
for (++new_it; new_it != range_end; ++new_it) {
RamDomain curlat = (*new_it)[arity - 1];
// set 2 input variables
ctxt_temp.setArguments( { biggestLat, curlat });
// evaluate binary constraint
for (const auto& cas : lub_func.getLatCase()) {
if (cas.match == nullptr
|| interpreter.evalCond(*cas.match,
ctxt_temp)) {
// get output if match
biggestLat = interpreter.evalVal(*cas.output,
ctxt_temp);
break;
}
}
}
high[arity - 1] = biggestLat;
OUT_Origin.insert(high);
OUT_New.insert(high);

fst.insert(high);
scd.insert(high);
} else {
// the cell exists in original lattice relation, already handled
new_it = range_end;
}
}

// while (it != itend) {
// const RamDomain* data = *(it);
// for (size_t i = 0; i < arity - 1; i++) {
// high[i] = data[i];
// }
// high[arity - 1] = MAX_RAM_DOMAIN; // must keep this
//
// // get iterator range
// auto range_end = totalIndex->UpperBound(high);
// // RamDomain biggestLat = latAssoc->getBot();
// RamDomain biggestLat = data[arity - 1];
// ++it;
// for (; it != range_end; ++it) {
// // const RamDomain* data = *(it);
// // auto curlat = data[arity-1];
// // TODO
// RamDomain curlat = (*it)[arity - 1];
// // set 2 input variables
// std::vector<RamDomain> args = { biggestLat, curlat };
// ctxt_temp.setArguments(args);
//
// // evaluate binary constraint
// for (const auto& cas : lub_func.getLatCase()) {
// if (cas.match == nullptr
// || interpreter.evalCond(*cas.match,
// ctxt_temp)) {
// // get output if match
// biggestLat = interpreter.evalVal(*cas.output,
// ctxt_temp);
// break;
// }
// }
// // biggestLat = latAssoc->applyLub(biggestLat, curlat);
// }
// high[arity - 1] = biggestLat;
//
// fst.insert(high);
// scd.insert(high);
// }

// fst.latnorm(scd, latticeAssoc);
// std::cout << "visitLatNorm finish.\n";
return true;
Expand Down
42 changes: 30 additions & 12 deletions src/InterpreterIndex.h
Original file line number Diff line number Diff line change
Expand Up @@ -33,8 +33,10 @@ class InterpreterIndexOrder {
public:
// -- constructors --

InterpreterIndexOrder(std::vector<unsigned char> order = std::vector<unsigned char>())
: columns(std::move(order)) {}
InterpreterIndexOrder(
std::vector<unsigned char> order = std::vector<unsigned char>()) :
columns(std::move(order)) {
}

InterpreterIndexOrder(const InterpreterIndexOrder&) = default;
InterpreterIndexOrder(InterpreterIndexOrder&&) = default;
Expand Down Expand Up @@ -120,10 +122,13 @@ class InterpreterIndexOrder {

/** Enables the index order to be printed */
void print(std::ostream& out) const {
out << "[" << join(columns, ",", [](std::ostream& out, int i) { out << i; }) << "]";
out << "["
<< join(columns, ",", [](std::ostream& out, int i) {out << i;})
<< "]";
}

friend std::ostream& operator<<(std::ostream& out, const InterpreterIndexOrder& order) {
friend std::ostream& operator<<(std::ostream& out,
const InterpreterIndexOrder& order) {
order.print(out);
return out;
}
Expand All @@ -139,7 +144,9 @@ class InterpreterIndex {
const InterpreterIndexOrder& order;

/* constructor to initialize state */
comparator(const InterpreterIndexOrder& order) : order(order) {}
comparator(const InterpreterIndexOrder& order) :
order(order) {
}

/* comparison function */
int operator()(const RamDomain* x, const RamDomain* y) const {
Expand Down Expand Up @@ -175,8 +182,10 @@ class InterpreterIndex {

using iterator = index_set::iterator;

InterpreterIndex(InterpreterIndexOrder order)
: theOrder(std::move(order)), set(comparator(theOrder), comparator(theOrder)) {}
InterpreterIndex(InterpreterIndexOrder order) :
theOrder(std::move(order)), set(comparator(theOrder),
comparator(theOrder)) {
}

const InterpreterIndexOrder& order() const {
return theOrder;
Expand All @@ -196,10 +205,11 @@ class InterpreterIndex {
*
* precondition: the tuples do not exist in the index
*/
template <class Iter>
template<class Iter>
void insert(const Iter& a, const Iter& b) {
set.insert(a, b);
};
}
;

/** check whether tuple exists in index */
bool exists(const RamDomain* value) {
Expand Down Expand Up @@ -227,17 +237,25 @@ class InterpreterIndex {
}

/** return start and end iterator of an equal range */
inline std::pair<iterator, iterator> equalRange(const RamDomain* value) const {
inline std::pair<iterator, iterator> equalRange(
const RamDomain* value) const {
return lowerUpperBound(value, value);
}

/** return start iterator of a range */
inline iterator LowerBound(const RamDomain* low) const {
return set.lower_bound(low);
}

/** return end iterator of a range */
inline iterator UpperBound(const RamDomain* high) const {
return set.upper_bound(high);
}
/** return start and end iterator of a range */
inline std::pair<iterator, iterator> lowerUpperBound(const RamDomain* low, const RamDomain* high) const {
return std::pair<iterator, iterator>(set.lower_bound(low), set.upper_bound(high));
inline std::pair<iterator, iterator> lowerUpperBound(const RamDomain* low,
const RamDomain* high) const {
return std::pair<iterator, iterator>(set.lower_bound(low),
set.upper_bound(high));
}

private:
Expand Down
Loading

0 comments on commit 27c98c0

Please sign in to comment.