Question on Calling Julia functions from C++ with CxxWrap (and Eventually Interfacing with Julia from MATLAB)

Hello everyone,

I have a relatively unique use case for Julia and CxxWrap.jl. To provide some background, my current research involves employing heuristic optimization algorithms to assist in solving spacecraft trajectory optimization problems. Previously, I employed a particle swarm optimization algorithm written in Julia (see link if interested) with promising results. Now, I hope to present a new conference paper comparing several different heuristic optimization algorithms, and would like to include MATLAB’s Genetic Algorithm and Simulated Annealing implementations.

Using MATLAB poses some problems though, namely:

  • The cost function I plan to minimize relies heavily on features within DifferentialEquations.jl, so simply re-writing the code in MATLAB is not an option.
  • Mex.jl provides the ability to call Julia functions directly from MATLAB, but is no longer maintained. (I’ve also attempted to use the fork at jebej/Mex.jl without success, but this may still be an option if I can get it working)
  • The cost function will be called many times per optimization run (potentially > 1,000,000 function calls), so low latency is extremely desirable.

Why not just use other optimization algorithms written in Julia? I plan to! Especially some of the fantastic algorithms contained in BlackBoxOptim.jl. That said, MATLAB is (one of) the most widely used languages in my field (Aerospace Eng.), and results produced by MATLAB optimization algorithms may be more relatable. Not to mention the MATLAB global optimization suite is very mature and heavily tested.

After spending a few days looking into options, I’ve tentatively settled on employing CxxWrap.jl for calling Julia functions from C++ and compiling a dynamic library containing C++ functions that call corresponding Julia functions. It’s then relatively simple to call C++ dynamic libraries from MATLAB, so ideally, MATLAB would interface with the C++ library, and would call a C++ function, which then calls its associated Julia function. I’m relatively inexperienced with C++, so please bare with me and/or correct me if any of the language I’m using is incorrect.

The use case of calling C++ in Julia is relatively common at this point, but the inverse does not seem to be true. As such, I’ve been struggling to get even a MWE using CxxWrap.jl working at this point. Following the documentation at JuliaInterop/CxxWrap.jl, on the Julia side I have:

module TestModule

using CxxWrap
testf(x,y) = x*y
c_func = @safe_cfunction(testf, Float64, (Float64, Float64))

end

On the C++ side, for now I want to just simply call the Julia function using CxxWrap, with something along the lines of:

#include <iostream>
#include <julia.h>
#include "jlcxx/jlcxx.hpp"

int main(int argc, char *arg[])
{
    double result;
    \\ Call Julia c_func from TestModule and store result in result

    std::cout << "Julia function returned: " << result << std::endl;

    return 0;
}

Any and all help on getting my simple MWE working would be greatly appreciated. Once working, hopefully we can then use this discussion for further assistance on implementing my full use case if needed. I’m also completely open to alternative suggestions for calling Julia from MATLAB if my current plan is not possible or if easier solutions exist.

Thank you!

I have a rough, rudimentary example, where I pass a Julia function to a C++ minimization algorithm (Minuit2). It works as a proof of principle. Please feel free to check it out. GitHub - jstrube/Minuit2.jl

You’ll want to look at the tests.
I’m sure it could be improved in many ways, but I hope it serves as a good starting point for you.

2 Likes

First, thank you @jstrube, your example has been incredibly helpful while trying to get my use case working. Unfortunately, I’ve still not had much success getting my simple MWE working. My biggest point of confusion revolves around how to get the function wrapped by @safe_cfunction to be accessible within C++. Forgive me if I’m incorrect about this, but in your example @jstrube, it appears that functions wrapped by @safe_cfunction are always passed in as arguments from a Julia environment to be evaluated within C++ Minuit2. Because of my end goal of calling a Julia function from MATLAB, I don’t know if this workflow is possible, but I welcome any suggestions.

Thankfully, after taking a longer look at the Mex.jl source code and making some slight modifications, I was able to successfully call Julia functions from within MATLAB with seemingly low latency (still need to do some more testing before I say this definitively). Therefor, at least for now, I may forgo attempting to employ CxxWrap.jl.

In case there is anyone else trying to call Julia from within MATLAB on Windows with Julia v1.6.2, my fork of Mex.jl can be found at GrantHecht/Mex.jl. Note, on Windows when using the MSVC compiler, I also had to make slight modifications to atomics.h and dtype.h, which were suggested in #34201 and #39595. For anyone on Julia v1.5 or prior, I believe jebej/Mex.jl should work for you.