souffle  2.0.2-371-g6315b36
Namespaces | Macros
Engine.cpp File Reference
#include "interpreter/Engine.h"
#include "AggregateOp.h"
#include "FunctorOps.h"
#include "Global.h"
#include "interpreter/Context.h"
#include "interpreter/Index.h"
#include "interpreter/Node.h"
#include "interpreter/Relation.h"
#include "interpreter/ViewContext.h"
#include "ram/Aggregate.h"
#include "ram/AutoIncrement.h"
#include "ram/Break.h"
#include "ram/Call.h"
#include "ram/Choice.h"
#include "ram/Clear.h"
#include "ram/Conjunction.h"
#include "ram/Constant.h"
#include "ram/Constraint.h"
#include "ram/DebugInfo.h"
#include "ram/EmptinessCheck.h"
#include "ram/ExistenceCheck.h"
#include "ram/Exit.h"
#include "ram/Extend.h"
#include "ram/False.h"
#include "ram/Filter.h"
#include "ram/IO.h"
#include "ram/IndexAggregate.h"
#include "ram/IndexChoice.h"
#include "ram/IndexScan.h"
#include "ram/IntrinsicOperator.h"
#include "ram/LogRelationTimer.h"
#include "ram/LogSize.h"
#include "ram/LogTimer.h"
#include "ram/Loop.h"
#include "ram/Negation.h"
#include "ram/NestedIntrinsicOperator.h"
#include "ram/PackRecord.h"
#include "ram/Parallel.h"
#include "ram/ParallelAggregate.h"
#include "ram/ParallelChoice.h"
#include "ram/ParallelIndexAggregate.h"
#include "ram/ParallelIndexChoice.h"
#include "ram/ParallelIndexScan.h"
#include "ram/ParallelScan.h"
#include "ram/Program.h"
#include "ram/Project.h"
#include "ram/ProvenanceExistenceCheck.h"
#include "ram/Query.h"
#include "ram/Relation.h"
#include "ram/RelationSize.h"
#include "ram/Scan.h"
#include "ram/Sequence.h"
#include "ram/Statement.h"
#include "ram/SubroutineArgument.h"
#include "ram/SubroutineReturn.h"
#include "ram/Swap.h"
#include "ram/TranslationUnit.h"
#include "ram/True.h"
#include "ram/TupleElement.h"
#include "ram/TupleOperation.h"
#include "ram/UnpackRecord.h"
#include "ram/UserDefinedOperator.h"
#include "ram/utility/Visitor.h"
#include "souffle/BinaryConstraintOps.h"
#include "souffle/RamTypes.h"
#include "souffle/RecordTable.h"
#include "souffle/SignalHandler.h"
#include "souffle/SymbolTable.h"
#include "souffle/TypeAttribute.h"
#include "souffle/io/IOSystem.h"
#include "souffle/io/ReadStream.h"
#include "souffle/io/WriteStream.h"
#include "souffle/profile/Logger.h"
#include "souffle/profile/ProfileEvent.h"
#include "souffle/utility/EvaluatorUtil.h"
#include "souffle/utility/MiscUtil.h"
#include "souffle/utility/ParallelUtil.h"
#include "souffle/utility/StringUtil.h"
#include <algorithm>
#include <array>
#include <atomic>
#include <cassert>
#include <cstdint>
#include <cstdlib>
#include <cstring>
#include <deque>
#include <functional>
#include <iostream>
#include <iterator>
#include <map>
#include <memory>
#include <regex>
#include <sstream>
#include <string>
#include <utility>
#include <vector>
#include <dlfcn.h>
#include <ffi.h>

Go to the source code of this file.

Namespaces

 souffle
 
 souffle::interpreter
 

Macros

#define AGGREGATE(Structure, Arity, ...)
 
#define BASE_CASE(Kind)
 
#define BINARY_OP_INTEGRAL(opcode, op)
 
#define BINARY_OP_INTEGRAL_SHIFT(opcode, op, tySigned, tyUnsigned)
 
#define BINARY_OP_LOGICAL(opcode, op)   BINARY_OP_INTEGRAL(opcode, op)
 
#define BINARY_OP_NUMERIC(opcode, op)
 
#define BINARY_OP_SHIFT_MASK(ty, op)   return ramBitCast(EVAL_CHILD(ty, 0) op (EVAL_CHILD(ty, 1) & RAM_BIT_SHIFT_MASK))
 
#define BINARY_OP_TYPED(ty, op)   return ramBitCast(static_cast<ty>(EVAL_CHILD(ty, 0) op EVAL_CHILD(ty, 1)))
 
#define CAL_SEARCH_BOUND(superInfo, low, high)
 
#define CASE(...)   GET_MACRO(__VA_ARGS__, EXTEND_CASE, _Dummy, BASE_CASE)(__VA_ARGS__)
 
#define CHOICE(Structure, Arity, ...)
 
#define CLEAR(Structure, Arity, ...)
 
#define COMPARE(opCode, op)
 
#define COMPARE_EQ_NE(opCode, op)
 
#define COMPARE_NUMERIC(ty, op)   return EVAL_LEFT(ty) op EVAL_RIGHT(ty)
 
#define COMPARE_STRING(op)
 
#define CONV_FROM_STRING(op, ty)
 
#define CONV_TO_STRING(op, ty)   case FunctorOp::op: return getSymbolTable().lookup(std::to_string(EVAL_CHILD(ty, 0)));
 
#define DEBUG(Kind)   std::cout << "Running Node: " << #Kind << "\n";
 
#define dynamicLibSuffix   ".so";
 
#define EMPTINESS_CHECK(Structure, Arity, ...)
 
#define ESAC(Kind)
 
#define EVAL_CHILD(ty, idx)   ramBitCast<ty>(execute(shadow.getChild(idx), ctxt))
 
#define EVAL_LEFT(ty)   ramBitCast<ty>(execute(shadow.getLhs(), ctxt))
 
#define EVAL_RIGHT(ty)   ramBitCast<ty>(execute(shadow.getRhs(), ctxt))
 
#define EXISTENCE_CHECK(Structure, Arity, ...)
 
#define EXTEND_CASE(Kind, Structure, Arity)
 
#define FFI_RamFloat   ffi_type_float
 
#define FFI_RamSigned   ffi_type_sint32
 
#define FFI_RamUnsigned   ffi_type_uint32
 
#define FFI_Symbol   ffi_type_pointer
 
#define GET_MACRO(_1, _2, _3, NAME, ...)   NAME
 
#define INDEX_AGGREGATE(Structure, Arity, ...)
 
#define INDEX_CHOICE(Structure, Arity, ...)
 
#define INDEX_SCAN(Structure, Arity, ...)
 
#define MINMAX_NUMERIC(opCode, op)
 
#define MINMAX_OP(ty, op)
 
#define MINMAX_OP_SYM(op)
 
#define PARALLEL_AGGREGATE(Structure, Arity, ...)
 
#define PARALLEL_CHOICE(Structure, Arity, ...)
 
#define PARALLEL_INDEX_AGGREGATE(Structure, Arity, ...)
 
#define PARALLEL_INDEX_CHOICE(Structure, Arity, ...)
 
#define PARALLEL_INDEX_SCAN(Structure, Arity, ...)
 
#define PARALLEL_SCAN(Structure, Arity, ...)
 
#define PROJECT(Structure, Arity, ...)
 
#define PROVENANCE_EXISTENCE_CHECK(Structure, Arity, ...)
 
#define RELATION_SIZE(Structure, Arity, ...)
 
#define RUN_RANGE(ty)
 
#define SCAN(Structure, Arity, ...)
 
#define TUPLE_COPY_FROM(dst, src)
 
#define UNARY_OP(op, ty, func)
 

Macro Definition Documentation

◆ AGGREGATE

#define AGGREGATE (   Structure,
  Arity,
  ... 
)
Value:
CASE(Aggregate, Structure, Arity) \
const auto& rel = *static_cast<RelType*>(node->getRelation()); \
return evalAggregate(cur, *shadow.getCondition(), shadow.getExpr(), *shadow.getNestedOperation(), \
rel.scan(), ctxt); \
ESAC(Aggregate)

