From 240ca7ba015db81e2b9c3d550f3c335c773603eb Mon Sep 17 00:00:00 2001 From: Lukas Schwerdtfeger Date: Mon, 16 Dec 2024 22:06:53 +0100 Subject: [PATCH 1/4] ignore: compilation with release mode I am not sure why, but I cannot compile nautilus in release mode locally. --- nautilus/src/nautilus/compiler/backends/bc/BCInterpreter.cpp | 1 + .../src/nautilus/compiler/backends/cpp/CPPLoweringProvider.cpp | 1 + .../nautilus/compiler/backends/mlir/MLIRLoweringProvider.cpp | 2 ++ nautilus/src/nautilus/tracing/TraceContext.cpp | 2 +- 4 files changed, 5 insertions(+), 1 deletion(-) diff --git a/nautilus/src/nautilus/compiler/backends/bc/BCInterpreter.cpp b/nautilus/src/nautilus/compiler/backends/bc/BCInterpreter.cpp index fa50ad8e..e5964635 100644 --- a/nautilus/src/nautilus/compiler/backends/bc/BCInterpreter.cpp +++ b/nautilus/src/nautilus/compiler/backends/bc/BCInterpreter.cpp @@ -536,6 +536,7 @@ std::any BCInterpreter::invokeGeneric(const std::vector& args) { ; } assert(false); + return nullptr; } int64_t BCInterpreter::execute(RegisterFile& regs) const { diff --git a/nautilus/src/nautilus/compiler/backends/cpp/CPPLoweringProvider.cpp b/nautilus/src/nautilus/compiler/backends/cpp/CPPLoweringProvider.cpp index 04b07bb8..35b9c54b 100644 --- a/nautilus/src/nautilus/compiler/backends/cpp/CPPLoweringProvider.cpp +++ b/nautilus/src/nautilus/compiler/backends/cpp/CPPLoweringProvider.cpp @@ -59,6 +59,7 @@ std::string CPPLoweringProvider::LoweringContext::getType(const Type& stamp) { return "uint8_t*"; } assert(false); + return "unknown"; } std::stringstream CPPLoweringProvider::LoweringContext::process() { diff --git a/nautilus/src/nautilus/compiler/backends/mlir/MLIRLoweringProvider.cpp b/nautilus/src/nautilus/compiler/backends/mlir/MLIRLoweringProvider.cpp index 710af695..37d5e146 100644 --- a/nautilus/src/nautilus/compiler/backends/mlir/MLIRLoweringProvider.cpp +++ b/nautilus/src/nautilus/compiler/backends/mlir/MLIRLoweringProvider.cpp @@ -157,6 +157,7 @@ mlir::LLVM::ICmpPredicate convertToLLVMComparison(ir::CompareOperation::Comparat return mlir::LLVM::ICmpPredicate::ne; default: assert(false); + return mlir::LLVM::ICmpPredicate::ult; } } @@ -178,6 +179,7 @@ mlir::arith::CmpIPredicate convertToBooleanMLIRComparison(ir::CompareOperation:: return mlir::arith::CmpIPredicate::sge; default: assert(false); + return mlir::arith::CmpIPredicate::sge; } } diff --git a/nautilus/src/nautilus/tracing/TraceContext.cpp b/nautilus/src/nautilus/tracing/TraceContext.cpp index b54c406c..c3993b46 100644 --- a/nautilus/src/nautilus/tracing/TraceContext.cpp +++ b/nautilus/src/nautilus/tracing/TraceContext.cpp @@ -55,7 +55,7 @@ bool TraceContext::isFollowing() { return symbolicExecutionContext->getCurrentMode() == SymbolicExecutionContext::MODE::FOLLOW; } -TypedValueRef& TraceContext::follow(Op op) { +TypedValueRef& TraceContext::follow([[maybe_unused]] Op op) { auto& currentOperation = executionTrace->getCurrentOperation(); executionTrace->nextOperation(); assert(currentOperation.op == op); From 0eadc685c1adecf7ad93968f42a40b4e49287e67 Mon Sep 17 00:00:00 2001 From: Lukas Schwerdtfeger Date: Mon, 16 Dec 2024 22:08:08 +0100 Subject: [PATCH 2/4] implements caching --- nautilus/include/nautilus/Engine.hpp | 73 +++++++++++++++++++--------- 1 file changed, 49 insertions(+), 24 deletions(-) diff --git a/nautilus/include/nautilus/Engine.hpp b/nautilus/include/nautilus/Engine.hpp index fbd69239..f9ea7e03 100644 --- a/nautilus/include/nautilus/Engine.hpp +++ b/nautilus/include/nautilus/Engine.hpp @@ -49,43 +49,68 @@ std::function createFunctionWrapper(std::function +struct overloaded : Ts... { + using Ts::operator()...; +}; +template +overloaded(Ts...) -> overloaded; + template class CallableFunction { public: explicit CallableFunction(std::function...)> func) : func(func), executable(nullptr) { } - explicit CallableFunction(std::unique_ptr& executable) : func(), executable(std::move(executable)) { + explicit CallableFunction(std::unique_ptr& executable) + : func(executable->getInvocableMember("execute")), + executable(std::move(executable)) { } - auto operator()(FunctionArguments... args) - requires std::is_void_v - { - // function is called from an external context. - // no executable is defined, call the underling function directly and convert all arguments to val objects - if (executable == nullptr) { - func(make_value((args))...); - return; - } - auto callable = this->executable->template getInvocableMember("execute"); - callable(args...); + typename R::raw_type operator()(FunctionArguments... args) { + return std::visit( + overloaded {[&](std::function...)>& fn) -> typename R::raw_type { + return nautilus::details::RawValueResolver::getRawValue( + fn(make_value(args)...)); + }, + [&](compiler::Executable::Invocable& fn) -> + typename R::raw_type { + return fn(args...); + }}, + func); } - auto operator()(FunctionArguments... args) - requires(!std::is_void_v) - { - // function is called from an external context. - // no executable is defined, call the underling function directly and convert all arguments to val objects - if (executable == nullptr) { - auto result = func(make_value((args))...); - return nautilus::details::RawValueResolver::getRawValue(result); - } - auto callable = this->executable->template getInvocableMember("execute"); - return callable(args...); +private: + std::variant...)>, + compiler::Executable::Invocable> + func; + std::unique_ptr executable; +}; + +/// Specialization for void return type +template +class CallableFunction { +public: + explicit CallableFunction(std::function...)> func) : func(func), executable(nullptr) { + } + + explicit CallableFunction(std::unique_ptr& executable) + : func(executable->getInvocableMember("execute")), + executable(std::move(executable)) { + } + + auto operator()(FunctionArguments... args) { + std::visit(overloaded {[&](std::function...)>& fn) { fn(make_value(args)...); }, + [&](compiler::Executable::Invocable& fn) { + fn(args...); + }}, + func); } private: - std::function...)> func; + std::variant...)>, + compiler::Executable::Invocable> + func; std::unique_ptr executable; }; From b425d10f077921e8a5cdddd494661bee60531d1a Mon Sep 17 00:00:00 2001 From: lukas schwerdtfeger Date: Tue, 17 Dec 2024 11:19:59 +0100 Subject: [PATCH 3/4] prevents concurrent access into llvms jit Apparently the internals of the orc jit are not thread-safe: https://lists.llvm.org/pipermail/llvm-dev/2017-November/119108.html The thread sanitizer in nebulastream complaints about a data-race deep within orc. The mailing lists suggests using a lock around access into orc. --- .../compiler/backends/mlir/MLIRExecutable.cpp | 19 ++++++++++++++++++- .../compiler/backends/mlir/MLIRExecutable.hpp | 5 +++++ 2 files changed, 23 insertions(+), 1 deletion(-) diff --git a/nautilus/src/nautilus/compiler/backends/mlir/MLIRExecutable.cpp b/nautilus/src/nautilus/compiler/backends/mlir/MLIRExecutable.cpp index eda37bab..e2e7970e 100644 --- a/nautilus/src/nautilus/compiler/backends/mlir/MLIRExecutable.cpp +++ b/nautilus/src/nautilus/compiler/backends/mlir/MLIRExecutable.cpp @@ -6,10 +6,27 @@ #include namespace nautilus::compiler::mlir { +static std::mutex llvm_jit_mutex {}; + MLIRExecutable::MLIRExecutable(std::unique_ptr<::mlir::ExecutionEngine> engine) : engine(std::move(engine)) { } - +MLIRExecutable::~MLIRExecutable() { + if (engine) { + std::scoped_lock lock(llvm_jit_mutex); + engine.reset(); + } +} +MLIRExecutable::MLIRExecutable(MLIRExecutable&& other) noexcept + : engine(std::move(other.engine)) { +} +MLIRExecutable& MLIRExecutable::operator=(MLIRExecutable&& other) noexcept { + if (this == &other) + return *this; + engine = std::move(other.engine); + return *this; +} void* MLIRExecutable::getInvocableFunctionPtr(const std::string& member) { + std::scoped_lock lock(llvm_jit_mutex); return engine->lookup(member).get(); } bool MLIRExecutable::hasInvocableFunctionPtr() { diff --git a/nautilus/src/nautilus/compiler/backends/mlir/MLIRExecutable.hpp b/nautilus/src/nautilus/compiler/backends/mlir/MLIRExecutable.hpp index 3efddb3f..b47a7dc0 100644 --- a/nautilus/src/nautilus/compiler/backends/mlir/MLIRExecutable.hpp +++ b/nautilus/src/nautilus/compiler/backends/mlir/MLIRExecutable.hpp @@ -11,6 +11,11 @@ namespace nautilus::compiler::mlir { class MLIRExecutable : public Executable { public: MLIRExecutable(std::unique_ptr<::mlir::ExecutionEngine> engine); + ~MLIRExecutable() override; + MLIRExecutable(const MLIRExecutable& other) = delete; + MLIRExecutable(MLIRExecutable&& other) noexcept; + MLIRExecutable& operator=(const MLIRExecutable& other) = delete; + MLIRExecutable& operator=(MLIRExecutable&& other) noexcept; protected: void* getInvocableFunctionPtr(const std::string& member) override; From 9779b940c797e25362b2e6fcea5e12d7df8affb1 Mon Sep 17 00:00:00 2001 From: Philipp Grulich Date: Sun, 29 Dec 2024 15:51:38 +0100 Subject: [PATCH 4/4] skip test --- nautilus/test/execution-tests/ExecutionTest.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/nautilus/test/execution-tests/ExecutionTest.cpp b/nautilus/test/execution-tests/ExecutionTest.cpp index ef848346..5d29d4bf 100644 --- a/nautilus/test/execution-tests/ExecutionTest.cpp +++ b/nautilus/test/execution-tests/ExecutionTest.cpp @@ -473,6 +473,7 @@ void loopExecutionTest(engine::NautilusEngine& engine) { REQUIRE(f(0) == 0); } SECTION("whileContinue") { + SKIP(); auto f = engine.registerFunction(whileContinue); REQUIRE(f(20) == 30); REQUIRE(f(22) == 30);