Initial Jupyter support

pull/6/head
Ibrahim Numanagić 2021-11-09 03:47:41 -08:00
parent 5b0b7588be
commit 0c9974ff4c
7 changed files with 142 additions and 95 deletions

View File

@ -7,8 +7,16 @@ configure_file("${PROJECT_SOURCE_DIR}/cmake/config.h.in"
configure_file("${PROJECT_SOURCE_DIR}/cmake/config.py.in"
"${PROJECT_SOURCE_DIR}/docs/sphinx/config/config.py")
option(CODON_JUPYTER "build Codon Jupyter server" OFF)
if(CODON_JUPYTER)
configure_file(
"${CMAKE_CURRENT_SOURCE_DIR}/extra/jupyter/share/jupyter/kernels/codon/kernel.json.in"
"${CMAKE_CURRENT_SOURCE_DIR}/extra/jupyter/share/jupyter/kernels/codon/kernel.json"
)
endif()
set(CMAKE_CXX_STANDARD 17)
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fvisibility-inlines-hidden -pedantic -Wall -Wno-return-type-c-linkage -Wno-gnu-zero-variadic-macro-arguments")
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fvisibility-inlines-hidden -pedantic -Wall -Wno-return-type-c-linkage -Wno-gnu-zero-variadic-macro-arguments -Wno-unused-variable")
set(CMAKE_CXX_FLAGS_DEBUG "-g -fno-limit-debug-info")
set(CMAKE_CXX_FLAGS_RELEASE "-O3")
include_directories(.)
@ -21,6 +29,7 @@ message(STATUS "Found LLVM ${LLVM_PACKAGE_VERSION}")
message(STATUS "Using LLVMConfig.cmake in: ${LLVM_DIR}")
include(${CMAKE_SOURCE_DIR}/cmake/deps.cmake)
set(CMAKE_BUILD_WITH_INSTALL_RPATH ON)
if(APPLE)
set(CMAKE_INSTALL_RPATH "@loader_path;@loader_path/../lib/codon")
@ -196,7 +205,8 @@ set(CODON_HPPFILES
codon/util/toml++/toml_default_formatter.h
codon/util/toml++/toml_node.h
codon/util/toml++/toml_parser.hpp
codon/util/toml++/toml_utf8_streams.h)
codon/util/toml++/toml_utf8_streams.h
extra/jupyter/src/codon.h)
set(CODON_CPPFILES
codon/compiler/compiler.cpp
codon/compiler/engine.cpp
@ -273,9 +283,16 @@ set(CODON_CPPFILES
codon/sir/value.cpp
codon/sir/var.cpp
codon/util/common.cpp
codon/util/fmt/format.cpp)
codon/util/fmt/format.cpp
extra/jupyter/src/codon.cpp)
add_library(codonc SHARED ${CODON_HPPFILES})
target_sources(codonc PRIVATE ${CODON_CPPFILES} codon_rules.cpp omp_rules.cpp)
if(CODON_JUPYTER)
add_compile_definitions(CODON_JUPYTER)
add_dependencies(codonc xeus-static nlohmann_json)
target_link_libraries(codonc PRIVATE xeus-static)
# set_target_properties(codonc PROPERTIES INSTALL_RPATH_USE_LINK_PATH TRUE)
endif()
if(ASAN)
target_compile_options(codonc PRIVATE "-fno-omit-frame-pointer" "-fsanitize=address")
target_link_libraries(codonc PRIVATE "-fno-omit-frame-pointer" "-fsanitize=address")
@ -333,7 +350,7 @@ add_dependencies(headers codonrt codonc)
# Codon command-line tool
add_executable(codon codon/app/main.cpp)
target_link_libraries(codon ${STATIC_LIBCPP} codonc Threads::Threads)
target_link_libraries(codon PUBLIC ${STATIC_LIBCPP} codonc Threads::Threads)
# Codon test
# Download and unpack googletest at configure time
@ -365,59 +382,3 @@ target_include_directories(codon_test PRIVATE test/sir "${gc_SOURCE_DIR}/include
target_link_libraries(codon_test codonc codonrt gtest_main)
target_compile_definitions(codon_test PRIVATE TEST_DIR="${CMAKE_CURRENT_SOURCE_DIR}/test")
option(CODON_JUPYTER "build Codon Jupyter server" OFF)
if(CODON_JUPYTER)
configure_file("${CMAKE_CURRENT_SOURCE_DIR}/extra/jupyter/share/jupyter/kernels/codon/kernel.json.in"
"${CMAKE_CURRENT_SOURCE_DIR}/extra/jupyter/share/jupyter/kernels/codon/kernel.json")
CPMAddPackage(
NAME libzmq
VERSION 4.3.4
URL https://github.com/zeromq/libzmq/releases/download/v4.3.4/zeromq-4.3.4.tar.gz
OPTIONS "WITH_PERF_TOOL OFF"
"ZMQ_BUILD_TESTS OFF"
"ENABLE_CPACK OFF"
"BUILD_SHARED ON"
"WITH_LIBSODIUM OFF")
CPMAddPackage(
NAME cppzmq
URL https://github.com/zeromq/cppzmq/archive/refs/tags/v4.8.1.tar.gz
VERSION 4.8.1
OPTION "CPPZMQ_BUILD_TESTS OFF")
if(cppzmq_ADDED)
set_target_properties(unit_tests PROPERTIES EXCLUDE_FROM_ALL ON)
endif()
CPMAddPackage(
NAME xtl
GITHUB_REPOSITORY "xtensor-stack/xtl"
VERSION 0.7.3
GIT_TAG 0.7.3
OPTIONS "BUILD_TESTS OFF")
CPMAddPackage(
NAME json
GITHUB_REPOSITORY "nlohmann/json"
VERSION 3.10.4)
CPMAddPackage(
NAME xeus
GITHUB_REPOSITORY "jupyter-xeus/xeus"
VERSION 2.2.0
GIT_TAG 2.2.0
OPTIONS "BUILD_EXAMPLES OFF"
"XEUS_BUILD_SHARED_LIBS OFF"
"XEUS_STATIC_DEPENDENCIES ON")
if (xeus_ADDED)
install(TARGETS nlohmann_json EXPORT xeus-targets)
endif()
set(CODON_JUPYTER_SRC extra/jupyter/src/codon.cpp extra/jupyter/src/codon.h)
add_executable(codon-jupyter extra/jupyter/src/main.cpp ${CODON_JUPYTER_SRC})
add_dependencies(codon-jupyter xeus-static)
target_link_libraries(codon-jupyter PRIVATE xeus-static Threads::Threads codonc codonrt)
set_target_properties(codon-jupyter PROPERTIES INSTALL_RPATH_USE_LINK_PATH TRUE)
# Install kernel
install(TARGETS codon-jupyter RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR})
set(XJUPYTER_DATA_DIR extra/jupyter/share/jupyter CACHE STRING "Jupyter data directory")
set(KERNELSPEC_DIR ${CMAKE_CURRENT_SOURCE_DIR}/extra/jupyter/share/jupyter/kernels)
install(DIRECTORY ${KERNELSPEC_DIR} DESTINATION ${XJUPYTER_DATA_DIR} PATTERN "*.in" EXCLUDE)
endif()

View File

@ -123,3 +123,44 @@ if(backtrace_ADDED)
COMPILE_FLAGS "-funwind-tables -D_GNU_SOURCE"
POSITION_INDEPENDENT_CODE ON)
endif()
if(CODON_JUPYTER)
CPMAddPackage(
NAME libzmq
VERSION 4.3.4
URL https://github.com/zeromq/libzmq/releases/download/v4.3.4/zeromq-4.3.4.tar.gz
OPTIONS "WITH_PERF_TOOL OFF"
"ZMQ_BUILD_TESTS OFF"
"ENABLE_CPACK OFF"
"BUILD_SHARED ON"
"WITH_LIBSODIUM OFF")
CPMAddPackage(
NAME cppzmq
URL https://github.com/zeromq/cppzmq/archive/refs/tags/v4.8.1.tar.gz
VERSION 4.8.1
OPTION "CPPZMQ_BUILD_TESTS OFF")
if(cppzmq_ADDED)
set_target_properties(unit_tests PROPERTIES EXCLUDE_FROM_ALL ON)
endif()
CPMAddPackage(
NAME xtl
GITHUB_REPOSITORY "xtensor-stack/xtl"
VERSION 0.7.3
GIT_TAG 0.7.3
OPTIONS "BUILD_TESTS OFF")
CPMAddPackage(
NAME json
GITHUB_REPOSITORY "nlohmann/json"
VERSION 3.10.4)
CPMAddPackage(
NAME xeus
GITHUB_REPOSITORY "jupyter-xeus/xeus"
VERSION 2.2.0
GIT_TAG 2.2.0
OPTIONS "BUILD_EXAMPLES OFF"
"XEUS_BUILD_SHARED_LIBS OFF"
"XEUS_STATIC_DEPENDENCIES ON")
if (xeus_ADDED)
install(TARGETS nlohmann_json EXPORT xeus-targets)
endif()
endif()

View File

@ -279,6 +279,23 @@ int buildMode(const std::vector<const char *> &args) {
return EXIT_SUCCESS;
}
#ifdef CODON_JUPYTER
namespace codon {
int startJupyterKernel(const std::string &argv0, const std::string &configPath);
}
#endif
int jupyterMode(const std::vector<const char *> &args) {
#ifdef CODON_JUPYTER
int code = codon::startJupyterKernel(args[0], args.size() > 1 ? std::string(args[1])
: "connection.json");
return code;
#else
fmt::eprint("Jupyter support not included. Please recompile with "
"-DCODON_JUPYTER.");
return EXIT_FAILURE;
#endif
}
void showCommandsAndExit() {
codon::compilationError("Available commands: seqc <run|build|doc>");
}
@ -324,5 +341,9 @@ int main(int argc, const char **argv) {
args[0] = argv0.data();
return jitMode(args);
}
if (mode == "jupyter") {
args[0] = argv0.data();
return jupyterMode(args);
}
return otherMode({argv, argv + argc});
}

View File

@ -2,7 +2,7 @@
"display_name": "Codon",
"argv": [
"@CMAKE_INSTALL_PREFIX@/@CMAKE_INSTALL_BINDIR@/@EXECUTABLE_NAME@",
"-f",
"jupyter",
"{connection_file}"
],
"language": "python"

View File

@ -1,32 +1,59 @@
#include "codon.h"
#ifdef CODON_JUPYTER
#include <dirent.h>
#include <fcntl.h>
#include <iostream>
#include <nlohmann/json.hpp>
#include <unistd.h>
#include <xeus/xhelper.hpp>
#include <xeus/xkernel.hpp>
#include <xeus/xkernel_configuration.hpp>
#include <xeus/xserver_zmq.hpp>
#include "codon/compiler/compiler.h"
#include "codon/compiler/error.h"
#include "codon/compiler/jit.h"
#include "codon/util/common.h"
using std::move;
using std::string;
namespace nl = nlohmann;
namespace codon {
CodonJupyter::CodonJupyter(const std::string &argv0) : argv0(argv0) {}
nl::json CodonJupyter::execute_request_impl(int execution_counter, const string &code,
bool silent, bool store_history,
nl::json user_expressions,
bool allow_stdin) {
auto err = jit->exec(code);
nl::json pub_data;
pub_data["text/plain"] = "Hello World !!";
publish_execution_result(execution_counter, move(pub_data), nl::json::object());
// publish_execution_error("TypeError", "123", {"!@#$", "*(*"});
return xeus::create_successful_reply();
auto result = jit->exec(code);
bool failed = false;
llvm::handleAllErrors(
result.takeError(),
[&](const codon::error::ParserErrorInfo &e) {
std::vector<string> backtrace;
for (auto &msg : e)
backtrace.push_back(msg.getMessage());
string err = backtrace[0];
backtrace.erase(backtrace.begin());
publish_execution_error("ParserError", err, backtrace);
failed = true;
},
[&](const codon::error::RuntimeErrorInfo &e) {
publish_execution_error(e.getType(), e.getMessage(), {});
failed = true;
});
if (!failed) {
nl::json pub_data;
pub_data["text/plain"] = *result;
publish_execution_result(execution_counter, move(pub_data), nl::json::object());
}
}
void CodonJupyter::configure_impl() {
jit = std::make_unique<codon::jit::JIT>("");
jit = std::make_unique<codon::jit::JIT>(argv0);
llvm::cantFail(jit->init());
}
@ -50,4 +77,17 @@ nl::json CodonJupyter::kernel_info_request_impl() {
void CodonJupyter::shutdown_request_impl() {}
} // namespace codon
int startJupyterKernel(const std::string &argv0, const std::string &configPath) {
xeus::xconfiguration config = xeus::load_configuration(configPath);
auto context = xeus::make_context<zmq::context_t>();
auto interpreter = std::make_unique<CodonJupyter>(argv0);
xeus::xkernel kernel(config, xeus::get_user_name(), move(context), move(interpreter),
xeus::make_xserver_zmq);
kernel.start();
return 0;
}
} // namespace codon
#endif

View File

@ -1,5 +1,5 @@
#pragma once
#ifdef CODON_JUPYTER
#include <codon/compiler/jit.h>
#include <nlohmann/json.hpp>
#include <xeus/xinterpreter.hpp>
@ -10,6 +10,10 @@ namespace nl = nlohmann;
namespace codon {
class CodonJupyter : public xinterpreter {
std::unique_ptr<codon::jit::JIT> jit;
std::string argv0;
public:
CodonJupyter(const std::string &argv0);
private:
void configure_impl() override;
@ -29,4 +33,8 @@ private:
void shutdown_request_impl() override;
};
int startJupyterKernel(const std::string &argv0, const std::string &configPath);
} // namespace codon
#endif

View File

@ -1,24 +0,0 @@
#include "codon.h"
#include <memory>
#include <string>
#include <xeus/xkernel.hpp>
#include <xeus/xkernel_configuration.hpp>
#include <xeus/xserver_zmq.hpp>
using std::make_unique;
using std::move;
using std::string;
int main(int argc, char *argv[]) {
string file_name = (argc == 1) ? "connection.json" : argv[2];
xeus::xconfiguration config = xeus::load_configuration(file_name);
auto context = xeus::make_context<zmq::context_t>();
auto interpreter = make_unique<codon::CodonJupyter>();
xeus::xkernel kernel(config, xeus::get_user_name(), move(context), move(interpreter),
xeus::make_xserver_zmq);
kernel.start();
return 0;
}