├── eigen ├── devcontainer │ ├── Dockerfile │ └── devcontainer.json └── sample-solution │ ├── Eigen │ ├── Project.toml │ ├── src │ │ └── Eigen.jl │ └── Manifest.toml │ └── jleigen │ ├── CMakeLists.txt │ ├── jleigen_notemplates.cpp │ ├── jleigen_simpletemplates.cpp │ ├── jleigen_inheritance_map_wip.cpp │ └── jleigen.cpp └── README.md /eigen/devcontainer/Dockerfile: -------------------------------------------------------------------------------- 1 | FROM barche/libcxxwrapjulia:latest 2 | 3 | RUN apt-get update && apt-get install -y libeigen3-dev -------------------------------------------------------------------------------- /eigen/sample-solution/Eigen/Project.toml: -------------------------------------------------------------------------------- 1 | name = "Eigen" 2 | uuid = "278dc3df-1028-49cd-b698-cdaf125394af" 3 | authors = ["Bart Janssens "] 4 | version = "0.1.0" 5 | 6 | [deps] 7 | CxxWrap = "1f15a43c-97ca-5a2a-ae31-89f07a497df4" 8 | -------------------------------------------------------------------------------- /eigen/devcontainer/devcontainer.json: -------------------------------------------------------------------------------- 1 | { 2 | "dockerFile": "Dockerfile", 3 | "extensions": [ 4 | "julialang.language-julia", 5 | "ms-vscode.cpptools", 6 | "twxs.cmake", 7 | "ms-vscode.cmake-tools" 8 | ], 9 | "runArgs": ["--privileged"] 10 | } 11 | -------------------------------------------------------------------------------- /eigen/sample-solution/Eigen/src/Eigen.jl: -------------------------------------------------------------------------------- 1 | module Eigen 2 | 3 | using CxxWrap 4 | 5 | abstract type AbstractEigenMatrix{T,Rows,Cols,Storage} <: AbstractMatrix{T} end 6 | 7 | @wrapmodule "/workspaces/eigen-wrapper/build/lib/libjleigen" 8 | 9 | function __init__() 10 | @initcxx 11 | end 12 | 13 | Base.size(m::Matrix) = (rows(m),cols(m)) 14 | Base.IndexStyle(::Type{<:Matrix}) = IndexCartesian() 15 | 16 | const Matrix4d = Matrix{Float64, 4, 4, ColMajor} 17 | const MatrixXd = Matrix{Float64, Dynamic, Dynamic, ColMajor} 18 | 19 | end # module 20 | -------------------------------------------------------------------------------- /eigen/sample-solution/jleigen/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | project(JlEigen) 2 | 3 | cmake_minimum_required(VERSION 3.1) 4 | 5 | set(CMAKE_MACOSX_RPATH 1) 6 | set(CMAKE_LIBRARY_OUTPUT_DIRECTORY "${CMAKE_BINARY_DIR}/lib") 7 | 8 | find_package(JlCxx) 9 | get_target_property(JlCxx_location JlCxx::cxxwrap_julia LOCATION) 10 | get_filename_component(JlCxx_location ${JlCxx_location} DIRECTORY) 11 | set(CMAKE_INSTALL_RPATH "${CMAKE_INSTALL_PREFIX}/lib;${JlCxx_location}") 12 | 13 | find_package (Eigen3 3.3 REQUIRED NO_MODULE) 14 | 15 | add_library(jleigen SHARED jleigen.cpp) 16 | 17 | target_link_libraries(jleigen JlCxx::cxxwrap_julia JlCxx::cxxwrap_julia_stl Eigen3::Eigen) 18 | 19 | install(TARGETS jleigen 20 | ARCHIVE DESTINATION lib 21 | LIBRARY DESTINATION lib 22 | RUNTIME DESTINATION bin) -------------------------------------------------------------------------------- /eigen/sample-solution/jleigen/jleigen_notemplates.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | #include 5 | 6 | 7 | JLCXX_MODULE define_julia_module(jlcxx::Module& mod) 8 | { 9 | mod.add_type("MatrixXd", jlcxx::julia_type("AbstractMatrixXd")) 10 | .constructor() 11 | .method("cols", &Eigen::MatrixXd::cols) 12 | .method("rows", &Eigen::MatrixXd::rows) 13 | .method("norm", &Eigen::MatrixXd::norm) 14 | .method("setConstant", static_cast(&Eigen::MatrixXd::setConstant)); 15 | 16 | mod.set_override_module(jl_base_module); 17 | mod.method("getindex", [](const Eigen::MatrixXd& m, int_t i, int_t j) { return m(i-1,j-1); }); 18 | mod.method("setindex!", [](Eigen::MatrixXd& m, double value, int_t i, int_t j) { m(i-1,j-1) = value; }); 19 | mod.unset_override_module(); 20 | 21 | mod.method("toString", [] (const Eigen::MatrixXd& m) 22 | { 23 | std::stringstream stream; 24 | stream << m; 25 | return stream.str(); 26 | }); 27 | 28 | } 29 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # cxxwrap-juliacon2020 2 | 3 | This repository hosts the tutorial files for a proposed JuliaCon 2020 workshop on [CxxWrap.jl](https://github.com/JuliaInterop/CxxWrap.jl). 4 | 5 | ## Prerequisites (do this before the workshop) 6 | 7 | The recommended method for new users is to use Docker. If you already have a C++ development setup, you should be able to follow the manual procedure also. The demo during the workshop will use the Docker approach because it works the same way on all platforms. 8 | 9 | ### Docker dev container 10 | 11 | * Install docker: https://docs.docker.com/get-docker/ 12 | * Install vscode: https://code.visualstudio.com 13 | * Launch vscode and install the `ms-vscode-remote.remote-containers` extension (just enter this id in the extension searchbox and click install) 14 | * Use the "Open repository in container" command to open https://github.com/barche/libfoo.git . **Note: This can take several minutes, it downloads a 2.7 GB docker image that includes some BinaryBuilder compiler shards** 15 | 16 | ### Manual setup 17 | #### Basic toolkit 18 | 19 | Aside from a working Julia 1.4 installation, a C++17 compiler is also needed to follow along the tutorial: 20 | * Linux: Install the packages containing g++ and CMake 21 | * macOS: Run `xcode-select --install` and install CMake from: https://cmake.org/download/ 22 | * Windows: Install Visual Studio Community edition from https://visualstudio.microsoft.com/vs/ and make sure to activate the "Desktop development with C++" workload, with CMake activated. 23 | 24 | #### Compile libcxxwrap-julia 25 | 26 | Follow the instructions at the https://github.com/JuliaInterop/libcxxwrap-julia README to build `libcxxwrap-julia` from scratch, and create an override file 27 | 28 | 29 | ## Tutorial 30 | 31 | Use the slides at https://barche.github.io/cxxwrap-juliacon2020/ to follow along during the workshop, for clickable links and code snippets. -------------------------------------------------------------------------------- /eigen/sample-solution/jleigen/jleigen_simpletemplates.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | #include 5 | 6 | 7 | namespace jleigen 8 | { 9 | struct WrapMatrix 10 | { 11 | template 12 | void operator()(TypeWrapperT&& wrapped) 13 | { 14 | using WrappedT = typename TypeWrapperT::type; 15 | using ScalarT = typename WrappedT::Scalar; 16 | wrapped.template constructor(); 17 | wrapped.method("cols", &WrappedT::cols); 18 | wrapped.method("rows", &WrappedT::rows); 19 | wrapped.method("norm", &WrappedT::norm); 20 | wrapped.method("setConstant", static_cast(&WrappedT::setConstant)); 21 | 22 | wrapped.module().set_override_module(jl_base_module); 23 | wrapped.module().method("getindex", [](const WrappedT& m, int_t i, int_t j) { return m(i-1,j-1); }); 24 | wrapped.module().method("setindex!", [](WrappedT& m, ScalarT value, int_t i, int_t j) { m(i-1,j-1) = value; }); 25 | wrapped.module().unset_override_module(); 26 | 27 | wrapped.module().method("toString", [] (const WrappedT& m) 28 | { 29 | std::stringstream stream; 30 | stream << m; 31 | return stream.str(); 32 | }); 33 | } 34 | }; 35 | } 36 | 37 | namespace jlcxx 38 | { 39 | 40 | template 41 | struct BuildParameterList> 42 | { 43 | typedef ParameterList type; 44 | }; 45 | 46 | } 47 | 48 | 49 | JLCXX_MODULE define_julia_module(jlcxx::Module& mod) 50 | { 51 | using jlcxx::Parametric; 52 | using jlcxx::TypeVar; 53 | mod.add_type>>("Matrix", jlcxx::julia_type("AbstractMatrix")) 54 | .apply, Eigen::Matrix>(jleigen::WrapMatrix()); 55 | } 56 | -------------------------------------------------------------------------------- /eigen/sample-solution/Eigen/Manifest.toml: -------------------------------------------------------------------------------- 1 | # This file is machine-generated - editing it directly is not advised 2 | 3 | [[Base64]] 4 | uuid = "2a0f44e3-6c83-55bd-87e4-b1978d98bd5f" 5 | 6 | [[CxxWrap]] 7 | deps = ["Libdl", "MacroTools", "libcxxwrap_julia_jll"] 8 | git-tree-sha1 = "762359626941f45b21238eb373a0bcedf6b61dd7" 9 | uuid = "1f15a43c-97ca-5a2a-ae31-89f07a497df4" 10 | version = "0.11.0" 11 | 12 | [[Dates]] 13 | deps = ["Printf"] 14 | uuid = "ade2ca70-3891-5945-98fb-dc099432e06a" 15 | 16 | [[InteractiveUtils]] 17 | deps = ["Markdown"] 18 | uuid = "b77e0a4c-d291-57a0-90e8-8db25a27a240" 19 | 20 | [[LibGit2]] 21 | deps = ["Printf"] 22 | uuid = "76f85450-5226-5b5a-8eaa-529ad045b433" 23 | 24 | [[Libdl]] 25 | uuid = "8f399da3-3557-5675-b5ff-fb832c97cbdb" 26 | 27 | [[Logging]] 28 | uuid = "56ddb016-857b-54e1-b83d-db4d58db5568" 29 | 30 | [[MacroTools]] 31 | deps = ["Markdown", "Random"] 32 | git-tree-sha1 = "f7d2e3f654af75f01ec49be82c231c382214223a" 33 | uuid = "1914dd2f-81c6-5fcd-8719-6d5c9610ff09" 34 | version = "0.5.5" 35 | 36 | [[Markdown]] 37 | deps = ["Base64"] 38 | uuid = "d6f4376e-aef5-505a-96c1-9c027394607a" 39 | 40 | [[Pkg]] 41 | deps = ["Dates", "LibGit2", "Libdl", "Logging", "Markdown", "Printf", "REPL", "Random", "SHA", "UUIDs"] 42 | uuid = "44cfe95a-1eb2-52ea-b672-e2afdf69b78f" 43 | 44 | [[Printf]] 45 | deps = ["Unicode"] 46 | uuid = "de0858da-6303-5e67-8744-51eddeeeb8d7" 47 | 48 | [[REPL]] 49 | deps = ["InteractiveUtils", "Markdown", "Sockets"] 50 | uuid = "3fa0cd96-eef1-5676-8a61-b3b8758bbffb" 51 | 52 | [[Random]] 53 | deps = ["Serialization"] 54 | uuid = "9a3f8284-a2c9-5f02-9a11-845980a1fd5c" 55 | 56 | [[SHA]] 57 | uuid = "ea8e919c-243c-51af-8825-aaa63cd721ce" 58 | 59 | [[Serialization]] 60 | uuid = "9e88b42a-f829-5b0c-bbe9-9e923198166b" 61 | 62 | [[Sockets]] 63 | uuid = "6462fe0b-24de-5631-8697-dd941f90decc" 64 | 65 | [[UUIDs]] 66 | deps = ["Random", "SHA"] 67 | uuid = "cf7118a7-6976-5b1a-9a39-7adc72f591a4" 68 | 69 | [[Unicode]] 70 | uuid = "4ec0a83e-493e-50e2-b9ac-8f72acf5a8f5" 71 | 72 | [[libcxxwrap_julia_jll]] 73 | deps = ["Libdl", "Pkg"] 74 | git-tree-sha1 = "1b2520ea0c1d5cbc12e8a97c15427133d726f743" 75 | uuid = "3eaa8342-bff7-56a5-9981-c04077f7cee7" 76 | version = "0.8.0+0" 77 | -------------------------------------------------------------------------------- /eigen/sample-solution/jleigen/jleigen_inheritance_map_wip.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | #include 5 | 6 | 7 | namespace jleigen 8 | { 9 | struct WrapMatrix 10 | { 11 | template 12 | void operator()(TypeWrapperT&& wrapped) 13 | { 14 | using WrappedT = typename TypeWrapperT::type; 15 | using ScalarT = typename WrappedT::Scalar; 16 | wrapped.template constructor(); 17 | wrapped.method("cols", &WrappedT::cols); 18 | wrapped.method("rows", &WrappedT::rows); 19 | wrapped.method("norm", &WrappedT::norm); 20 | wrapped.method("setConstant", static_cast(&WrappedT::setConstant)); 21 | 22 | wrapped.module().set_override_module(jl_base_module); 23 | wrapped.module().method("getindex", [](const WrappedT& m, int_t i, int_t j) { return m(i-1,j-1); }); 24 | wrapped.module().method("setindex!", [](WrappedT& m, ScalarT value, int_t i, int_t j) { m(i-1,j-1) = value; }); 25 | wrapped.module().unset_override_module(); 26 | 27 | wrapped.module().method("toString", [] (const WrappedT& m) 28 | { 29 | std::stringstream stream; 30 | stream << m; 31 | return stream.str(); 32 | }); 33 | } 34 | }; 35 | 36 | struct WrapMap 37 | { 38 | template 39 | void operator()(TypeWrapperT&& wrapped) 40 | { 41 | using WrappedT = typename TypeWrapperT::type; 42 | using ScalarT = typename WrappedT::Scalar; 43 | wrapped.template constructor(); 44 | } 45 | }; 46 | 47 | struct ApplyMatrix 48 | { 49 | template using apply = Eigen::Matrix; 50 | }; 51 | } 52 | 53 | namespace jlcxx 54 | { 55 | 56 | template 57 | struct BuildParameterList> 58 | { 59 | using type = ParameterList, std::integral_constant, std::integral_constant>; 60 | }; 61 | 62 | template 63 | struct BuildParameterList>> 64 | { 65 | using type = ParameterList, std::integral_constant, std::integral_constant>; 66 | }; 67 | 68 | template 69 | struct SuperType> 70 | { 71 | using type = typename Eigen::Map::Base::Base::Base::Base; 72 | }; 73 | 74 | } 75 | 76 | 77 | JLCXX_MODULE define_julia_module(jlcxx::Module& mod) 78 | { 79 | mod.set_const("Dynamic", int_t(Eigen::Dynamic)); 80 | 81 | mod.add_bits("StorageOptions", jlcxx::julia_type("CppEnum")); 82 | mod.set_const("ColMajor", Eigen::ColMajor); 83 | mod.set_const("RowMajor", Eigen::RowMajor); 84 | 85 | using jlcxx::Parametric; 86 | using jlcxx::TypeVar; 87 | using jlcxx::ParameterList; 88 | 89 | using scalar_types = ParameterList; 90 | using sizes = ParameterList, std::integral_constant>; 91 | using storage = ParameterList, std::integral_constant>; 92 | 93 | auto matrix_base = mod.add_type, TypeVar<2>, TypeVar<3>, TypeVar<4>>>("Matrix", jlcxx::julia_type("AbstractEigenMatrix")); 94 | matrix_base.apply_combination(jleigen::WrapMatrix()); 95 | 96 | mod.add_type, TypeVar<2>, TypeVar<3>, TypeVar<4>>>("Map", matrix_base.dt()) 97 | .apply>>(jleigen::WrapMap()); 98 | } 99 | -------------------------------------------------------------------------------- /eigen/sample-solution/jleigen/jleigen.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | 5 | #include 6 | 7 | 8 | namespace jleigen 9 | { 10 | struct WrapMatrix 11 | { 12 | template 13 | void operator()(TypeWrapperT&& wrapped) 14 | { 15 | using WrappedT = typename TypeWrapperT::type; 16 | using ScalarT = typename WrappedT::Scalar; 17 | wrapped.template constructor(); 18 | wrapped.method("cols", &WrappedT::cols); 19 | wrapped.method("rows", &WrappedT::rows); 20 | wrapped.method("norm", &WrappedT::norm); 21 | wrapped.method("setConstant", static_cast(&WrappedT::setConstant)); 22 | 23 | wrapped.module().set_override_module(jl_base_module); 24 | wrapped.module().method("getindex", [](const WrappedT& m, int_t i, int_t j) { return m(i-1,j-1); }); 25 | wrapped.module().method("setindex!", [](WrappedT& m, ScalarT value, int_t i, int_t j) { m(i-1,j-1) = value; }); 26 | wrapped.module().unset_override_module(); 27 | 28 | wrapped.module().method("toString", [] (const WrappedT& m) 29 | { 30 | std::stringstream stream; 31 | stream << m; 32 | return stream.str(); 33 | }); 34 | } 35 | }; 36 | 37 | struct ApplyMatrix 38 | { 39 | template using apply = Eigen::Matrix; 40 | }; 41 | 42 | class ExtendedMatrix : public Eigen::Matrix 43 | { 44 | public: 45 | using base_t = Eigen::Matrix; 46 | ExtendedMatrix() : base_t() { setConstant(1.0); } 47 | 48 | // This constructor allows you to construct ExtendedMatrix from Eigen expressions 49 | template 50 | ExtendedMatrix(const Eigen::MatrixBase& other) 51 | : base_t(other) 52 | { } 53 | 54 | // This method allows you to assign Eigen expressions to ExtendedMatrix 55 | template 56 | ExtendedMatrix& operator=(const Eigen::MatrixBase & other) 57 | { 58 | this->base_t::operator=(other); 59 | return *this; 60 | } 61 | }; 62 | } 63 | 64 | namespace jlcxx 65 | { 66 | 67 | template 68 | struct BuildParameterList> 69 | { 70 | using type = ParameterList, std::integral_constant, std::integral_constant>; 71 | }; 72 | 73 | template<> struct SuperType { using type = Eigen::Matrix; }; 74 | 75 | } 76 | 77 | 78 | JLCXX_MODULE define_julia_module(jlcxx::Module& mod) 79 | { 80 | mod.set_const("Dynamic", int_t(Eigen::Dynamic)); 81 | 82 | mod.add_bits("StorageOptions", jlcxx::julia_type("CppEnum")); 83 | mod.set_const("ColMajor", Eigen::ColMajor); 84 | mod.set_const("RowMajor", Eigen::RowMajor); 85 | 86 | using jlcxx::Parametric; 87 | using jlcxx::TypeVar; 88 | using jlcxx::ParameterList; 89 | 90 | using scalar_types = ParameterList; 91 | using sizes = ParameterList, std::integral_constant>; 92 | using storage = ParameterList, std::integral_constant>; 93 | 94 | auto matrix_base = mod.add_type, TypeVar<2>, TypeVar<3>, TypeVar<4>>>("Matrix", jlcxx::julia_type("AbstractEigenMatrix")); 95 | matrix_base.apply_combination(jleigen::WrapMatrix()); 96 | 97 | mod.add_type("ExtendedMatrix", jlcxx::julia_base_type>()); 98 | mod.method("make_shared", [] () 99 | { 100 | return std::make_shared(3,3); 101 | }); 102 | 103 | mod.method("processvec", [] (const std::vector& v) 104 | { 105 | for(auto val : v) 106 | { 107 | std::cout << val << std::endl; 108 | } 109 | }); 110 | } 111 | --------------------------------------------------------------------------------