mirror of https://github.com/exaloop/codon
Jupyter quanto fixes (#22)
* Add methods to check for passes/analyses * Fix xeus build * clang-format * Optimize JIT * Allow jit mode to take data from file * Fix OpenMP in JIT mode * Update JIT main * Update cloning Co-authored-by: Ibrahim Numanagić <ibrahimpasa@gmail.com>pull/27/head
parent
8bffbc88a5
commit
b47a9a844b
|
@ -155,7 +155,8 @@ if(CODON_JUPYTER)
|
||||||
OPTIONS "BUILD_EXAMPLES OFF"
|
OPTIONS "BUILD_EXAMPLES OFF"
|
||||||
"XEUS_BUILD_SHARED_LIBS OFF"
|
"XEUS_BUILD_SHARED_LIBS OFF"
|
||||||
"XEUS_STATIC_DEPENDENCIES ON"
|
"XEUS_STATIC_DEPENDENCIES ON"
|
||||||
"CMAKE_POSITION_INDEPENDENT_CODE ON")
|
"CMAKE_POSITION_INDEPENDENT_CODE ON"
|
||||||
|
"XEUS_DISABLE_ARCH_NATIVE ON")
|
||||||
if (xeus_ADDED)
|
if (xeus_ADDED)
|
||||||
install(TARGETS nlohmann_json EXPORT xeus-targets)
|
install(TARGETS nlohmann_json EXPORT xeus-targets)
|
||||||
endif()
|
endif()
|
||||||
|
|
|
@ -207,9 +207,26 @@ std::string jitExec(codon::jit::JIT *jit, const std::string &code) {
|
||||||
}
|
}
|
||||||
return *result;
|
return *result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void jitLoop(codon::jit::JIT *jit, std::istream &fp) {
|
||||||
|
std::string code;
|
||||||
|
for (std::string line; std::getline(fp, line);) {
|
||||||
|
if (line != "#%%") {
|
||||||
|
code += line + "\n";
|
||||||
|
} else {
|
||||||
|
fmt::print("{}[done]\n", jitExec(jit, code));
|
||||||
|
code = "";
|
||||||
|
fflush(stdout);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (!code.empty())
|
||||||
|
fmt::print("{}[done]\n", jitExec(jit, code));
|
||||||
|
}
|
||||||
} // namespace
|
} // namespace
|
||||||
|
|
||||||
int jitMode(const std::vector<const char *> &args) {
|
int jitMode(const std::vector<const char *> &args) {
|
||||||
|
llvm::cl::opt<std::string> input(llvm::cl::Positional, llvm::cl::desc("<input file>"),
|
||||||
|
llvm::cl::init("-"));
|
||||||
llvm::cl::list<std::string> plugins("plugin",
|
llvm::cl::list<std::string> plugins("plugin",
|
||||||
llvm::cl::desc("Load specified plugin"));
|
llvm::cl::desc("Load specified plugin"));
|
||||||
llvm::cl::opt<std::string> log("log", llvm::cl::desc("Enable given log streams"));
|
llvm::cl::opt<std::string> log("log", llvm::cl::desc("Enable given log streams"));
|
||||||
|
@ -233,18 +250,12 @@ int jitMode(const std::vector<const char *> &args) {
|
||||||
|
|
||||||
llvm::cantFail(jit.init());
|
llvm::cantFail(jit.init());
|
||||||
fmt::print(">>> Codon JIT v{} <<<\n", CODON_VERSION);
|
fmt::print(">>> Codon JIT v{} <<<\n", CODON_VERSION);
|
||||||
std::string code;
|
if (input == "-") {
|
||||||
for (std::string line; std::getline(std::cin, line);) {
|
jitLoop(&jit, std::cin);
|
||||||
if (line != "#%%") {
|
|
||||||
code += line + "\n";
|
|
||||||
} else {
|
} else {
|
||||||
fmt::print("{}[done]\n", jitExec(&jit, code));
|
std::ifstream fileInput(input);
|
||||||
code = "";
|
jitLoop(&jit, fileInput);
|
||||||
fflush(stdout);
|
|
||||||
}
|
}
|
||||||
}
|
|
||||||
if (!code.empty())
|
|
||||||
fmt::print("{}[done]\n", jitExec(&jit, code));
|
|
||||||
return EXIT_SUCCESS;
|
return EXIT_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -15,7 +15,7 @@ llvm::Expected<llvm::orc::ThreadSafeModule>
|
||||||
Engine::optimizeModule(llvm::orc::ThreadSafeModule module,
|
Engine::optimizeModule(llvm::orc::ThreadSafeModule module,
|
||||||
const llvm::orc::MaterializationResponsibility &R) {
|
const llvm::orc::MaterializationResponsibility &R) {
|
||||||
module.withModuleDo([](llvm::Module &module) {
|
module.withModuleDo([](llvm::Module &module) {
|
||||||
ir::optimize(&module, /*debug=*/true, /*jit=*/true);
|
ir::optimize(&module, /*debug=*/false, /*jit=*/true);
|
||||||
});
|
});
|
||||||
return std::move(module);
|
return std::move(module);
|
||||||
}
|
}
|
||||||
|
|
|
@ -1067,7 +1067,6 @@ void SimplifyVisitor::visit(ClassStmt *stmt) {
|
||||||
seqassert(c, "not a class AST for {}", canonicalName);
|
seqassert(c, "not a class AST for {}", canonicalName);
|
||||||
preamble->globals.push_back(c->clone());
|
preamble->globals.push_back(c->clone());
|
||||||
c->suite = clone(suite);
|
c->suite = clone(suite);
|
||||||
|
|
||||||
}
|
}
|
||||||
stmts[0] = N<ClassStmt>(canonicalName, std::vector<Param>{}, N<SuiteStmt>(),
|
stmts[0] = N<ClassStmt>(canonicalName, std::vector<Param>{}, N<SuiteStmt>(),
|
||||||
Attr({Attr::Extend}), std::vector<ExprPtr>{},
|
Attr({Attr::Extend}), std::vector<ExprPtr>{},
|
||||||
|
|
|
@ -109,6 +109,28 @@ public:
|
||||||
explicit PassManager(bool debug = false, std::vector<std::string> disabled = {})
|
explicit PassManager(bool debug = false, std::vector<std::string> disabled = {})
|
||||||
: PassManager(debug ? Init::DEBUG : Init::RELEASE, std::move(disabled)) {}
|
: PassManager(debug ? Init::DEBUG : Init::RELEASE, std::move(disabled)) {}
|
||||||
|
|
||||||
|
/// Checks if the given pass is included in this manager.
|
||||||
|
/// @param key the pass key
|
||||||
|
/// @return true if manager has the given pass
|
||||||
|
bool hasPass(const std::string &key) {
|
||||||
|
for (auto &pair : passes) {
|
||||||
|
if (pair.first == key)
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Checks if the given analysis is included in this manager.
|
||||||
|
/// @param key the analysis key
|
||||||
|
/// @return true if manager has the given analysis
|
||||||
|
bool hasAnalysis(const std::string &key) {
|
||||||
|
for (auto &pair : analyses) {
|
||||||
|
if (pair.first == key)
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
/// Registers a pass and appends it to the execution order.
|
/// Registers a pass and appends it to the execution order.
|
||||||
/// @param pass the pass
|
/// @param pass the pass
|
||||||
/// @param insertBefore insert pass before the pass with this given key
|
/// @param insertBefore insert pass before the pass with this given key
|
||||||
|
|
|
@ -1,8 +1,61 @@
|
||||||
#include "cloning.h"
|
#include "cloning.h"
|
||||||
|
|
||||||
|
#include "codon/sir/util/operator.h"
|
||||||
|
|
||||||
namespace codon {
|
namespace codon {
|
||||||
namespace ir {
|
namespace ir {
|
||||||
namespace util {
|
namespace util {
|
||||||
|
namespace {
|
||||||
|
struct GatherLocals : public util::Operator {
|
||||||
|
std::vector<Var *> locals;
|
||||||
|
void preHook(Node *node) override {
|
||||||
|
for (auto *v : node->getUsedVariables()) {
|
||||||
|
if (!v->isGlobal())
|
||||||
|
locals.push_back(v);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
} // namespace
|
||||||
|
|
||||||
|
Value *CloneVisitor::clone(const Value *other, BodiedFunc *cloneTo) {
|
||||||
|
if (!other)
|
||||||
|
return nullptr;
|
||||||
|
|
||||||
|
if (cloneTo) {
|
||||||
|
auto *M = cloneTo->getModule();
|
||||||
|
GatherLocals gl;
|
||||||
|
const_cast<Value *>(other)->accept(gl);
|
||||||
|
for (auto *v : gl.locals) {
|
||||||
|
auto *clonedVar = M->N<Var>(v, v->getType(), v->isGlobal(), v->getName());
|
||||||
|
cloneTo->push_back(clonedVar);
|
||||||
|
forceRemap(v, clonedVar);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
auto id = other->getId();
|
||||||
|
if (ctx.find(id) == ctx.end()) {
|
||||||
|
other->accept(*this);
|
||||||
|
ctx[id] = result;
|
||||||
|
|
||||||
|
for (auto it = other->attributes_begin(); it != other->attributes_end(); ++it) {
|
||||||
|
const auto *attr = other->getAttribute(*it);
|
||||||
|
if (attr->needsClone()) {
|
||||||
|
ctx[id]->setAttribute(attr->clone(*this), *it);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return cast<Value>(ctx[id]);
|
||||||
|
}
|
||||||
|
|
||||||
|
Var *CloneVisitor::clone(const Var *other) {
|
||||||
|
if (!other)
|
||||||
|
return nullptr;
|
||||||
|
auto id = other->getId();
|
||||||
|
if (ctx.find(id) != ctx.end())
|
||||||
|
return cast<Var>(ctx[id]);
|
||||||
|
|
||||||
|
return const_cast<Var *>(other);
|
||||||
|
}
|
||||||
|
|
||||||
void CloneVisitor::visit(const Var *v) {
|
void CloneVisitor::visit(const Var *v) {
|
||||||
result = module->N<Var>(v, v->getType(), v->isGlobal(), v->getName());
|
result = module->N<Var>(v, v->getType(), v->isGlobal(), v->getName());
|
||||||
|
|
|
@ -12,7 +12,7 @@ private:
|
||||||
/// the clone context
|
/// the clone context
|
||||||
std::unordered_map<int, Node *> ctx;
|
std::unordered_map<int, Node *> ctx;
|
||||||
/// the result
|
/// the result
|
||||||
Node *result = nullptr;
|
Node *result;
|
||||||
/// the module
|
/// the module
|
||||||
Module *module;
|
Module *module;
|
||||||
/// true if break/continue loops should be cloned
|
/// true if break/continue loops should be cloned
|
||||||
|
@ -22,7 +22,8 @@ public:
|
||||||
/// Constructs a clone visitor.
|
/// Constructs a clone visitor.
|
||||||
/// @param module the module
|
/// @param module the module
|
||||||
/// @param cloneLoop true if break/continue loops should be cloned
|
/// @param cloneLoop true if break/continue loops should be cloned
|
||||||
explicit CloneVisitor(Module *module, bool cloneLoop = true) : module(module) {}
|
explicit CloneVisitor(Module *module, bool cloneLoop = true)
|
||||||
|
: ctx(), result(nullptr), module(module), cloneLoop(cloneLoop) {}
|
||||||
|
|
||||||
virtual ~CloneVisitor() noexcept = default;
|
virtual ~CloneVisitor() noexcept = default;
|
||||||
|
|
||||||
|
@ -69,38 +70,14 @@ public:
|
||||||
|
|
||||||
/// Clones a value, returning the previous value if other has already been cloned.
|
/// Clones a value, returning the previous value if other has already been cloned.
|
||||||
/// @param other the original
|
/// @param other the original
|
||||||
|
/// @param cloneTo the function to clone locals to, or null if none
|
||||||
/// @return the clone
|
/// @return the clone
|
||||||
Value *clone(const Value *other) {
|
Value *clone(const Value *other, BodiedFunc *cloneTo = nullptr);
|
||||||
if (!other)
|
|
||||||
return nullptr;
|
|
||||||
|
|
||||||
auto id = other->getId();
|
|
||||||
if (ctx.find(id) == ctx.end()) {
|
|
||||||
other->accept(*this);
|
|
||||||
ctx[id] = result;
|
|
||||||
|
|
||||||
for (auto it = other->attributes_begin(); it != other->attributes_end(); ++it) {
|
|
||||||
const auto *attr = other->getAttribute(*it);
|
|
||||||
if (attr->needsClone()) {
|
|
||||||
ctx[id]->setAttribute(attr->clone(*this), *it);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return cast<Value>(ctx[id]);
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Returns the original unless the variable has been force cloned.
|
/// Returns the original unless the variable has been force cloned.
|
||||||
/// @param other the original
|
/// @param other the original
|
||||||
/// @return the original or the previous clone
|
/// @return the original or the previous clone
|
||||||
Var *clone(const Var *other) {
|
Var *clone(const Var *other);
|
||||||
if (!other)
|
|
||||||
return nullptr;
|
|
||||||
auto id = other->getId();
|
|
||||||
if (ctx.find(id) != ctx.end())
|
|
||||||
return cast<Var>(ctx[id]);
|
|
||||||
|
|
||||||
return const_cast<Var *>(other);
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Clones a flow, returning the previous value if other has already been cloned.
|
/// Clones a flow, returning the previous value if other has already been cloned.
|
||||||
/// @param other the original
|
/// @param other the original
|
||||||
|
|
|
@ -113,8 +113,10 @@ VarValue *makeVar(Value *x, SeriesFlow *flow, BodiedFunc *parent, bool prepend)
|
||||||
const bool global = (parent == nullptr);
|
const bool global = (parent == nullptr);
|
||||||
auto *M = x->getModule();
|
auto *M = x->getModule();
|
||||||
auto *v = M->Nr<Var>(x->getType(), global);
|
auto *v = M->Nr<Var>(x->getType(), global);
|
||||||
if (global)
|
if (global) {
|
||||||
v->setName("_anon_global");
|
static int counter = 1;
|
||||||
|
v->setName("_anon_global_" + std::to_string(counter++));
|
||||||
|
}
|
||||||
auto *a = M->Nr<AssignInstr>(v, x);
|
auto *a = M->Nr<AssignInstr>(v, x);
|
||||||
if (prepend) {
|
if (prepend) {
|
||||||
flow->insert(flow->begin(), a);
|
flow->insert(flow->begin(), a);
|
||||||
|
|
|
@ -323,23 +323,29 @@ def _fork_call(microtask: cobj, args):
|
||||||
|
|
||||||
|
|
||||||
def _static_loop_outline_template(gtid_ptr: Ptr[i32], btid_ptr: Ptr[i32], args):
|
def _static_loop_outline_template(gtid_ptr: Ptr[i32], btid_ptr: Ptr[i32], args):
|
||||||
|
@nonpure
|
||||||
def _loop_step():
|
def _loop_step():
|
||||||
return 1
|
return 1
|
||||||
|
|
||||||
|
@nonpure
|
||||||
def _loop_loc_and_gtid(
|
def _loop_loc_and_gtid(
|
||||||
loc_ref: Ptr[Ident], reduction_loc_ref: Ptr[Ident], gtid: int
|
loc_ref: Ptr[Ident], reduction_loc_ref: Ptr[Ident], gtid: int
|
||||||
):
|
):
|
||||||
pass
|
pass
|
||||||
|
|
||||||
|
@nonpure
|
||||||
def _loop_body_stub(i, args):
|
def _loop_body_stub(i, args):
|
||||||
pass
|
pass
|
||||||
|
|
||||||
|
@nonpure
|
||||||
def _loop_schedule():
|
def _loop_schedule():
|
||||||
return (1 << 30) | 35 # nonmonotonic, dynamic chunked
|
return (1 << 30) | 35 # nonmonotonic, dynamic chunked
|
||||||
|
|
||||||
|
@nonpure
|
||||||
def _loop_shared_updates(args):
|
def _loop_shared_updates(args):
|
||||||
pass
|
pass
|
||||||
|
|
||||||
|
@nonpure
|
||||||
def _loop_reductions(args):
|
def _loop_reductions(args):
|
||||||
pass
|
pass
|
||||||
|
|
||||||
|
@ -371,23 +377,29 @@ def _static_loop_outline_template(gtid_ptr: Ptr[i32], btid_ptr: Ptr[i32], args):
|
||||||
|
|
||||||
|
|
||||||
def _static_chunked_loop_outline_template(gtid_ptr: Ptr[i32], btid_ptr: Ptr[i32], args):
|
def _static_chunked_loop_outline_template(gtid_ptr: Ptr[i32], btid_ptr: Ptr[i32], args):
|
||||||
|
@nonpure
|
||||||
def _loop_step():
|
def _loop_step():
|
||||||
return 1
|
return 1
|
||||||
|
|
||||||
|
@nonpure
|
||||||
def _loop_loc_and_gtid(
|
def _loop_loc_and_gtid(
|
||||||
loc_ref: Ptr[Ident], reduction_loc_ref: Ptr[Ident], gtid: int
|
loc_ref: Ptr[Ident], reduction_loc_ref: Ptr[Ident], gtid: int
|
||||||
):
|
):
|
||||||
pass
|
pass
|
||||||
|
|
||||||
|
@nonpure
|
||||||
def _loop_body_stub(i, args):
|
def _loop_body_stub(i, args):
|
||||||
pass
|
pass
|
||||||
|
|
||||||
|
@nonpure
|
||||||
def _loop_schedule():
|
def _loop_schedule():
|
||||||
return (1 << 30) | 35 # nonmonotonic, dynamic chunked
|
return (1 << 30) | 35 # nonmonotonic, dynamic chunked
|
||||||
|
|
||||||
|
@nonpure
|
||||||
def _loop_shared_updates(args):
|
def _loop_shared_updates(args):
|
||||||
pass
|
pass
|
||||||
|
|
||||||
|
@nonpure
|
||||||
def _loop_reductions(args):
|
def _loop_reductions(args):
|
||||||
pass
|
pass
|
||||||
|
|
||||||
|
@ -425,26 +437,33 @@ def _static_chunked_loop_outline_template(gtid_ptr: Ptr[i32], btid_ptr: Ptr[i32]
|
||||||
|
|
||||||
|
|
||||||
def _dynamic_loop_outline_template(gtid_ptr: Ptr[i32], btid_ptr: Ptr[i32], args):
|
def _dynamic_loop_outline_template(gtid_ptr: Ptr[i32], btid_ptr: Ptr[i32], args):
|
||||||
|
@nonpure
|
||||||
def _loop_step():
|
def _loop_step():
|
||||||
return 1
|
return 1
|
||||||
|
|
||||||
|
@nonpure
|
||||||
def _loop_loc_and_gtid(
|
def _loop_loc_and_gtid(
|
||||||
loc_ref: Ptr[Ident], reduction_loc_ref: Ptr[Ident], gtid: int
|
loc_ref: Ptr[Ident], reduction_loc_ref: Ptr[Ident], gtid: int
|
||||||
):
|
):
|
||||||
pass
|
pass
|
||||||
|
|
||||||
|
@nonpure
|
||||||
def _loop_body_stub(i, args):
|
def _loop_body_stub(i, args):
|
||||||
pass
|
pass
|
||||||
|
|
||||||
|
@nonpure
|
||||||
def _loop_schedule():
|
def _loop_schedule():
|
||||||
return (1 << 30) | 35 # nonmonotonic, dynamic chunked
|
return (1 << 30) | 35 # nonmonotonic, dynamic chunked
|
||||||
|
|
||||||
|
@nonpure
|
||||||
def _loop_shared_updates(args):
|
def _loop_shared_updates(args):
|
||||||
pass
|
pass
|
||||||
|
|
||||||
|
@nonpure
|
||||||
def _loop_reductions(args):
|
def _loop_reductions(args):
|
||||||
pass
|
pass
|
||||||
|
|
||||||
|
@nonpure
|
||||||
def _loop_ordered():
|
def _loop_ordered():
|
||||||
return False
|
return False
|
||||||
|
|
||||||
|
@ -510,6 +529,7 @@ def _spawn_and_run_task(
|
||||||
# spawns a new task for each loop iteration.
|
# spawns a new task for each loop iteration.
|
||||||
def _task_loop_outline_template(gtid_ptr: Ptr[i32], btid_ptr: Ptr[i32], args):
|
def _task_loop_outline_template(gtid_ptr: Ptr[i32], btid_ptr: Ptr[i32], args):
|
||||||
def _routine_stub(gtid: i32, data: cobj, P: type, S: type):
|
def _routine_stub(gtid: i32, data: cobj, P: type, S: type):
|
||||||
|
@nonpure
|
||||||
def _task_loop_body_stub(priv, shared):
|
def _task_loop_body_stub(priv, shared):
|
||||||
pass
|
pass
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue