souffle
2.0.2-371-g6315b36
|
This class translate the RAM Program into executable format and interpreter it.
More...
#include <Engine.h>
|
void | createRelation (const ram::Relation &id, const size_t idx) |
| Create and add relation into the runtime environment. More...
|
|
void | dropRelation (const size_t relId) |
| Remove a relation from the environment. More...
|
|
template<typename Aggregate , typename Iter > |
RamDomain | evalAggregate (const Aggregate &aggregate, const Node &filter, const Node *expression, const Node &nestedOperation, const Iter &ranges, Context &ctxt) |
|
template<typename Rel > |
RamDomain | evalChoice (const Rel &rel, const ram::Choice &cur, const Choice &shadow, Context &ctxt) |
|
template<typename Rel > |
RamDomain | evalExistenceCheck (const ExistenceCheck &shadow, Context &ctxt) |
|
template<typename Rel > |
RamDomain | evalIndexAggregate (const ram::IndexAggregate &cur, const IndexAggregate &shadow, Context &ctxt) |
|
template<typename Rel > |
RamDomain | evalIndexChoice (const ram::IndexChoice &cur, const IndexChoice &shadow, Context &ctxt) |
|
template<typename Rel > |
RamDomain | evalIndexScan (const ram::IndexScan &cur, const IndexScan &shadow, Context &ctxt) |
|
template<typename Rel > |
RamDomain | evalParallelAggregate (const Rel &rel, const ram::ParallelAggregate &cur, const ParallelAggregate &shadow, Context &ctxt) |
|
template<typename Rel > |
RamDomain | evalParallelChoice (const Rel &rel, const ram::ParallelChoice &cur, const ParallelChoice &shadow, Context &ctxt) |
|
template<typename Rel > |
RamDomain | evalParallelIndexAggregate (const ram::ParallelIndexAggregate &cur, const ParallelIndexAggregate &shadow, Context &ctxt) |
|
template<typename Rel > |
RamDomain | evalParallelIndexChoice (const Rel &rel, const ram::ParallelIndexChoice &cur, const ParallelIndexChoice &shadow, Context &ctxt) |
|
template<typename Rel > |
RamDomain | evalParallelIndexScan (const Rel &rel, const ram::ParallelIndexScan &cur, const ParallelIndexScan &shadow, Context &ctxt) |
|
template<typename Rel > |
RamDomain | evalParallelScan (const Rel &rel, const ram::ParallelScan &cur, const ParallelScan &shadow, Context &ctxt) |
|
template<typename Rel > |
RamDomain | evalProject (Rel &rel, const Project &shadow, Context &ctxt) |
|
template<typename Rel > |
RamDomain | evalProvenanceExistenceCheck (const ProvenanceExistenceCheck &shadow, Context &ctxt) |
|
template<typename Rel > |
RamDomain | evalScan (const Rel &rel, const ram::Scan &cur, const Scan &shadow, Context &ctxt) |
|
RamDomain | execute (const Node *, Context &) |
| Execute the program. More...
|
|
void | generateIR () |
| Generate intermediate representation from RAM. More...
|
|
size_t | getIterationNumber () const |
| Return current iteration number for loop operation. More...
|
|
void * | getMethodHandle (const std::string &method) |
| Return method handler. More...
|
|
RecordTable & | getRecordTable () |
| Return the record table. More...
|
|
RelationHandle & | getRelationHandle (const size_t idx) |
| Return a reference to the relation on the given index. More...
|
|
VecOwn< RelationHandle > & | getRelationMap () |
| Return the relation map. More...
|
|
SymbolTable & | getSymbolTable () |
| Return the string symbol table. More...
|
|
ram::TranslationUnit & | getTranslationUnit () |
| Return the ram::TranslationUnit. More...
|
|
int | incCounter () |
| Increment the counter. More...
|
|
void | incIterationNumber () |
| Increase iteration number by one. More...
|
|
const std::vector< void * > & | loadDLL () |
| Load DLL. More...
|
|
void | resetIterationNumber () |
| Reset iteration number. More...
|
|
void | swapRelation (const size_t ramRel1, const size_t ramRel2) |
| Swap the content of two relations. More...
|
|
This class translate the RAM Program into executable format and interpreter it.
Definition at line 56 of file Engine.h.
◆ RelationHandle
◆ Engine()
◆ createRelation()
void souffle::interpreter::Engine::createRelation |
( |
const ram::Relation & |
id, |
|
|
const size_t |
idx |
|
) |
| |
|
private |
◆ dropRelation()
void souffle::interpreter::Engine::dropRelation |
( |
const size_t |
relId | ) |
|
|
private |
Remove a relation from the environment.
◆ evalAggregate()
template<typename Aggregate , typename Iter >
RamDomain souffle::interpreter::Engine::evalAggregate |
( |
const Aggregate & |
aggregate, |
|
|
const Node & |
filter, |
|
|
const Node * |
expression, |
|
|
const Node & |
nestedOperation, |
|
|
const Iter & |
ranges, |
|
|
Context & |
ctxt |
|
) |
| |
|
private |
Definition at line 1511 of file Engine.cpp.
1527 shouldRunNested =
true;
1531 shouldRunNested =
true;
1535 shouldRunNested =
true;
1540 accumulateMean = {0, 0};
1545 shouldRunNested =
true;
1549 for (
const auto& tuple : ranges) {
1550 ctxt[aggregate.getTupleId()] = tuple.data();
1556 shouldRunNested =
true;
1568 switch (aggregate.getFunction()) {
1571 res =
ramBitCast(std::min(ramBitCast<RamFloat>(res), ramBitCast<RamFloat>(val)));
1574 res =
ramBitCast(std::min(ramBitCast<RamUnsigned>(res), ramBitCast<RamUnsigned>(val)));
1579 res =
ramBitCast(std::max(ramBitCast<RamFloat>(res), ramBitCast<RamFloat>(val)));
1582 res =
ramBitCast(std::max(ramBitCast<RamUnsigned>(res), ramBitCast<RamUnsigned>(val)));
1587 res =
ramBitCast(ramBitCast<RamFloat>(res) + ramBitCast<RamFloat>(val));
1590 res =
ramBitCast(ramBitCast<RamUnsigned>(res) + ramBitCast<RamUnsigned>(val));
1594 accumulateMean.first += ramBitCast<RamFloat>(val);
1595 accumulateMean.second++;
1602 if (aggregate.getFunction() ==
AggregateOp::MEAN && accumulateMean.second != 0) {
1603 res =
ramBitCast(accumulateMean.first / accumulateMean.second);
1609 ctxt[aggregate.getTupleId()] = tuple.data();
1611 if (!shouldRunNested) {
1614 return execute(&nestedOperation, ctxt);
1617 template <
typename Rel>
1619 const Rel&
rel,
const ram::ParallelAggregate& cur,
const ParallelAggregate& shadow, Context& ctxt) {
1621 auto viewContext = shadow.getViewContext();
References souffle::MAX_RAM_FLOAT, souffle::MAX_RAM_SIGNED, souffle::MAX_RAM_UNSIGNED, souffle::MIN_RAM_FLOAT, souffle::MIN_RAM_SIGNED, souffle::MIN_RAM_UNSIGNED, and souffle::ramBitCast().
◆ evalChoice()
Definition at line 1416 of file Engine.cpp.
1426 auto viewContext = shadow.getViewContext();
◆ evalExistenceCheck()
Definition at line 1237 of file Engine.cpp.
1246 for (
const auto& tupleElement : superInfo.tupleFirst) {
1247 tuple[tupleElement[0]] = ctxt[tupleElement[1]][tupleElement[2]];
1250 for (
const auto& expr : superInfo.exprFirst) {
1251 tuple[expr.first] =
execute(expr.second.get(), ctxt);
1253 return Rel::castView(ctxt.getView(viewPos))->contains(tuple);
1263 for (
const auto& tupleElement : superInfo.tupleFirst) {
1264 low[tupleElement[0]] = ctxt[tupleElement[1]][tupleElement[2]];
1265 high[tupleElement[0]] =
low[tupleElement[0]];
1268 for (
const auto& expr : superInfo.exprFirst) {
1269 low[expr.first] =
execute(expr.second.get(), ctxt);
1270 high[expr.first] =
low[expr.first];
1273 return Rel::castView(ctxt.getView(viewPos))->contains(
low,
high);
1276 template <
typename Rel>
1279 constexpr
size_t Arity = Rel::Arity;
◆ evalIndexAggregate()
Definition at line 1664 of file Engine.cpp.
1677 constexpr
size_t Arity = Rel::Arity;
1678 const auto& superInfo = shadow.getSuperInst();
◆ evalIndexChoice()
Definition at line 1454 of file Engine.cpp.
1460 ctxt[cur.getTupleId()] = tuple.data();
1461 if (
execute(shadow.getCondition(), ctxt)) {
1462 execute(shadow.getNestedOperation(), ctxt);
1469 template <
typename Rel>
1471 const ParallelIndexChoice& shadow, Context& ctxt) {
1472 auto viewContext = shadow.getViewContext();
◆ evalIndexScan()
Definition at line 1363 of file Engine.cpp.
1370 ctxt[cur.getTupleId()] = tuple.data();
1371 if (!
execute(shadow.getNestedOperation(), ctxt)) {
1378 template <
typename Rel>
1380 const Rel&
rel,
const ram::ParallelIndexScan& cur,
const ParallelIndexScan& shadow, Context& ctxt) {
1381 auto viewContext = shadow.getViewContext();
◆ evalParallelAggregate()
Definition at line 1623 of file Engine.cpp.
1629 cur, *shadow.getCondition(), shadow.getExpr(), *shadow.getNestedOperation(),
rel.scan(), newCtxt);
1632 template <
typename Rel>
1634 const ram::ParallelIndexAggregate& cur,
const ParallelIndexAggregate& shadow, Context& ctxt) {
◆ evalParallelChoice()
Definition at line 1429 of file Engine.cpp.
1435 pfor(
auto it = pStream.begin(); it < pStream.end(); it++) {
1436 for (
const auto& tuple : *it) {
1437 newCtxt[cur.getTupleId()] = tuple.data();
1438 if (
execute(shadow.getCondition(), newCtxt)) {
1439 execute(shadow.getNestedOperation(), newCtxt);
1448 template <
typename Rel>
1450 constexpr
size_t Arity = Rel::Arity;
1451 const auto& superInfo = shadow.getSuperInst();
◆ evalParallelIndexAggregate()
Definition at line 1638 of file Engine.cpp.
1644 constexpr
size_t Arity = Rel::Arity;
1645 const auto& superInfo = shadow.getSuperInst();
1651 size_t viewId = shadow.getViewId();
1652 auto view = Rel::castView(newCtxt.getView(viewId));
1654 return evalAggregate(cur, *shadow.getCondition(), shadow.getExpr(), *shadow.getNestedOperation(),
1655 view->range(
low,
high), newCtxt);
1658 template <
typename Rel>
1660 const ram::IndexAggregate& cur,
const IndexAggregate& shadow, Context& ctxt) {
◆ evalParallelIndexChoice()
Definition at line 1475 of file Engine.cpp.
1491 pfor(
auto it = pStream.begin(); it < pStream.end(); it++) {
1492 for (
const auto& tuple : *it) {
1493 newCtxt[cur.getTupleId()] = tuple.data();
1494 if (
execute(shadow.getCondition(), newCtxt)) {
1495 execute(shadow.getNestedOperation(), newCtxt);
1505 template <
typename Aggregate,
typename Iter>
1507 const Node& nestedOperation,
const Iter& ranges, Context& ctxt) {
1508 bool shouldRunNested =
false;
◆ evalParallelIndexScan()
Definition at line 1384 of file Engine.cpp.
1398 pfor(
auto it = pStream.begin(); it < pStream.end(); it++) {
1399 for (
const auto& tuple : *it) {
1400 newCtxt[cur.getTupleId()] = tuple.data();
1401 if (!
execute(shadow.getNestedOperation(), newCtxt)) {
1410 template <
typename Rel>
1413 for (
const auto& tuple :
rel.scan()) {
◆ evalParallelScan()
Definition at line 1338 of file Engine.cpp.
1345 pfor(
auto it = pStream.begin(); it < pStream.end(); it++) {
1346 for (
const auto& tuple : *it) {
1347 newCtxt[cur.getTupleId()] = tuple.data();
1348 if (!
execute(shadow.getNestedOperation(), newCtxt)) {
1357 template <
typename Rel>
1359 constexpr
size_t Arity = Rel::Arity;
◆ evalProject()
Definition at line 1681 of file Engine.cpp.
1683 : superInfo.tupleFirst) {
1684 tuple[tupleElement[0]] = ctxt[tupleElement[1]][tupleElement[2]];
1687 for (
const auto& expr : superInfo.exprFirst) {
1688 tuple[expr.first] =
execute(expr.second.get(), ctxt);
◆ evalProvenanceExistenceCheck()
Definition at line 1282 of file Engine.cpp.
1289 : superInfo.tupleFirst) {
1290 low[tupleElement[0]] = ctxt[tupleElement[1]][tupleElement[2]];
1291 high[tupleElement[0]] =
low[tupleElement[0]];
1294 for (
const auto& expr : superInfo.exprFirst) {
1295 assert(expr.second.get() !=
nullptr &&
1296 "ProvenanceExistenceCheck should always be specified for payload");
1297 low[expr.first] =
execute(expr.second.get(), ctxt);
1298 high[expr.first] =
low[expr.first];
1307 size_t viewPos = shadow.getViewId();
1310 auto equalRange = Rel::castView(ctxt.getView(viewPos))->range(
low,
high);
1313 if (equalRange.begin() == equalRange.end()) {
1318 return (*equalRange.begin())[Arity - 1] <=
execute(shadow.getChild(), ctxt);
1321 template <
typename Rel>
1323 for (
const auto& tuple :
rel.scan()) {
1324 ctxt[cur.getTupleId()] = tuple.data();
◆ evalScan()
Definition at line 1327 of file Engine.cpp.
1335 auto viewContext = shadow.getViewContext();
◆ execute()
Execute the program.
Unary Functor Operators
numeric coersions follow C++ semantics.
Binary Functor Operators
Ternary Functor Operators
Definition at line 359 of file Engine.cpp.
369 [[maybe_unused]]
const auto& shadow = *
static_cast<const interpreter::Kind*
>(node); \
370 [[maybe_unused]]
const auto& cur = *
static_cast<const ram::Kind*
>(node->getShadow());
372 #define EXTEND_CASE(Kind, Structure, Arity) \
373 case (I_##Kind##_##Structure##_##Arity): { \
374 return [&]() -> RamDomain { \
375 [[maybe_unused]] const auto& shadow = *static_cast<const interpreter::Kind*>(node); \
376 [[maybe_unused]] const auto& cur = *static_cast<const ram::Kind*>(node->getShadow());\
377 using RelType = Relation<Arity, interpreter::Structure>;
383 #define TUPLE_COPY_FROM(dst, src) \
384 assert(dst.size() == src.size()); \
385 std::copy_n(src.begin(), dst.size(), dst.begin())
387 #define CAL_SEARCH_BOUND(superInfo, low, high) \
389 TUPLE_COPY_FROM(low, superInfo.first); \
390 TUPLE_COPY_FROM(high, superInfo.second); \
392 for (const auto& tupleElement : superInfo.tupleFirst) { \
393 low[tupleElement[0]] = ctxt[tupleElement[1]][tupleElement[2]]; \
395 for (const auto& tupleElement : superInfo.tupleSecond) { \
396 high[tupleElement[0]] = ctxt[tupleElement[1]][tupleElement[2]]; \
399 for (const auto& expr : superInfo.exprFirst) { \
400 low[expr.first] = execute(expr.second.get(), ctxt); \
402 for (const auto& expr : superInfo.exprSecond) { \
403 high[expr.first] = execute(expr.second.get(), ctxt); \
406 switch (node->getType()) {
408 return cur.getConstant();
412 return ctxt[shadow.getTupleId()][shadow.getElement()];
419 CASE(IntrinsicOperator)
421 #define BINARY_OP_TYPED(ty, op) return ramBitCast(static_cast<ty>(EVAL_CHILD(ty, 0) op EVAL_CHILD(ty, 1)))
423 #define BINARY_OP_LOGICAL(opcode, op) BINARY_OP_INTEGRAL(opcode, op)
424 #define BINARY_OP_INTEGRAL(opcode, op) \
425 case FunctorOp:: opcode: BINARY_OP_TYPED(RamSigned , op); \
426 case FunctorOp::U##opcode: BINARY_OP_TYPED(RamUnsigned, op);
427 #define BINARY_OP_NUMERIC(opcode, op) \
428 BINARY_OP_INTEGRAL(opcode, op) \
429 case FunctorOp::F##opcode: BINARY_OP_TYPED(RamFloat, op);
431 #define BINARY_OP_SHIFT_MASK(ty, op) \
432 return ramBitCast(EVAL_CHILD(ty, 0) op (EVAL_CHILD(ty, 1) & RAM_BIT_SHIFT_MASK))
433 #define BINARY_OP_INTEGRAL_SHIFT(opcode, op, tySigned, tyUnsigned) \
434 case FunctorOp:: opcode: BINARY_OP_SHIFT_MASK(tySigned , op); \
435 case FunctorOp::U##opcode: BINARY_OP_SHIFT_MASK(tyUnsigned , op);
437 #define MINMAX_OP_SYM(op) \
439 auto result = EVAL_CHILD(RamDomain, 0); \
440 auto* result_val = &getSymbolTable().resolve(result); \
441 for (size_t i = 1; i < args.size(); i++) { \
442 auto alt = EVAL_CHILD(RamDomain, i); \
443 if (alt == result) continue; \
445 const auto& alt_val = getSymbolTable().resolve(alt); \
446 if (*result_val op alt_val) { \
447 result_val = &alt_val; \
453 #define MINMAX_OP(ty, op) \
455 auto result = EVAL_CHILD(ty, 0); \
456 for (size_t i = 1; i < args.size(); i++) { \
457 result = op(result, EVAL_CHILD(ty, i)); \
459 return ramBitCast(result); \
461 #define MINMAX_NUMERIC(opCode, op) \
462 case FunctorOp:: opCode: MINMAX_OP(RamSigned , op) \
463 case FunctorOp::U##opCode: MINMAX_OP(RamUnsigned, op) \
464 case FunctorOp::F##opCode: MINMAX_OP(RamFloat , op)
466 #define UNARY_OP(op, ty, func) \
467 case FunctorOp::op: { \
468 auto x = EVAL_CHILD(ty, 0); \
469 return ramBitCast(func(x)); \
471 #define CONV_TO_STRING(op, ty) \
472 case FunctorOp::op: return getSymbolTable().lookup(std::to_string(EVAL_CHILD(ty, 0)));
473 #define CONV_FROM_STRING(op, ty) \
474 case FunctorOp::op: return evaluator::symbol2numeric<ty>( \
475 getSymbolTable().resolve(EVAL_CHILD(RamDomain, 0)));
478 const auto& args = cur.getArguments();
479 switch (cur.getOperator()) {
487 return ramBitCast(-ramBitCast<RamFloat>(result));
492 return ramBitCast(~ramBitCast<RamUnsigned>(result));
527 return std::pow(
execute(shadow.getChild(0), ctxt),
execute(shadow.getChild(1), ctxt));
531 auto first = ramBitCast<RamUnsigned>(
execute(shadow.getChild(0), ctxt));
532 auto second = ramBitCast<RamUnsigned>(
execute(shadow.getChild(1), ctxt));
538 auto first = ramBitCast<RamFloat>(
execute(shadow.getChild(0), ctxt));
539 auto second = ramBitCast<RamFloat>(
execute(shadow.getChild(1), ctxt));
568 std::stringstream
ss;
569 for (
size_t i = 0;
i < args.size();
i++) {
576 auto symbol =
execute(shadow.getChild(0), ctxt);
578 auto idx =
execute(shadow.getChild(1), ctxt);
579 auto len =
execute(shadow.getChild(2), ctxt);
582 sub_str =
str.substr(idx, len);
584 std::cerr <<
"warning: wrong index position provided by substr(\"";
585 std::cerr <<
str <<
"\"," << (int32_t)idx <<
"," << (int32_t)len <<
") functor.\n";
593 fatal(
"ICE: functor `%s` must map onto `NestedIntrinsicOperator`", cur.getOperator());
598 #undef BINARY_OP_LOGICAL
599 #undef BINARY_OP_INTEGRAL
600 #undef BINARY_OP_NUMERIC
601 #undef BINARY_OP_SHIFT_MASK
602 #undef BINARY_OP_INTEGRAL_SHIFT
605 #undef MINMAX_NUMERIC
607 #undef CONV_TO_STRING
608 #undef CONV_FROM_STRING
609 ESAC(IntrinsicOperator)
611 CASE(NestedIntrinsicOperator)
612 auto numArgs = cur.getArguments().size();
613 auto runNested = [&](
auto&& tuple) {
614 ctxt[cur.getTupleId()] = tuple.data();
615 execute(shadow.getChild(numArgs), ctxt);
618 #define RUN_RANGE(ty) \
620 ? evaluator::runRange<ty>(EVAL_CHILD(ty, 0), EVAL_CHILD(ty, 1), EVAL_CHILD(ty, 2), runNested) \
621 : evaluator::runRange<ty>(EVAL_CHILD(ty, 0), EVAL_CHILD(ty, 1), runNested), \
624 switch (cur.getFunction()) {
632 ESAC(NestedIntrinsicOperator)
634 CASE(UserDefinedOperator)
635 const std::string& name = cur.getName();
638 if (fn ==
nullptr)
fatal(
"cannot find user-defined operator `%s`", name);
639 size_t arity = cur.getArguments().size();
641 if (cur.isStateful()) {
644 ffi_type* args[arity + 2];
645 void* values[arity + 2];
650 args[0] = args[1] = &ffi_type_pointer;
652 values[0] = &symbolTable;
655 for (
size_t i = 0;
i < arity;
i++) {
656 intVal[
i] =
execute(shadow.getChild(
i), ctxt);
658 values[
i + 2] = &intVal[
i];
665 const auto prepStatus = ffi_prep_cif(&cif, FFI_DEFAULT_ABI, arity + 2, codomain, args);
666 if (prepStatus != FFI_OK) {
667 fatal(
"Failed to prepare CIF for user-defined operator `%s`; error code = %d", name,
670 ffi_call(&cif, fn, &rc, values);
674 const std::vector<TypeAttribute>&
type = cur.getArgsTypes();
678 ffi_type* args[arity];
683 const char* strVal[arity];
687 for (
size_t i = 0;
i < arity;
i++) {
693 values[
i] = &strVal[
i];
698 values[
i] = &intVal[
i];
702 uintVal[
i] = ramBitCast<RamUnsigned>(arg);
703 values[
i] = &uintVal[
i];
707 floatVal[
i] = ramBitCast<RamFloat>(arg);
708 values[
i] = &floatVal[
i];
717 switch (cur.getReturnType()) {
728 const auto prepStatus = ffi_prep_cif(&cif, FFI_DEFAULT_ABI, arity, codomain, args);
729 if (prepStatus != FFI_OK) {
730 fatal(
"Failed to prepare CIF for user-defined operator `%s`; error code = %d", name,
733 ffi_call(&cif, fn, &rc, values);
735 switch (cur.getReturnType()) {
745 fatal(
"Unsupported user defined operator");
748 ESAC(UserDefinedOperator)
751 auto values = cur.getArguments();
752 size_t arity = values.size();
754 for (
size_t i = 0;
i < arity; ++
i) {
760 CASE(SubroutineArgument)
761 return ctxt.getArgument(cur.getArgument());
762 ESAC(SubroutineArgument)
773 return execute(shadow.getLhs(), ctxt) &&
execute(shadow.getRhs(), ctxt);
777 return !
execute(shadow.getChild(), ctxt);
780 #define EMPTINESS_CHECK(Structure, Arity, ...) \
781 CASE(EmptinessCheck, Structure, Arity) \
782 const auto& rel = *static_cast<RelType*>(node->getRelation()); \
783 return rel.empty(); \
787 #undef EMPTINESS_CHECK
789 #define RELATION_SIZE(Structure, Arity, ...) \
790 CASE(RelationSize, Structure, Arity) \
791 const auto& rel = *static_cast<RelType*>(node->getRelation()); \
798 #define EXISTENCE_CHECK(Structure, Arity, ...) \
799 CASE(ExistenceCheck, Structure, Arity) \
800 return evalExistenceCheck<RelType>(shadow, ctxt); \
804 #undef EXISTENCE_CHECK
806 #define PROVENANCE_EXISTENCE_CHECK(Structure, Arity, ...) \
807 CASE(ProvenanceExistenceCheck, Structure, Arity) \
808 return evalProvenanceExistenceCheck<RelType>(shadow, ctxt); \
809 ESAC(ProvenanceExistenceCheck)
812 #undef PROVENANCE_EXISTENCE_CHECK
816 #define COMPARE_NUMERIC(ty, op) return EVAL_LEFT(ty) op EVAL_RIGHT(ty)
817 #define COMPARE_STRING(op) \
818 return (getSymbolTable().resolve(EVAL_LEFT(RamDomain)) op \
819 getSymbolTable().resolve(EVAL_RIGHT(RamDomain)))
820 #define COMPARE_EQ_NE(opCode, op) \
821 case BinaryConstraintOp:: opCode: COMPARE_NUMERIC(RamDomain , op); \
822 case BinaryConstraintOp::F##opCode: COMPARE_NUMERIC(RamFloat , op);
823 #define COMPARE(opCode, op) \
824 case BinaryConstraintOp:: opCode: COMPARE_NUMERIC(RamSigned , op); \
825 case BinaryConstraintOp::U##opCode: COMPARE_NUMERIC(RamUnsigned, op); \
826 case BinaryConstraintOp::F##opCode: COMPARE_NUMERIC(RamFloat , op); \
827 case BinaryConstraintOp::S##opCode: COMPARE_STRING(op);
830 switch (cur.getOperator()) {
846 result = std::regex_match(text, std::regex(pattern));
848 std::cerr <<
"warning: wrong pattern provided for match(\"" << pattern <<
"\",\""
860 result = !std::regex_match(text, std::regex(pattern));
862 std::cerr <<
"warning: wrong pattern provided for !match(\"" << pattern <<
"\",\""
872 return text.find(pattern) != std::string::npos;
879 return text.find(pattern) == std::string::npos;
885 #undef COMPARE_NUMERIC
886 #undef COMPARE_STRING
892 bool result =
execute(shadow.getChild(), ctxt);
895 auto& currentFrequencies =
frequencies[cur.getProfileText()];
897 #pragma omp critical(frequencies)
898 currentFrequencies.emplace_back(0);
905 #define SCAN(Structure, Arity, ...) \
906 CASE(Scan, Structure, Arity) \
907 const auto& rel = *static_cast<RelType*>(node->getRelation()); \
908 return evalScan(rel, cur, shadow, ctxt); \
914 #define PARALLEL_SCAN(Structure, Arity, ...) \
915 CASE(ParallelScan, Structure, Arity) \
916 const auto& rel = *static_cast<RelType*>(node->getRelation()); \
917 return evalParallelScan(rel, cur, shadow, ctxt); \
922 #define INDEX_SCAN(Structure, Arity, ...) \
923 CASE(IndexScan, Structure, Arity) \
924 return evalIndexScan<RelType>(cur, shadow, ctxt); \
930 #define PARALLEL_INDEX_SCAN(Structure, Arity, ...) \
931 CASE(ParallelIndexScan, Structure, Arity) \
932 const auto& rel = *static_cast<RelType*>(node->getRelation()); \
933 return evalParallelIndexScan(rel, cur, shadow, ctxt); \
934 ESAC(ParallelIndexScan)
937 #undef PARALLEL_INDEX_SCAN
939 #define CHOICE(Structure, Arity, ...) \
940 CASE(Choice, Structure, Arity) \
941 const auto& rel = *static_cast<RelType*>(node->getRelation()); \
942 return evalChoice(rel, cur, shadow, ctxt); \
948 #define PARALLEL_CHOICE(Structure, Arity, ...) \
949 CASE(ParallelChoice, Structure, Arity) \
950 const auto& rel = *static_cast<RelType*>(node->getRelation()); \
951 return evalParallelChoice(rel, cur, shadow, ctxt); \
955 #undef PARALLEL_CHOICE
957 #define INDEX_CHOICE(Structure, Arity, ...) \
958 CASE(IndexChoice, Structure, Arity) \
959 return evalIndexChoice<RelType>(cur, shadow, ctxt); \
965 #define PARALLEL_INDEX_CHOICE(Structure, Arity, ...) \
966 CASE(ParallelIndexChoice, Structure, Arity) \
967 const auto& rel = *static_cast<RelType*>(node->getRelation()); \
968 return evalParallelIndexChoice(rel, cur, shadow, ctxt); \
969 ESAC(ParallelIndexChoice)
972 #undef PARALLEL_INDEX_CHOICE
983 size_t arity = cur.getArity();
987 ctxt[cur.getTupleId()] = tuple;
990 return execute(shadow.getNestedOperation(), ctxt);
993 #define PARALLEL_AGGREGATE(Structure, Arity, ...) \
994 CASE(ParallelAggregate, Structure, Arity) \
995 const auto& rel = *static_cast<RelType*>(node->getRelation()); \
996 return evalParallelAggregate(rel, cur, shadow, ctxt); \
997 ESAC(ParallelAggregate)
1000 #undef PARALLEL_AGGREGATE
1002 #define AGGREGATE(Structure, Arity, ...) \
1003 CASE(Aggregate, Structure, Arity) \
1004 const auto& rel = *static_cast<RelType*>(node->getRelation()); \
1005 return evalAggregate(cur, *shadow.getCondition(), shadow.getExpr(), *shadow.getNestedOperation(), \
1006 rel.scan(), ctxt); \
1012 #define PARALLEL_INDEX_AGGREGATE(Structure, Arity, ...) \
1013 CASE(ParallelIndexAggregate, Structure, Arity) \
1014 return evalParallelIndexAggregate<RelType>(cur, shadow, ctxt); \
1015 ESAC(ParallelIndexAggregate)
1018 #undef PARALLEL_INDEX_AGGREGATE
1020 #define INDEX_AGGREGATE(Structure, Arity, ...) \
1021 CASE(IndexAggregate, Structure, Arity) \
1022 return evalIndexAggregate<RelType>(cur, shadow, ctxt); \
1023 ESAC(IndexAggregate)
1026 #undef INDEX_AGGREGATE
1030 if (
execute(shadow.getCondition(), ctxt)) {
1033 return execute(shadow.getNestedOperation(), ctxt);
1039 if (
execute(shadow.getCondition(), ctxt)) {
1041 result =
execute(shadow.getNestedOperation(), ctxt);
1045 auto& currentFrequencies =
frequencies[cur.getProfileText()];
1047 currentFrequencies.emplace_back(0);
1054 #define PROJECT(Structure, Arity, ...) \
1055 CASE(Project, Structure, Arity) \
1056 auto& rel = *static_cast<RelType*>(node->getRelation()); \
1057 return evalProject(rel, shadow, ctxt); \
1063 CASE(SubroutineReturn)
1064 for (
size_t i = 0;
i < cur.getValues().
size(); ++
i) {
1065 if (shadow.getChild(
i) ==
nullptr) {
1066 ctxt.addReturnValue(0);
1068 ctxt.addReturnValue(
execute(shadow.getChild(
i), ctxt));
1072 ESAC(SubroutineReturn)
1075 for (
const auto& child : shadow.getChildren()) {
1076 if (!
execute(child.get(), ctxt)) {
1084 for (
const auto& child : shadow.getChildren()) {
1085 if (!
execute(child.get(), ctxt)) {
1094 while (
execute(shadow.getChild(), ctxt)) {
1102 return !
execute(shadow.getChild(), ctxt);
1105 CASE(LogRelationTimer)
1108 return execute(shadow.getChild(), ctxt);
1109 ESAC(LogRelationTimer)
1113 return execute(shadow.getChild(), ctxt);
1118 return execute(shadow.getChild(), ctxt);
1121 #define CLEAR(Structure, Arity, ...) \
1122 CASE(Clear, Structure, Arity) \
1123 auto& rel = *static_cast<RelType*>(node->getRelation()); \
1137 const auto&
rel = *node->getRelation();
1144 const auto& directive = cur.getDirectives();
1145 const std::string& op = cur.get(
"operation");
1146 auto&
rel = *node->getRelation();
1148 if (op ==
"input") {
1153 }
catch (std::exception&
e) {
1154 std::cerr <<
"Error loading data: " <<
e.what() <<
"\n";
1157 }
else if (op ==
"output" || op ==
"printsize") {
1162 }
catch (std::exception&
e) {
1163 std::cerr <<
e.what();
1168 assert(
"wrong i/o operation");
1174 ViewContext* viewContext = shadow.getViewContext();
1177 auto& viewFreeOps = viewContext->getOuterFilterViewFreeOps();
1178 for (
auto& op : viewFreeOps) {
1179 if (!
execute(op.get(), ctxt)) {
1185 auto& viewsForOuter = viewContext->getViewInfoForFilter();
1186 for (
auto& info : viewsForOuter) {
1191 auto& viewOps = viewContext->getOuterFilterViewOps();
1192 for (
auto& op : viewOps) {
1193 if (!
execute(op.get(), ctxt)) {
1198 if (viewContext->isParallel) {
1202 auto& viewsForNested = viewContext->getViewInfoForNested();
1203 for (
auto& info : viewsForNested) {
1207 execute(shadow.getChild(), ctxt);
1212 auto& src = *
static_cast<EqrelRelation*
>(
getRelationHandle(shadow.getSourceId()).get());
1213 auto& trg = *
static_cast<EqrelRelation*
>(
getRelationHandle(shadow.getTargetId()).get());
1220 swapRelation(shadow.getSourceId(), shadow.getTargetId());
1231 template <
typename Rel>
1233 constexpr
size_t Arity = Rel::Arity;
1234 size_t viewPos = shadow.getViewId();
References souffle::ADD, souffle::interpreter::Context::addReturnValue(), AGGREGATE, souffle::BAND, BINARY_OP_INTEGRAL, BINARY_OP_INTEGRAL_SHIFT, BINARY_OP_LOGICAL, BINARY_OP_NUMERIC, souffle::BOR, souffle::BSHIFT_L, souffle::BSHIFT_R, souffle::BSHIFT_R_UNSIGNED, souffle::BXOR, CASE, CHOICE, CLEAR, COMPARE, COMPARE_EQ_NE, CONV_FROM_STRING, CONV_TO_STRING, souffle::interpreter::Context::createView(), TCB_SPAN_NAMESPACE_NAME::detail::data(), souffle::tuple::data, souffle::DIV, e, EMPTINESS_CHECK, souffle::EQ, ESAC, EXISTENCE_CHECK, souffle::interpreter::EqrelRelation::extend(), souffle::F2I, souffle::F2S, souffle::F2U, souffle::fatal(), FFI_RamFloat, FFI_RamSigned, FFI_RamUnsigned, FFI_Symbol, FOR_EACH, FOR_EACH_PROVENANCE, souffle::GE, souffle::interpreter::Context::getArgument(), souffle::getInstance(), souffle::interpreter::ViewContext::getOuterFilterViewFreeOps(), souffle::interpreter::ViewContext::getOuterFilterViewOps(), souffle::interpreter::Node::getRelation(), souffle::interpreter::ViewContext::getViewInfoForFilter(), souffle::interpreter::ViewContext::getViewInfoForNested(), souffle::GT, i, souffle::I2F, souffle::I2S, souffle::I2U, INDEX_AGGREGATE, INDEX_CHOICE, INDEX_SCAN, souffle::interpreter::ViewContext::isParallel, souffle::LAND, souffle::LE, souffle::LOR, souffle::LT, souffle::LXOR, souffle::MAX, souffle::MIN, MINMAX_NUMERIC, MINMAX_OP_SYM, souffle::MOD, souffle::MUL, souffle::NE, PARALLEL_AGGREGATE, PARALLEL_CHOICE, PARALLEL_INDEX_AGGREGATE, PARALLEL_INDEX_CHOICE, PARALLEL_INDEX_SCAN, PARALLEL_SCAN, PROJECT, PROVENANCE_EXISTENCE_CHECK, souffle::ramBitCast(), rel(), RELATION_SIZE, RUN_RANGE, souffle::S2F, souffle::S2I, souffle::S2U, SCAN, TCB_SPAN_NAMESPACE_NAME::detail::size(), souffle::profile::ss, str, souffle::SUB, souffle::U2F, souffle::U2I, souffle::U2S, UNARY_OP, and UNREACHABLE_BAD_CASE_ANALYSIS.
◆ executeMain()
void souffle::interpreter::Engine::executeMain |
( |
| ) |
|
Execute the main program.
Definition at line 272 of file Engine.cpp.
286 if (!node.getProfileText().empty()) {
287 frequencies.emplace(node.getProfileText(), std::deque<std::atomic<size_t>>());
288 frequencies[node.getProfileText()].emplace_back(0);
299 size_t relationCount = 0;
301 if (
rel->getName()[0] !=
'@') {
309 size_t ruleCount = 0;
317 for (
size_t i = 0;
i < cur.second.size(); ++
i) {
321 for (
auto const& cur :
reads) {
323 "@relation-reads;" + cur.first, cur.second, 0);
◆ executeSubroutine()
void souffle::interpreter::Engine::executeSubroutine |
( |
const std::string & |
name, |
|
|
const std::vector< RamDomain > & |
args, |
|
|
std::vector< RamDomain > & |
ret |
|
) |
| |
Execute the subroutine program.
Definition at line 347 of file Engine.cpp.
355 #define DEBUG(Kind) std::cout << "Running Node: " << #Kind << "\n";
356 #define EVAL_CHILD(ty, idx) ramBitCast<ty>(execute(shadow.getChild(idx), ctxt))
357 #define EVAL_LEFT(ty) ramBitCast<ty>(execute(shadow.getLhs(), ctxt))
◆ generateIR()
void souffle::interpreter::Engine::generateIR |
( |
| ) |
|
|
private |
Generate intermediate representation from RAM.
Definition at line 334 of file Engine.cpp.
338 main = generator.generateTree(program.getMain());
343 const std::string& name,
const std::vector<RamDomain>& args, std::vector<RamDomain>& ret) {
345 ctxt.setReturnValues(ret);
◆ getIterationNumber()
size_t souffle::interpreter::Engine::getIterationNumber |
( |
| ) |
const |
|
private |
Return current iteration number for loop operation.
Definition at line 262 of file Engine.cpp.
◆ getMethodHandle()
void * souffle::interpreter::Engine::getMethodHandle |
( |
const std::string & |
method | ) |
|
|
private |
Return method handler.
Definition at line 183 of file Engine.cpp.
◆ getRecordTable()
RecordTable & souffle::interpreter::Engine::getRecordTable |
( |
| ) |
|
|
private |
Return the record table.
Definition at line 175 of file Engine.cpp.
◆ getRelationHandle()
Return a reference to the relation on the given index.
Definition at line 157 of file Engine.cpp.
◆ getRelationMap()
◆ getSymbolTable()
SymbolTable & souffle::interpreter::Engine::getSymbolTable |
( |
| ) |
|
|
private |
Return the string symbol table.
Definition at line 171 of file Engine.cpp.
◆ getTranslationUnit()
◆ incCounter()
int souffle::interpreter::Engine::incCounter |
( |
| ) |
|
|
private |
Increment the counter.
Definition at line 167 of file Engine.cpp.
◆ incIterationNumber()
void souffle::interpreter::Engine::incIterationNumber |
( |
| ) |
|
|
private |
Increase iteration number by one.
Definition at line 265 of file Engine.cpp.
◆ loadDLL()
const std::vector< void * > & souffle::interpreter::Engine::loadDLL |
( |
| ) |
|
|
private |
Load DLL.
Definition at line 217 of file Engine.cpp.
226 if (library.empty()) {
231 for (std::string& path : paths) {
232 if (path.back() !=
'/') {
237 if (library.find(
'/') != std::string::npos) {
244 for (
const std::string& path : paths) {
246 tmp = dlopen(fullpath.c_str(), RTLD_LAZY);
247 if (tmp !=
nullptr) {
◆ resetIterationNumber()
void souffle::interpreter::Engine::resetIterationNumber |
( |
| ) |
|
|
private |
Reset iteration number.
Definition at line 268 of file Engine.cpp.
◆ swapRelation()
void souffle::interpreter::Engine::swapRelation |
( |
const size_t |
ramRel1, |
|
|
const size_t |
ramRel2 |
|
) |
| |
|
private |
◆ counter
std::atomic<RamDomain> souffle::interpreter::Engine::counter {0} |
|
private |
Profile counter.
Definition at line 168 of file Engine.h.
◆ dll
std::vector<void*> souffle::interpreter::Engine::dll |
|
private |
◆ frequencies
std::map<std::string, std::deque<std::atomic<size_t> > > souffle::interpreter::Engine::frequencies |
|
private |
Profile for rule frequencies.
Definition at line 172 of file Engine.h.
◆ isa
IndexAnalysis.
Definition at line 180 of file Engine.h.
◆ isProvenance
const bool souffle::interpreter::Engine::isProvenance |
|
private |
If running a provenance program.
Definition at line 160 of file Engine.h.
◆ iteration
size_t souffle::interpreter::Engine::iteration = 0 |
|
private |
◆ main
Own<Node> souffle::interpreter::Engine::main |
|
private |
◆ NodeGenerator
friend souffle::interpreter::Engine::NodeGenerator |
|
private |
◆ numOfThreads
size_t souffle::interpreter::Engine::numOfThreads |
|
private |
Number of threads enabled for this program.
Definition at line 166 of file Engine.h.
◆ profileEnabled
const bool souffle::interpreter::Engine::profileEnabled |
|
private |
If profile is enable in this program.
Definition at line 158 of file Engine.h.
◆ ProgInterface
friend souffle::interpreter::Engine::ProgInterface |
|
private |
◆ reads
std::map<std::string, std::atomic<size_t> > souffle::interpreter::Engine::reads |
|
private |
Profile for relation reads.
Definition at line 174 of file Engine.h.
◆ recordTable
◆ relations
Symbol table for relations.
Definition at line 184 of file Engine.h.
◆ subroutine
VecOwn<Node> souffle::interpreter::Engine::subroutine |
|
private |
◆ tUnit
The documentation for this class was generated from the following files:
std::vector< void * > dll
DLL.
size_t numOfThreads
Number of threads enabled for this program.
void executeSubroutine(const std::string &name, const std::vector< RamDomain > &args, std::vector< RamDomain > &ret)
Execute the subroutine program.
VecOwn< RelationHandle > relations
Symbol table for relations.
void setMsg(const char *m)
constexpr auto size(const C &c) -> decltype(c.size())
#define UNREACHABLE_BAD_CASE_ANALYSIS
int incCounter()
Increment the counter.
#define BINARY_OP_INTEGRAL_SHIFT(opcode, op, tySigned, tyUnsigned)
std::atomic< RamDomain > counter
Profile counter.
const std::string & resolve(const RamDomain index) const
Find a symbol in the table by its index, note that this gives an error if the index is out of bounds.
#define BINARY_OP_INTEGRAL(opcode, op)
constexpr RamSigned MAX_RAM_SIGNED
RecordTable & getRecordTable()
Return the record table.
#define INDEX_AGGREGATE(Structure, Arity,...)
#define FOR_EACH(func,...)
Own< RelationWrapper > createEqrelRelation(const ram::Relation &id, const ram::analysis::MinIndexSelection &orderSet)
#define PARALLEL_AGGREGATE(Structure, Arity,...)
RamDomain evalParallelIndexChoice(const Rel &rel, const ram::ParallelIndexChoice &cur, const ParallelIndexChoice &shadow, Context &ctxt)
#define AGGREGATE(Structure, Arity,...)
Own< RelationWrapper > createBTreeRelation(const ram::Relation &id, const ram::analysis::MinIndexSelection &orderSet)
RamDomain evalExistenceCheck(const ExistenceCheck &shadow, Context &ctxt)
void stopTimer()
Stop timer.
RamDomain evalAggregate(const Aggregate &aggregate, const Node &filter, const Node *expression, const Node &nestedOperation, const Iter &ranges, Context &ctxt)
const bool isProvenance
If running a provenance program.
static ProfileEventSingleton & instance()
get instance
#define UNARY_OP(op, ty, func)
l j a showGridBackground &&c b raw series this eventEmitter e
#define SCAN(Structure, Arity,...)
#define CLEAR(Structure, Arity,...)
const bool profileEnabled
If profile is enable in this program.
size_t iteration
Loop iteration counter.
constexpr RamFloat MIN_RAM_FLOAT
@ ORD
Unary Functor Operators.
#define PARALLEL_INDEX_AGGREGATE(Structure, Arity,...)
Own< RelationWrapper > createProvenanceRelation(const ram::Relation &id, const ram::analysis::MinIndexSelection &orderSet)
#define PROJECT(Structure, Arity,...)
void * getMethodHandle(const std::string &method)
Return method handler.
void swapRelation(const size_t ramRel1, const size_t ramRel2)
Swap the content of two relations.
static IOSystem & getInstance()
ram::TranslationUnit & tUnit
Program.
RelationHandle & getRelationHandle(const size_t idx)
Return a reference to the relation on the given index.
Program & getProgram() const
Get the RAM Program of the translation unit
RamDomain lookup(const std::string &symbol)
Find the index of a symbol in the table, inserting a new symbol if it does not exist there already.
#define EXISTENCE_CHECK(Structure, Arity,...)
constexpr RamUnsigned MAX_RAM_UNSIGNED
const RamDomain * unpack(RamDomain ref, size_t arity) const
convert record reference to a record
#define CONV_TO_STRING(op, ty)
RecordTable recordTable
Record Table.
RamDomain evalScan(const Rel &rel, const ram::Scan &cur, const Scan &shadow, Context &ctxt)
std::vector< A > filter(std::vector< A > xs, F &&f)
Filter a vector to include certain elements.
constexpr RamFloat MAX_RAM_FLOAT
#define CAL_SEARCH_BOUND(superInfo, low, high)
#define PARALLEL_SCAN(Structure, Arity,...)
#define RELATION_SIZE(Structure, Arity,...)
RamDomain evalProvenanceExistenceCheck(const ProvenanceExistenceCheck &shadow, Context &ctxt)
#define EMPTINESS_CHECK(Structure, Arity,...)
void resetIterationNumber()
Reset iteration number.
constexpr auto get(span< E, S > s) -> decltype(s[N])
RamDomain evalParallelIndexScan(const Rel &rel, const ram::ParallelIndexScan &cur, const ParallelIndexScan &shadow, Context &ctxt)
void makeQuantityEvent(const std::string &txt, size_t number, int iteration)
create quantity event
Own< WriteStream > getWriter(const std::map< std::string, std::string > &rwOperation, const SymbolTable &symbolTable, const RecordTable &recordTable) const
Return a new WriteStream.
BinaryConstraintOp
Binary Constraint Operators.
constexpr RamSigned MIN_RAM_SIGNED
lower and upper boundaries for the ram types
#define INDEX_CHOICE(Structure, Arity,...)
RamDomain pack(const RamDomain *tuple, size_t arity)
convert record to record reference
RamDomain execute(const Node *, Context &)
Execute the program.
#define COMPARE(opCode, op)
std::vector< Relation * > getRelations() const
Get all relations of RAM program
#define BINARY_OP_LOGICAL(opcode, op)
void setOutputFile(std::string outputFilename)
VecOwn< Node > subroutine
subroutines
size_t getIterationNumber() const
Return current iteration number for loop operation.
RamDomain evalIndexScan(const ram::IndexScan &cur, const IndexScan &shadow, Context &ctxt)
void makeConfigRecord(const std::string &key, const std::string &value)
create config record
Own< RelationWrapper > RelationHandle
#define CHOICE(Structure, Arity,...)
constexpr RamUnsigned MIN_RAM_UNSIGNED
static MainConfig & config()
#define PARALLEL_INDEX_CHOICE(Structure, Arity,...)
RamDomain evalIndexChoice(const ram::IndexChoice &cur, const IndexChoice &shadow, Context &ctxt)
#define FOR_EACH_PROVENANCE(func,...)
#define MINMAX_OP_SYM(op)
RamDomain evalParallelIndexAggregate(const ram::ParallelIndexAggregate &cur, const ParallelIndexAggregate &shadow, Context &ctxt)
void makeTimeEvent(const std::string &txt)
create time event
#define CONV_FROM_STRING(op, ty)
Own< Node > main
main program
std::vector< std::string > splitString(const std::string &str, char delimiter)
Splits a string given a delimiter.
#define MINMAX_NUMERIC(opCode, op)
std::map< std::string, std::atomic< size_t > > reads
Profile for relation reads.
#define PARALLEL_CHOICE(Structure, Arity,...)
void fatal(const char *format, const Args &... args)
static SignalHandler * instance()
constexpr auto data(C &c) -> decltype(c.data())
To ramBitCast(From source)
In C++20 there will be a new way to cast between types by reinterpreting bits (std::bit_cast),...
RamDomain evalParallelAggregate(const Rel &rel, const ram::ParallelAggregate &cur, const ParallelAggregate &shadow, Context &ctxt)
RamDomain evalIndexAggregate(const ram::IndexAggregate &cur, const IndexAggregate &shadow, Context &ctxt)
void visitDepthFirst(const Node &root, Visitor< R, Ps... > &visitor, Args &... args)
A utility function visiting all nodes within the RAM fragments rooted by the given node recursively i...
void rel(size_t limit, bool showLimit=true)
void incIterationNumber()
Increase iteration number by one.
virtual size_t size() const =0
void generateIR()
Generate intermediate representation from RAM.
#define BINARY_OP_NUMERIC(opcode, op)
@ SUBSTR
Ternary Functor Operators.
#define PARALLEL_INDEX_SCAN(Structure, Arity,...)
#define INDEX_SCAN(Structure, Arity,...)
#define TUPLE_COPY_FROM(dst, src)
RamDomain evalChoice(const Rel &rel, const ram::Choice &cur, const Choice &shadow, Context &ctxt)
#define COMPARE_EQ_NE(opCode, op)
const std::vector< void * > & loadDLL()
Load DLL.
std::map< std::string, std::deque< std::atomic< size_t > > > frequencies
Profile for rule frequencies.
void startTimer()
Start timer.
class souffle::profile::Tui ss
#define PROVENANCE_EXISTENCE_CHECK(Structure, Arity,...)
SymbolTable & getSymbolTable()
Return the string symbol table.
Own< ReadStream > getReader(const std::map< std::string, std::string > &rwOperation, SymbolTable &symbolTable, RecordTable &recordTable) const
Return a new ReadStream.