Coder Social home page Coder Social logo

clemapfel / jluna Goto Github PK

View Code? Open in Web Editor NEW
231.0 3.0 10.0 1.35 MB

Julia Wrapper for C++ with Focus on Safety, Elegance, and Ease of Use

Home Page: https://clemens-cords.com/jluna

License: MIT License

CMake 3.46% C++ 89.91% Julia 6.63%
julia julia-language julialang julia-wrapper wrapper wrapper-api wrapper-library cpp cpp20 modern-cpp

jluna's People

Contributors

clemapfel avatar connorfuhrman avatar friendlyanon avatar granthecht avatar melonedo avatar pallharaldsson avatar paulerikf avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar

jluna's Issues

README FIRST

Welcome to the dark side of the jmoonluna

Please be patient and understanding when opening issues, we're a very small team, but we'll try our best to get back to you in a timely manner and implement fixes where they are needed.

If you are posting about a bug / crash / compiler error, please make sure you went through the troubleshooting steps outlined in the installation tutorial first.

If the issue is a runtime bug, please post the output of the CTest bundled with jluna. You can call it from inside jluna/build using

# in jluna/build
ctest --verbose

More information about this also available in the installation guide .

Thank you for helping jluna evolve!

Docker + JLuna

Thanks for building this library! and documenting it so well. I really look forward to using this in my projects.

I had a little bit of trouble trying to follow the documentation on how to install/setup jluna, so I wrote a small docker container to test things in.

If you wish to add a section in your documentation on this, it might be helpful.

In case it is helpful, here is my working dockerfile: https://github.com/dev10110/jluna-docker

Multi-threading example is not multi-threading

On Windows 10 and with julia 1.9.3-64 bit, the multi-threading examples from the documentation do not seem to multi-thread. The supposedly multi-threading tasks are executed in the main thread upon calling join(), they do not start before the sleep_for statement in main.

#include
#include <julia.h>
#include <jluna.hpp>
JULIA_DEFINE_FAST_TLS // only define this once, in an executable (not in a shared library) if you want fast code.

using namespace std;
using namespace jluna;

int main(int argc, char* argv[])
{
jluna::initialize(8);
std::vector<Task> tasks;
{
// declare lambda
std::function<void()> print_numbers = -> void
{
for (size_t i = 0; i < 10000; ++i)
if (i%100 == 0)
std::cout << i << std::endl;
};

	// add task to storage
	tasks.push_back(ThreadPool::create(print_numbers));

	// wait for 1ms
	std::this_thread::sleep_for(1ms);
}

for (auto& Task : tasks)
	Task.schedule();

// wait for another 10ms
std::this_thread::sleep_for(10000ms);
std::cout << "Main waited 10 sec" << std::endl;

for (auto& Task : tasks)
	Task.join();

return 0;

}

Idea: Use a manager thread to support full C++ multi-threading

I am calling Julia from C++ in kotekan, independent of jluna. (I was not aware of jluna when I implemented this.) kotekan is multi-threaded.

To support multi-threading, kotekan is using the following approach:

  • To initialize Julia, a new C++ thread ("Julia manager thread") is created
  • There is a global variable containing a task queue
  • The Julia manager thread waits for tasks in the queue and executes them
  • When a thread wants to call Julia, this call is placed onto the queue

A "task" is a std::function<void(void)> wrapping a closure. A std::future is used to return the value from Julia to the calling thread.

See https://github.com/kotekan/kotekan/blob/1b930517ab9fbc71cbc02a787af197a316627a09/lib/core/juliaManager.hpp and https://github.com/kotekan/kotekan/blob/1b930517ab9fbc71cbc02a787af197a316627a09/lib/core/juliaManager.cpp for the implementation in kotekan. A similar implementation would be possible for jluna.

Confusion about how sleeping main thread affects task execution

The multithreading docs show examples where sleep is called on the main c++ thread, but issues seem to arise in more complicated scenarios (i.e. if any calls to julia functions are made in the task code).

I've been trying to use jluna in a situation where I'm not fully in charge of the c++ thread. I use it to set up and schedule julia-side tasks, and then it sleeps and occasionally runs callbacks at intervals outside of my direct control.

In attempting to get this working I've become rather confused about how sleeping the main thread affects task execution.

Here's an example that hopefully illustrates what I'm seeing:

initialize(2);

auto lambda = [&]() {
    int i = 0;
    while(true) {
        // somehow print i
        i++;
    }
};

Task<void> t1 = ThreadPool::create<void()>(lambda);
t1.schedule();

while(true) {
    // somehow print "main_loop"
    // somehow sleep for 1s
}

Cases where sleep is done with std::this_thread::sleep_for(1000ms):

  • task and main thread use std::cout
    • task runs nonstop
  • task uses Julia println, main thread uses std::cout
    • task prints 0 then gets stuck forever
  • task and main thread use Julia println
    • task prints one number for every time main thread prints "main_thread"

Cases where sleep is done using Julia sleep function:

  • task runs nonstop no matter how print is done.

Extended examples:

Task and main thread use std::cout:

initialize(2);

auto lambda = [&]() {
    int i = 0;
    while(true) {
        std::cout << i << std::endl;
        i++;
    }
};

Task<void> t1 = ThreadPool::create<void()>(lambda);
t1.schedule();

while(true) {
    std::cout << "main_loop" << std::endl;
    std::this_thread::sleep_for(1000ms);
}
...
3444624
3444625
3444626
3444627
3444628
3444629
3444630
3444630
3444631
3444632
3444632
3444633
...

Task uses jl println, main thread uses std::cout

    initialize(2);
    auto println_jl = Main.safe_eval("return println");
    
    auto lambda = [&]() {
        int i = 0;
        while(true) {
            println_jl.safe_call<void>(i);
            i++;
        }
    };

    Task<void> t1 = ThreadPool::create<void()>(lambda);
    t1.schedule();

    while(true) {
        std::cout << "main_loop\n" << std::endl;
        std::this_thread::sleep_for(1000ms);
    }
[JULIA][LOG] initialization successful (4 thread(s)).
main_loop

0main_loop

main_loop

main_loop

main_loop

...

Both task and main thread us jl println

    initialize(2);
    auto println_jl = Main.safe_eval("return println");
    
    auto lambda = [&]() {
        int i = 0;
        while(true) {
            println_jl.safe_call<void>(i);
            i++;
        }
    };

    Task<void> t1 = ThreadPool::create<void()>(lambda);
    t1.schedule();

    while(true) {
        println_jl.safe_call<void>("main_loop");
        std::this_thread::sleep_for(1000ms);
    }
[JULIA][LOG] initialization successful (4 thread(s)).
main_loop
0
1
main_loop
2
main_loop
3
main_loop
4
main_loop
5
...

Installation failed on Ubuntu 22.04 with Julia 1.10.0-beta3

OS: Ubuntu 22.04
g++: 11.4.0
Julia version: 1.10.0-beta3

Error message after running make install:

[  7%] Building CXX object CMakeFiles/jluna.dir/.src/exceptions.cpp.o
[ 15%] Building CXX object CMakeFiles/jluna.dir/.src/unsafe_utilities.cpp.o
/home/lyx/opt/jluna/.src/unsafe_utilities.cpp: In function ‘void jluna::unsafe::resize_array(jluna::unsafe::Array*, uint64_t)’:
/home/lyx/opt/jluna/.src/unsafe_utilities.cpp:197:41: error: cannot convert ‘_jl_value_t*’ to ‘jl_datatype_t*’ {aka ‘_jl_datatype_t*’}
  197 |             auto* tuple = jl_new_struct(tuple_type, jl_box_int64(static_cast<Int64>(one_d)));
      |                                         ^~~~~~~~~~
      |                                         |
      |                                         _jl_value_t*
In file included from /home/lyx/opt/jluna/include/julia_wrapper.hpp:13,
                 from /home/lyx/opt/jluna/include/typedefs.hpp:8,
                 from /home/lyx/opt/jluna/include/unsafe_utilities.hpp:8,
                 from /home/lyx/opt/jluna/.src/unsafe_utilities.cpp:6:
/home/lyx/.julia/juliaup/julia-1.10.0-beta3+0.x64.linux.gnu/include/julia/julia.h:1573:55: note:   initializing argument 1 of ‘jl_value_t* jl_new_struct(jl_datatype_t*, ...)’
 1573 | JL_DLLEXPORT jl_value_t *jl_new_struct(jl_datatype_t *type, ...);
      |                                        ~~~~~~~~~~~~~~~^~~~
In file included from /home/lyx/.julia/juliaup/julia-1.10.0-beta3+0.x64.linux.gnu/include/julia/julia.h:80,
                 from /home/lyx/opt/jluna/include/julia_wrapper.hpp:13,
                 from /home/lyx/opt/jluna/include/typedefs.hpp:8,
                 from /home/lyx/opt/jluna/include/unsafe_utilities.hpp:8,
                 from /home/lyx/opt/jluna/.src/unsafe_utilities.cpp:6:
/home/lyx/.julia/juliaup/julia-1.10.0-beta3+0.x64.linux.gnu/include/julia/julia_threads.h:245:12: note: class type ‘_jl_value_t’ is incomplete
  245 |     struct _jl_value_t *sig_exception;
      |            ^~~~~~~~~~~
/home/lyx/opt/jluna/.src/unsafe_utilities.cpp: In function ‘void jluna::unsafe::resize_array(jluna::unsafe::Array*, uint64_t, uint64_t)’:
/home/lyx/opt/jluna/.src/unsafe_utilities.cpp:222:41: error: cannot convert ‘_jl_value_t*’ to ‘jl_datatype_t*’ {aka ‘_jl_datatype_t*’}
  222 |             auto* tuple = jl_new_struct(tuple_type, jl_box_int64(static_cast<Int64>(one_d)), jl_box_int64(static_cast<Int64>(two_d)));
      |                                         ^~~~~~~~~~
      |                                         |
      |                                         _jl_value_t*
In file included from /home/lyx/opt/jluna/include/julia_wrapper.hpp:13,
                 from /home/lyx/opt/jluna/include/typedefs.hpp:8,
                 from /home/lyx/opt/jluna/include/unsafe_utilities.hpp:8,
                 from /home/lyx/opt/jluna/.src/unsafe_utilities.cpp:6:
/home/lyx/.julia/juliaup/julia-1.10.0-beta3+0.x64.linux.gnu/include/julia/julia.h:1573:55: note:   initializing argument 1 of ‘jl_value_t* jl_new_struct(jl_datatype_t*, ...)’
 1573 | JL_DLLEXPORT jl_value_t *jl_new_struct(jl_datatype_t *type, ...);
      |                                        ~~~~~~~~~~~~~~~^~~~
In file included from /home/lyx/.julia/juliaup/julia-1.10.0-beta3+0.x64.linux.gnu/include/julia/julia.h:80,
                 from /home/lyx/opt/jluna/include/julia_wrapper.hpp:13,
                 from /home/lyx/opt/jluna/include/typedefs.hpp:8,
                 from /home/lyx/opt/jluna/include/unsafe_utilities.hpp:8,
                 from /home/lyx/opt/jluna/.src/unsafe_utilities.cpp:6:
/home/lyx/.julia/juliaup/julia-1.10.0-beta3+0.x64.linux.gnu/include/julia/julia_threads.h:245:12: note: class type ‘_jl_value_t’ is incomplete
  245 |     struct _jl_value_t *sig_exception;
      |            ^~~~~~~~~~~
make[2]: *** [CMakeFiles/jluna.dir/build.make:90: CMakeFiles/jluna.dir/.src/unsafe_utilities.cpp.o] Error 1
make[1]: *** [CMakeFiles/Makefile2:113: CMakeFiles/jluna.dir/all] Error 2
make: *** [Makefile:166: all] Error 2

Usertype best practices?

Hey clem, haven't been working with Jluna for a few weeks, but back at it.

Got a couple of quick question about usertypes best practices.

  1. How should I be setting up a jluna usertype for something I already have a Julia side type for?
    Should I be making an equivalent type through the jluna usertype system and doing conversions Julia side (or using multiple dispatch when possible)? Or could I somehow link my jluna usertype to the existing Julia side struct?

  2. Can I use a usertype in another usertype? Is there anything I need to do to make that possible?
    Currently getting the following error when trying to build the example below: In template: no member named 'type_name' in 'jluna::detail::as_julia_type_aux<JlunaStamp>'

#ifndef JLUNA_WRAPPER_JLUNA_STAMP_H
#define JLUNA_WRAPPER_JLUNA_STAMP_H
#include <jluna.hpp>
using namespace jluna;

struct JlunaStamp {
    Int32 sec;
    UInt32 nanosec;

    JlunaStamp() {}
    JlunaStamp(Int32 sec, UInt32 nanosec)
    : sec(sec), nanosec(nanosec) {}

    static void addProperties(jluna::Module m = jl_main_module);
};

set_usertype_enabled(JlunaStamp);

#endif //JLUNA_WRAPPER_JLUNA_STAMP_H

-------------------

#include <jluna_wrapper/types/jluna_stamp.h>

void JlunaStamp::addProperties(jluna::Module m) {
    jluna::Usertype<JlunaStamp>::add_property<Int32>(
            "sec",
            [](JlunaStamp& in) -> Int32 {return in.sec;},
            [](JlunaStamp& out, Int32 in) -> void {out.sec = in;}
    );
    jluna::Usertype<JlunaStamp>::add_property<UInt32>(
            "nanosec",
            [](JlunaStamp& in) -> UInt32 {return in.nanosec;},
            [](JlunaStamp& out, UInt32 in) -> void {out.nanosec = in;}
    );

    Usertype<JlunaStamp>::implement(m);
}
#ifndef JLUNA_WRAPPER_JLUNA_HEADER_H
#define JLUNA_WRAPPER_JLUNA_HEADER_H
#include <jluna.hpp>
#include <jluna_wrapper/types/jluna_stamp.h>
using namespace jluna;

struct JlunaHeader {
    JlunaStamp stamp;
    std::string frame_id;

    JlunaHeader() {}
    JlunaHeader(JlunaStamp stamp, std::string frame_id)
    : stamp(stamp), frame_id(frame_id) {}

    static void addProperties(jluna::Module m = jl_main_module);
};

set_usertype_enabled(JlunaHeader);

#endif //JLUNA_WRAPPER_JLUNA_HEADER_H

---------------------------

#include <jluna_wrapper/types/jluna_header.h>

void JlunaHeader::addProperties(jluna::Module m) {
    jluna::Usertype<JlunaHeader>::add_property<JlunaStamp>(
            "stamp",
            [](JlunaHeader& in) -> JlunaStamp {return in.stamp;},
            [](JlunaHeader& out, JlunaStamp in) -> void {out.stamp = in;}
    );
    jluna::Usertype<JlunaHeader>::add_property<std::string>(
            "frame_id",
            [](JlunaHeader& in) -> std::string {return in.frame_id;},
            [](JlunaHeader& out, std::string in) -> void {out.frame_id = in;}
    );


    Usertype<JlunaHeader>::implement(m);
}
    jluna::initialize();
    jluna::Module m = jluna::Main.safe_eval("return jluna_wrapper");
    JlunaStamp::addProperties(m);
    JlunaHeader::addProperties(m);

Error unsolved after troubleshooting: concept does not name a type

Hello,
I installed Jluna on my Ubuntu 20.04, and the tests were successfully passed.

Anyway, now I'm trying to construct a simple "hello world" test, but I'm finding an error
error: unknown type name 'concept' concept to_julia_type_convertable = requires(T) [and others...]
similar to the one that you already consider in the troubleshooting:
error: concept does not name a type.

I tried all the solutions that you proposed in the troubleshooting: updated my compilers (I tried clang++-12 and g++-10) and
_add target_compile_features(<your target> PRIVATE cxx_std_20)_
after the target creation.

Do you have any suggestions to solve the problem?
Thank you in advance.

P.S.:
I'm calling cmake with:

_cmake .. -DCMAKE_C_COMPILER=clang-12 -DCMAKE_CXX_COMPILER=clang++-12_

My CmakeList file is:

cmake_minimum_required(VERSION 3.12)

project(TestLib)

set(CMAKE_C_COMPILER "clang-12")
set(CMAKE_CXX_COMPILER "/usr/bin/clang++-12")
set(CMAKE_CXX_STANDARD 20)
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -v  -rpath" )#-lpthread")

set(CMAKE_LIBRARY_OUTPUT_DIRECTORY "${CMAKE_BINARY_DIR}")

find_library(jluna REQUIRED 
    NAMES jluna
    PATHS /home/user/jluna/
)

find_package(jluna REQUIRED)

add_executable(test test.cpp)

target_compile_features(test PRIVATE cxx_std_20)

target_link_libraries(test PRIVATE
    "${jluna}" 
    "${/home/user/julia-1.9.2/lib/}"
)

target_include_directories(test PRIVATE
    "/home/user/jluna"
    "/home/user/julia-1.9.2/include/julia"
)

v0.9.0 build issues Ubuntu g++10

I encounters some build issues with version 0.9.0 when building in Ubuntu 20.04.

  • Got an error that mutex isn't a member of namespace std and had to add a #include directive in safe_utilities.cpp
  • Got an error that reference to ThreadPool is ambiguous in a testing file and had to explicitly resolve namespace in friend class in multi_threading.inl

I was able to install and ctest did not report any errors so I'm assuming these changes are correct 🤷 . These are small changes so I'll submit a PR quickly and let y'all determine if my errors are one-offs or not.

OS: Ubuntu 20.04
Compiler: GCC 11 (installed via apt)

EXCEPTION_ACCESS_VIOLATION Windows 10 Visual Studio 2022

If I make an exe with VS 2022 with this code:

#include <iostream>
#include <jluna.hpp>

using namespace jluna;

int main()
{
    initialize();
    // our application here
    Array<Int64, 1> array = Main.safe_eval("return Int64[1, 2, 3, 4]");

    Int64 third = array[2];
    std::cout << third << std::endl;

    return 0;
}

I get the following EXCEPTION_ACCESS_VIOLATION.

Exception: EXCEPTION_ACCESS_VIOLATION at 0x7ff998aa1490 -- memcpy at C:\Windows\SYSTEM32\VCRUNTIME140.dll (unknown line)
in expression starting at none:0
memcpy at C:\Windows\SYSTEM32\VCRUNTIME140.dll (unknown line)
jluna::safe_eval at D:\julia-1.8.5-win64\Jluna_test\x64\Debug\jluna.dll (unknown line)
jluna::Module::safe_eval at D:\julia-1.8.5-win64\Jluna_test\x64\Debug\jluna.dll (unknown line)
unknown function (ip: 00007ff6fac75288)
unknown function (ip: 00007ff6fac76d58)
unknown function (ip: 00007ff6fac76c3d)
unknown function (ip: 00007ff6fac76afd)
unknown function (ip: 00007ff6fac76ded)
BaseThreadInitThunk at C:\Windows\System32\KERNEL32.DLL (unknown line)
RtlUserThreadStart at C:\Windows\SYSTEM32\ntdll.dll (unknown line)
Allocations: 1694229 (Pool: 1693071; Big: 1158); GC: 1

What could be the cause of this?

Inconsistent julia include directory

This package uses both #include <julia/julia.h>

#include <julia/julia.h>
and #include <julia.h>
#include <julia.h>
for include, while the build commands configures the include directory as /path/to/include/julia, which makes the file include/box.hpp error during compilation.
set(JULIA_INCLUDE "$ENV{JULIA_PATH}/include/julia")
include_directories(${JULIA_INCLUDE})

I am not sure whether I missed anything. Anyway, it is exciting to see this package!

Thread adoption

Hi!

I've got to admit I'm not a user of JLuna, but rather someone who's working on a similar library. Considering you've put a lot of effort in mutithreading support, I think you might also be interested in thread adoption. This is a feature that will be available in Julia 1.9 that can be used to create a pool of threads that can call into Julia.

Feel free to ask any questions you have, or close this issue if you're not interested :)

Linker error when casting Task to unsafe::Value*

Noticed that this example from the docs on interacting with julia-side Tasks fails to compile:

// declare lambda
auto lambda = [](){ //...
    
// create task
auto task = ThreadPool::create<void>(lambda);

// create proxy to task
auto task_proxy = Proxy(static_cast<unsafe::Value*>(task));

// all Julia-only attributes can now be accessed:
std::cout << (bool) task_proxy["sticky"] << std::endl;

make install output:

/usr/bin/ld: CMakeFiles/jluna_test.dir/.test/main.cpp.o: in function `main::$_90::operator()() const':
main.cpp:(.text+0x2a20a): undefined reference to `jluna::Task<unsigned long>::operator _jl_value_t*()'
clang: error: linker command failed with exit code 1 (use -v to see invocation)

operator unsafe::Value*() is declared in both Task<T> & Task<void>, but not implemented.

Multithreading crashes: KeyError in get_reference(key::UInt64) / free_reference(key::UInt64) && No method matching create_reference(::UInt64)

Hey there clem, I'm running into a few different crashes whenever I try multithreading. Here's a minimal example that tends to crash in 5 seconds or less. Am I misunderstanding the docs and doing something unsafe here?

ctest --verbose output is all fine (except for the resize_array test #25)
Ubuntu 20.04, Julia 1.7.1, clang-14

Minimal Example:

#include <jluna.hpp>

using namespace jluna;

int main() {
    initialize(4);

    auto lambda = [](){
        while(true) {
            Main.safe_eval("@info \"lambda:\" Threads.threadid()");
            Main.safe_eval("sleep(1)");
        }
    };

    Task<void> t1 = ThreadPool::create<void()>(lambda);
    t1.schedule();

    while(true) {
        Main.safe_eval("@info \"main:\" Threads.threadid()");
        Main.safe_eval("sleep(1)");
    }

    return 0;
}

Most common crash output
Worth noting the crash sometimes happens in free_reference(key::UInt64) rather than get_reference(key::UInt64).

terminate called after throwing an instance of 'jluna::JuliaException'
  what():  [JULIA][EXCEPTION] KeyError: key 0x00007f88f5adc750 not found
Stacktrace:
 [1] getindex
   @ ./dict.jl:481 [inlined]
 [2] get_reference(key::UInt64)
   @ Main.jluna.memory_handler ./none:594
 [3] safe_call(f::Function, args::UInt64)
   @ Main.jluna ./none:18
 [4] (::Main.jluna.cppcall.var"#3#4"{UInt64})()
   @ Main.jluna.cppcall ./none:813

signal (6): Aborted
in expression starting at none:1
gsignal at /lib/x86_64-linux-gnu/libc.so.6 (unknown line)
abort at /lib/x86_64-linux-gnu/libc.so.6 (unknown line)
unknown function (ip: 0x7f89591a9a30)
unknown function (ip: 0x7f89591b55db)
_ZSt9terminatev at /lib/x86_64-linux-gnu/libstdc++.so.6 (unknown line)
__cxa_throw at /lib/x86_64-linux-gnu/libstdc++.so.6 (unknown line)
safe_call<_jl_value_t *> at /home/frivold/kef_env/warm_dep_ws/install/jluna/include/jluna/.src/safe_utilities.inl:44
ProxyValue at /home/frivold/kef_env/warm_dep_ws/build/jluna/../../src/jluna/.src/proxy.cpp:31
Proxy at /home/frivold/kef_env/warm_dep_ws/build/jluna/../../src/jluna/.src/proxy.cpp:106
safe_eval at /home/frivold/kef_env/warm_dep_ws/build/jluna/../../src/jluna/.src/module.cpp:67
operator() at /home/frivold/kef_env/kef_ws/src/jluna_wrapper/src/jluna_test.cpp:11
_M_invoke at /usr/bin/../lib/gcc/x86_64-linux-gnu/9/../../../../include/c++/9/bits/std_function.h:300
operator() at /usr/bin/../lib/gcc/x86_64-linux-gnu/9/../../../../include/c++/9/bits/std_function.h:688
operator() at /home/frivold/kef_env/warm_dep_ws/install/jluna/include/jluna/.src/multi_threading.inl:327
_M_invoke at /usr/bin/../lib/gcc/x86_64-linux-gnu/9/../../../../include/c++/9/bits/std_function.h:285
#3 at ./none:813
unknown function (ip: 0x7f88f8d7453f)
_jl_invoke at /buildworker/worker/package_linux64/build/src/gf.c:2247 [inlined]
jl_apply_generic at /buildworker/worker/package_linux64/build/src/gf.c:2429
jl_apply at /buildworker/worker/package_linux64/build/src/julia.h:1788 [inlined]
start_task at /buildworker/worker/package_linux64/build/src/task.c:877
Allocations: 1620960 (Pool: 1620032; Big: 928); GC: 1

Less common crash output

terminate called after throwing an instance of 'jluna::JuliaException'
  what():  [JULIA][EXCEPTION] MethodError: no method matching create_reference(::UInt64)
Closest candidates are:
  create_reference(!Matched::Ptr{Nothing}) at none:546
  create_reference(!Matched::Nothing) at none:567
Stacktrace:
 [1] safe_call(f::Function, args::UInt64)
   @ Main.jluna ./none:18

signal (6): Aborted
in expression starting at none:0
gsignal at /lib/x86_64-linux-gnu/libc.so.6 (unknown line)
abort at /lib/x86_64-linux-gnu/libc.so.6 (unknown line)
unknown function (ip: 0x7f16feea8a30)
unknown function (ip: 0x7f16feeb45db)
_ZSt9terminatev at /lib/x86_64-linux-gnu/libstdc++.so.6 (unknown line)
__clang_call_terminate at /home/frivold/kef_env/warm_dep_ws/install/jluna/lib/libjluna.so.0.9.1 (unknown line)
~ProxyValue at /home/frivold/kef_env/warm_dep_ws/build/jluna/../../src/jluna/.src/proxy.cpp:62
_M_dispose at /usr/bin/../lib/gcc/x86_64-linux-gnu/9/../../../../include/c++/9/bits/shared_ptr_base.h:377
_M_release at /usr/bin/../lib/gcc/x86_64-linux-gnu/9/../../../../include/c++/9/bits/shared_ptr_base.h:155 [inlined]
~__shared_count at /usr/bin/../lib/gcc/x86_64-linux-gnu/9/../../../../include/c++/9/bits/shared_ptr_base.h:730 [inlined]
~__shared_ptr at /usr/bin/../lib/gcc/x86_64-linux-gnu/9/../../../../include/c++/9/bits/shared_ptr_base.h:1169 [inlined]
reset at /usr/bin/../lib/gcc/x86_64-linux-gnu/9/../../../../include/c++/9/bits/shared_ptr_base.h:1287 [inlined]
~Proxy at /home/frivold/kef_env/warm_dep_ws/build/jluna/../../src/jluna/.src/proxy.cpp:111
main at /home/frivold/kef_env/kef_ws/src/jluna_wrapper/src/jluna_test.cpp:31
__libc_start_main at /lib/x86_64-linux-gnu/libc.so.6 (unknown line)
_start at /home/frivold/kef_env/kef_ws/src/jluna_wrapper/cmake-build-debug/jluna_test (unknown line)
Allocations: 2722 (Pool: 2712; Big: 10); GC: 0

docs for simple examples, and necessity of unboxing

Dear Clem,
Thanks for this package. I am very interested in calling Julia from C (or C++ if it must be).
Forgive the newbie questions.

  1. docs. I struggled to find a simple "hello world" example - the "showcase" in the readme.md is too complicated for me, advertizing various advanced features that I cannot understand. I only use a bit of C++ and certainly not fancy features of C++20. As a scientific programmer I, and many others, would benefit most from a series of examples of calling simple julia code (first a command, then function, then module...) from C++ (or even from C if possible). So my request is: could you kindly simplify the first examples? (in the readme, and in the manual).

  2. unboxing. In the manual you describe that unboxing is essential. (maybe I misunderstood?). However, one needs to be able to simply pass pointers to existing arrays without forcing a copy each time, for obvious reasons (avoiding slow-down for relatively cheap functions performed on large arrays, and also for saving RAM in large problems).
    A year ago I set up some demos of C calling Julia, using pointers:

https://github.com/ahbarnett/multilingual-julia/tree/main/ccallj

These examples start simple (calling a julia base function, then a julia function, then a julia module).
Eg see https://github.com/ahbarnett/multilingual-julia/blob/main/ccallj/cfuncmodarr.c
which wraps multi-threaded functions in the simple julia module
https://github.com/ahbarnett/multilingual-julia/blob/main/ccallj/ArrMod.jl

They are incomplete, just a couple of days work, are not as elegant as I'd hoped (but SGJohnson helped), and nothing like the scale of your big project. (I also had trouble compiling/linking, as you will see from comments.)
However, they do show what we consider essential in scientific programming --- eg, passing large arrays by pointers, accessing multithreaded high-performance julia code from a low-level langauge --- so I would be curious if/how your project can showcase some similar very simple array-passing and multithreaded examples? Maybe my simple examples could influence some of the documented examples you start with? (ties back to part 1 above).
[Sadly I have not had time to use my own examples in projects yet, but plan to.]

Thanks and best wishes, Alex

Segfault when original Task object goes out of scope

Hey Clem, sorry to bother you with another issue. Not sure if I'm missing something basic here, but struggling to get multithreading working.

Quick stats before getting into things:

  • Ubuntu 20.04
  • Julia 1.7.1
  • Same behavior with gcc-11 & clang-14
  • On latest master ce9a1f5
  • ctests --verbose still pass w/ gcc-11 & still fail w/ clang-14
  • unsure if relevant at all, but still happens when preceeded by unsafe::gc_disable()

Ok, so I've been working my way through the multithreading docs, and things were great until I started trying to manage Task lifetimes.

Tasks seem to terminate the moment the original task object goes out of scope, even when it's added to an std::vector which is still in scope. If I create a task with auto task = ThreadPool::create(f) then add task to a std::vector, the task terminates when task goes out of scope, despite the vector still being in scope. Even more immediate, when I directly add the task to the std::vector with tasks.push_back(ThreadPool::create(f)) the program segfaults the moment I attempt tasks.back().schedule().

Not sure if that explanation made any sense, here are a few examples to hopefully illustrate what I'm seeing.

Basic example

using namespace jluna;

int main() {
    initialize(8);

    std::function<void()> f = []() -> void {
        std::cout << "This is Thread: " << ThreadPool::thread_id << std::endl;
    };

    // naive spawn task (this works fine)
    auto task = ThreadPool::create(f);
    task.schedule();
    task.join();

    // vector for managing task lifetimes
    std::vector<Task<void>> tasks;

    // spawn task into vector
    tasks.push_back(ThreadPool::create(f));
    tasks.back().schedule();
    tasks.back().join();
}
[JULIA][LOG] initialization successful (8 thread(s)).
This is Thread: 1

signal (11): Segmentation fault
in expression starting at none:0
unknown function (ip: 0x7fd2e8479e40)
operator() at /home/frivold/Code/jluna/install/include/jluna/.src/multi_threading.inl:252
__invoke_impl<_jl_value_t*, jluna::ThreadPool::create<>(const std::function<void()>&)::<lambda()>&> at /usr/include/c++/11/bits/invoke.h:61
__invoke_r<_jl_value_t*, jluna::ThreadPool::create<>(const std::function<void()>&)::<lambda()>&> at /usr/include/c++/11/bits/invoke.h:114
_M_invoke at /usr/include/c++/11/bits/std_function.h:291
_ZNKSt8functionIFP11_jl_value_tvEEclEv at /home/frivold/Code/jluna/install/libjluna.so.0.9.1 (unknown line)
jluna_invoke_from_task at /home/frivold/Code/jluna/install/libjluna.so.0.9.1 (unknown line)
#3 at ./none:813
unknown function (ip: 0x7fd2eb6ef89f)
_jl_invoke at /buildworker/worker/package_linux64/build/src/gf.c:2247 [inlined]
jl_apply_generic at /buildworker/worker/package_linux64/build/src/gf.c:2429
jl_apply at /buildworker/worker/package_linux64/build/src/julia.h:1788 [inlined]
start_task at /buildworker/worker/package_linux64/build/src/task.c:877
Allocations: 1626159 (Pool: 1625207; Big: 952); GC: 1

Process finished with exit code 139 (interrupted by signal 11: SIGSEGV)

Example with scope block

#include <jluna.hpp>

using namespace jluna;

int main() {
    initialize(8);
    auto println_jl = Main.safe_eval("return println");
    auto sleep_jl = Main.safe_eval("return sleep");

    std::function<void()> five_mississippi = [&]() -> void {
        for (int i=1; i<=5; i++) {
            println_jl(i, " Mississippi");
            sleep_jl(1);
        }
        println_jl("Done");
    };

    // vector for managing task lifetimes
    std::vector<Task<void>> tasks;

    // scope block
    {
        auto task = ThreadPool::create(five_mississippi);
        tasks.push_back(task);
        tasks.back().schedule();
        sleep_jl(2);
    }
    tasks.back().join();
}
[JULIA][LOG] initialization successful (8 thread(s)).
1 Mississippi
2 Mississippi

signal (11): Segmentation fault
in expression starting at none:0
jl_get_nth_field at /buildworker/worker/package_linux64/build/src/datatype.c:1392
_ZNK5jluna5Proxy10ProxyValue5valueEv at /home/frivold/Code/jluna/install/libjluna.so.0.9.1 (unknown line)
safe_call<int&, char const (&)[13]> at /home/frivold/Code/jluna/install/include/jluna/.src/proxy.inl:93
operator()<int&, char const (&)[13]> at /home/frivold/Code/jluna/install/include/jluna/.src/proxy.inl:115
operator() at /home/frivold/kef_env/kef_ws/src/jluna_wrapper/src/gcc_test.cpp:12
__invoke_impl<void, main()::<lambda()>&> at /usr/include/c++/11/bits/invoke.h:61
__invoke_r<void, main()::<lambda()>&> at /usr/include/c++/11/bits/invoke.h:111
_M_invoke at /usr/include/c++/11/bits/std_function.h:291
operator() at /usr/include/c++/11/bits/std_function.h:560
operator() at /home/frivold/Code/jluna/install/include/jluna/.src/multi_threading.inl:252
__invoke_impl<_jl_value_t*, jluna::ThreadPool::create<>(const std::function<void()>&)::<lambda()>&> at /usr/include/c++/11/bits/invoke.h:61
__invoke_r<_jl_value_t*, jluna::ThreadPool::create<>(const std::function<void()>&)::<lambda()>&> at /usr/include/c++/11/bits/invoke.h:114
_M_invoke at /usr/include/c++/11/bits/std_function.h:291
_ZNKSt8functionIFP11_jl_value_tvEEclEv at /home/frivold/Code/jluna/install/libjluna.so.0.9.1 (unknown line)
jluna_invoke_from_task at /home/frivold/Code/jluna/install/libjluna.so.0.9.1 (unknown line)
#3 at ./none:813
unknown function (ip: 0x7f9540090b9f)
_jl_invoke at /buildworker/worker/package_linux64/build/src/gf.c:2247 [inlined]
jl_apply_generic at /buildworker/worker/package_linux64/build/src/gf.c:2429
jl_apply at /buildworker/worker/package_linux64/build/src/julia.h:1788 [inlined]
start_task at /buildworker/worker/package_linux64/build/src/task.c:877
Allocations: 1625914 (Pool: 1624963; Big: 951); GC: 1

Process finished with exit code 139 (interrupted by signal 11: SIGSEGV)

Example from multithreading docs

int main() {
    using namespace jluna;
    using namespace std::chrono_literals;

    /// in main.cpp
    jluna::initialize(8);

    // task storage
    std::vector<Task<void>> tasks;

    {
        // declare lambda
        std::function<void()> print_numbers = []() -> void
        {
            for (size_t i = 0; i < 10000; ++i)
                std::cout << i << std::endl;
        };

        // add task to storage
        tasks.push_back(ThreadPool::create(print_numbers));

        // start just pushed task
        tasks.back().schedule();

        // wait for 1ms
        std::this_thread::sleep_for(1ms);
    }

    // wait for another 10ms
    std::this_thread::sleep_for(10ms);
    return 0;
}
[JULIA][LOG] initialization successful (8 thread(s)).

signal (11): Segmentation fault
in expression starting at none:0
unknown function (ip: 0x55cf03eabce0)
jluna_invoke_from_task at /home/frivold/Code/jluna/install/libjluna.so.0.9.1 (unknown line)
#3 at ./none:813
unknown function (ip: 0x7f0ac586291f)
_jl_invoke at /buildworker/worker/package_linux64/build/src/gf.c:2247 [inlined]
jl_apply_generic at /buildworker/worker/package_linux64/build/src/gf.c:2429
jl_apply at /buildworker/worker/package_linux64/build/src/julia.h:1788 [inlined]
start_task at /buildworker/worker/package_linux64/build/src/task.c:877
Allocations: 1626138 (Pool: 1625189; Big: 949); GC: 1

ctest --verbose fails when built with clang++-14

Note: This issue occurs for me when compiling with clang++-14, but not with g++-11.

Working my way through the install instructions, however, ctest --verbose fails after make install.

The test seems to segfault during unsafe: resize_array: reshape at unsafe::resize_array(arr, 5, 5);

signal (11): Segmentation fault
in expression starting at none:0
...

"Segmentation fault in expression starting at none:0" are mentioned in the troubleshooting guide, but specifically in a multithreading context.

Additional details:
Ubuntu 20.04
Using -DCMAKE_CXX_COMPILER=clang++-14 (Note: ctests pass when built with g++-11)

Full ctest --verbose output:

UpdateCTestConfiguration  from :/home/frivold/Code/jluna/build/DartConfiguration.tcl
Parse Config file:/home/frivold/Code/jluna/build/DartConfiguration.tcl
UpdateCTestConfiguration  from :/home/frivold/Code/jluna/build/DartConfiguration.tcl
Parse Config file:/home/frivold/Code/jluna/build/DartConfiguration.tcl
Test project /home/frivold/Code/jluna/build
Constructing a list of tests
Done constructing a list of tests
Updating test list for fixtures
Added 0 tests to meet fixture requirements
Checking test dependency graph...
Checking test dependency graph end
test 1
    Start 1: jluna_test

1: Test command: /home/frivold/Code/jluna/build/jluna_test
1: Test timeout computed to be: 1500
1: [JULIA][LOG] initialization successful (1 thread(s)).
1: starting test...
1:
1: c_adapter found: [OK]
1: unsafe: gc_push / gc_pop: [OK]
1: unsafe: gc: [OK]
1: unsafe: _sym: [OK]
1: as_julia_pointer: [OK]
1: unsafe: get_function: [OK]
1: unsafe: Expr & eval: [OK]
1: unsafe: get/set value: [OK]
1: unsafe: get_field: [OK]
1: unsafe: set_field: [OK]
1: unsafe: call: [OK]
1: unsafe: new_array: [OK]
1: unsafe: new_array_from_data: [OK]
1: unsafe: override_array: [OK]
1: unsafe: swap_array_data: [OK]
1: unsafe: set_array_data: [OK]
1:
1: signal (11): Segmentation fault
1: in expression starting at none:0
1: set_nth_field at /buildworker/worker/package_linux64/build/src/datatype.c:1498 [inlined]
1: jl_new_struct at /buildworker/worker/package_linux64/build/src/datatype.c:1251
1: _ZN5jluna6unsafe12resize_arrayEP10jl_array_tmm at /home/frivold/Code/jluna/install/libjluna.so.0.9.1 (unknown line)
1: _ZZ4mainENK4$_19clEv at /home/frivold/Code/jluna/build/jluna_test (unknown line)
1: _ZN5jluna6detail4Test4testIZ4mainE4$_19EEvNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEEOT_ at /home/frivold/Code/jluna/build/jluna_test (unknown line)
1: main at /home/frivold/Code/jluna/build/jluna_test (unknown line)
1: __libc_start_main at /lib/x86_64-linux-gnu/libc.so.6 (unknown line)
1: _start at /home/frivold/Code/jluna/build/jluna_test (unknown line)
1: Allocations: 1724877 (Pool: 1723947; Big: 930); GC: 3
1/1 Test #1: jluna_test .......................***Exception: SegFault  0.92 sec

0% tests passed, 1 tests failed out of 1

Total Test time (real) =   0.92 sec

The following tests FAILED:
          1 - jluna_test (SEGFAULT)
Errors while running CTest
Output from these tests are in: /home/frivold/Code/jluna/build/Testing/Temporary/LastTest.log
Use "--rerun-failed --output-on-failure" to re-run the failed cases verbosely.

Build Error on M1 MacBook Pro

I'm currently getting build errors (no matching function for call to box<size_t>(it) and unbox<size_t>(it)) on my M1 MacBook Pro when following the build instructions provided in README.md.

Here's the CMAKE configuration and make output:
buildoutput.txt

Apple aarch64 Compiler Error, unable to compile jluna

On Apple machines with the aarch64 architecture, such as the M1/M2 Macs, compiler errors of the following type may appear when compiling jluna. These is due to integer-sizes of common types such as size_t or uint64_t being unusually redefined on these platforms.

Currently, there is no fix for this, I'm sure it is perfectly fixable I just do not have access to a machine to test and debug for it, and Apple makes it impossible to legally obtain such a platform without spending the money to get a physical device.

In file included from /Users/username/Documents/dev/ExternalThreads/jluna/.test/main.cpp:4:
In file included from /Users/username/Documents/dev/ExternalThreads/jluna/jluna.hpp:23:
In file included from /Users/username/Documents/dev/ExternalThreads/jluna/include/module.hpp:281:
/Users/username/Documents/dev/ExternalThreads/jluna/.src/module.inl:256:32: error: no matching function for call to 'box'
        create_or_assign(name, box<std::tuple<Ts...>>(std::make_tuple(args...)));
                               ^~~~~~~~~~~~~~~~~~~~~~
/Users/username/Documents/dev/ExternalThreads/jluna/.test/main.cpp:542:25: note: in instantiation of function template specialization 'jluna::Module::new_tuple<unsigned long long, std::string, int>' requested here
        auto res = Main.new_tuple("test", std::get<0>(value), std::get<1>(value), std::get<2>(value));
                        ^
/Users/username/Documents/dev/ExternalThreads/jluna/.src/symbol.inl:24:27: note: candidate function template not viable: no known conversion from 'tuple<typename __unwrap_ref_decay<unsigned long long &>::type, typename __unwrap_ref_decay<string &>::type, typename __unwrap_ref_decay<int &>::type>' (aka 'tuple<unsigned long long, std::string, int>') to 'const std::string' (aka 'const basic_string<char>') for 1st argument
    inline unsafe::Value* box(const std::string& value)
                          ^
/Users/username/Documents/dev/ExternalThreads/jluna/.src/box.inl:26:20: note: candidate template ignored: constraints not satisfied [with T = std::tuple<unsigned long long, std::string, int>]
    unsafe::Value* box(T value)
                   ^
/Users/username/Documents/dev/ExternalThreads/jluna/.src/box.inl:25:14: note: because 'std::tuple<unsigned long long, std::string, int>' does not satisfy 'is_julia_value_pointer'
    template<is_julia_value_pointer T>
             ^
/Users/username/Documents/dev/ExternalThreads/jluna/include/concepts.hpp:139:9: note: because 'std::is_same_v<std::tuple<unsigned long long, std::string, int>, jl_value_t *>' evaluated to false
        std::is_same_v<T, jl_value_t*> or
        ^
/Users/username/Documents/dev/ExternalThreads/jluna/include/concepts.hpp:140:9: note: and 'std::is_same_v<std::tuple<unsigned long long, std::string, int>, jl_module_t *>' evaluated to false
        std::is_same_v<T, jl_module_t*> or
        ^
/Users/username/Documents/dev/ExternalThreads/jluna/include/concepts.hpp:141:9: note: and 'std::is_same_v<std::tuple<unsigned long long, std::string, int>, jl_array_t *>' evaluated to false
        std::is_same_v<T, jl_array_t*> or
        ^
/Users/username/Documents/dev/ExternalThreads/jluna/include/concepts.hpp:142:9: note: and 'std::is_same_v<std::tuple<unsigned long long, std::string, int>, jl_datatype_t *>' evaluated to false
        std::is_same_v<T, jl_datatype_t*> or
        ^
/Users/username/Documents/dev/ExternalThreads/jluna/include/concepts.hpp:143:9: note: and 'std::is_same_v<std::tuple<unsigned long long, std::string, int>, jl_function_t *>' evaluated to false
        std::is_same_v<T, jl_function_t*> or
        ^
/Users/username/Documents/dev/ExternalThreads/jluna/include/concepts.hpp:144:9: note: and 'std::is_same_v<std::tuple<unsigned long long, std::string, int>, jl_sym_t *>' evaluated to false
        std::is_same_v<T, jl_sym_t*> or
        ^
/Users/username/Documents/dev/ExternalThreads/jluna/include/concepts.hpp:145:9: note: and 'std::is_same_v<std::tuple<unsigned long long, std::string, int>, jl_expr_t *>' evaluated to false
        std::is_same_v<T, jl_expr_t*> or
        ^
/Users/username/Documents/dev/ExternalThreads/jluna/include/concepts.hpp:146:9: note: and 'std::is_same_v<std::tuple<unsigned long long, std::string, int>, jl_unionall_t *>' evaluated to false
        std::is_same_v<T, jl_unionall_t*>;
        ^
/Users/username/Documents/dev/ExternalThreads/jluna/.src/box.inl:32:20: note: candidate template ignored: constraints not satisfied [with T = std::tuple<unsigned long long, std::string, int>]
    unsafe::Value* box(T)
                   ^
/Users/username/Documents/dev/ExternalThreads/jluna/.src/box.inl:31:14: note: because 'is<std::tuple<unsigned long long, std::string, int>, std::nullptr_t>' evaluated to false
    template<is<std::nullptr_t> T>
             ^
/Users/username/Documents/dev/ExternalThreads/jluna/include/concepts.hpp:39:18: note: because 'std::conditional_t<std::is_void_v<tuple<unsigned long long, string, int> >, std::is_void<std::nullptr_t>, is_same_or_const<tuple<unsigned long long, string, int>, std::nullptr_t> >::value' evaluated to false
    concept is = std::conditional_t<
                 ^
/Users/username/Documents/dev/ExternalThreads/jluna/.src/box.inl:38:20: note: candidate template ignored: constraints not satisfied [with T = std::tuple<unsigned long long, std::string, int>]
    unsafe::Value* box(T value)
                   ^
/Users/username/Documents/dev/ExternalThreads/jluna/.src/box.inl:37:14: note: because 'is<std::tuple<unsigned long long, std::string, int>, void *>' evaluated to false
    template<is<void*> T>
             ^
/Users/username/Documents/dev/ExternalThreads/jluna/include/concepts.hpp:39:18: note: because 'std::conditional_t<std::is_void_v<tuple<unsigned long long, string, int> >, std::is_void<void *>, is_same_or_const<tuple<unsigned long long, string, int>, void *> >::value' evaluated to false
    concept is = std::conditional_t<
                 ^
/Users/username/Documents/dev/ExternalThreads/jluna/.src/box.inl:50:20: note: candidate template ignored: constraints not satisfied [with T = std::tuple<unsigned long long, std::string, int>]
    unsafe::Value* box(T value)
                   ^
/Users/username/Documents/dev/ExternalThreads/jluna/.src/box.inl:49:14: note: because 'is<std::tuple<unsigned long long, std::string, int>, _Bool>' evaluated to false
    template<is<bool> T>
             ^
/Users/username/Documents/dev/ExternalThreads/jluna/include/concepts.hpp:39:18: note: because 'std::conditional_t<std::is_void_v<tuple<unsigned long long, string, int> >, std::is_void<_Bool>, is_same_or_const<tuple<unsigned long long, string, int>, _Bool> >::value' evaluated to false
    concept is = std::conditional_t<
                 ^
/Users/username/Documents/dev/ExternalThreads/jluna/.src/box.inl:56:20: note: candidate template ignored: constraints not satisfied [with T = std::tuple<unsigned long long, std::string, int>]
    unsafe::Value* box(T)
                   ^
/Users/username/Documents/dev/ExternalThreads/jluna/.src/box.inl:55:14: note: because 'is<std::tuple<unsigned long long, std::string, int>, std::bool_constant<true> >' evaluated to false
    template<is<std::bool_constant<true>> T>
             ^
/Users/username/Documents/dev/ExternalThreads/jluna/include/concepts.hpp:39:18: note: because 'std::conditional_t<std::is_void_v<tuple<unsigned long long, string, int> >, std::is_void<integral_constant<_Bool, true> >, is_same_or_const<tuple<unsigned long long, string, int>, integral_constant<_Bool, true> > >::value' evaluated to false
    concept is = std::conditional_t<
                 ^
/Users/username/Documents/dev/ExternalThreads/jluna/.src/box.inl:62:20: note: candidate template ignored: constraints not satisfied [with T = std::tuple<unsigned long long, std::string, int>]
    unsafe::Value* box(T)
                   ^
/Users/username/Documents/dev/ExternalThreads/jluna/.src/box.inl:61:14: note: because 'is<std::tuple<unsigned long long, std::string, int>, std::bool_constant<false> >' evaluated to false
    template<is<std::bool_constant<false>> T>
             ^
/Users/username/Documents/dev/ExternalThreads/jluna/include/concepts.hpp:39:18: note: because 'std::conditional_t<std::is_void_v<tuple<unsigned long long, string, int> >, std::is_void<integral_constant<_Bool, false> >, is_same_or_const<tuple<unsigned long long, string, int>, integral_constant<_Bool, false> > >::value' evaluated to false
    concept is = std::conditional_t<
                 ^
/Users/username/Documents/dev/ExternalThreads/jluna/.src/box.inl:68:20: note: candidate template ignored: constraints not satisfied [with T = std::tuple<unsigned long long, std::string, int>]
    unsafe::Value* box(T value)
                   ^
/Users/username/Documents/dev/ExternalThreads/jluna/.src/box.inl:67:14: note: because 'is<std::tuple<unsigned long long, std::string, int>, char>' evaluated to false
    template<is<char> T>
             ^
/Users/username/Documents/dev/ExternalThreads/jluna/include/concepts.hpp:39:18: note: because 'std::conditional_t<std::is_void_v<tuple<unsigned long long, string, int> >, std::is_void<char>, is_same_or_const<tuple<unsigned long long, string, int>, char> >::value' evaluated to false
    concept is = std::conditional_t<
                 ^
/Users/username/Documents/dev/ExternalThreads/jluna/.src/box.inl:74:20: note: candidate template ignored: constraints not satisfied [with T = std::tuple<unsigned long long, std::string, int>]
    unsafe::Value* box(T value)
                   ^
/Users/username/Documents/dev/ExternalThreads/jluna/.src/box.inl:73:14: note: because 'is<std::tuple<unsigned long long, std::string, int>, uint8_t>' evaluated to false
    template<is<uint8_t> T>
             ^
/Users/username/Documents/dev/ExternalThreads/jluna/include/concepts.hpp:39:18: note: because 'std::conditional_t<std::is_void_v<tuple<unsigned long long, string, int> >, std::is_void<unsigned char>, is_same_or_const<tuple<unsigned long long, string, int>, unsigned char> >::value' evaluated to false
    concept is = std::conditional_t<
                 ^
/Users/username/Documents/dev/ExternalThreads/jluna/.src/box.inl:80:20: note: candidate template ignored: constraints not satisfied [with T = std::tuple<unsigned long long, std::string, int>]
    unsafe::Value* box(T value)
                   ^
/Users/username/Documents/dev/ExternalThreads/jluna/.src/box.inl:79:14: note: because 'is<std::tuple<unsigned long long, std::string, int>, uint16_t>' evaluated to false
    template<is<uint16_t> T>
             ^
/Users/username/Documents/dev/ExternalThreads/jluna/include/concepts.hpp:39:18: note: because 'std::conditional_t<std::is_void_v<tuple<unsigned long long, string, int> >, std::is_void<unsigned short>, is_same_or_const<tuple<unsigned long long, string, int>, unsigned short> >::value' evaluated to false
    concept is = std::conditional_t<
                 ^
/Users/username/Documents/dev/ExternalThreads/jluna/.src/box.inl:86:20: note: candidate template ignored: constraints not satisfied [with T = std::tuple<unsigned long long, std::string, int>]
    unsafe::Value* box(T value)
                   ^
/Users/username/Documents/dev/ExternalThreads/jluna/.src/box.inl:85:14: note: because 'is<std::tuple<unsigned long long, std::string, int>, uint32_t>' evaluated to false
    template<is<uint32_t> T>
             ^
/Users/username/Documents/dev/ExternalThreads/jluna/include/concepts.hpp:39:18: note: because 'std::conditional_t<std::is_void_v<tuple<unsigned long long, string, int> >, std::is_void<unsigned int>, is_same_or_const<tuple<unsigned long long, string, int>, unsigned int> >::value' evaluated to false
    concept is = std::conditional_t<
                 ^
/Users/username/Documents/dev/ExternalThreads/jluna/.src/box.inl:92:20: note: candidate template ignored: constraints not satisfied [with T = std::tuple<unsigned long long, std::string, int>]
    unsafe::Value* box(T value)
                   ^
/Users/username/Documents/dev/ExternalThreads/jluna/.src/box.inl:91:14: note: because 'is<std::tuple<unsigned long long, std::string, int>, uint64_t>' evaluated to false
    template<is<uint64_t> T>
             ^
/Users/username/Documents/dev/ExternalThreads/jluna/include/concepts.hpp:39:18: note: because 'std::conditional_t<std::is_void_v<tuple<unsigned long long, string, int> >, std::is_void<unsigned long long>, is_same_or_const<tuple<unsigned long long, string, int>, unsigned long long> >::value' evaluated to false
    concept is = std::conditional_t<
                 ^
/Users/username/Documents/dev/ExternalThreads/jluna/.src/box.inl:98:20: note: candidate template ignored: constraints not satisfied [with T = std::tuple<unsigned long long, std::string, int>]
    unsafe::Value* box(T value)
                   ^
/Users/username/Documents/dev/ExternalThreads/jluna/.src/box.inl:97:14: note: because 'is<std::tuple<unsigned long long, std::string, int>, int8_t>' evaluated to false
    template<is<int8_t> T>
             ^
/Users/username/Documents/dev/ExternalThreads/jluna/include/concepts.hpp:39:18: note: because 'std::conditional_t<std::is_void_v<tuple<unsigned long long, string, int> >, std::is_void<signed char>, is_same_or_const<tuple<unsigned long long, string, int>, signed char> >::value' evaluated to false
    concept is = std::conditional_t<
                 ^
/Users/username/Documents/dev/ExternalThreads/jluna/.src/box.inl:104:20: note: candidate template ignored: constraints not satisfied [with T = std::tuple<unsigned long long, std::string, int>]
    unsafe::Value* box(T value)
                   ^
/Users/username/Documents/dev/ExternalThreads/jluna/.src/box.inl:103:14: note: because 'is<std::tuple<unsigned long long, std::string, int>, int16_t>' evaluated to false
    template<is<int16_t> T>
             ^
/Users/username/Documents/dev/ExternalThreads/jluna/include/concepts.hpp:39:18: note: because 'std::conditional_t<std::is_void_v<tuple<unsigned long long, string, int> >, std::is_void<short>, is_same_or_const<tuple<unsigned long long, string, int>, short> >::value' evaluated to false
    concept is = std::conditional_t<
                 ^
/Users/username/Documents/dev/ExternalThreads/jluna/.src/box.inl:110:20: note: candidate template ignored: constraints not satisfied [with T = std::tuple<unsigned long long, std::string, int>]
    unsafe::Value* box(T value)
                   ^
/Users/username/Documents/dev/ExternalThreads/jluna/.src/box.inl:109:14: note: because 'is<std::tuple<unsigned long long, std::string, int>, int32_t>' evaluated to false
    template<is<int32_t> T>
             ^
/Users/username/Documents/dev/ExternalThreads/jluna/include/concepts.hpp:39:18: note: because 'std::conditional_t<std::is_void_v<tuple<unsigned long long, string, int> >, std::is_void<int>, is_same_or_const<tuple<unsigned long long, string, int>, int> >::value' evaluated to false
    concept is = std::conditional_t<
                 ^
/Users/username/Documents/dev/ExternalThreads/jluna/.src/box.inl:116:20: note: candidate template ignored: constraints not satisfied [with T = std::tuple<unsigned long long, std::string, int>]
    unsafe::Value* box(T value)
                   ^
/Users/username/Documents/dev/ExternalThreads/jluna/.src/box.inl:115:14: note: because 'is<std::tuple<unsigned long long, std::string, int>, int64_t>' evaluated to false
    template<is<int64_t> T>
             ^
/Users/username/Documents/dev/ExternalThreads/jluna/include/concepts.hpp:39:18: note: because 'std::conditional_t<std::is_void_v<tuple<unsigned long long, string, int> >, std::is_void<long long>, is_same_or_const<tuple<unsigned long long, string, int>, long long> >::value' evaluated to false
    concept is = std::conditional_t<
                 ^
/Users/username/Documents/dev/ExternalThreads/jluna/.src/box.inl:122:20: note: candidate template ignored: constraints not satisfied [with T = std::tuple<unsigned long long, std::string, int>]
    unsafe::Value* box(T value)
                   ^
/Users/username/Documents/dev/ExternalThreads/jluna/.src/box.inl:121:14: note: because 'is<std::tuple<unsigned long long, std::string, int>, float>' evaluated to false
    template<is<float> T>
             ^
/Users/username/Documents/dev/ExternalThreads/jluna/include/concepts.hpp:39:18: note: because 'std::conditional_t<std::is_void_v<tuple<unsigned long long, string, int> >, std::is_void<float>, is_same_or_const<tuple<unsigned long long, string, int>, float> >::value' evaluated to false
    concept is = std::conditional_t<
                 ^
/Users/username/Documents/dev/ExternalThreads/jluna/.src/box.inl:128:20: note: candidate template ignored: constraints not satisfied [with T = std::tuple<unsigned long long, std::string, int>]
    unsafe::Value* box(T value)
                   ^
/Users/username/Documents/dev/ExternalThreads/jluna/.src/box.inl:127:14: note: because 'is<std::tuple<unsigned long long, std::string, int>, double>' evaluated to false
    template<is<double> T>
             ^
/Users/username/Documents/dev/ExternalThreads/jluna/include/concepts.hpp:39:18: note: because 'std::conditional_t<std::is_void_v<tuple<unsigned long long, string, int> >, std::is_void<double>, is_same_or_const<tuple<unsigned long long, string, int>, double> >::value' evaluated to false
    concept is = std::conditional_t<
                 ^
/Users/username/Documents/dev/ExternalThreads/jluna/.src/box.inl:134:20: note: candidate template ignored: constraints not satisfied [with T = std::tuple<unsigned long long, std::string, int>]
    unsafe::Value* box(T value)
                   ^
/Users/username/Documents/dev/ExternalThreads/jluna/.src/box.inl:133:14: note: because 'is<std::tuple<unsigned long long, std::string, int>, std::string>' evaluated to false
    template<is<std::string> T>
             ^
/Users/username/Documents/dev/ExternalThreads/jluna/include/concepts.hpp:39:18: note: because 'std::conditional_t<std::is_void_v<tuple<unsigned long long, string, int> >, std::is_void<string>, is_same_or_const<tuple<unsigned long long, string, int>, string> >::value' evaluated to false
    concept is = std::conditional_t<
                 ^
/Users/username/Documents/dev/ExternalThreads/jluna/.src/box.inl:144:20: note: candidate template ignored: constraints not satisfied [with T = std::tuple<unsigned long long, std::string, int>]
    unsafe::Value* box(T value)
                   ^
/Users/username/Documents/dev/ExternalThreads/jluna/.src/box.inl:143:14: note: because 'is<std::tuple<unsigned long long, std::string, int>, const char *>' evaluated to false
    template<is<const char*> T>
             ^
/Users/username/Documents/dev/ExternalThreads/jluna/include/concepts.hpp:39:18: note: because 'std::conditional_t<std::is_void_v<tuple<unsigned long long, string, int> >, std::is_void<const char *>, is_same_or_const<tuple<unsigned long long, string, int>, const char *> >::value' evaluated to false
    concept is = std::conditional_t<
                 ^
/Users/username/Documents/dev/ExternalThreads/jluna/.src/module.inl:20:27: note: candidate template ignored: constraints not satisfied [with T = std::tuple<unsigned long long, std::string, int>]
    inline unsafe::Value* box(T value)
                          ^
/Users/username/Documents/dev/ExternalThreads/jluna/.src/module.inl:19:14: note: because 'is<std::tuple<unsigned long long, std::string, int>, Module>' evaluated to false
    template<is<Module> T>
             ^
/Users/username/Documents/dev/ExternalThreads/jluna/include/concepts.hpp:39:18: note: because 'std::conditional_t<std::is_void_v<tuple<unsigned long long, string, int> >, std::is_void<Module>, is_same_or_const<tuple<unsigned long long, string, int>, Module> >::value' evaluated to false
    concept is = std::conditional_t<
                 ^
/Users/username/Documents/dev/ExternalThreads/jluna/include/box.hpp:116:20: note: candidate template ignored: substitution failure [with T = std::tuple<unsigned long long, std::string, int>]: no type named 'key_type' in 'std::tuple<unsigned long long, std::string, int>'
    unsafe::Value* box(const T& value);
                   ^
/Users/username/Documents/dev/ExternalThreads/jluna/.src/box.inl:155:20: note: candidate template ignored: substitution failure [with T = std::tuple<unsigned long long, std::string, int>]: no type named 'value_type' in 'std::tuple<unsigned long long, std::string, int>'
    unsafe::Value* box(T value)
                   ^
/Users/username/Documents/dev/ExternalThreads/jluna/.src/box.inl:162:20: note: candidate template ignored: substitution failure [with T = std::tuple<unsigned long long, std::string, int>]: no type named 'value_type' in 'std::tuple<unsigned long long, std::string, int>'
    unsafe::Value* box(const T& value)
                   ^
/Users/username/Documents/dev/ExternalThreads/jluna/.src/box.inl:180:20: note: candidate template ignored: substitution failure [with T = std::tuple<unsigned long long, std::string, int>]: no type named 'key_type' in 'std::tuple<unsigned long long, std::string, int>'
    unsafe::Value* box(const T& value)
                   ^
/Users/username/Documents/dev/ExternalThreads/jluna/.src/box.inl:196:20: note: candidate template ignored: substitution failure [with T = std::tuple<unsigned long long, std::string, int>]: no type named 'value_type' in 'std::tuple<unsigned long long, std::string, int>'
    unsafe::Value* box(const T& value)
                   ^
/Users/username/Documents/dev/ExternalThreads/jluna/.src/box.inl:213:20: note: candidate template ignored: substitution failure [with T = std::tuple<unsigned long long, std::string, int>]: no type named 'first_type' in 'std::tuple<unsigned long long, std::string, int>'
    unsafe::Value* box(const T& value)
                   ^
/Users/username/Documents/dev/ExternalThreads/jluna/include/box.hpp:166:20: note: candidate template ignored: constraints not satisfied [with T = std::tuple<unsigned long long, std::string, int>]
    unsafe::Value* box(T);
                   ^
/Users/username/Documents/dev/ExternalThreads/jluna/include/box.hpp:165:14: note: because 'std::tuple<unsigned long long, std::string, int>' does not satisfy 'is_usertype'
    template<is_usertype T>
             ^
/Users/username/Documents/dev/ExternalThreads/jluna/include/concepts.hpp:244:27: note: because 'usertype_enabled<tuple<unsigned long long, string, int> >::value' evaluated to false
    concept is_usertype = usertype_enabled<T>::value;
                          ^
/Users/username/Documents/dev/ExternalThreads/jluna/.src/box.inl:44:20: note: candidate template ignored: constraints not satisfied [with T = std::tuple<unsigned long long, std::string, int>]
    unsafe::Value* box(T)
                   ^
/Users/username/Documents/dev/ExternalThreads/jluna/.src/box.inl:43:14: note: because 'is<std::tuple<unsigned long long, std::string, int>, void>' evaluated to false
    template<is<void> T>
             ^
/Users/username/Documents/dev/ExternalThreads/jluna/include/concepts.hpp:39:18: note: because 'std::conditional_t<std::is_void_v<tuple<unsigned long long, string, int> >, std::is_void<void>, is_same_or_const<tuple<unsigned long long, string, int>, void> >::value' evaluated to false
    concept is = std::conditional_t<
                 ^
/Users/username/Documents/dev/ExternalThreads/jluna/.src/box.inl:226:20: note: candidate template ignored: constraints not satisfied [with T = std::tuple<unsigned long long, std::string, int>]
    unsafe::Value* box(const T& value)
                   ^
/Users/username/Documents/dev/ExternalThreads/jluna/.src/box.inl:225:14: note: because 'std::tuple<unsigned long long, std::string, int>' does not satisfy 'is_tuple'
    template<is_tuple T>
             ^
/Users/username/Documents/dev/ExternalThreads/jluna/include/concepts.hpp:233:24: note: because substituted constraint expression is ill-formed: no matching function for call to 'is_tuple_aux'
    concept is_tuple = detail::is_tuple_aux<T>(std::make_index_sequence<std::tuple_size<T>::value>());
                       ^
/Users/username/Documents/dev/ExternalThreads/jluna/.src/proxy.inl:19:27: note: candidate template ignored: constraints not satisfied [with T = std::tuple<unsigned long long, std::string, int>]
    inline unsafe::Value* box(T value)
                          ^
/Users/username/Documents/dev/ExternalThreads/jluna/.src/proxy.inl:18:14: note: because 'is<std::tuple<unsigned long long, std::string, int>, Proxy>' evaluated to false
    template<is<Proxy> T>
             ^
/Users/username/Documents/dev/ExternalThreads/jluna/include/concepts.hpp:39:18: note: because 'std::conditional_t<std::is_void_v<tuple<unsigned long long, string, int> >, std::is_void<Proxy>, is_same_or_const<tuple<unsigned long long, string, int>, Proxy> >::value' evaluated to false
    concept is = std::conditional_t<
                 ^
/Users/username/Documents/dev/ExternalThreads/jluna/.src/mutex.inl:11:20: note: candidate template ignored: constraints not satisfied [with T = std::tuple<unsigned long long, std::string, int>]
    unsafe::Value* box(T in)
                   ^
/Users/username/Documents/dev/ExternalThreads/jluna/.src/mutex.inl:10:14: note: because 'is<std::tuple<unsigned long long, std::string, int>, jluna::Mutex>' evaluated to false
    template<is<jluna::Mutex> T>
             ^
/Users/username/Documents/dev/ExternalThreads/jluna/include/concepts.hpp:39:18: note: because 'std::conditional_t<std::is_void_v<tuple<unsigned long long, string, int> >, std::is_void<Mutex>, is_same_or_const<tuple<unsigned long long, string, int>, Mutex> >::value' evaluated to false
    concept is = std::conditional_t<
                 ^
/Users/username/Documents/dev/ExternalThreads/jluna/.src/symbol.inl:18:27: note: candidate template ignored: constraints not satisfied [with T = std::tuple<unsigned long long, std::string, int>]
    inline unsafe::Value* box(T value)
                          ^
/Users/username/Documents/dev/ExternalThreads/jluna/.src/symbol.inl:17:14: note: because 'is<std::tuple<unsigned long long, std::string, int>, Symbol>' evaluated to false
    template<is<Symbol> T>
             ^
/Users/username/Documents/dev/ExternalThreads/jluna/include/concepts.hpp:39:18: note: because 'std::conditional_t<std::is_void_v<tuple<unsigned long long, string, int> >, std::is_void<Symbol>, is_same_or_const<tuple<unsigned long long, string, int>, Symbol> >::value' evaluated to false
    concept is = std::conditional_t<
                 ^
/Users/username/Documents/dev/ExternalThreads/jluna/.src/type.inl:19:27: note: candidate template ignored: constraints not satisfied [with T = std::tuple<unsigned long long, std::string, int>]
    inline unsafe::Value* box(T value)
                          ^
/Users/username/Documents/dev/ExternalThreads/jluna/.src/type.inl:18:14: note: because 'is<std::tuple<unsigned long long, std::string, int>, Type>' evaluated to false
    template<is<Type> T>
             ^
/Users/username/Documents/dev/ExternalThreads/jluna/include/concepts.hpp:39:18: note: because 'std::conditional_t<std::is_void_v<tuple<unsigned long long, string, int> >, std::is_void<Type>, is_same_or_const<tuple<unsigned long long, string, int>, Type> >::value' evaluated to false
    concept is = std::conditional_t<
                 ^
/Users/username/Documents/dev/ExternalThreads/jluna/.src/array.inl:15:20: note: candidate template ignored: substitution failure [with T = std::tuple<unsigned long long, std::string, int>]: no type named 'value_type' in 'std::tuple<unsigned long long, std::string, int>'
    unsafe::Value* box(T value)
                   ^
/Users/username/Documents/dev/ExternalThreads/jluna/.src/array.inl:26:20: note: candidate template ignored: substitution failure [with T = std::tuple<unsigned long long, std::string, int>]: no type named 'value_type' in 'std::tuple<unsigned long long, std::string, int>'
    unsafe::Value* box(T value)

Warnings generated

with GCC 12 and clang 15 the code

initialize();
Base["println"]("hello julia");

/// declare function
Main.safe_eval("f(x) = x^x");

// bind function to C++-side variable
auto f = Main.safe_eval("return f");

// call function
Int64 result = f(3);

// print result
std::cout << result << std::endl;

return 0;

Produce these warnings before program output:

warning: copy relocation against non-copyable protected symbol `jl_int32_type' in `/home/jonkam/Programmering/julia/julia-1.8.5-linux-x86_64/julia-1.8.5/lib/libjulia.so.1'
warning: copy relocation against non-copyable protected symbol `jl_float32_type' in `/home/jonkam/Programmering/julia/julia-1.8.5-linux-x86_64/julia-1.8.5/lib/libjulia.so.1'
warning: copy relocation against non-copyable protected symbol `jl_float64_type' in `/home/jonkam/Programmering/julia/julia-1.8.5-linux-x86_64/julia-1.8.5/lib/libjulia.so.1'
warning: copy relocation against non-copyable protected symbol `jl_int64_type' in `/home/jonkam/Programmering/julia/julia-1.8.5-linux-x86_64/julia-1.8.5/lib/libjulia.so.1'
warning: copy relocation against non-copyable protected symbol `jl_base_module' in `/home/jonkam/Programmering/julia/julia-1.8.5-linux-x86_64/julia-1.8.5/lib/libjulia.so.1'
warning: copy relocation against non-copyable protected symbol `jl_bool_type' in `/home/jonkam/Programmering/julia/julia-1.8.5-linux-x86_64/julia-1.8.5/lib/libjulia.so.1'
warning: copy relocation against non-copyable protected symbol `jl_uint64_type' in `/home/jonkam/Programmering/julia/julia-1.8.5-linux-x86_64/julia-1.8.5/lib/libjulia.so.1'
warning: copy relocation against non-copyable protected symbol `jl_uint16_type' in `/home/jonkam/Programmering/julia/julia-1.8.5-linux-x86_64/julia-1.8.5/lib/libjulia.so.1'
warning: copy relocation against non-copyable protected symbol `jl_int16_type' in `/home/jonkam/Programmering/julia/julia-1.8.5-linux-x86_64/julia-1.8.5/lib/libjulia.so.1'
warning: copy relocation against non-copyable protected symbol `jl_float16_type' in `/home/jonkam/Programmering/julia/julia-1.8.5-linux-x86_64/julia-1.8.5/lib/libjulia.so.1'
warning: copy relocation against non-copyable protected symbol `jl_uint32_type' in `/home/jonkam/Programmering/julia/julia-1.8.5-linux-x86_64/julia-1.8.5/lib/libjulia.so.1'
warning: copy relocation against non-copyable protected symbol `jl_int8_type' in `/home/jonkam/Programmering/julia/julia-1.8.5-linux-x86_64/julia-1.8.5/lib/libjulia.so.1'
warning: copy relocation against non-copyable protected symbol `jl_uint8_type' in `/home/jonkam/Programmering/julia/julia-1.8.5-linux-x86_64/julia-1.8.5/lib/libjulia.so.1'
warning: copy relocation against non-copyable protected symbol `jl_char_type' in `/home/jonkam/Programmering/julia/julia-1.8.5-linux-x86_64/julia-1.8.5/lib/libjulia.so.1'
[JULIA][LOG] initialization successful (1 thread(s)).
hello julia
27

Process finished with exit code 0

Do I need to add some compiler flags ?

`make install` deadlocks with `CMAKE_INSTALL_PREFIX=*/jluna`

After installing a fresh version of jluna into ~/Desktop/jluna:

mkdir build
cd build
cmake .. -DCMAKE_INSTALL_PREFIX=~/Desktop/jluna/
make install

Causes a loop:

-- Installing: /home/clem/Desktop/jluna/include/jluna/include/jluna/include/jluna/include/jluna/include/jluna/include/jluna/include/jluna/include/jluna/include/jluna/include/jluna/include/jluna/include/jluna/include/jluna/include/jluna/include/jluna/include/jluna/include/jluna/include/jluna/include/jluna/include/jluna/include/jluna/include/jluna/include/jluna/include/jluna/include/jluna/include/jluna/include/jluna/include/jluna/include/jluna/include/jluna/include/jluna/include/jluna/include/jluna/include/jluna/include/jluna/include/jluna/include/jluna/include/jluna/include/jluna/include/jluna/include/jluna/include/jluna/include/jluna/include/jluna/include/jluna/include/jluna/include/jluna/include/jluna/include/jluna/include/jluna/include/jluna/include/jluna/include/jluna/include/jluna/include/jluna/include/jluna/include/jluna/include/jluna/include/jluna/include/jluna/include/jluna/include/jluna/include/jluna/include/jluna/include/jluna/include/jluna/include/jluna/include/jluna/include/jluna/include/jluna/include/jluna/include/jluna/include/jluna/include/jluna/include/jluna/include/jluna/include/jluna/include/jluna/include/jluna/include/jluna/include/jluna/include/jluna/include/jluna/include/jluna/include/jluna/include/jluna/include/jluna/include/jluna/include/jluna/include/jluna/include/jluna/include/jluna/include/jluna/include/jluna/include/jluna/include/jluna/include/jluna/include/jluna/include/jluna/include/jluna/include/jluna/include/jluna/include/jluna/include/jluna/include/jluna/include/jluna/include/jluna/include/jluna/include/jluna/include/jluna/include/jluna/include/jluna/include/jluna/include/jluna/include/jluna/include/jluna/include/jluna/include/jluna/include/jluna/include/jluna/include/jluna/include/jluna/include/jluna/include/jluna/include/jluna/include/jluna/include/jluna/include/jluna/include/jluna/include/jluna/include/jluna/include/jluna/include/jluna/include/jluna/include/jluna/include/jluna/include/jluna/include/jluna/include/jluna/include/jluna/include/jluna/include/jluna/include/jluna/include/jluna/include/jluna/include/jluna/include/jluna/include/jluna/include/jluna/include/jluna/include/jluna/include/jluna/include/array.hpp

Where jluna/include/jluna/include is appended to itself infinitely. Most likely an issue with cmake/install-rules.cmake

Installation Issue with MinGW_64

Hi,
I was trying to install that library as I saw it supposed to be quite handy. But after several tries, I couldn't do it. After getting successful build I don't have the dll file in release or debug folder.

Build Command I used

  1. cmake .. -DCMAKE_CXX_COMPILER=<clang++> -DCMAKE_INSTALL_PREFIX=<E:\Jluna> -G "Ninja Multi-Config" (The CXX compiler identification is Clang 15.0.7)
  2. cmake .. -DCMAKE_CXX_COMPILER=<g++> -DCMAKE_INSTALL_PREFIX=<E:\Jluna> -G "Ninja Multi-Config"

I don't really get what's the actual problem I am sending the console and the build directory screenshot for further evaluation. If you help me, I will be grateful to you! Thank you in advance.

image

image

Usertype<T>::implement not respecting module argument

This is not a high priority for me at all, but dropping an issue here since I noticed it the other day.

Usertypes seem to always be implemented in Main module scope, rather than the module specified in Usertype<T>::implement(unsafe::Module* module).

The module argument doesn't seem to be used at all:

jluna/.src/usertype.inl

Lines 61 to 81 in 05a827c

template<typename T>
void Usertype<T>::implement(unsafe::Module* module)
{
if (_name.get() == nullptr)
initialize();
gc_pause;
static jl_function_t* implement = unsafe::get_function("jluna"_sym, "implement"_sym);
static jl_function_t* new_proxy = unsafe::get_function("jluna"_sym, "new_proxy"_sym);
static jl_function_t* setfield = jl_get_function(jl_base_module, "setindex!");
auto default_instance = T();
auto* template_proxy = jluna::safe_call(new_proxy, _name->operator unsafe::Value*());
for (auto& field_name : _fieldnames_in_order)
jluna::safe_call(setfield, template_proxy, (unsafe::Value*) std::get<0>(_mapping.at(field_name))(default_instance), (unsafe::Value*) field_name);
_type = std::make_unique<Type>((jl_datatype_t*) jluna::safe_call(implement, template_proxy));
_implemented = true;
gc_unpause;
}

Array index on a 2D matrix not correct

While trying out the examples in the excellent manual, I see a discrepancy between what the manual reports and code that I try in Visual Studio 2022.

// create arrays
Array<Int64, 1> array_1d = jluna::safe_eval("return Int64[1, 2, 3, 4, 5]");
Array<Int64, 2> array_2d = jluna::safe_eval("return reshape(Int64[i for i in 1:9], 3, 3)");

// print
Base["println"]("array_1d: ", array_1d);
Base["println"]("array_2d: ", array_2d);

// access elements at index (0-based)
Int64 one_d_at_3 = array_1d[2];
Int64 two_d_at_2_2 = array_2d[1, 1];

// print
std::cout << one_d_at_3 << std::endl;
std::cout << two_d_at_2_2 << std::endl;

This generates
[JULIA][LOG] initialization successful (1 thread(s)).
array_1d: [1, 2, 3, 4, 5]
array_2d: [1 4 7; 2 5 8; 3 6 9]
3
2

For array_2d the element first element of the second row is returned instead of the second, which is 5 as shown in the manual

State::initialize crashes with "KeyError: key 0x0000000001c4cdd0 not found"

Not yet reproduced by the devs, but by an anonymous User on ubuntu 20, compiling with G++-11:

Code:

jluna::State::initialize();

Error:

[JULIA][LOG] initialization successfull.
terminate called after throwing an instance of 'jluna::JuliaException'
  what():  [JULIA][EXCEPTION] KeyError: key 0x5845741900000048 not found
Stacktrace:
 [1] getindex
   @ ./dict.jl:481 [inlined]
 [2] free_reference(key::UInt64)
   @ Main.jluna.memory_handler ./none:762
 [3] safe_call(f::Function, args::UInt64)
   @ Main.jluna.exception_handler ./none:517

signal (6): Aborted
in expression starting at none:0
gsignal at /lib/x86_64-linux-gnu/libc.so.6 (unknown line)
abort at /lib/x86_64-linux-gnu/libc.so.6 (unknown line)
unknown function (ip: 0x7f3ff3a10a30)
unknown function (ip: 0x7f3ff3a1c5db)
unknown function (ip: 0x7f3ff3a1b5a8)
__gxx_personality_v0 at /lib/x86_64-linux-gnu/libstdc++.so.6 (unknown line)
unknown function (ip: 0x7f3ff3816493)
_Unwind_Resume at /lib/x86_64-linux-gnu/libgcc_s.so.1 (unknown line)
_ZN5jluna9safe_callIJP11_jl_value_tEEES2_S2_DpT_ at /home/redacted/jluna/build/libjluna.so.0.8.4 (unknown line)
_ZN5jluna5State6detail14free_referenceEm at /home/redacted/jluna/build/libjluna.so.0.8.4 (unknown line)
_ZN5jluna5Proxy10ProxyValueD1Ev at /home/redacted/jluna/build/libjluna.so.0.8.4 (unknown line)
_ZNSt15_Sp_counted_ptrIPN5jluna5Proxy10ProxyValueELN9__gnu_cxx12_Lock_policyE2EE10_M_disposeEv at /home/redacted/jluna/build/libjluna.so.0.8.4 (unknown line)
_ZNSt16_Sp_counted_baseILN9__gnu_cxx12_Lock_policyE2EE10_M_releaseEv at /home/redacted/jluna/build/libjluna.so.0.8.4 (unknown line)
_ZNSt14__shared_countILN9__gnu_cxx12_Lock_policyE2EEaSERKS2_ at /home/redacted/jluna/build/libjluna.so.0.8.4 (unknown line)
_ZNSt12__shared_ptrIN5jluna5Proxy10ProxyValueELN9__gnu_cxx12_Lock_policyE2EEaSERKS5_ at /home/redacted/jluna/build/libjluna.so.0.8.4 (unknown line)
_ZNSt10shared_ptrIN5jluna5Proxy10ProxyValueEEaSERKS3_ at /home/redacted/jluna/build/libjluna.so.0.8.4 (unknown line)
_ZN5jluna5ProxyaSERKS0_ at /home/redacted/jluna/build/libjluna.so.0.8.4 (unknown line)
_ZN5jluna4TypeaSEOS0_ at /home/redacted/jluna/build/libjluna.so.0.8.4 (unknown line)
_ZN5jluna5State6detail16initialize_typesEv at /home/redacted/jluna/build/libjluna.so.0.8.4 (unknown line)
_ZN5jluna5State10initializeERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE at /home/redacted/jluna/build/libjluna.so.0.8.4 (unknown line)
_ZN5jluna5State10initializeEv at /home/redacted/jluna/build/libjluna.so.0.8.4 (unknown line)
_ZN18MinimalAudioPluginC1Ev at /home/redacted/.vst3/Minimal Plugin Template.vst3/Contents/x86_64-linux/Minimal Plugin Template.so (unknown line)
_Z18createPluginFilterv at /home/redacted/.vst3/Minimal Plugin Template.vst3/Contents/x86_64-linux/Minimal Plugin Template.so (unknown line)
_ZN4juce24createPluginFilterOfTypeENS_14AudioProcessor11WrapperTypeE at /home/redacted/.vst3/Minimal Plugin Template.vst3/Contents/x86_64-linux/Minimal Plugin Template.so (unknown line)
_ZN4juce17JuceVST3ComponentC1EPN9Steinberg3Vst16IHostApplicationE at /home/redacted/.vst3/Minimal Plugin Template.vst3/Contents/x86_64-linux/Minimal Plugin Template.so (unknown line)
_ZN4juceL23createComponentInstanceEPN9Steinberg3Vst16IHostApplicationE at /home/redacted/.vst3/Minimal Plugin Template.vst3/Contents/x86_64-linux/Minimal Plugin Template.so (unknown line)
_ZN4juce17JucePluginFactory14createInstanceEPKcS2_PPv at /home/redacted/.vst3/Minimal Plugin Template.vst3/Contents/x86_64-linux/Minimal Plugin Template.so (unknown line)
unknown function (ip: 0x96cb4d)
unknown function (ip: 0x950220)
unknown function (ip: 0x7bc9e5)
unknown function (ip: 0x79401e)
unknown function (ip: 0x771091)
unknown function (ip: 0x407db3)
unknown function (ip: 0x77e892)
unknown function (ip: 0x7f3ff338e845)
unknown function (ip: 0x7f3ff3381b46)
unknown function (ip: 0x7f3ff3391637)
unknown function (ip: 0x7f3ff33ac3f2)
unknown function (ip: 0x7f3ff33ac866)
unknown function (ip: 0x7f3ff33accec)
unknown function (ip: 0x7f3ff2dd9f78)
unknown function (ip: 0x7f3ff2e0d105)
g_main_context_dispatch at /lib/x86_64-linux-gnu/libglib-2.0.so.0 (unknown line)
unknown function (ip: 0x7f3ff29f03ff)
g_main_context_iteration at /lib/x86_64-linux-gnu/libglib-2.0.so.0 (unknown line)
unknown function (ip: 0x7f3ff33aebf9)
unknown function (ip: 0x7f3ff338ebd1)
unknown function (ip: 0x40d805)
__libc_start_main at /lib/x86_64-linux-gnu/libc.so.6 (unknown line)
_start at ./reaper (unknown line)
Allocations: 796294 (Pool: 795918; Big: 376); GC: 1
Aborted (core dumped)

Julia and multi-threading

I just came across https://clemens-cords.com/jluna/multi_threading.html and I wanted to provide a little bit of context.
Julia uses thread-local-state on it's worker-threads and the GC needs to be able to find that TLS in order to scan the task
stack. This causes your observation:

This is, because the Julia C-API is seemingly hardcoded to prevent any call of C-API functions from anywhere but master scope (the scope of the thread main is executed in).

The first thing many Julia functions do is to look at the TLS and use it to allocate, or interact with the runtime in other ways.

Julia 1.9 finally allows for foreign threads to be added JuliaLang/julia#46609, hopefully this will simplify your work.

Issues compiling on Mac

Hi, when trying to get jluna to make on Mac, I'm getting the following errors:
2 of those:

git/jluna/include/unsafe_utilities.hpp:16:49: error: invalid literal operator parameter type 'uint64_t' (aka 'unsigned long long'), did you mean 'unsigned long'?
    unsafe::Symbol* operator""_sym(const char*, uint64_t);
                                                ^~~~~~~~

and another few of those:

git/jluna/.src/unsafe_utilities.inl:34:84: error: no matching literal operator for call to 'operator""_sym' with arguments of types 'const char *' and 'unsigned long', and no matching literal operator template
        static unsafe::Function* expr = unsafe::get_function(jl_base_module, "Expr"_sym);
                                                                                   ^

My environment:

  • cmake version 3.20.3
  • Apple clang version 15.0.0 (clang-1500.0.40.1)
  • julia version 1.9.3

I'd appreciate any hint where to look at!

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.