◆ BASE_CASE

#define BASE_CASE (   Kind)
Value:
case (I_##Kind): { \
return [&]() -> RamDomain { \
[[maybe_unused]] const auto& shadow = *static_cast<const interpreter::Kind*>(node); \
[[maybe_unused]] const auto& cur = *static_cast<const ram::Kind*>(node->getShadow());

◆ BINARY_OP_INTEGRAL

#define BINARY_OP_INTEGRAL (   opcode,
  op 
)
Value:
case FunctorOp:: opcode: BINARY_OP_TYPED(RamSigned , op); \
case FunctorOp::U##opcode: BINARY_OP_TYPED(RamUnsigned, op);

◆ BINARY_OP_INTEGRAL_SHIFT

#define BINARY_OP_INTEGRAL_SHIFT (   opcode,
  op,
  tySigned,
  tyUnsigned 
)
Value:
case FunctorOp:: opcode: BINARY_OP_SHIFT_MASK(tySigned , op); \
case FunctorOp::U##opcode: BINARY_OP_SHIFT_MASK(tyUnsigned , op);

◆ BINARY_OP_LOGICAL

#define BINARY_OP_LOGICAL (   opcode,
  op 
)    BINARY_OP_INTEGRAL(opcode, op)

◆ BINARY_OP_NUMERIC

#define BINARY_OP_NUMERIC (   opcode,
  op 
)
Value:
BINARY_OP_INTEGRAL(opcode, op) \
case FunctorOp::F##opcode: BINARY_OP_TYPED(RamFloat, op);

◆ BINARY_OP_SHIFT_MASK

#define BINARY_OP_SHIFT_MASK (   ty,
  op 
)    return ramBitCast(EVAL_CHILD(ty, 0) op (EVAL_CHILD(ty, 1) & RAM_BIT_SHIFT_MASK))

◆ BINARY_OP_TYPED

#define BINARY_OP_TYPED (   ty,
  op 
)    return ramBitCast(static_cast<ty>(EVAL_CHILD(ty, 0) op EVAL_CHILD(ty, 1)))

◆ CAL_SEARCH_BOUND

#define CAL_SEARCH_BOUND (   superInfo,
  low,
  high 
)
Value:
/** Unbounded and Constant */ \
TUPLE_COPY_FROM(low, superInfo.first); \
TUPLE_COPY_FROM(high, superInfo.second); \
/* TupleElement */ \
for (const auto& tupleElement : superInfo.tupleFirst) { \
low[tupleElement[0]] = ctxt[tupleElement[1]][tupleElement[2]]; \
} \
for (const auto& tupleElement : superInfo.tupleSecond) { \
high[tupleElement[0]] = ctxt[tupleElement[1]][tupleElement[2]]; \
} \
/* Generic */ \
for (const auto& expr : superInfo.exprFirst) { \
low[expr.first] = execute(expr.second.get(), ctxt); \
} \
for (const auto& expr : superInfo.exprSecond) { \
high[expr.first] = execute(expr.second.get(), ctxt); \
}

◆ CASE

#define CASE (   ...)    GET_MACRO(__VA_ARGS__, EXTEND_CASE, _Dummy, BASE_CASE)(__VA_ARGS__)

◆ CHOICE

#define CHOICE (   Structure,
  Arity,
  ... 
)
Value:
CASE(Choice, Structure, Arity) \
const auto& rel = *static_cast<RelType*>(node->getRelation()); \
return evalChoice(rel, cur, shadow, ctxt); \
ESAC(Choice)

◆ CLEAR

#define CLEAR (   Structure,
  Arity,
  ... 
)
Value:
CASE(Clear, Structure, Arity) \
auto& rel = *static_cast<RelType*>(node->getRelation()); \
rel.__purge(); \
return true; \
ESAC(Clear)

◆ COMPARE

#define COMPARE (   opCode,
  op 
)
Value:
case BinaryConstraintOp:: opCode: COMPARE_NUMERIC(RamSigned , op); \
case BinaryConstraintOp::U##opCode: COMPARE_NUMERIC(RamUnsigned, op); \
case BinaryConstraintOp::F##opCode: COMPARE_NUMERIC(RamFloat , op); \

◆ COMPARE_EQ_NE

#define COMPARE_EQ_NE (   opCode,
  op 
)
Value:
case BinaryConstraintOp:: opCode: COMPARE_NUMERIC(RamDomain , op); \
case BinaryConstraintOp::F##opCode: COMPARE_NUMERIC(RamFloat , op);

◆ COMPARE_NUMERIC

#define COMPARE_NUMERIC (   ty,
  op 
)    return EVAL_LEFT(ty) op EVAL_RIGHT(ty)

◆ COMPARE_STRING

#define COMPARE_STRING (   op)
Value:
return (getSymbolTable().resolve(EVAL_LEFT(RamDomain)) op \
getSymbolTable().resolve(EVAL_RIGHT(RamDomain)))

◆ CONV_FROM_STRING

#define CONV_FROM_STRING (   op,
  ty 
)
Value:
case FunctorOp::op: return evaluator::symbol2numeric<ty>( \
getSymbolTable().resolve(EVAL_CHILD(RamDomain, 0)));

◆ CONV_TO_STRING

#define CONV_TO_STRING (   op,
  ty 
)    case FunctorOp::op: return getSymbolTable().lookup(std::to_string(EVAL_CHILD(ty, 0)));

◆ DEBUG

#define DEBUG (   Kind)    std::cout << "Running Node: " << #Kind << "\n";

◆ dynamicLibSuffix

#define dynamicLibSuffix   ".so";

Definition at line 126 of file Engine.cpp.

◆ EMPTINESS_CHECK

#define EMPTINESS_CHECK (   Structure,
  Arity,
  ... 
)
Value:
CASE(EmptinessCheck, Structure, Arity) \
const auto& rel = *static_cast<RelType*>(node->getRelation()); \
return rel.empty(); \
ESAC(EmptinessCheck)

◆ ESAC

#define ESAC (   Kind)
Value:
} \
(); \
}

◆ EVAL_CHILD

#define EVAL_CHILD (   ty,
  idx 
)    ramBitCast<ty>(execute(shadow.getChild(idx), ctxt))

◆ EVAL_LEFT

#define EVAL_LEFT (   ty)    ramBitCast<ty>(execute(shadow.getLhs(), ctxt))

◆ EVAL_RIGHT

#define EVAL_RIGHT (   ty)    ramBitCast<ty>(execute(shadow.getRhs(), ctxt))

◆ EXISTENCE_CHECK

#define EXISTENCE_CHECK (   Structure,
  Arity,
  ... 
)
Value:
CASE(ExistenceCheck, Structure, Arity) \
return evalExistenceCheck<RelType>(shadow, ctxt); \
ESAC(ExistenceCheck)

◆ EXTEND_CASE

#define EXTEND_CASE (   Kind,
  Structure,
  Arity 
)
Value:
case (I_##Kind##_##Structure##_##Arity): { \
return [&]() -> RamDomain { \
[[maybe_unused]] const auto& shadow = *static_cast<const interpreter::Kind*>(node); \
[[maybe_unused]] const auto& cur = *static_cast<const ram::Kind*>(node->getShadow());\
using RelType = Relation<Arity, interpreter::Structure>;

◆ FFI_RamFloat

#define FFI_RamFloat   ffi_type_float

Definition at line 137 of file Engine.cpp.

◆ FFI_RamSigned

#define FFI_RamSigned   ffi_type_sint32

Definition at line 135 of file Engine.cpp.

◆ FFI_RamUnsigned

#define FFI_RamUnsigned   ffi_type_uint32

Definition at line 136 of file Engine.cpp.

◆ FFI_Symbol

#define FFI_Symbol   ffi_type_pointer

Definition at line 140 of file Engine.cpp.

◆ GET_MACRO

#define GET_MACRO (   _1,
  _2,
  _3,
  NAME,
  ... 
)    NAME

◆ INDEX_AGGREGATE

#define INDEX_AGGREGATE (   Structure,
  Arity,
  ... 
)
Value:
CASE(IndexAggregate, Structure, Arity) \
return evalIndexAggregate<RelType>(cur, shadow, ctxt); \
ESAC(IndexAggregate)

◆ INDEX_CHOICE

#define INDEX_CHOICE (   Structure,
  Arity,
  ... 
)
Value:
CASE(IndexChoice, Structure, Arity) \
return evalIndexChoice<RelType>(cur, shadow, ctxt); \
ESAC(IndexChoice)

◆ INDEX_SCAN

#define INDEX_SCAN (   Structure,
  Arity,
  ... 
)
Value:
CASE(IndexScan, Structure, Arity) \
return evalIndexScan<RelType>(cur, shadow, ctxt); \
ESAC(IndexScan)

◆ MINMAX_NUMERIC

#define MINMAX_NUMERIC (   opCode,
  op 
)
Value:
case FunctorOp:: opCode: MINMAX_OP(RamSigned , op) \
case FunctorOp::U##opCode: MINMAX_OP(RamUnsigned, op) \
case FunctorOp::F##opCode: MINMAX_OP(RamFloat , op)

◆ MINMAX_OP

#define MINMAX_OP (   ty,
  op 
)
Value:
{ \
auto result = EVAL_CHILD(ty, 0); \
for (size_t i = 1; i < args.size(); i++) { \
result = op(result, EVAL_CHILD(ty, i)); \
} \
return ramBitCast(result); \
}

◆ MINMAX_OP_SYM

#define MINMAX_OP_SYM (   op)
Value:
{ \
auto result = EVAL_CHILD(RamDomain, 0); \
auto* result_val = &getSymbolTable().resolve(result); \
for (size_t i = 1; i < args.size(); i++) { \
auto alt = EVAL_CHILD(RamDomain, i); \
if (alt == result) continue; \
\
const auto& alt_val = getSymbolTable().resolve(alt); \
if (*result_val op alt_val) { \
result_val = &alt_val; \
result = alt; \
} \
} \
return result; \
}

◆ PARALLEL_AGGREGATE

#define PARALLEL_AGGREGATE (   Structure,
  Arity,
  ... 
)
Value:
CASE(ParallelAggregate, Structure, Arity) \
const auto& rel = *static_cast<RelType*>(node->getRelation()); \
return evalParallelAggregate(rel, cur, shadow, ctxt); \
ESAC(ParallelAggregate)

◆ PARALLEL_CHOICE

#define PARALLEL_CHOICE (   Structure,
  Arity,
  ... 
)
Value:
CASE(ParallelChoice, Structure, Arity) \
const auto& rel = *static_cast<RelType*>(node->getRelation()); \
return evalParallelChoice(rel, cur, shadow, ctxt); \
ESAC(ParallelChoice)

◆ PARALLEL_INDEX_AGGREGATE

#define PARALLEL_INDEX_AGGREGATE (   Structure,
  Arity,
  ... 
)
Value:
CASE(ParallelIndexAggregate, Structure, Arity) \
return evalParallelIndexAggregate<RelType>(cur, shadow, ctxt); \
ESAC(ParallelIndexAggregate)

◆ PARALLEL_INDEX_CHOICE

#define PARALLEL_INDEX_CHOICE (   Structure,
  Arity,
  ... 
)
Value:
CASE(ParallelIndexChoice, Structure, Arity) \
const auto& rel = *static_cast<RelType*>(node->getRelation()); \
return evalParallelIndexChoice(rel, cur, shadow, ctxt); \
ESAC(ParallelIndexChoice)

◆ PARALLEL_INDEX_SCAN

#define PARALLEL_INDEX_SCAN (   Structure,
  Arity,
  ... 
)
Value:
CASE(ParallelIndexScan, Structure, Arity) \
const auto& rel = *static_cast<RelType*>(node->getRelation()); \
return evalParallelIndexScan(rel, cur, shadow, ctxt); \
ESAC(ParallelIndexScan)

