Calling C++ function having std::vectors as input and output parameters from Julia


#1

Dear All
I am new to Julia and and I am trying to access my C++ code from Julia. I have asked this question already at Stack Overflow, but were not able to find an answer there.
I am trying to call a C++ function from Julia using Cxx. The input and output parameters of the C++ function are std::vectors, see the function compute_sum in the example below:

#include
#include

std::vector< int > compute_sum( const std::vector< std::vector >& input )
{
std::vector< int > resut( input.size() , 0 );
for ( std::size_t i = 0 ; i != input.size() ; ++i )
{
for ( std::size_t j = 0 ; j != input[i].size() ; ++j )
{
resut[i] += input[i][j];
}
}
return resut;
}

void simple_function( int i )
{
std::cout << "The numbers is : " << i << std::endl;
}

Assuming this function is stored as code.cpp I am compiling it to a shared object code.so using:

g++ -shared -fPIC code.cpp -o code.so

and as a result I obtain a file code.so

Having this, I run Julia in the same folder as code.so. My version of Julia is 0.6.2. Then I import Cxx and the code.so file using:

julia> using Cxx
julia> const path_to_lib = pwd()
julia> addHeaderDir(path_to_lib, kind=C_System)
julia> Libdl.dlopen(path_to_lib * “/code.so”, Libdl.RTLD_GLOBAL)
Ptr{Void} @0x00000000044bda30
julia> cxxinclude(“code.cpp”)

In odder to test if the process is successful I am calling the simple_function and obtain the correct results:

julia> @cxx simple_function(1234)
The numbers is : 1234

Then I want to call compute_sum function. For that I need somehow to create, or convert Julia vector into C++ std::vector< std::vector >. I am trying the following:

julia> cxx" std::vector< std::vector > a;“
true
julia> icxx” a.push_back( std::vector(1,2) ); “
julia> icxx” a.push_back( std::vector(1,3) ); “
julia> icxx” a.push_back( std::vector(1,4) ); “
julia> icxx” a.size(); "
0x0000000000000003

So I assume that the vector is created in a correct way. Then I trying to call the function with it, but I fail:

julia> @cxx compute_sum(a)
ERROR: UndefVarError: a not defined
julia> @cxx compute_sum(“a”)
ERROR: Got bad type information while compiling Cxx.CppNNS{Tuple{:compute_sum}} (got String for argument 1)
julia> icxx " compute_sum(a);“
ERROR: syntax: extra token “”” after end of expression

Could anyone help me please with the following question(s):

  1. How to call compute_sum function from Julia? I am happy to use any technique (not necessary Cxx) that works and is reasonably fast.
  2. How to convert the result of compute_sum to Julia array?

If one cannot do it with std::vector on C++ side, I would appreciate any advice on how to transfer large vectors (for instance in the form int**) from Julia to C++ and back.

Thank you very much!

pawel


#2

Hi,

The following code should work in Julia, the trick is to use the icxx string macro with interpolation:

using Cxx

cxx"""
#include <iostream>
#include <vector>

std::vector<int> compute_sum(const std::vector<std::vector<int>> &input)
{
  std::vector<int> result(input.size(), 0);
  for (std::size_t i = 0; i != input.size(); ++i)
  {
    for (std::size_t j = 0; j != input[i].size(); ++j)
    {
      result[i] += input[i][j];
    }
  }
  return result;
}
"""

cxx_v = icxx"std::vector<std::vector<int>>{{1,2},{1,2,3}};"
println("Input vectors:")
for v in cxx_v
  println("  ", collect(v))
end

cxx_sum = icxx"compute_sum($cxx_v);"
println("Cxx sums: $(collect(cxx_sum))")

I have also posted this answer on Stack Overflow


#3

If you want to convert a julia array of arrays to std::vectors and pass it to C++, and vice versa, you can do the following.

as = [rand(1:10,5), rand(1:10,6)]
x = convert(cxxt"std::vector< std::vector< int > > >", as)
collect(icxx"compute_sum($x);")

#4

x = cxxt"std::vector< std::vector< int > > >"(as) also works. You can convert julia arrays to std::vectors for a number of different types. Cxx also implements the iterator interface on std::vectors, which is why you can call collect on it.


#5

Thank you, that solution works, and this is what I need.


#6

Thank you for suggesting it. It works as a way of converting Julia arrays to std::vectors.