I was prepossessing data in C++ using the Armadillo library. The program end product is a ucube, which is a cube filled with unsigned integers. After its run, I want to load the ucube to R to perform some final statistical tests. To do so, I made a C++ function that load the ucube returning an array.
But it does not work!
I got the following warning: "warning: Cube::load(): incorrect header in B.bin" and the program returns a 0x0x0 array.
Trying to find why, I made a toy C++ program, which works fine. It is able to load the cubes without any problem.
#include <iostream>
#include <armadillo>
using namespace arma;
void read_cubes(char const* A, char const* B){
cube C;
ucube D;
C.load(A, arma_binary);
D.load(B, arma_binary);
}
int main(int argc, char** argv){
cube A = randu<cube>(5,5,5);
ucube B = randi<ucube>(5,5,5, distr_param(1, 10));
A.save(argv[1], arma_binary);
B.save(argv[2], arma_binary);
read_cubes(argv[1], argv[2]);
}
But I do not know why, doing the same steps in R does not work. To illustrate, please run the toy program as ./a.out A.bin B.bin. It will yield the Cube<double> A.bin and the Cube<uword> B.bin, which I will mention later.
The problem
If I source the following C++ code with Rcpp::sourceCpp and I try to read the Cube<double> A.bin with read_cube("A.bin") it works, but if I do the same for the Cube<uword> B.bin with read_ucube("B.bin") it does not (I get the warning).
#include <RcppArmadillo.h>
#include <iostream>
// [[Rcpp::depends(RcppArmadillo)]]
// [[Rcpp::export]]
arma::cube read_cube(char const* x){
arma::cube A;
A.load(x, arma::arma_binary);
return A;
}
// [[Rcpp::export]]
arma::ucube read_ucube(char const* x){
arma::ucube B;
B.load(x, arma::arma_binary);
return B;
}
Of course I could cast the Cube<uword> to a Cube<double> before ending the C++ program, but I would like to know why this happen and if it is possible to load a Cube<uword> in RcppArmadillo. Because it should be possible, right?
Unfortunately R still only supports 32 bit integers, so RcppArmadillo forces Armadillo to use 32 bit integers. This is done by defining ARMA_32BIT_WORD before including the armadillo header. See RcppArmadillo's configuration here.
You can apply the same "trick" with your Armadillo programs like so:
#define ARMA_32BIT_WORD
#include <armadillo>
One of the effects is that ucube (Cube<uword>) will use 32 bit unsigned integers.
After doing the above trick, recompile your Armadillo programs and save the ucubes again. They can then be loaded in RcppArmadillo.
Related
I am using Eigen for some simulations. I get segmentation fault error (more precisely Segmentation fault (core dumped) with no other details) whenever I include even the smallest overload Eigen operation (even if I have x=y where x,y are Eigen::VectorXd of the same size). What make this very strange is that it only happens if I have the matrix operations in certain functions.
Let me show you:
//main.cu
#include <Eigen/Dense>
#include "def.h"
using namespace std;
int main(int argc, char *argv[])
{
params p;
int ns;
//some code here
MatrixXR A(ns,ns);
VectorXR u(ns);
VectorXR v(ns);
VectorXR unew(ns);
VectorXR aux(ns);
VectorXR vnew(ns);
VectorXR vcouple(ns);
VectorXR q(ns);
Real* output;
output=new Real[output_size];
//output_size is a number depending on the system I am simulating, usually about 1000000.
CPUsim(output,p,u,v,A,unew,vnew,q,aux,vcouple);
delete [] &(output[0]);
return 0;
}
//def.h
#ifndef DEF_H_
#include <Eigen/Dense>
#define DEF_H_
#ifdef DOUBLE
typedef double Real;
typedef Eigen::MatrixXd MatrixXR;
typedef Eigen::VectorXd VectorXR;
#else
typedef float Real;
typedef Eigen::MatrixXf MatrixXR;
typedef Eigen::VectorXf VectorXR;
#endif
struct params
{
//some parameters
};
#endif
//sim.h
#ifndef SIM_H_
#define SIM_H_
#include "def.h"
#include <Eigen/Dense>
void CPUsim(Real* output,params &p, VectorXR& u,VectorXR& v,MatrixXR& A,VectorXR& unew,VectorXR& vnew,VectorXR& q,VectorXR& aux,VectorXR& vcouple);
//other functions
#endif
//sim.cu
#include "sim.h"
#include "coupling.h"
//some functions
void CPUsim(Real* output,params &p, VectorXR& u,VectorXR& v,MatrixXR& A,VectorXR& unew,VectorXR& vnew,VectorXR& q,VectorXR& aux,VectorXR& vcouple)
{
//some code
coupling(u,unew,v,vnew,p,A,vcouple,aux,no);
}
//coupling.h
#ifndef COUPLING_H_
#define COUPLING_H_
#include <Eigen/Dense>
#include "def.h"
//some declarations
void coupling(VectorXR& u,VectorXR& unew,VectorXR& v,VectorXR& vnew,params& p,MatrixXR& A,VectorXR& vcouple,VectorXR& aux,noise& no);
//coupling.cpp
void coupling(VectorXR& u,VectorXR& unew,VectorXR& v,VectorXR& vnew,params& p,MatrixXR& A,VectorXR& vcouple,VectorXR& aux,noise& no)
{
vcouple=A*v;
//some other stuff
}
Now, some explanations:
If I have vcouple=vcouple in coupling, I get no error, if I have vcouple=v, I do get the error. I get no errors if I have vcouple=A*v in main or in CPUsim. Somebody recommended defining 'EIGEN_DONT_ALIGN', but that works only in some cases (i.e. for the same ns, but different values for the elements of the matrices and vectors, it might show the error or it might not). Do you happen to know what might be causing this error?
BTW, I use the nvcc compiler because I am using CUDA for some parts of the simulation. However, Eigen is used only for portions of the code that run entirely on the CPU. For the host compiler, I use GCC 5.4.1 and I have ubuntu 16.04.
Edit:
The error disappears if I don't store the result (i.e. just A*v; instead of vcouple=A*v;)
I finally found the answer. Apparently nvcc and gcc align Eigen arrays differently. This explains why there was no problem when calculating (and assigning) the matrix product in the .cu files while getting an error in the .cpp ones. Simply changing the extension of the coupling.cpp file to .cu solved the problem.
More details can be found here:
https://listengine.tuxfamily.org/lists.tuxfamily.org/eigen/2016/06/msg00003.html
I've developed a C++ program which calculates a set of coordinates (x, y) within a loop. Every iteration I want to send the coordinate to Matlab for further processing, at a speed of about 25 times per second. I have a Matlab function that then takes this coordinate and uses it in real time; however, I haven't found an effective way of sending variables quickly from C++ to Matlab.
I've tried using the Matlab engine here: Passing Variable from C++ to Matlab (Workspace), except I want this variable to be used in the existing Matlab session and not simply run Matlab commands through C++.
I've also tried writing the C++ coordinate to a binary file and then reading this file in Matlab - this method is very fast but I'm having problems with the timing between both languages. Setting the Matlab code to an infinite loop reading the binary file, whilst running the C++ program writing the coordinate to the file, means that Matlab reads in a very strange order (ie. Matlab reads 15, 200, 70, 12 when I write the i values to file). I suspect this is due to poor timing between each program trying to open and either read or write the file.
C++:
#include "opencv2/highgui/highgui.hpp"
#include "opencv2/opencv.hpp"
#include <iostream>
#include <math.h>
#include <fstream>
#include <stdio.h>
#include <Windows.h>
using namespace cv;
using namespace std;
int main()
{
int a = 0
for (int i = 0; i < 100000; ++i)
{
a = i;
std::ofstream ofile("foobar.bin", std::ios::binary);
ofile.write((char*) &a, sizeof(int));
ofile.close();
}
return 0;
}
Matlab:
A = fopen('foobar.bin');
fread(A)
fclose(A);
Is there a way to quickly and accurately send data between C++ and Matlab by writing to binary OR some other method which I can implement?
Thank you very much!
I cannot provide code samples because it has been a few years since I did this, but I know that you can use a create a COM object and interface it with matlab. Here is the link describing how to interface a COM object with matlab. http://www.mathworks.com/help/matlab/using-com-objects-in-matlab.html
I am aware there are numerous similar queries on here, however I haven't been able to resolve this, not has a colleague, so:
I am using MinGW (4.8.x) with Eclipse CDT Kepler.
1) I have my own code and to clean it up I changed it to use a vector of structs - all is fine, except that the function that receives it complains about Invalid Argument'.
2) I reduced my code down to a minimum working example, if I place it all in a single file it works, however if I move out my definitions to the header (which I need to do in my main code) it suddenly cannot resolve the fields in the struct...
The code below is for a three file configuration, header/function/main.
(In my main code I use namespace std - but that doesn't seem to be the problem. Also, there are extraneous headers for a minimum working example in this, however they are needed in my main code.)
myheaders.h
/*************************/
/****** myheaders.h ******/
/*************************/
/**-- Header Files --**/
// File Streams and IO
#include <stdio.h>
#include <sstream>
#include <iostream>
#include <fstream>
// For strtod -> string to double
#include <stdlib.h>
// Math Operations
//#include <math.h>
#include <cmath>
// To get the CPU time
#include <time.h>
// For Vectors
#include <vector>
// For strings, C strings right now...
#include <cstring>
// Needed globally for the function definitions
// using namespace std;
#ifndef MY_HEADERS
#define MY_HEADERS
struct SpeciesLoss {
int ReactionID;
int SpeciesID;
double coefficient;
};
std::vector< double > SpeciesLossRate(std::vector<SpeciesLoss> , int, const std::vector< double > & );
#endif
function.cpp
/*************************/
/****** function.cpp *****/
/*************************/
#include "myheaders.h"
std::vector< double > SpeciesLossRate(
std::vector< SpeciesLoss > SpeciesLossList,
int Number_Species,
const std::vector< double >& Combined_Rates
)
{
std::vector< double > temp_species_loss;
temp_species_loss.resize(1);
temp_species_loss[0]=SpeciesLossList[0].ReactionID;
return temp_species_loss;
}
main.cpp
/*************************/
/******** main.cpp *******/
/*************************/
#include "myheaders.h"
std::vector< SpeciesLoss > SpeciesLossAll; // New vector for recording species loss, uses a vector of structs
int main(int argc, char* argv[])
{
std::vector< double > Rates;
Rates.push_back(1);
SpeciesLossAll.push_back(SpeciesLoss());
SpeciesLossAll[0].ReactionID = 0;
SpeciesLossAll[0].SpeciesID = 0;
SpeciesLossAll[0].coefficient = 0;
std::vector< double > SpeciesConcentrationChange = SpeciesLossRate(SpeciesLossAll,1, Rates);
return 0;
}
Edit:
Screenshot
Edit 2:
And interesting update - it compiles fine on Linux with GCC. Better than nothing, but I still want to know what is going wrong, plus I'd like my code to be cross platform...
Edit 3:
This is more and more bizarre - I just tested my code (the full project that compiles on Linux) on my home PC which runs Windows 7 where it builds fine while my laptop runs Windows 8 and the problem occurs.
The Settings for the C++ build are absolutely identical.
Both run MinGW 4.8.1...
Both run the latest Eclipse Kepler...
And yes, I am aware that I need to test some suggestions still.
#ifndef MY_HEADERS
#define MY_HEADERS
Should be at the beginning of your file. Since you have no idea in what order the compiler is going to include headers this might be causing a problem... Especially if you are including your personal header in multiple files, wich will definitely make it behave like so. Also, keep in mind that since you are not providing a default constructor but rather using the one the compiler provides for you, those variables inside the struct will most likely not be initialized to zero as you expect them.
EDIT#1
Are you compiling everything NOT just main... I just copied your code into VS and it works!
EDIT#2
Try defining the function inline instead of a separate implementation file.
static std::vector< double > SpeciesLossRate(
std::vector< SpeciesLoss > SpeciesLossList,
int Number_Species,
const std::vector< double >& Combined_Rates
)
{
std::vector< double > temp_species_loss;
temp_species_loss.resize(1);
temp_species_loss[0]=SpeciesLossList[0].ReactionID;
return temp_species_loss;
}
EDIT#3
Ok, from the screen-shot this is definitely valid code. For sake of trying everything; implement your own constructor and copy constructor of the struct. I know this might sound silly but maybe Eclipse doesn't think so.
OK - I have found the answer - I think - and it boils down to Eclipse.
-> Project -> C/C++ Index -> Rebuild
This resolves the issue.
In fact, this problem is known on earlier Eclipse CDT versions: https://bugs.eclipse.org/bugs/show_bug.cgi?id=348170
Is element wise multiplication (%) speed in armadillo depends whether LAPACK/BLAS is installed? Im currently running armadillo without them installed and speed is awful.
Ok here is the simplest code, which takes eternity to calculate
#include <iostream>
#include "conio.h"
#include "armadillo"
using namespace arma;
using namespace std;
int main(int argc, char** argv)
{
int n=250;
mat X=ones(n,n);
mat quan;
for (int xi=1;xi<=256;xi++)
{
quan = exp(X)%exp(X);
}
getch();
return 0;
}
Make sure you have optimisation flags enabled in your compiler settings (eg. in GCC or Clang, use -O2 or -O3). Armadillo makes use of template metaprogramming, and like any C++ template library, this absolutely requires optimisation enabled within the compiler to be effective. For example, this also applies to C++ template libraries such as Boost.
Why are you calculating exp(X) twice? You're not benchmarking elementwise multiplication; you're apparently benchmarking exp(). Also, why are you not using expmat() or expmat_sym()?
This is my program:
#include "stdafx.h"
#include <iostream>
using namespace std;
double areaofcircle(double r)
{
return 3.14 * r * r;
}
int main()
{
cout << areaofcircle(5);
}
I should be getting the output of "78.5" but I keep getting "78.512". What is going on?!
I've also tried float, but I still get the same output.
Also just a side question, do I really need to add "return 0;" to the main function?
One more side question, do I need to write "using namespace std;" inside every function, or can I just write it outside of everything, like how I've been doing it.
You're passing the literal for an integer (5) so somewhere an implicit conversion is required to turn it into a double. You would be better off passing 5.0. The C++ default for doubles requires no specifier so your 3.14 is fine. (specifying a float requires 3.14f). That said, I tried both with 5 and 5.0 and got 78.5 both times on my compiler.
How you're using the std namespace is fine, but as pointed out it does bring ALL of the standard namespace into scope. I see this a lot in teaching material. It is better to just use
using std::cout;
or just explicitly add std::cout to all uses. However, there is nothing "wrong" from a compilation standpoint in the way you did it.
I think you are doing something wrong. I tried the same on GCC compiler, and I do get 78.5. Which compiler are you using?
Regarding your other questions
It is always a good idea to return the state of your program from main. Usually, you can return EXIT_SUCCESS if everything works okay, else you can return EXIT_FAILURE.
No it is not necessary to include using namespace std. Instead, it is bad practice to pollute your standard namespace. You should include only those functions that you use very frequently.
To read more about C++. Check this link
Hope this helps.
Tried a few experiments on VS 2008 to see if I could get a similar error. By changing pi to a float I do get 78.500002622604370 which is different but not the same as your issue. But I do get 78.5 when pi is a double.
I'd recommend you let us know which compiler and version you're using, then possibly someone may be able to help.
#include "stdafx.h"
#include <iostream>
const double pi = 3.14;
double areaofcircle(double r)
{
return pi * r * r;
}
int _tmain(int argc, _TCHAR* argv[])
{
double temp = areaofcircle(5);
std::cout << temp;
return 0;
}