retrieving values from array of future objects, std::vector - c++

I'm receiving an error message I have no idea how to respond to. I'm trying to retrieve the values from a vector of future objects and then output them, but I'm having trouble confirming if I'm retrieving the values.
Code:
std::vector<std::future<double>> threadResults;
int numThreads = 4;
double output;
for (int j=0; j<numThreads; j++) {
threadResults.push_back(std::async(launch::async, someCalculation, array1, array2, dimension));
}
for (auto& fut : threadResults) {
auto output = fut.get();
}
I'm new to using std::vector, so I'm unsure of how to use get() with it. Some researching brought me to the bottom for-loop, which I'm unsure if it's working. If anyone sees any obvious mistakes, please let me know, but my main concern is how to correctly use std::vector with the future class.
Here is my error message:
/tmp/ccQ19btT.o: In function `std::thread::thread<std::__future_base::_Async_state_impl<std::_Bind_simple<double (*(double*, double*, double*, int))(double*, double*, double*, int)>, double>::_Async_state_impl(std::_Bind_simple<double (*(double*, double*, double*, int))(double*, double*, double*, int)>&&)::{lambda()#1}>(std::__future_base::_Async_state_impl<std::_Bind_simple<double (*(double*, double*, double*, int))(double*, double*, double*, int)>, double>::_Async_state_impl(std::_Bind_simple<double (*(double*, double*, double*, int))(double*, double*, double*, int)>&&)::{lambda()#1}&&)':
nonOptimizedNonThreaded.cpp:(.text._ZNSt6threadC2IZNSt13__future_base17_Async_state_implISt12_Bind_simpleIFPFdPdS4_S4_iES4_S4_S4_iEEdEC4EOS8_EUlvE_IEEEOT_DpOT0_[_ZNSt6threadC5IZNSt13__future_base17_Async_state_implISt12_Bind_simpleIFPFdPdS4_S4_iES4_S4_S4_iEEdEC4EOS8_EUlvE_IEEEOT_DpOT0_]+0x2d): undefined reference to `pthread_create'
collect2: error: ld returned 1 exit status
Sorry for the long horizontal scroll, let me know if there's a better to format it.
Here is how I'm compiling:
g++ threadingVector.cpp -o threadingVector -std=c++0x

Let me know if this isn't the right answer, and I shall delete it to avoid confusing other people, but I had the exact same issue yesterday and adding -pthread to the compiler args worked. Try:
g++ -pthread threadingVector.cpp -o threadingVector -std=c++0x
On different architectures the std::thread & company leave some of the low-level implementation of multi-threading down to the environment, and one popular library that would complete the threading implementation on linux would be pthread.

Related

C++ code compiled with g++ works, but XCode fails

I'm trying to compile a small C++ example in XCode 12.5.1 using the linear algebra library armadillo, which I've installed without problems:
//example.cpp
#include <armadillo>
#include <iostream>
using namespace std;
using namespace arma;
int
main(int argc, char** argv)
{
cout << "Armadillo version: " << arma_version::as_string() << endl;
cx_vec eigval;
cx_mat eigvec;
mat A(3,3,fill::zeros);
eig_gen(eigval, eigvec, A);
cout << A << "\n";
cout << eigval << "\n";
cout << eigvec << "\n";
return 0;
}
Specifically, I'm trying to figure out why the inclusion function eig_gen() gives me linking errors in XCode (removing the function call allows for proper compilation):
Undefined symbols for architecture x86_64:
"_dgeev_", referenced from:
void arma::lapack::geev<double>(char*, char*, int*, double*, int*, double*, double*, double*, int*, double*, int*, double*, int*, int*) in main.o
"_dgeevx_", referenced from:
void arma::lapack::geevx<double>(char*, char*, char*, char*, int*, double*, int*, double*, double*, double*, int*, double*, int*, int*, int*, double*, double*, double*, double*, double*, int*, int*, int*) in main.o
ld: symbol(s) not found for architecture x86_64
clang: error: linker command failed with exit code 1 (use -v to see invocation)
Since if I compile the program using g++ on the command line,g++ example.cpp -o example -std=c++11 -O2 -larmadillo, the compilation is successful and the program outputs:
Armadillo version: 10.6.2 (Keep Calm)
0 0 0
0 0 0
0 0 0
(0,0)
(0,0)
(0,0)
(+1.000e+00,+0.000e+00) (+1.000e+00,-0.000e+00) (0,0)
(+0.000e+00,+1.000e+00) (+0.000e+00,-1.000e+00) (0,0)
(0,0) (0,0) (+1.000e+00,+0.000e+00)
The only change I made to XCode's default linking setup (the project is a Command Line Tool project) is to include /usr/local/include in System Header Search Paths, so that I can use the code's first line #include <armadillo>.
Any suggestions as to why XCode specifically might be giving me this error?
############################### Update
I've noticed that if I place the definition #define ARMA_DONT_USE_WRAPPER in the fist line of the program above #include <armadillo>, then the command-line compilation using g++ also outputs the same linking errors. This suggests to me that the error is related to armadillo.

Compilation of Eigen3 with MKL

During an integration work of TensorFlow 1.1 with my ongoing C++ project on Ubuntu 16... I want to include a support to MKL and 64 bit integers.
I encountered a compilation problem in Eigen library while instantiate a template struct that has a direct call to MKL:
In file included from /usr/local/include/eigen3/unsupported/Eigen/CXX11/../../../Eigen/Core:526:0,
from /usr/local/include/eigen3/unsupported/Eigen/CXX11/Tensor:14,
from /home/drormeirovich/projects/tensorflow/third_party/eigen3/unsupported/Eigen/CXX11/Tensor:1,
from /home/drormeirovich/projects/tensorflow/tensorflow/core/framework/tensor.h:19,
from /home/drormeirovich/projects/tensorflow/tensorflow/cc/framework/ops.h:21,
from /home/drormeirovich/projects/tensorflow/tensorflow/cc/client/client_session.h:24,
from /home/drormeirovich/projects/my_project.cpp:10:
/usr/local/include/eigen3/unsupported/Eigen/CXX11/../../../Eigen/src/Core/products/GeneralMatrixMatrix_BLAS.h: In static member function ‘static void Eigen::internal::general_matrix_matrix_product<Index, double, LhsStorageOrder, ConjugateLhs, double, RhsStorageOrder, ConjugateRhs, 0>::run(Index, Index, Index, const double*, Index, const double*, Index, double*, Index, double, Eigen::internal::level3_blocking<double, double>&, Eigen::internal::GemmParallelInfo<Index>*)’:
/usr/local/include/eigen3/unsupported/Eigen/CXX11/../../../Eigen/src/Core/products/GeneralMatrixMatrix_BLAS.h:103:173: error: cannot convert ‘char*’ to ‘CBLAS_LAYOUT’ for argument ‘1’ to ‘void cblas_dgemm(CBLAS_LAYOUT, CBLAS_TRANSPOSE, CBLAS_TRANSPOSE, long long int, long long int, long long int, double, const double*, long long int, const double*, long long int, double, double*, long long int)’
BLASPREFIX##gemm(&transa, &transb, &m, &n, &k, &numext::real_ref(alpha), (const BLASTYPE*)a, &lda, (const BLASTYPE*)b, &ldb, &numext::real_ref(beta), (BLASTYPE*)res, &ldc); \
^
/usr/local/include/eigen3/unsupported/Eigen/CXX11/../../../Eigen/src/Core/products/GeneralMatrixMatrix_BLAS.h:106:1: note: in expansion of macro ‘GEMM_SPECIALIZATION’
GEMM_SPECIALIZATION(double, d, double, cblas_d)
^
For more details... My whole progress on this integration issue is in this link:
https://docs.google.com/document/d/1VFTdPJy59QTCTHO8NHMNmnO8AOoQhNXgWixas9KmLLM/edit?usp=drivesdk
Do I have to remove the support of MKL from Eigen3?
Any help would be appreciated...
disclaimer: I used to be an EasyBuild developer.
In EasyBuild we can build Eigen3 with MKL support, so this should work.
One of our contributers seems to have figured out that for eigen3 you need to copy the 'signature_of_eigen3_matrix_library' file into the path you use for your includes, see
https://github.com/hpcugent/easybuild-easyblocks/blob/master/easybuild/easyblocks/e/eigen.py
https://github.com/RLovelett/eigen/blob/master/signature_of_eigen3_matrix_library

Undefined reference ZGETRI/ZGETREF [duplicate]

I'm currently writing a header-only wrapper library which is supposed to provide C++ access to some FORTRAN code. But I'm stuck at the 'undefined reference (...)'
I must say I'm a little bit surprised because I compiled my own functions in C++ using this FORTRAN routine, with no problems at all.
Maybe a few words about the structure. The library follows the singleton pattern, but without the possibility of instantiating the Library by the user. So the only entry point for the user is a static method MultiNestWrapper::Wrapper<T>::run(). MultiNestWrapper is a namespace, Wrapper<T> is a templated class (so that in future you can benchmark how choosing on which type to perform calculations affects results and performance). The FORTRAN routine is declared outside of this namespace, as
extern "C" {
extern void __nested_MOD_nestrun(int *, int *, int *, double *, double *, int *, int *, int *, int *, int *, double *, const char *, int *, int *, int *, int *, void (*Loglike)(double *, int *, int *, double *), void (*dumper)(int *, int *, int *, double **, double **, double *, double *, double *), int *context);
}
and I call it like
__nested_MOD_nestrun(&_mmodal, &_ceff, &_nlive, &_tol, &_efr, &_ndims, &_nPar, &_nClsPar, &_maxModes, &_updInt, &_Ztol, _root, &_seed, _pWrap, &_fb, &_resume, internalLogLike, internalDumper, &_context);
And the types for arguments match.
When I try to compile it, I get the following error:
[dare2be#schroedinger multinest-interfejs]$ make all
g++ -c ExampleLibMnCpp.cpp -o ExampleLibMnCpp.o
gfortran -lstdc++ -llapack -lblas -lnest3 -L/usr/local/lib ExampleLibMnCpp.o -o ExampleLibMnCpp
ExampleLibMnCpp.o: In function `MultiNestWrapper::Wrapper<double>::run(MultiNestWrapper::MNParams<double>*, double (*)(double const*, int), bool, std::basic_string<char, std::char_traits<char>, std::allocator<char> >, int, double, int, double, void (*)(int*, int*, int*, double**, double**, double*, double*, double*), int, double, bool)':
ExampleLibMnCpp.cpp:(.text._ZN16MultiNestWrapper7WrapperIdE3runEPNS_8MNParamsIdEEPFdPKdiEbSsididPFvPiS9_S9_PPdSB_SA_SA_SA_Eidb[MultiNestWrapper::Wrapper<double>::run(MultiNestWrapper::MNParams<double>*, double (*)(double const*, int), bool, std::basic_string<char, std::char_traits<char>, std::allocator<char> >, int, double, int, double, void (*)(int*, int*, int*, double**, double**, double*, double*, double*), int, double, bool)]+0x585): undefined reference to `__nested_MOD_nestrun'
collect2: ld returned 1 exit status
make: *** [ExampleLibMnCpp] Error 1
But, note that
[dare2be#schroedinger multinest-interfejs]$ nm /usr/local/lib/libnest3.a | grep __nested_MOD_nestrun
000000000001e0f0 T __nested_MOD_nestrun
I've always dealt with those undefined references myself. But now I can't wrap my head around this. I specify -lnest3 -L/usr/local/lib explicite and /usr/local/lib/libnest3.a contains the routine the linker whines about... Please, help a brother out! :)
EDIT: fixed typos
The order in which you specify libraries in GCC's command-line matters. Read GCC man pages for details - in short you have to specify libraries (-lnest3 etc) after modules that use them. (I always specify libraries in the end of the command-line.)
In your case you have to write
gfortran ExampleLibMnCpp.o -o ExampleLibMnCpp -L/usr/local/lib -lstdc++ -llapack -lblas -lnest3
Maybe you need to specify the source files before the libraries when linking everything together. Like this:
gfortran *.o -lblas -l... ...
Linkers are sometimes picky about the order of their arguments.

A mix of c++ and cublas code isn't compiling

So I have this code that's suppose to compute the dot product of a matrix in different ways (one of which is to use blas in a c++), but when I try to use nvcc to compile the code, it doesn't work and it says that I have an undefined reference to ddot. This is weird because I'm pretty sure I'm using the calling notation referenced here for cublas: http://www.sdsc.edu/us/training/assets/docs/NVIDIA-03-Toolkit.pdf
Can anyone help me? Here's a snip of code I'm having trouble with:
#include <cublas.h> //just some included files here. No problems with these
#include <fstream>
#include <string>
#include <sstream>
using namespace std;
extern "C" //This is where I mention the cublas functions are external.
//I think this is necessary since I also have cuda pieces of code
{
double cublasDDOT_(int *n, double *A, int *incA, double *B, int *incB);
void cublasDAXPY_(int *n, double *a, double *A, int *incA, double *B, int *incB);
}
//Stuff happens here
C[i][t]=cublasDDOT_(&n, partA, &incA, partB, &incB); //This is a piece of my function and where the compiler chokes up
This is weird to me. I've also tried removing the "_"'s with no luck.
Here's the compile command I use: nvcc program
Do I need to mention the cublas library during the compile somehow? I have the cuda toolkit installed, but I don't know how to reference the library other than with
#include <cublas.h>
New update
It turns out I get the same output whether I include the cublas.h header or not
I also get the same output whether I type -lcublas or not
Here's the output, which is garbage for all compiles (with/without cublas.h & with/without -lcublas)
nvcc project4.cu -lcublas
/tmp/tmpxft_000051cb_00000000-14_project4.o: In function `ddot(int&, int&, int&, double**&, double**&, double**&, double*&, double*&, int&, int&, double&, double&, double*)':
tmpxft_000051cb_00000000-3_project4.cudafe1.cpp:(.text+0xda1): undefined reference to `cublasDDOT'
/tmp/tmpxft_000051cb_00000000-14_project4.o: In function `daxpy(int&, int&, int&, double**&, double**&, double**&, double**&, double*&, double*&, int&, int&, double&, double&, double*)':
tmpxft_000051cb_00000000-3_project4.cudafe1.cpp:(.text+0xff3): undefined reference to `cublasDAXPY'
collect2: ld returned 1 exit status
Even when compiling with nvcc, you still need to specify the -lcublas link switch.
It looks like you're calling out the function names incorrectly:
cublasDDOT_()
should be:
cublasDdot()
and:
cublasDAXPY_()
should be:
cublasDaxpy()
The naming is case-sensitive.
If you're not sure about the correct naming, refer to the cublas documentation and take a look at the usage in the sample codes
And yes, remove the underscores. I don't understand why you're calling the function names that way. If you mangle a name, there's no way the linker knows what you intend to link it to.
I'm also not sure any of the "extern C" stuff is necessary. That depends on what else is going on in your project, but I don't think you should use "extern C" wrapped around functions that you intend to be linked with the cublas library, if you are compiling/linking with nvcc

Can't get past "undefined reference to `XXXX'"

I'm currently writing a header-only wrapper library which is supposed to provide C++ access to some FORTRAN code. But I'm stuck at the 'undefined reference (...)'
I must say I'm a little bit surprised because I compiled my own functions in C++ using this FORTRAN routine, with no problems at all.
Maybe a few words about the structure. The library follows the singleton pattern, but without the possibility of instantiating the Library by the user. So the only entry point for the user is a static method MultiNestWrapper::Wrapper<T>::run(). MultiNestWrapper is a namespace, Wrapper<T> is a templated class (so that in future you can benchmark how choosing on which type to perform calculations affects results and performance). The FORTRAN routine is declared outside of this namespace, as
extern "C" {
extern void __nested_MOD_nestrun(int *, int *, int *, double *, double *, int *, int *, int *, int *, int *, double *, const char *, int *, int *, int *, int *, void (*Loglike)(double *, int *, int *, double *), void (*dumper)(int *, int *, int *, double **, double **, double *, double *, double *), int *context);
}
and I call it like
__nested_MOD_nestrun(&_mmodal, &_ceff, &_nlive, &_tol, &_efr, &_ndims, &_nPar, &_nClsPar, &_maxModes, &_updInt, &_Ztol, _root, &_seed, _pWrap, &_fb, &_resume, internalLogLike, internalDumper, &_context);
And the types for arguments match.
When I try to compile it, I get the following error:
[dare2be#schroedinger multinest-interfejs]$ make all
g++ -c ExampleLibMnCpp.cpp -o ExampleLibMnCpp.o
gfortran -lstdc++ -llapack -lblas -lnest3 -L/usr/local/lib ExampleLibMnCpp.o -o ExampleLibMnCpp
ExampleLibMnCpp.o: In function `MultiNestWrapper::Wrapper<double>::run(MultiNestWrapper::MNParams<double>*, double (*)(double const*, int), bool, std::basic_string<char, std::char_traits<char>, std::allocator<char> >, int, double, int, double, void (*)(int*, int*, int*, double**, double**, double*, double*, double*), int, double, bool)':
ExampleLibMnCpp.cpp:(.text._ZN16MultiNestWrapper7WrapperIdE3runEPNS_8MNParamsIdEEPFdPKdiEbSsididPFvPiS9_S9_PPdSB_SA_SA_SA_Eidb[MultiNestWrapper::Wrapper<double>::run(MultiNestWrapper::MNParams<double>*, double (*)(double const*, int), bool, std::basic_string<char, std::char_traits<char>, std::allocator<char> >, int, double, int, double, void (*)(int*, int*, int*, double**, double**, double*, double*, double*), int, double, bool)]+0x585): undefined reference to `__nested_MOD_nestrun'
collect2: ld returned 1 exit status
make: *** [ExampleLibMnCpp] Error 1
But, note that
[dare2be#schroedinger multinest-interfejs]$ nm /usr/local/lib/libnest3.a | grep __nested_MOD_nestrun
000000000001e0f0 T __nested_MOD_nestrun
I've always dealt with those undefined references myself. But now I can't wrap my head around this. I specify -lnest3 -L/usr/local/lib explicite and /usr/local/lib/libnest3.a contains the routine the linker whines about... Please, help a brother out! :)
EDIT: fixed typos
The order in which you specify libraries in GCC's command-line matters. Read GCC man pages for details - in short you have to specify libraries (-lnest3 etc) after modules that use them. (I always specify libraries in the end of the command-line.)
In your case you have to write
gfortran ExampleLibMnCpp.o -o ExampleLibMnCpp -L/usr/local/lib -lstdc++ -llapack -lblas -lnest3
Maybe you need to specify the source files before the libraries when linking everything together. Like this:
gfortran *.o -lblas -l... ...
Linkers are sometimes picky about the order of their arguments.