Loading a sparse matrix Armadillo C++ - c++

I'm having a bit of a strange problem. I generally use the CLion IDE to compile and run code but I want to make use of a profiler to try to optimize my software and CLion does not include a profiler extension. So I need to compile and run at command line.
OK, no problem but for some reason when I do so, I get errors when loading sparse matrices saved in the form arma_binary (which the Armadillo documentation states is the only possible file format for sparse matrices).
The following is an example script saved as main.cpp:
#include <iostream>
#include <armadillo>
using namespace std;
using namespace arma;
void DenseMult (mat& I, mat& B);
void SparseMult (sp_mat& I, mat& B);
int main() {
mat Int; Int.load("intMatDense.mat");
cout << Int.n_cols << endl;
sp_mat IntSp; IntSp.load("intMatSparse.mat", arma_binary);
cout << IntSp.n_cols << endl;
mat B; B.load("biomassMat.mat");
DenseMult(Int, B);
SparseMult(IntSp, B);
return 0;
}
void DenseMult (mat& I, mat& B) {
I * B;
}
void SparseMult (sp_mat& I, mat& B) {
I * B;
}
Which gives the following output when built and run in CLion:
/home/jack/CLionProjects/Optimization/cmake-build-debug/Optimization
307
307
Process finished with exit code 0
So far so good but when I do (what I think is) the same at the command line:
jack#jack-MacBookPro:~/CLionProjects/Optimization$ g++ main.cpp -o main -O2 -larmadillo
jack#jack-MacBookPro:~/CLionProjects/Optimization$ ./main
I get the following output:
307
warning: SpMat::load(): inconsistent data in intMatSparse.mat
0
error: matrix multiplication: incompatible matrix dimensions: 0x0 and 307x3
terminate called after throwing an instance of 'std::logic_error'
what(): matrix multiplication: incompatible matrix dimensions: 0x0 and 307x3
Aborted (core dumped)
Is it possible I need to link to the Armadillo library differently in order to access the sparse matrix functionality?
Thanks in advance.
Jack

Related

Unable to load armadillo Cube<uword> when using RcppArmadillo

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.

Strange compilation error: compiler bug or my own?

