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.
Related
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
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.
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.
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
I use boost test for unit testing and gcov and lcov for measuring the coverage.
Unfortuanlly genhtml generates reports like that for function coverage:
I now want to know what the function _ZN7UtilLib11ProgressBarC2EjdRSo actually is.
So far I can not correlate this function to any of the class interface of ProgressBar:
class ProgressBar {
public:
explicit ProgressBar(
unsigned int expected_count,
double updateInterval = 30,
std::ostream& os = std::cout);
unsigned int operator+=(unsigned int increment);
unsigned int operator++();
unsigned int operator++(int i);
}
Can any one help me how to either get better function names with gcov or how does one understand these function names.
The application is compiled with gcc4.7 with the following flags:-g -g -save-temps=obj -Wall -Wextra -Wno-unused-parameter -Wno-error=unused-parameter -O0 -pedantic
These are mangled C++ symbols, use c++filt in a shell to demangle it:
> c++filt _ZN7UtilLib11ProgressBarC2EjdRSo
UtilLib::ProgressBar::ProgressBar(unsigned int, double, std::basic_ostream<char, std::char_traits<char> >&)
Also, since you seem to use genhtml, check out the --demangle-cpp option to do the demangling automatically for you.
Note that the compiler emits two implementations for the ctor you wrote, using --demangle-cpp will hide the difference which is visible only in the mangled symbol name. To understand what the compiler is doing, have a look here.
Use c++filt, like this:
$c++filt -n _ZN7UtilLib11ProgressBarC2EjdRSo
which outputs:
UtilLib::ProgressBar::ProgressBar(unsigned int, double, std::basic_ostream<char, std::char_traits<char> >&)