Compiling multiple source files in Rcpp - c++

I have the following directory structure
my_func
- my_func_r.cpp
- my_func.c
- my_func.h
- my_func_test.c
- matrix/
- matrix.h
- matrix.c
The matrix directory contains some matrix structures in matrix.h and some initialisation, free, print etc. functions in matrix.c. The my_func.h file is something like
#include <math.h>
#include <stdio.h>
#include <stdlib.h>
#include "matrix/matrix.h"
... some structures and templates ...
The my_func.c file is then
#include "my_func.h"
... helper functions ...
int my_func(...) {
... my_func stuff ...
return 0;
}
The my_func_test.c is something like
#include "my_func.h"
int main() {
... some test ...
return 0;
}
With gcc/g++ I can run this fine with
gcc my_func_test.c my_func.c matrix/matrix.c -o test -lm
The final file my_func_r.cpp is an interface between the Rcpp structures and the structures used in my_func.c. It is currently something like
#include "my_func.h"
#include <Rcpp.h>
// [[Rcpp::export]]
int my_func_r(Rcpp::List x, ...) {
... convert inputs to structure recognised by my_func.h ...
... run my_func.c ...
... put returned objects back into one of the R structure ...
return 0;
}
The problem I have is if I now run
sourceCpp('my_func_r.cpp', verbose=TRUE, rebuild=TRUE)
It complains about missing symbols for functions located in matrix/matrix.c. A workaround is to simply paste all my header and source code from both the my_func and matrix files at the top of my_func_r.cpp.
This however feels a very unsatisfactory solution especially for code maintenance. What is the easiest way to accomplish what I am trying to do?

Quick ones:
This is not really particular to Rcpp per se
You are simply struggling with a more advanced / complicated src/ directory in an R build.
There is official documentation about this in Writing R Extensions, and the questions has come up here on SO before.
You could compile a libmatrix.a first in the subdirectory and link to that. This is doable via a simple src/Makevars but still discouraged. So read on.
But this is a self-inflicted wound. Just copy matrix.h and matrix.c into src/, adjust the include path, and you are done.
As always: Create a package. Don't use sourceCpp() on larger setup. It is not made for that,

Related

Keep MATLAB engine open in C++ dll

I want to create a dll which keeps an instance of the MATLAB engine open for use by other scripts. That is, the goal is to not have to keep initialising and closing the MATLAB instance, which takes time.
For some background, I have a working C++ program which initialises a MATLAB engine and contains a load of functions to do various things in MATLAB. As some kind of minimum example, I have the three scripts below.
header.h
#pragma once
#include "MatlabEngine.hpp"
#include "MatlabDataArray.hpp"
#include <iostream>
#include <fstream>
#include <string>
#include <cmath>
#include <tuple>
#pragma comment (lib,"libmat.lib")
#pragma comment (lib,"libmx.lib")
#pragma comment (lib,"libmex.lib")
#pragma comment (lib,"libeng.lib")
// Example function definition
void setWorkingDir(std::unique_ptr<matlab::engine::MATLABEngine>& matlabPtr, std::string dir);
MatlabFunctions.cpp
#include "header.h"
// Example function
void setWorkingDir(std::unique_ptr<matlab::engine::MATLABEngine>& matlabPtr, std::string dir){
std::u16string matlabCommand = matlab::engine::convertUTF8StringToUTF16String("cd '"+dir+"'");
matlabPtr->eval(matlabCommand);
}
Main.cpp
#include "header.h"
int main(){
using namespace matlab::engine;
matlab::data::ArrayFactory factory; // Create MATLAB data array factory
std::unique_ptr<MATLABEngine> matlabPtr = startMATLAB(); // Start MATLAB engine
// Do various functions
}
My goal is to get rid of Main.cpp and create a dll which keeps keeps the MATLAB engine open, allowing the functions in MatlabFunctions.cpp to be run without having to start the MATLAB engine each time.
Is this possible? And if so, how can it be done?
Some people suggested to use IPC here for the task to be done. Using something like COM is not cross-platform and, well, pretty outdated at the moment. As a modern and cross-platform solution, I'd use an actual server application (which will start MATLAB engine and wait for requests) with, for example, gRPC running. Here's tutorial, pretty good one.
Other than that, you can specify your own networking protocol to run your tasks on the server application without the need of IPC, but the gRPC solution works simply out of the box, no bloat coding included.

Dulmage-Mendelsohn decomposition in R

I am trying to implement Dulmage-Mendelsohn decomposition in R, which is also known as breadth-first search for coarse decomposition and I want to do this:
dulmage_mendelsohn <- function(mat) {...}
dulmage_mendelsohn(mat)
> mat_with_blocks
Dulmage-Mendelsoh is widely known in MATLAB an Octave (see, for example, https://www.mathworks.com/help/matlab/ref/dmperm.html) and there are C and C# implementations.
It is by using the Rcpp:: package that I am trying to use CSparse already existing function ::cs_dmperm (https://github.com/ibayer/CSparse/blob/master/Source/cs_dmperm.c#L1) and after editing the header in a new cpp file in this way:
#include <Rcpp.h>
#include <cs.h>
It returns the error:
cs_dmperm.cpp:2:10: fatal error: cs.h: No such file or directory
2 | #include <cs.h>
This is not really different from the steps described in https://math.stackexchange.com/a/3023469
Do you know a workaround to use the C function or an existing implementation? I have user search engines extensively with no result.

how to resolve header order issue

I have the following problem:
My code relies on two external packages
EIGEN (Headers only)
IAU SOFA (static library + headers)
If I write the following code:
#include "sofa.h"
#include "Eigen/Dense"
I get the following error messages:
/some_path/sofam.h:85:18: error: expected unqualified-id before numeric constant #define DAYSEC ( 86400.0 ) ...
and many more lines of errors.
However, if I change the order of the includes it compiles:
#include "Eigen/Dense"
#include "sofa.h"
works fine.
What is causing the problem?
My main problem is that I do not know how this behavior is called so I cannot really google it effectively.
It is not an option to change any of the source code of EIGEN or IAU SOFA (since they are maintained by other groups and we regularly update them from their webpage)
It is also not an option to just fix it once and never touch it again. The order of our header files is automatically rearranged to be in alphabetic order which is messing up everything every time we commit any change and we regularly use an optimize imports algorithm which is also changing the includes automatically.

cusp::extract_diagonal not found

I'm using CUSP for part of my GPU accelerated code. I have a need to extract the diagonal from a cusp matrix, C. Which should be put into diagonal in the below code.
cusp::extract_diagonal(C, diagonal);
However on compilation I get "cusp" has no member "extract_diagonal"
If I have:
#include <cusp/format_utils.h>
As in the example I get format_utils.h cannot be found. If I insert detail in to complete the path to the header as below:
#include <cusp/detail/format_utils.h>
Compilation is able to find format_utils.h but still says there is no "extract_diagonal"
The example I'm looking at is:
// include cusp array1d header file
#include <cusp/array1d.h>
#include <cusp/coo_matrix.h>
#include <cusp/print.h>
#incldue <cusp/gallery/poisson.h>
#include <cusp/format_utils.h>
int main()
{
// initialize 5x5 poisson matrix
cusp::coo_matrix<int,float,cusp::host_memory> A;
cusp::gallery::poisson5pt(A, 5, 5);
// allocate array to hold diagonal entries
cusp::array1d<float, cusp::host_memory> diagonal(A.num_rows);
// extract diagonal of A
cusp::extract_diagonal(A, diagonal);
// print diagonal entries
cusp::print(diagonal);
}
Versions are as below:
The following libraries were found:
CUDA v6.0
Thrust v1.7.1
Cusp v0.4.0
Am I missing some include or other? As a last resort I included all headers in the main cusp directory to no avail.
Any suggestions would be great.
You cannot find cusp/format_utils.h because it doesn't exist in the CUSP version you are using, which is close to 4 years old, and the codebase has been refactored since then. If you upgrade to CUSP 0.5.1 (for which the example you are using was written), you should find it works.
Alternatively, if you change the include to cusp/format.h, you might find it works as well, although I cannot guarantee it and am too lazy to pull an ancient version of CUSP and check.

Include string in file on compilation

I work on a team project using a teensy and matlab, and to avoid version differences (e.g one person loads the teensy with version A, and the person now using it with matlab has version B of the code), I'd like to send a version string on pairing.
However, I want the version string to sit in a shared file between the matlab code and the teensy, and every time the program is loaded to the teensy, have it included on compilation as a constant.
Sort of like:
const string version = "<included file content>";
The matlab on its part can read it at runtime.
I thought of using a file whose contents are an assignment to a variable whose name is shared both by teensy and matlab, however I would prefer a more elegant solution if such exists, especially one that doesn't include executing code from an external file at runtime.
One way is just to have a simple setup like so:
version.inc:
"1.0.0rc1";
main.cpp:
const string version =
#include "version.inc"
...
Note that the newline between the = and the #include is in place to keep the compiler happy. Also, if you don't want to include the semicolon in the .inc file, you can do this:
main.cpp:
const string version =
#include "version.inc"
; // Put the semicolon on a newline, again to keep the compiler happy
EDIT: Instead of a .inc file, you can really have any file extension you desire. It's all up to taste
EDIT: If you really wanted to, you could omit the quotes from the .inc file, but that would lead to messy code like this:
version.inc:
STRINGIFY(
1.0.0rc1
);
main.cpp:
#define STRINGIFY(X) #X
const string version =
#include "version.inc"
...
EDIT:
As #Ôrel pointed out, you could handle the generation of a version.h or similar in your Makefile. Assuming you're running a *nix system, you could try a setup like this:
Makefile:
...
# "1.0.0rc1"; > version.h
echo \"`cat version.inc`\"\; > version.h
...
version.inc:
1.0.0rc1
main.cpp:
const string version =
#include "version.h"