I have header-only library, and I'm getting the strangest compilation error. The problem in proceeding is that I'm not getting this error in a representative minimal example, and not on all compilers (on macOS everything compiles and runs like a charm). I am not sure if I should be worried about something in my code, or if it is an upstream bug. Regardless, I'm not sure how to work around this.
I'm getting the following compiler error:
In file included from /home/tdegeus/opt/include/eigen3/Eigen/SparseCore:59:0,
from /home/tdegeus/opt/include/eigen3/Eigen/Sparse:26,
from /home/tdegeus/opt/include/eigen3/Eigen/Eigen:2,
from /home/tdegeus/prog/src/GooseFEM/docs/examples/Statics/Periodic/LinearElasticity/main.cpp:1:
/home/tdegeus/opt/include/eigen3/Eigen/src/SparseCore/SparseSelfAdjointView.h: In function ‘void Eigen::internal::permute_symm_to_symm(const MatrixType&, Eigen::SparseMatrix<typename MatrixType::Scalar, DestOrder, typename MatrixType::StorageIndex>&, const typename MatrixType::StorageIndex*) [with int SrcMode = 1; int DstMode = 2; MatrixType = Eigen::SparseMatrix<double>; int DestOrder = 0]’:
/home/tdegeus/opt/include/eigen3/Eigen/src/SparseCore/SparseSelfAdjointView.h:517:6: internal compiler error: in predicate_mem_writes, at tree-if-conv.c:2252
void permute_symm_to_symm(const MatrixType& mat, SparseMatrix<typename MatrixType::Scalar,DstOrder,typename MatrixType::StorageIndex>& _dest, const typename MatrixType::StorageIndex* perm)
^~~~~~~~~~~~~~~~~~~~
0xb3530b predicate_mem_writes
/ssoft/spack/paien/spack.v2/var/spack/stage/gcc-7.3.0-drb5cfgzldhzbrs6lyzk7xdqqcixbxhb/gcc-7.3.0/gcc/tree-if-conv.c:2252
0xb3530b combine_blocks
/ssoft/spack/paien/spack.v2/var/spack/stage/gcc-7.3.0-drb5cfgzldhzbrs6lyzk7xdqqcixbxhb/gcc-7.3.0/gcc/tree-if-conv.c:2377
0xb359bb tree_if_conversion(loop*)
/ssoft/spack/paien/spack.v2/var/spack/stage/gcc-7.3.0-drb5cfgzldhzbrs6lyzk7xdqqcixbxhb/gcc-7.3.0/gcc/tree-if-conv.c:2883
0xb3663b execute
/ssoft/spack/paien/spack.v2/var/spack/stage/gcc-7.3.0-drb5cfgzldhzbrs6lyzk7xdqqcixbxhb/gcc-7.3.0/gcc/tree-if-conv.c:2961
Please submit a full bug report,
with preprocessed source if appropriate.
Please include the complete backtrace with any bug report.
See <https://gcc.gnu.org/bugs/> for instructions.
Which disappears if I comment this line (obviously breaking functionality):
m_solver.compute(m_ACuu);
Note that:
Eigen::SparseMatrix<double> m_ACuu;
Eigen::SimplicialLDLT<Eigen::SparseMatrix<double>> m_solver;
I tried a minimal example:
#include <iostream>
#include <iomanip>
#include <math.h>
#include <vector>
#include <Eigen/Dense>
#include <Eigen/Sparse>
#include <Eigen/SparseCholesky>
int main()
{
size_t N = 11;
// allocate system
Eigen::SparseMatrix<double> A(N,N);
Eigen::VectorXd f(N);
// set force
f *= 0.0;
f((N-1)/2) = 1.0;
// construct list of Triplets (row,col,data) that from the matrix "A"
std::vector<Eigen::Triplet<double>> Atr;
// - first equation
Atr.push_back(Eigen::Triplet<double>(0,0,+2.0));
Atr.push_back(Eigen::Triplet<double>(0,1,-1.0));
// - body
for ( size_t i=1; i<N-1; ++i ) {
Atr.push_back(Eigen::Triplet<double>(i,i-1,-1.0));
Atr.push_back(Eigen::Triplet<double>(i,i ,+2.0));
Atr.push_back(Eigen::Triplet<double>(i,i+1,-1.0));
}
// - last equation
Atr.push_back(Eigen::Triplet<double>(N-1,N-2,-1.0));
Atr.push_back(Eigen::Triplet<double>(N-1,N-1,+2.0));
// build matrix from Triplets
A.setFromTriplets(Atr.begin(),Atr.end());
// solve the linear system
// - define solver (according to type above)
Eigen::SimplicialLDLT<Eigen::SparseMatrix<double>> solver;
// - analyze the system, and factorize (one could solve different right-hand-sides)
// solver.analyzePattern(A);
solver.factorize(A);
// - solve "A * x = f"
Eigen::VectorXd u = solver.solve(f);
// print to screen
std::cout << A << std::endl;
std::cout << u << std::endl;
return 0;
}
Compiled on the same system with the same libraries and with similar options:
g++ -march=native -O3 test.cpp
But this compiles and runs like a charm!?
Note that I've tried several Eigen versions, including 3.3.90.
Edit
Also note that this problem occurs with
g++ --version
g++ (GCC) 7.3.0
But is gone for
g++ (GCC) 6.4.0

include LAPACK on c++ code