◆ PARALLEL_SCAN

#define PARALLEL_SCAN (   Structure,
  Arity,
  ... 
)
Value:
CASE(ParallelScan, Structure, Arity) \
const auto& rel = *static_cast<RelType*>(node->getRelation()); \
return evalParallelScan(rel, cur, shadow, ctxt); \
ESAC(ParallelScan)

◆ PROJECT

#define PROJECT (   Structure,
  Arity,
  ... 
)
Value:
CASE(Project, Structure, Arity) \
auto& rel = *static_cast<RelType*>(node->getRelation()); \
return evalProject(rel, shadow, ctxt); \
ESAC(Project)

◆ PROVENANCE_EXISTENCE_CHECK

#define PROVENANCE_EXISTENCE_CHECK (   Structure,
  Arity,
  ... 
)
Value:
CASE(ProvenanceExistenceCheck, Structure, Arity) \
return evalProvenanceExistenceCheck<RelType>(shadow, ctxt); \
ESAC(ProvenanceExistenceCheck)

◆ RELATION_SIZE

#define RELATION_SIZE (   Structure,
  Arity,
  ... 
)
Value:
CASE(RelationSize, Structure, Arity) \
const auto& rel = *static_cast<RelType*>(node->getRelation()); \
return rel.size(); \
ESAC(RelationSize)

◆ RUN_RANGE

#define RUN_RANGE (   ty)
Value:
numArgs == 3 \
? evaluator::runRange<ty>(EVAL_CHILD(ty, 0), EVAL_CHILD(ty, 1), EVAL_CHILD(ty, 2), runNested) \
: evaluator::runRange<ty>(EVAL_CHILD(ty, 0), EVAL_CHILD(ty, 1), runNested), \
true

◆ SCAN

#define SCAN (   Structure,
  Arity,
  ... 
)
Value:
CASE(Scan, Structure, Arity) \
const auto& rel = *static_cast<RelType*>(node->getRelation()); \
return evalScan(rel, cur, shadow, ctxt); \
ESAC(Scan)

◆ TUPLE_COPY_FROM

#define TUPLE_COPY_FROM (   dst,
  src 
)
Value:
assert(dst.size() == src.size()); \
std::copy_n(src.begin(), dst.size(), dst.begin())

◆ UNARY_OP

#define UNARY_OP (   op,
  ty,
  func 
)
Value:
case FunctorOp::op: { \
auto x = EVAL_CHILD(ty, 0); \
return ramBitCast(func(x)); \
}
souffle::RamUnsigned
uint32_t RamUnsigned
Definition: RamTypes.h:58
EVAL_LEFT
#define EVAL_LEFT(ty)
BINARY_OP_INTEGRAL
#define BINARY_OP_INTEGRAL(opcode, op)
MINMAX_OP
#define MINMAX_OP(ty, op)
souffle::RamDomain
int32_t RamDomain
Definition: RamTypes.h:56
low
d d low
Definition: htmlJsChartistMin.h:15
high
d high
Definition: htmlJsChartistMin.h:15
S
#define S(x)
Definition: test.h:179
souffle::RamFloat
float RamFloat
Definition: RamTypes.h:60
i
size_t i
Definition: json11.h:663
COMPARE_STRING
#define COMPARE_STRING(op)
EVAL_CHILD
#define EVAL_CHILD(ty, idx)
CASE
#define CASE(...)
COMPARE_NUMERIC
#define COMPARE_NUMERIC(ty, op)
EVAL_RIGHT
#define EVAL_RIGHT(ty)
souffle::ramBitCast
To ramBitCast(From source)
In C++20 there will be a new way to cast between types by reinterpreting bits (std::bit_cast),...
Definition: RamTypes.h:87
souffle::RamSigned
RamDomain RamSigned
Definition: RamTypes.h:57
BINARY_OP_TYPED
#define BINARY_OP_TYPED(ty, op)
rel
void rel(size_t limit, bool showLimit=true)
Definition: Tui.h:1086
BINARY_OP_SHIFT_MASK
#define BINARY_OP_SHIFT_MASK(ty, op)