Last active
March 14, 2022 20:40
-
-
Save Clemapfel/47906ecb28f2681b6a6759b5bb663943 to your computer and use it in GitHub Desktop.
Example code for https://github.com/Clemapfel/jluna/issues/12
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// | |
// Copyright 2022 Clemens Cords | |
// Created on 14.03.22 by clem (mail@clemens-cords.com) | |
// | |
#include <jluna.hpp> | |
using namespace jluna; | |
// this code are examples given as a response to https://github.com/Clemapfel/jluna/issues/12 | |
int main() | |
{ | |
State::initialize(); | |
// first, we allocate an array julia-side | |
// State::safe_eval automatically creates a proxy that manages the julia-side memory | |
// this will make it be safe from the garbage collector (GC) | |
auto julia_side_array_proxy = State::safe_eval(R"( | |
julia_side_array = [Float32(i) for i in 1:100000] | |
return julia_side_array | |
)"); | |
// ### Method 1: Using jluna::Array (recommended) | |
{ | |
Array<Float32, 1> as_array = julia_side_array_proxy; // causes no reallocation | |
// accessing values | |
std::cout << (Float32) as_array.at(10) << std::endl; | |
// changing values | |
as_array.at(10) = 1234; | |
State::safe_eval("println(julia_side_array[11])"); // julia indices are 1-based | |
as_array.at(10) = 11; | |
// accessing raw c-data of the array | |
Float32* c_array = (Float32*) as_array.data(); | |
std::cout << c_array[10] << std::endl; | |
// converting an array iterator to a raw c-pointer | |
auto it = as_array.at(10); | |
Any* as_ptr = (Any*) it; | |
std::cout << *((Float32*) as_ptr) << std::endl; | |
} | |
std::cout << "\n---\n" << std::endl; | |
// ### Method 2: Using non-jluna Julia Functions (works for any objects, not just arrays) | |
{ | |
auto getindex = Base["getindex"]; | |
auto setindex = Base["setindex!"]; | |
// accessing values | |
std::cout << (Float32) getindex(julia_side_array_proxy, 10 + 1) << std::endl; | |
// changing values | |
setindex(julia_side_array_proxy, 1234, 10 + 1); | |
State::safe_eval("println(julia_side_array[11])"); | |
setindex(julia_side_array_proxy, 11, 10 + 1); | |
} | |
std::cout << "\n---\n" << std::endl; | |
// ### Method 2.5: Using non-jluna julia functions with less nice syntax but no overhead | |
{ | |
// create a garbage collector sentinel that protects any values that are inside this block | |
auto sentinel = GCSentinel(); | |
auto* getindex = jl_find_function("Base", "getindex"); | |
auto* setindex = jl_find_function("Base", "setindex!"); | |
// accessing values | |
Any* result = jluna::call(getindex, (Any*) julia_side_array_proxy, box<Int64>(10 + 1)); | |
std::cout << unbox<Float32>(result) << std::endl; | |
// changing values | |
jluna::call(setindex, (Any*) julia_side_array_proxy, box<Float32>(1234), box<Int64>(10 + 1)); | |
State::safe_eval("println(julia_side_array[11])"); | |
jluna::call(setindex, (Any*) julia_side_array_proxy, box<Float32>(11), box<Int64>(10 + 1)); | |
// because the block ends here, sentinel is destroyed and releases any values protected | |
} | |
std::cout << "\n---\n" << std::endl; | |
// ### Method 3: Using the C-API (also no overhead, same speed as Method 2.5) | |
{ | |
// first, disable gc | |
jl_gc_enable(false); | |
// get a C-API array pointer to proxies value | |
jl_array_t* as_array = (jl_array_t*) ((Any*) julia_side_array_proxy); | |
// accessing values | |
std::cout << jl_unbox_float32(jl_arrayref(as_array, 10)) << std::endl; | |
// changing values | |
jl_arrayset(as_array, jl_box_float32(1234.0), 10); | |
State::safe_eval("println(julia_side_array[11])"); | |
jl_arrayset(as_array, jl_box_float32(11.0), 10); | |
// reenable gc | |
jl_gc_enable(true); | |
} | |
return 0; | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment