Today I though I ruin my day by trying to interface our main DAQ framework (written in C++ and ROOT) in Julia and I think I am quite successful so far (haha). The best thing is, the software is closed source so I cannot share that code.
Anyways, maybe someone can push me into the right direction…
The framework I am trying to interface is mostly header-only and as a first step I tried to compile a basic function, which should not need any linking (as far as I can judge). At least, the code inside the cxx
string can be compiled with the following flags:
CC = g++
CFLAGS = -I${FRAMEWORK_DIR}/software -std=c++11
Here is a simple call of a dummy function which utilises a class from the framework (namely JMatrixND
):
using Cxx
const incpath = joinpath(ENV["FRAMEWORK_DIR"], "software")
addHeaderDir(incpath, kind=C_System)
cxx"""
#include <chrono>
#include <iostream>
#include "JMath/JMatrixND.hh"
void matrix_test(int N) {
std::cout << "Generating two " << N << "x" << N << " matrices." << std::endl;
JMATH::JMatrixND A(N);
JMATH::JMatrixND B(N);
for (size_t i = 0; i != A.size(); ++i) {
for (size_t j = 0; j != A.size(); ++j) {
A.at(i, j) = rand() / double(RAND_MAX);
B.at(i, j) = rand() / double(RAND_MAX);
}
}
std::cout << "Multiplying them..." << std::endl;
std::chrono::steady_clock::time_point begin = std::chrono::steady_clock::now();
A.mul(B);
std::chrono::steady_clock::time_point end = std::chrono::steady_clock::now();
int delta_t = std::chrono::duration_cast<std::chrono::microseconds>(end - begin).count();
std::cout << "Elapsed time: " << delta_t << " us" << std::endl;
}
"""
@cxx matrix_test(10)
When I run it, I get
LLVM ERROR: Program used external function '_ZNSt7__cxx1119basic_ostringstreamIcSt11char_traitsIcESaIcEEC1Ev' which could not be resolved!
and after commenting out some lines, I figured that it fails at A.mul(B);
, however things like std::cout << A.at(1, 2) << std::endl;
work, so it seems to be able to run some code.
I examined mul
and also copied the main multiplication routine into the cxx
string and it worked. Besides that, there is nothing more other than throwing an exception when the matrix sizes differ (which is not the case). Here is the source, which I simplified to not get any trouble:
JMatrixND& mul(const JMatrixND& A,
const JMatrixND& B)
{
if (A.size() == B.size()) {
this->resize(A.size());
// here the routine which works when copy&pasted instead of calling `A.mul(B)`
// the only methods used in the block are `.at()` and `.size()`
} else {
THROW(JException, "JMatrixND::mul() inconsistent matrix dimensions " << A.size() << ' ' << B.size());
}
return *this;
}
Any ideas?