I am trying to execute following simple c++ code in Qt environment on my mac. What I want with this code is to use libraries of LAPACK for simple mathematical operations. I just considered "dot product " function to test this case and got
"Symbols not found for architecture x86_64" and
"linker command failed with exit code 1 (use -v to see invocation) errors.
By the way, I am quite sure that i am repeating file or header file names that might cause these same errors.
Anyone knows how to overcome this ? Thanks in advance.
#include <iostream>
#include <vector>
#include <Accelerate/Accelerate.h>
extern "C"
{
double ddot_ (const int*, const double*, const int*, const double*, const int*);
}
int main()
{
std::vector<double> values(2, 1.);
int N = 2;
int one = 1;
double norm = ddot_(&N, &values[0], &one, &values[0], &one);
std::cout << "Hello world " <<norm << std::endl;
return 0;
}
The function ddot_() is part of the Blas library. It is not a part of the Lapack library. Hence, the program using ddot_() should be linked to the Blas library. For instance, the c++ program you posted can be compiled by:
g++ main.cpp -o main -lblas
provided #include <Accelerate/Accelerate.h> is commented.

CUDA does not seem to compile

I am currently running the CUDA 5.0 Toolkit on my Visual Studio 2012 Express.
I attempted to run the following code
I have searched high and low for methods of compiling .cu on Visual Studio but to no avail
Code I have attempted to compile:
//CUDA.cu
#include <iostream>
#include <cuda.h>
#include <cuda_runtime.h>
#include <device_launch_parameters.h>
using namespace std;
__global__ void Add(int* a, int* b)
{
a[0] += b[0];
}
int main()
{
int a = 5, b = 9;
int *d_a, *d_b;
cudaMalloc(&d_a, sizeof(int));
cudaMalloc(&d_b, sizeof(int));
cudaMemcpy(d_a, &a, sizeof(int), cudaMemcpyHostToDevice);
cudaMemcpy(d_b, &b, sizeof(int), cudaMemcpyHostToDevice);
Add<<< 1 , 1 >>>(d_a, d_b);
cudaMemcpy(&a, d_a, sizeof(int) , cudaMemcpyDeviceToHost);
cout << a << endl;
return 0;
}
The compiler shows an error in the line
Add<<< 1 , 1 >>>(d_a, d_b);
Where it says "Error:expected an expression"
Any attempts to compile this code results in a success. but no .exe is to be found hence I cannot debug whatsoever.
Unable to start program 'C:\Users\...\CUDATest3.exe'
The system cannot find the file specified
Any help whatsoever is VERY MUCH appreciated. Thanks
CK
Although I would love to understand as to WHY in my computer CUDA decided that VS is a deplorable program to be married to, I have taken a shortcut by handcuffing both of said program by means of copying from the templates provided by the CUDA installation toolkit. (The CUDA samples.)
Apparently those samples have everything already set up and ready to go; all you need to do is edit the code from inside the solution itself. For some reason the code would not work if I had written all of the code from square one.
I still have no idea as to why I am unable to get it to run from scratch but I guess
editing the sample templates would give a much satisfactory result
if one does not have the time for it.

Program gives program.exe has stopped working about 4 second after starting it

I am new to coding and I am trying to create a retro style game.
The idea is to have each square in the game be part of a string. Here is the code I got so far:
#include <iostream>
#include <stdlib.h>
using namespace std;
int main(){
int a,b=0;
char s[9][77]={};
while (true) {
s[a][b]={'_'};
b+=1;
if (b>77){
a+=1;
b=0;
}
if (a>9){
a=0;
b=0;
break;
}
}
s[0][0]={'H'};
cout << "################################################################################";
cout << "#" <<s[0][0]<<s[0][1];
return 0;
}
When I run it after about 4 second it gives me:
program.exe has stopped working.
If it helps I get the following when the error:
msg is closed(in cmd ):process returned -1073741819 (0xc0000005)
and i get the following when compiling;
warning: extended initializer lists only available with -std=c++11 or -std=gnu++11 [enabled by default]
ps:the snippet of coding is just for testing that I don’t get errors.
A few issues:
int a, b=0; // a is not initialized
Below while loop will access
while (true) {
s[a][b] = {'_'}; // b will be 78, access s[a][78] out of bounds
b+=1;
if (b>77){
//...
The problem is probably here:
int a,b=0;
Here you declare two variables, but you only initialize one of them. This means that the value of a is undefined, and using it in e.g. s[a][b] is undefined behavior.
if (b>77){
77 is already an illegal index; the test needs to use >=. Same for the one for a below.
And also the problem that Joachim found.