Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Is there a way to pass 2D array or matrix into the c++ code straight from Julia? #364

Open
GlockPL opened this issue Jul 24, 2023 · 3 comments

Comments

@GlockPL
Copy link

GlockPL commented Jul 24, 2023

I managed to pass 1D flatten vector like that:
jlcxx::Array<int> run_heuristic(const std::vector<double>& matrix, std::size_t rows, std::size_t cols)
with julia code looking like that:
solution = run_heuristic(CxxWrap.StdVector(vec_array), size(arr, 1), size(arr, 2))
but this is undesirable, is there a way to that with 2D vector or some other array?

@biona001
Copy link

I'm trying to do the same thing. Just want to pass a matrix into C++ and return the sum back to Julia. Somehow it's proven to be difficult and the examples in test is a bit hard to decipher.

@barche do you have any example, or know of any resources that could facilitate this? Thank you in advance.

@barche
Copy link
Collaborator

barche commented Aug 27, 2023

You can use jlcxx::ArrayRef<double, 2> as an argument on the C++ side, and then on the Julia side you can pass a 2D array. See the check_mutable_array function in the containers example for an example.

@biona001
Copy link

biona001 commented Aug 27, 2023

Thank you, Bart.

For future reference, here's my code to pass a matrix of Float64 into C++, sum them, then get the result back.

Here's my sumarray.cpp file:

#include "jlcxx/jlcxx.hpp"
#include <vector>
#include <iostream>
using namespace std;

double cpp_mat_sum(jlcxx::ArrayRef<double, 2> x) {
    cout << &x[0] << endl; // print memory address of x
    double total = 0;
    for(auto xij : x) {
        total += xij;
    }
    return total;
}

JLCXX_MODULE define_julia_module(jlcxx::Module& mod)
{
    mod.method("cpp_mat_sum", &cpp_mat_sum);
}

And here's my CMakeList.txt

project(Examples)

cmake_minimum_required(VERSION 3.5)
set(CMAKE_MACOSX_RPATH 1)
set(CMAKE_LIBRARY_OUTPUT_DIRECTORY "${CMAKE_BINARY_DIR}/lib")

find_package(JlCxx)
get_target_property(JlCxx_location JlCxx::cxxwrap_julia LOCATION)
get_filename_component(JlCxx_location ${JlCxx_location} DIRECTORY)
set(CMAKE_INSTALL_RPATH "${CMAKE_INSTALL_PREFIX}/lib;${JlCxx_location}")

message(STATUS "Found JlCxx at ${JlCxx_location}")

add_library(hello SHARED hello.cpp)
add_library(sumarray SHARED sumarray.cpp)

target_link_libraries(hello JlCxx::cxxwrap_julia)
target_link_libraries(sumarray JlCxx::cxxwrap_julia)

install(TARGETS
  sumarray 
LIBRARY DESTINATION lib
ARCHIVE DESTINATION lib
RUNTIME DESTINATION lib)

I put them in the same directory, and compile them with:

mkdir build && cd build
cmake -DCMAKE_BUILD_TYPE=Release -DCMAKE_PREFIX_PATH=/home/groups/sabatti/.julia/dev/libcxxwrap_julia_jll/override /home/users/bbchu/ghostbasilwrap
cmake --build . --config Release

Usage in Julia:

julia> module CppSumArray
       using CxxWrap
       @wrapmodule("/home/users/bbchu/ghostbasilwrap/build/lib/libsumarray")

       function __init__()
           @initcxx
       end
       end

Main.CppSumArray

julia> x = randn(10000, 10000);

julia> CppSumArray.cpp_mat_sum(x)
0x7feb5e860040
-9305.980886268122

julia> sum(x)
-9305.98088626438

julia> pointer(x)
Ptr{Float64} @0x00007feb5e860040

So we are getting the same result, and the matrix in Julia and C++ have the same address.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants