Using pardiso solver with eigen - c++

I'm trying to solve very large sparse matrix system (Ax = b) with eigen using pardiso solver.
When I compile the code with g++, This error comes out:
In file included from ${Eigenroot}/Eigen/PardisoSupport:31,
from code.cpp:8:
${Eigenroot}/Eigen/src/PardisoSupport/PardisoSupport.h: In static member function 'static IndexType Eigen::internal::pardiso_run_selector<IndexType>::run(void*, IndexType, IndexType, IndexType, IndexType, IndexType, void*, IndexType*, IndexType*, IndexType*, IndexType, IndexType*, IndexType, void*, void*) [with IndexType = int]':
${Eigenroot}/Eigen/src/PardisoSupport/PardisoSupport.h:269: instantiated from 'Derived& Eigen::PardisoImpl<Derived>::compute(const typename Eigen::internal::pardiso_traits<Derived>::MatrixType&) [with Derived = Eigen::PardisoLU<Eigen::SparseMatrix<double, 0, int> >]'
${Eigenroot}/Eigen/src/PardisoSupport/PardisoSupport.h:409: instantiated from 'Eigen::PardisoLU<_MatrixType>::PardisoLU(const MatrixType&) [with MatrixType = Eigen::SparseMatrix<double, 0, int>]'
code.cpp:82: instantiated from here
${Eigenroot}/Eigen/src/PardisoSupport/PardisoSupport.h:50: error: cannot convert 'int*' to 'const long long int*' for argument '2' to 'void pardiso(void*, const long long int*, const long long int*, const long long int*, const long long int*, const long long int*, const void*, const long long int*, const long long int*, long long int*, const long long int*, long long int*, const long long int*, void*, void*, long long int*)'
I thought that I don't need to change the sparse matrices' form but it seems like I need to change the sparse matrix form should fit into pardiso.
But when I found other's sample code, they didn't change sparse matrix form.
And it seems work too.
Am I getting it right? I'm not so sure.
Can anyone tell me what is the problem?
(About the A and B they aren't related to this problem. Cause I did get the answer with sparseLU which is built-in solver from eigen. But the speed of it was too slow, I try to use pardisoLU.)
#include <iostream>
#include <fstream>
#include <string>
#include <Eigen/Sparse>
#include <unsupported/Eigen/SparseExtra>
#include <Eigen/PardisoSupport>
using namespace std;
using namespace Eigen;
typedef Eigen::Triplet<double> T;
typedef Eigen::SparseMatrix<double> SpMat;
int main(){
int m = 10000; // number of rows;
int n = 10000; // number of cols;
SpMat A(m,n); // declare sparse matrix A
//
make tripletlist
//
A.setFromTriplets(TripletList.begin(), TripletList.end());
SpMat B(m,1);
//
insert values into B
//
PardisoLU< SparseMatrix<double> > solver( A );
x = solver.solve( B );
}
And compile this with g++ as
g++ -I ${Eigenroot} -DEIGEN_USE_MKL_ALL -DMKL_ILP64 -m64 -I ${mklroot}/linux/mkl/include -o out.out code.cpp -L ${mklroot}/linux/mkl/lib/intel64 -Wl, -lmkl_intel_ilp64 -lmkl_gnu_thread -lmkl_core -lmkl_blacs_intelmpi_ilp64 -lgomp -lpthread -lm -ldl

probably some problems happen with ILP64 linking. Could you try to link without -DMKL_ILP64 option and with -lmkl_intel_lp64 instead of -lmkl_intel_ilp64?

Related

inconsistent behavior in regard to passing a pointer to a C++17 Standard Variant to function expecting const reference [duplicate]

This question already has answers here:
What is the best way to disable implicit conversion from pointer types to bool when constructing an std::variant?
(2 answers)
Why is there an implicit type conversion from pointers to bool in C++?
(3 answers)
Closed 1 year ago.
I'm seeing some odd behavior in regard to passing a pointer into a function that expects a constant reference. Obviously C++ expects me to de reference the pointer before I pass it into the function expecting the reference. I'm looking for an error or warning but I'm not getting one UNLESS a certain condition is met that doesn't make any sense to me.
The type of the pointer and reference is a C++ 17 Standard Variant (below). If my C++17 variant includes the boolean in the template (as below) then GCC8.3 compiles the code just fine. But I have unexpected runtime results.
If I remove the boolean from the standard variant template, then the code does not compile as I expect. Why the difference?
#include <iostream>
#include <variant>
#include <stdint.h>
typedef std::variant <
std::monostate,
int8_t,
int16_t,
int32_t,
int64_t,
uint8_t,
uint16_t,
uint32_t,
uint64_t,
float,
double
,bool //If bool is in the variant, the compiler compiles the code without error and understandably has UB. Why isn't the lack of de-reference bug in DoThing not caught when that is the case?
> StdVARIANT;
//if 'bool' is commented out of the variant the error (expected) is:
//invalid initialization of reference of type ‘const StdVARIANT&’
static size_t GetIndexOfVariant(const StdVARIANT& RefToVariant);
static size_t DoThing(StdVARIANT* PtrToVariant);
static size_t DoThing(StdVARIANT* PtrToVariant){
return GetIndexOfVariant(PtrToVariant); //this is a bug-PtrToVariant should be de referenced!
}
static size_t GetIndexOfVariant(const StdVARIANT& RefToVariant){
size_t Index = RefToVariant.index();
return Index;
}
int main()
{
StdVARIANT* myvar = new StdVARIANT();
*myvar = (int32_t)1;
std::cout<<"long: "<<std::get<int32_t>(*myvar)<<" "<<sizeof(std::get<int32_t>(*myvar))<<std::endl;
*myvar = (double)2;
std::cout<<"double: "<<std::get<double>(*myvar)<<" "<<sizeof(std::get<double>(*myvar))<<std::endl;
std::cout<< myvar->index() << " " << DoThing(myvar)<<std::endl; //when 'bool' is in the std::variant, these two calls return different results (UB)
delete myvar;
return 0;
}
Compile and run as the code block above:
~/gcc-test$ g++ -std=c++17 -Wall -Wextra -pedantic main.cpp
~/gcc-test$ ./a.out
long: 1 4
double: 2 8
10 11
Comment 'bool' out of StdVARIANT, and:
~/gcc-test$ g++ -std=c++17 -Wall -Wextra -pedantic main.cpp
main.cpp: In function ‘size_t DoThing(StdVARIANT*)’:
main.cpp:27:30: error: invalid initialization of reference of type ‘const StdVARIANT&’ {aka ‘const std::variant<std::monostate, signed char, short int, int, long int, unsigned char, short unsigned int, unsigned int, long unsigned int, float, double>&’} from expression of type ‘StdVARIANT*’ {aka ‘std::variant<std::monostate, signed char, short int, int, long int, unsigned char, short unsigned int, unsigned int, long unsigned int, float, double>*’}
return GetIndexOfVariant(PtrToVariant); //this is a bug-PtrToVariant should be de referenced!
^~~~~~~~~~~~
main.cpp:23:15: note: in passing argument 1 of ‘size_t GetIndexOfVariant(const StdVARIANT&)’
static size_t GetIndexOfVariant(const StdVARIANT& RefToVariant);
^~~~~~~~~~~~~~~~~
Why don't I always get the error instead of just when bool is commented out?
To reproduce the problem, you can simplify your code as follows
#include <iostream>
#include <variant>
#include <stdint.h>
typedef std::variant <
std::monostate,
int8_t,
int16_t,
int32_t,
int64_t,
uint8_t,
uint16_t,
uint32_t,
uint64_t,
float,
double
,bool //If bool is in the variant, the compiler compiles the code without error and understandably has UB. Why isn't the lack of de-reference bug in DoThing not caught when that is the case?
> StdVARIANT;
int main()
{
StdVARIANT * pVar = new StdVARIANT();
StdVARIANT var = pVar;
}
The point is that a StdVARIANT * can't be converted to any of the StdVARIANT alternative except for bool.
So if StdVARIANT contains bool,
StdVARIANT var = pVar;
var is initialized as containing a bool value (a true, given that pVar isn't nullptr).
If StdVARIANT doesn't contains bool, the var initialization fails.
The same inside your DoThing() function: when you call
GetIndexOfVariant(PtrToVariant);
a temporary StdVARIANT is created (or not, if bool isn't available) and the constant reference is passed to GetIndexOfVariant().

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

Measuring heap usage by overriding the C standard library calls

With reference to the following code
#include <cassert>
#include <vector>
#include <dlfcn.h>
#include <limits>
#include <map>
#include <algorithm>
#include <iostream>
using std::cout;
using std::endl;
using std::vector;
/*
* Overload the malloc call
*/
int max_heap_usage = 0;
std::map<uintptr_t, int>& heap_memory_map;
void track_max_usage(std::map<uintptr_t, int> heap_memory_map,
int& max_heap_usage);
void* malloc(size_t size) {
// get the original malloc function call
static auto original_malloc = (decltype(&malloc)) dlsym(RTLD_NEXT, "malloc");
// Get the pointer from malloc
void* pointer = original_malloc(size);
uintptr_t pointer_handle = reinterpret_cast<uintptr_t>(pointer);
// assert that the pointer does not already exist in the memory map
assert("memory should not exist in memory map before allocation" &&
heap_memory_map.find(pointer_handle) == heap_memory_map.end());
// add to bookkeeping
heap_memory_map[pointer_handle] = size;
track_max_usage(heap_memory_map, max_heap_usage);
return pointer;
}
void* calloc(size_t count, size_t size) {
// get the original calloc
static auto original_calloc = (decltype(&calloc)) dlsym(RTLD_NEXT, "calloc");
// get the pointer returned by calloc
void* pointer = original_calloc(count, size);
uintptr_t pointer_handle = reinterpret_cast<uintptr_t>(pointer);
// assert that the memory has not been allocated before
assert("memory should not exist in the memory map before allocation" &&
heap_memory_map.find(pointer_handle) == heap_memory_map.end());
// add to bookkeeping
heap_memory_map[pointer_handle] = size * count;
track_max_usage(heap_memory_map, max_heap_usage);
return pointer;
}
void free(void* ptr) {
// get the original free function
static auto original_free = (decltype(&free)) dlsym(RTLD_NEXT, "free");
uintptr_t pointer_handle = reinterpret_cast<uintptr_t>(ptr);
// assert that the heap memory map already has the pointer
assert("memory to be freed does not exist in the heap memory map" &&
heap_memory_map.find(pointer_handle) != heap_memory_map.end());
// add to bookkeeping
heap_memory_map.erase(pointer_handle);
// free the memory
original_free(ptr);
}
/*
* Inputs: A map containing pointer values and the amount of heap memory used
* after that point
*
* The variable that keeps track of the max memory usage till this
* point
*
* This function updates the variable to have the max value if the current
* memory map dictates that the memory usage is greater than what it was
* before.
*/
void track_max_usage(std::map<uintptr_t, int>& heap_memory_map,
int& max_heap_usage) {
// loop through all keys and add up the values
int sum {0};
for (const auto ele : heap_memory_map) { sum += ele.second; }
// assign to max
max_heap_usage = std::max(max_heap_usage, sum);
}
int main() {
vector<int> vec {1, 2, 3, 4};
for (auto ele : vec) {
cout << ele << endl;
}
cout << "Total heap usage " << max_heap_usage << endl;
return 0;
}
I am trying to override the malloc, calloc and free calls so that anytime there is a heap allocation I can keep track of it. Somehow the vector class does not seem to allocate any memory on the heap. Could someone explain what exactly is going on here? Also how can I go about achieving the desired result?
Thanks!
Your program as posted - call it main.cpp - does not quite compile, so it can't be quite
the program whose disappointing behaviour you would like explained:
error: 'heap_memory_map' declared as reference but not initialized
std::map<uintptr_t, int>& heap_memory_map;
^
And if we fix that by declaring instead:
std::map<uintptr_t, int> heap_memory_map;
we then have a linkage error:
undefined reference to `track_max_usage(std::map<unsigned long, int, std::less<unsigned long>, std::allocator<std::pair<unsigned long const, int> > >, int&)'
because the declaration:
void track_max_usage(std::map<uintptr_t, int> heap_memory_map,
int& max_heap_usage);
does not match the definition:
void track_max_usage(std::map<uintptr_t, int>& heap_memory_map,
int& max_heap_usage) {
...
}
If we fix that also by declaring:
void track_max_usage(std::map<uintptr_t, int>& heap_memory_map,
int& max_heap_usage);
then we successfully compile and link, at least if we're not fussy
about standard conformance:
$ g++ -o prog -std=c++11 -Wall main.cpp -ldl
If we are fussy about Standard conformance:
$ g++ -o prog -std=c++11 -Wall -pedantic main.cpp -ldl
then there remain compilation errors:
main.cpp:20:25: error: declaration of ‘void* malloc(size_t)’ has a different exception specifier
void* malloc(size_t size) {
^
...
/usr/include/stdlib.h:466:14: error: from previous declaration ‘void* malloc(size_t) throw ()’
extern void *malloc (size_t __size) __THROW __attribute_malloc__ __wur;
^
main.cpp: In function ‘void* calloc(size_t, size_t)’:
main.cpp:40:39: error: declaration of ‘void* calloc(size_t, size_t)’ has a different exception specifier
void* calloc(size_t count, size_t size) {
^
...
/usr/include/stdlib.h:468:14: error: from previous declaration ‘void* calloc(size_t, size_t) throw ()’
extern void *calloc (size_t __nmemb, size_t __size)
^
main.cpp: In function ‘void free(void*)’:
main.cpp:60:20: error: declaration of ‘void free(void*)’ has a different exception specifier
void free(void* ptr) {
^
...
/usr/include/stdlib.h:483:13: error: from previous declaration ‘void free(void*) throw ()’
extern void free (void *__ptr) __THROW;
Another couple of passing carps:
int isn't guaranteed to store the size of heap block. Thus the Standard library says:
void* malloc(size_t size);
void* calloc(size_t num, size_t size);
and not:
void* malloc(int size);
void* calloc(int num, int size);
So by rights you'd have:
size_t max_heap_usage = 0;
std::map<uintptr_t, size_t> heap_memory_map;
Further, what you actually want is a map of void *-values to sizes,
and there's no reason at all not to have such a map:
std::map<void *, size_t> heap_memory_map;
Then the refrain:
uintptr_t pointer_handle = reinterpret_cast<uintptr_t>(pointer);
could be dispensed with.
Going with what we've got however (and remembering that we don't
know exactly what you have got) running prog does not simply
fail to tally any heap allocations; it crashes:
$ ./prog
Segmentation fault (core dumped)
If you debug this and peruse the backtrace to the segfault, you'll
see the circular call sequence:
operator new(unsigned long)
__gnu_cxx::new_allocator<std::_Rb_tree_node<std::pair<unsigned long const, int> > >::allocate /usr/include/c++/5/ext/new_allocator.h 104
std::allocator_traits<std::allocator<std::_Rb_tree_node<std::pair<unsigned long const, int> > > >::allocate /usr/include/c++/5/bits/alloc_traits.h 360
std::_Rb_tree<unsigned long, std::pair<unsigned long const, int>, std::_Select1st<std::pair<unsigned long const, int> >, std::less<unsigned long>, std::allocator<std::pair<unsigned long const, int> > >::_M_get_node /usr/include/c++/5/bits/stl_tree.h 491
std::_Rb_tree<unsigned long, std::pair<unsigned long const, int>, std::_Select1st<std::pair<unsigned long const, int> >, std::less<unsigned long>, std::allocator<std::pair<unsigned long const, int> > >::_M_create_node<std::piecewise_construct_t const&, std::tuple<unsigned long const&>, std::tuple<> >(std::piecewise_construct_t const&, std::tuple<unsigned long const&>&&, std::tuple<>&&) /usr/include/c++/5/bits/stl_tree.h 545
std::_Rb_tree<unsigned long, std::pair<unsigned long const, int>, std::_Select1st<std::pair<unsigned long const, int> >, std::less<unsigned long>, std::allocator<std::pair<unsigned long const, int> > >::_M_emplace_hint_unique<std::piecewise_construct_t const&, std::tuple<unsigned long const&>, std::tuple<> >(std::_Rb_tree_const_iterator<std::pair<unsigned long const, int> >, std::piecewise_construct_t const&, std::tuple<unsigned long const&>&&, std::tuple<>&&) /usr/include/c++/5/bits/stl_tree.h 2170
std::map<unsigned long, int, std::less<unsigned long>, std::allocator<std::pair<unsigned long const, int> > >::operator[] /usr/include/c++/5/bits/stl_map.h 483
malloc /home/imk/develop/so/heap_track_orig/main.cpp 34
operator new(unsigned long)
repeated ad nauseam. So the program is looping until it runs out of stack.
This is due to a fatal logical flaw. You're proceeding on the assumption that all the C++ dynamic memory management
operations in the program will be delegated to the Standard C library facilities
malloc, calloc and free.
Well, at least some of them are, and in particular the calls to operator new
that originate in
heap_memory_map[pointer_handle] = size;
when you allocate a new element of your heap map are delegated to malloc.
Which is your malloc. Which again calls:
heap_memory_map[pointer_handle] = size;
then operator new, then back to malloc, and so on to stack-exhaustion.
That is the fatal logical flaw, but the motivating assumption is also flaky.
The C++ Standard does not require even the default implementations of operator new and
operator delete to delegate respectively to malloc and free. It doesn't
specify any relationship between dynamic memory management in C++ and that of C.
The C++ compiler I'm using here (Linux, GCC) does in fact so delegate, and
probably so does yours, but an implementor might choose to delegate both
malloc/free and new/delete directly to OS APIs.
Don't attempt to roll your own heap-profiling. Use a proper heap-profiler.
For linux, the go-to heap profiler is Valgrind's massif.
Your distro will almost certainly provide a Valgrind package, including massif.
Here's a program that I'm going to profile with massif and check it's max heap usage:
main.cpp
#include <vector>
#include <iostream>
using namespace std;
int main() {
vector<int> vec;
for (int i = 0; i < 1000; ++i) {
vec.push_back(i);
}
for ( ;vec.size(); vec.pop_back()) {}
return 0;
}
Compile and link:
$ g++ -g -o prog -Wall main.cpp
Run valgrind with massif:
$ valgrind --tool=massif ./prog
==6479== Massif, a heap profiler
==6479== Copyright (C) 2003-2015, and GNU GPL'd, by Nicholas Nethercote
==6479== Using Valgrind-3.11.0 and LibVEX; rerun with -h for copyright info
==6479== Command: ./prog
==6479==
==6479==
The heap-profile is output by default in massif.out.NNNN. I find massif.out.6479
and run:
$ ms_print massif.out.6479 > heap_prof.txt
I look in heap_prof.txt and at line 32 I read:
Number of snapshots: 29
Detailed snapshots: [4, 14, 17, 20, 23, 26 (peak)]
which tells me that heap snapshot #26 shows the peak usage. I scroll to
snapshot #26 and see:
--------------------------------------------------------------------------------
n time(i) total(B) useful-heap(B) extra-heap(B) stacks(B)
--------------------------------------------------------------------------------
24 2,049,029 74,768 74,752 16 0
25 2,069,629 78,872 78,848 24 0
26 2,070,679 78,872 78,848 24 0
99.97% (78,848B) (heap allocation functions) malloc/new/new[], --alloc-fns, etc.
->92.18% (72,704B) 0x4EB91FE: ??? (in /usr/lib/x86_64-linux-gnu/libstdc++.so.6.0.21)
| ->92.18% (72,704B) 0x4010608: call_init.part.0 (dl-init.c:72)
| ->92.18% (72,704B) 0x4010719: _dl_init (dl-init.c:30)
| ->92.18% (72,704B) 0x4000D08: ??? (in /lib/x86_64-linux-gnu/ld-2.21.so)
|
->07.79% (6,144B) 0x401788: __gnu_cxx::new_allocator<int>::allocate(unsigned long, void const*) (new_allocator.h:104)
->07.79% (6,144B) 0x401665: __gnu_cxx::__alloc_traits<std::allocator<int> >::allocate(std::allocator<int>&, unsigned long) (alloc_traits.h:182)
->07.79% (6,144B) 0x4014B0: std::_Vector_base<int, std::allocator<int> >::_M_allocate(unsigned long) (stl_vector.h:170)
->07.79% (6,144B) 0x400F59: std::vector<int, std::allocator<int> >::_M_insert_aux(__gnu_cxx::__normal_iterator<int*, std::vector<int, std::allocator<int> > >, int const&) (vector.tcc:353)
->07.79% (6,144B) 0x400CC4: std::vector<int, std::allocator<int> >::push_back(int const&) (stl_vector.h:925)
->07.79% (6,144B) 0x400AEC: main (main.cpp:9)
So the program's top recorded heap consumption was 78,872 bytes, of
which (a mere) 6,144 bytes were allocated for my std::vector.
The C++ standard library containers don't use malloc and such directly, they use "allocator" objects, which are generally provided as a template parameter. You can look at providing a custom allocator, or, providing a custom operator new function, if you want to hook into things like this for measurement purposes.

Boost compilation error under OS X 10.8.5

I have an issue trying to compile a project under Mac OS X 10.8.5 using Boost libraries, version 1.34.1. I am using Xcode 4.6.3 and accompanying Command Line Tools. This must be an OS X specific issue, since the project compiles under CentOS Linux.
I am asking this here in hopes that someone has used Boost in OS X development and has maybe come across a similar issue.
I attach an excerpt of the compiler messages below. I have tried googling for the error, but can't seem to find satisfying answers. Please let me know if you can think of something from the top of your head or, which is more likely, if you need more info (e.g., source code excerpts) to be able to help me.
Thank you very much,
Best,
Sebastian
g++ -DPARC -DCPPPA_EXPORT= -fPIC -fno-common -D__STDC_LIMIT_MACROS -g -fno-inline -Wpointer-arith -Wwrite-strings -Wno-deprecated -Wreturn-type -W -I/usr/local/include -O2 -I../../src/include -I../../LexBase/src -I/include -I/usr/local/include/boost-1_34_1 -I/Users/sebastiansulger/projects/xle/dev/xfr/src/../../bgdb -Idb_client -I./ -I../include -Ifacts -Irules -Ichoices -Iterms -Imatches -Idriver -Iparser -Itriples -Iprolog -Idebug -Inew_parser -o terms/TermStorage.o -c terms/TermStorage.cpp
In file included from terms/TermStorage.cpp:9:
In file included from terms/TermStorage.h:28:
In file included from ./Types.h:26:
In file included from /usr/local/include/boost-1_34_1/boost/functional/hash.hpp:10:
/usr/local/include/boost-1_34_1/boost/functional/hash/hash.hpp:487:20: error:
call to 'hash_value' is ambiguous
return hash_value(val);
^~~~~~~~~~
/usr/include/c++/4.2.1/ext/hashtable.h:595:16: note: in instantiation of member
function 'boost::hash<long long>::operator()' requested here
{ return _M_hash(__key) % __n; }
^
/usr/include/c++/4.2.1/ext/hashtable.h:587:16: note: in instantiation of member
function '__gnu_cxx::hashtable<std::pair<const long long, unsigned int>,
long long, boost::hash<long long>, std::_Select1st<std::pair<const long
long, unsigned int> >, std::equal_to<long long>, std::allocator<unsigned
int> >::_M_bkt_num_key' requested here
{ return _M_bkt_num_key(__key, _M_buckets.size()); }
^
/usr/include/c++/4.2.1/ext/hashtable.h:522:18: note: in instantiation of member
function '__gnu_cxx::hashtable<std::pair<const long long, unsigned int>,
long long, boost::hash<long long>, std::_Select1st<std::pair<const long
long, unsigned int> >, std::equal_to<long long>, std::allocator<unsigned
int> >::_M_bkt_num_key' requested here
size_type __n = _M_bkt_num_key(__key);
^
/usr/include/c++/4.2.1/ext/hash_map:219:22: note: in instantiation of member
function '__gnu_cxx::hashtable<std::pair<const long long, unsigned int>,
long long, boost::hash<long long>, std::_Select1st<std::pair<const long
long, unsigned int> >, std::equal_to<long long>, std::allocator<unsigned
int> >::find' requested here
{ return _M_ht.find(__key); }
^
terms/TermStorage.h:97:46: note: in instantiation of member function
'__gnu_cxx::hash_map<long long, unsigned int, boost::hash<long long>,
std::equal_to<long long>, std::allocator<unsigned int> >::find' requested
here
TsHashMapIter iter = mParent->mHashMap.find(t);
^
terms/TermStorage.cpp:85:47: note: in instantiation of member function
'powerset::xfr::TermHashStorage<long long>::hashInsert' requested here
uint32_t index = (uint32_t) mIntTermStorage.hashInsert(intVal);
^
/usr/local/include/boost-1_34_1/boost/functional/hash/hash.hpp:105:24: note:
candidate function
inline std::size_t hash_value(int v)
^
/usr/local/include/boost-1_34_1/boost/functional/hash/hash.hpp:110:24: note:
candidate function
inline std::size_t hash_value(unsigned int v)
^
/usr/local/include/boost-1_34_1/boost/functional/hash/hash.hpp:115:24: note:
candidate function
inline std::size_t hash_value(long v)
^
/usr/local/include/boost-1_34_1/boost/functional/hash/hash.hpp:120:24: note:
candidate function
inline std::size_t hash_value(unsigned long v)
^
/usr/local/include/boost-1_34_1/boost/functional/hash/hash.hpp:229:24: note:
candidate function
inline std::size_t hash_value(float v)
^
/usr/local/include/boost-1_34_1/boost/functional/hash/hash.hpp:234:24: note:
candidate function
inline std::size_t hash_value(double v)
^
/usr/local/include/boost-1_34_1/boost/functional/hash/hash.hpp:239:24: note:
candidate function
inline std::size_t hash_value(long double v)
^
1 error generated.
make[1]: *** [terms/TermStorage.o] Error 1
make: *** [build] Error 2
Sebastian-Sulgers-MacBook-Pro:dev sebastiansulger$
EDIT: I have noticed that boost/functional/hash/hash.hpp includes the following:
#if defined(BOOST_HAS_LONG_LONG) && defined(_M_X64) && defined(_WIN64)
// On 64-bit windows std::size_t is a typedef for unsigned long long, which
// isn't due to be supported until Boost 1.35. So add support here.
// (Technically, Boost.Hash isn't actually documented as supporting
// std::size_t. But it would be pretty silly not to).
std::size_t hash_value(long long);
std::size_t hash_value(unsigned long long);
#endif
So it seems that the definition of the type is there, but not available for my system. Does that make any sense? Can I circumvent this somehow?
It basically says that there are lots of hash_value functions in hash.hpp, but none of them works for the type in your hash table (apparently long long).
Either your tools are too old for that type, or you don't compile with the proper -std=... parameter for the compiler.

How do I compute the max of two size_t variables

I have this in my code.
vector<unsigned int> import;
vector<unsigned int> aquired;
. . .
size_t new_size = max(import.size(),aquired.size());
and I get this error:
error: more than one instance of
overloaded function "max" matches the
argument list:
function "max(int, int)"
function "max(unsigned int, unsigned int)"
function "max(int, unsigned int)"
function "max(unsigned int, int)"
function "max(long long, long long)"
function "max(unsigned long long, unsigned long long)"
function "max(long long, unsigned long long)"
function "max(unsigned long long, long long)"
function "max(float, float)"
function "max(double, double)"
function "max(float, double)"
function "max(double, float)"
argument types are: (size_t, size_t)
my understanding is that size_t is an unsigned int. So why is this a problem and how do I get around it.
Compiling with:
$gcc --version
gcc (Ubuntu 4.4.3-4ubuntu5) 4.4.3
$nvcc --version
nvcc: NVIDIA (R) Cuda compiler driver
Copyright (c) 2005-2010 NVIDIA Corporation
Built on Wed_Sep__8_17:12:45_PDT_2010
Cuda compilation tools, release 3.2, V0.2.1221
#include <algorithm>
size_t val1;
size_t val2;
size_t maxValue = std::max<size_t>(val1, val2);
size_t is not an unsigned int necessarily, it is platform dependent. If you're compiling for 32 bit, or if you know that your vector will have size under 4 billion, you can safely cast to an unsigned int. Some 64-bit platforms use a 64-bit size_t, but have an unsigned int as only 32-bit.
Try using this instead of your current code:
size_t new_size = max((unsigned int)import.size(),(unsigned int)aquired.size());
I don't think size_t is actually unsigned int. I suspect it's its own type, not a typedef - at least in g++
Use std::max:
#include <algorithm>
int main(int argc, char **argv)
{
size_t a = 2, b=3;
std::max(a,b);
return 0;
}
Try this:
std::max((unsigned int)import.size(), (unsigned int)aquired.size());