Which library to link for boost::hash_combine - boost

I want to use boost::hash_combine in my project. However, I was unable to find the boost library that contains this function (the library libboost_functional does not exist). I am running Arch. Is it possible that I do not have all libraries installed?
Edit:
As sehe pointed out, including the right header was the key.
#include <iostream>
#include <boost/functional/hash.hpp>
int main() {
int x = 100;
int y = 10;
size_t h = 0;
boost::hash_combine(h, x);
boost::hash_combine(h, y);
std::cout << h << std::endl;
}

Luke 24:5:
“Why do you look for the living among the dead?"
Most of boost is header-only. There's nothing to link. In the case of hash-combine, everything is templates so there's nothing that could be hidden from the header file.

Related

GCC, clang/llvm, exe file size

Windows 10, LLVM 7, GCC 8.1, Visual studio 2019.
#include <iostream>
#include <fstream>
using namespace std;
char exe[1000000] = {};
int n = 0;
int filesize;
void read() {
int pointer = 0;
cin >> filesize;
fstream f;
f.open("s.exe", ios::in | ios::app | ios::binary);
f.seekp(pointer, ios::beg);
while (pointer < filesize) {
f.read((char*)&n,sizeof(char));
exe[pointer] = n;
pointer += 1;
}
f.close();
}
void showMassive(){
int pointer = 0;
while(pointer<filesize){
cout << pointer << ":" << (unsigned int8_t)exe[pointer] << endl;
pointer+=1;
}
}
void showAssembler(){
}
void write() {
int pointer = 0;
fstream f;
f.open("s1.exe", ios::out | ios::app | ios::binary);
f.seekp(pointer, ios::beg);
while (pointer < filesize) {
n=exe[pointer];
pointer += 1;
f.write((char*)&n,sizeof(char));
}
f.close();
}
void MachineCodeOptimizer(){
//some code
exe[1031] += 1;//just for example
}
int main(){
read();
showMassive();
showAssembler();
MachineCodeOptimizer();
write();
return 0;
}
this code. Clang creates an exe file 312 kilobytes size at best (-O1 key). GCC creates 66 KB size exe anyway. What happens? Why so difference between compilers? I look at machine code, but dont understand. Now i tried visual studio 2019 - 26 KB! Visual studio 2019 showing result close to assembler(in file size).
Clang and GCC are two completely independent compilers. When you write code in your source language, you only specify what you want the machine to execute, not how it should do that. Compilers are free in choosing their ways to get there, as long as they stay within the limits that are specified by your source language. So it's not surprising that the two resulting executables differ in file size. Also the chosen instructions by the two compilers might differ a lot (or completely) since there are, for example, a dozen different ways to represent loops in machine code (incl. taking advantage of parallel execution of the target processor ... or not). You might want to check out Matt Godbolt's talk from 2017 (https://www.youtube.com/watch?v=bSkpMdDe4g4); this can give you a short but exhaustive introduction in what compilers actually do (for you) behind the scenes.

Memory Access Error Inserting Point Into nD Delaunay Triangulation

I'm attempting to implement Schlomer's Max Min Dist sets in N dimensions for a project I'm working on using CGAL's nD Delaunay Triangulation for the algorithm. I'm able to compile and run the example code, but when incorporating the triangulation into my set's class, I get memory access errors after inserting a few points. As far as I can tell, besides the fact that the triangulation is living in the class instance memory space and not main, I'm not diverging significantly from the example code. I am using Dynamic_Dimension_tag instead of a compile-time fixed triangulation, but I tweak the example code to do the same and it's fine. I'll sample the header and source below, detailing the method I'm using to do the point additions. Another set of more experienced eyes would be greatly appreciated.
Header:
#include <boost/container/vector.hpp>
#include <CGAL\Epick_d.h>
#include <CGAL\Delaunay_triangulation.h>
#include <iostream>
using namespace boost::container;
typedef CGAL::Triangulation<CGAL::Epick_d<CGAL::Dynamic_dimension_tag>> T;
class DllExport MaxMinDist
{
public:
MaxMinDist(int);
const vector<T::Point>& points() const;
int createPointsFromData(const vector<double>&);
int dimension(void) const;
int size(void) const;
private:
T dt_;
vector<T::Point> points_;
double localMinDist(const T::Point&);
double globalMinDist(void);
double averageMinDist(void);
void iterateGlobalFPO(void);
void iterateLocalFPO(void);
double toroidalDistanceOnAxis(double, double);
double toroidalSquaredDistance(const T::Point&, const T::Point&);
};
Source:
int MaxMinDist::createPointsFromData(const vector<double>& data)
{
// data supplied doesn't match the dimension
if (data.size() % dimension() != 0) return -1;
// break up the data into points
points_.reserve(data.size() % dimension());
for (auto iter = data.begin(); iter != data.end(); iter += dimension()) {
T::Point p(iter, iter + dimension());
points_.push_back(p);
}
// add the points to the triangulation
T::Vertex_handle hint;
int i = 0;
for (auto pt_iter = points_.begin(); pt_iter != points_.end(); ++pt_iter) {
std::cout << "Processing: " << *pt_iter << ", " << ++i << " of " << int(points_.size()) << std::endl;
if (T::Vertex_handle() != hint) {
hint = dt_.insert(*pt_iter, hint);
}
else {
hint = dt_.insert(*pt_iter);
}
}
return 0;
The function that is throwing the exception is NT_Convertor, defined in NT_Convertor.h in the CGAL namespace.
NT_Convertor
template < class NT1, class NT2 >
struct NT_converter
: public CGAL::unary_function< NT1, NT2 >
{
NT2
operator()(const NT1 &a) const
{
return NT2(a); <-- source of exception
}
};
Ok, further development.
Examining the stack frames, I noted that the library holding the excepting function is "C:\Program Files\Autodesk\Maya2018\bin\libgmp-10.dll". The main project is a plugin for Autodesk Maya. Unfortunately, that self-same library is part of the CGAL install. CGAL has its own copy of the DLL in the linking folder. I removed the MaxMinDistSet class from the project to a new separate project, just a library for itself notably without the includes or linking from OpenMaya. Testing that separate project was successful. I was able to add all points in the test fixture to the Triangulation. So the issue appears to be a conflict between CGAL's libgmp-10.dll and Maya's libgmp-10.dll.
The next question then becomes, can CGAL be build to statically embed its version of the library, or is there a more correct way to resolve the conflict?

Separating out .cu and .cpp(using c++11 library)

I am trying to convert a c++ program I have which uses random library which is a C++11 feature. After having read through a couple of similar posts here, I tried by separating out the code into three files. At the outset I would like to say that I am not very conversant at C/C++ and mostly use R at work.
The main file looks as follows.
#ifndef _KERNEL_SUPPORT_
#define _KERNEL_SUPPORT_
#include <complex>
#include <random>
#include <iostream>
#include "my_code_header.h"
using namespace std;
std::default_random_engine generator;
std::normal_distribution<double> distribution(0.0,1.0);
const int rand_mat_length = 24561;
double rand_mat[rand_mat_length];// = {0};
void create_std_norm(){
for(int i = 0 ; i < rand_mat_length ; i++)
::rand_mat[i] = distribution(generator);
}
.
.
.
int main(void)
{
...
...
call_global();
return 0;
}
#endif
The header file looks as follows.
#ifndef mykernel_h
#define mykernel_h
void call_global();
void two_d_example(double *a, double *b, double *my_result, size_t length, size_t width);
#endif
And the .cu file looks like the following.
#ifndef _MY_KERNEL_
#define _MY_KERNEL_
#include <iostream>
#include "my_code_header.h"
#define TILE_WIDTH 8
using namespace std;
__global__ void two_d_example(double *a, double *b, double *my_result, size_t length, size_t width)
{
unsigned int row = blockIdx.y*blockDim.y + threadIdx.y;
unsigned int col = blockIdx.x*blockDim.x + threadIdx.x;
if ((row>length) || (col>width)) {
return;
}
...
}
void call_global()
{
const size_t imageLength = 528;
const size_t imageWidth = 528;
const dim3 threadsPerBlock(TILE_WIDTH,TILE_WIDTH);
const dim3 numBlocks(((imageLength) / threadsPerBlock.x), ((imageWidth) / threadsPerBlock.y));
double *d_a, *d_b, *mys ;
...
cudaMalloc((void**)&d_a, sizeof(double) * imageLength);
cudaMalloc((void**)&d_b, sizeof(double) * imageWidth);
cudaMalloc((void**)&mys, sizeof(double) * imageLength * imageWidth);
two_d_example<<<numBlocks,threadsPerBlock>>>(d_a, d_b, mys, imageLength, imageWidth);
...
cudaFree(d_a);
cudaFree(d_b);
}
#endif
Please note that the __global__ has been removed from .h since I was getting the following error owing to it being compiled by g++.
In file included from my_code_main.cpp:12:0:
my_code_header.h:5:1: error: ‘__global__’ does not name a type
When I compile the .cu file with nvcc it is all fine and generates a my_code_kernel.o. But since I am using C++11 in my .cpp I am trying to compile it with g++ and I am getting the following error.
/tmp/ccR2rXzf.o: In function `main':
my_code_main.cpp:(.text+0x1c4): undefined reference to `call_global()'
collect2: ld returned 1 exit status
I understand that this might not have to do anything with CUDA as such and may just be the wrong use of including the header at both places. Also what is the right way to compile and most importantly link the my_code_kernel.o and my_code_main.o(hopefully)? Sorry if this question is too trivial!
It looks like you are not linking with my_code_kernel.o. You have used -c for your nvcc command (causes it to compile but not link, i.e. generate the .o file), I'm going to guess that you're not using -c with your g++ command, in which case you need to add my_code_kernel.o to the list of inputs as well as the .cpp file.
The separation you are trying to achieve is completely possible, it just looks like your not linking properly. If you still have problems, add the compilation commands to your question.
FYI: You don't need to declare two_d_example() in your header file, it is only used within your .cu file (from call_global()).

boost library inside c++/cli.. exit with "code 0xC0020001: The string binding is invalid"

I am using the boost library for getting the current system time and my code works but visualt studio 2010 exits after the program.the debugger breaks while trying to free the non existing pointer. I know this is because of the boost native code.Since there is no error if I comment the boost portion of code.
Till now I tried using the #pragma as explained in MSDN but with no success.Can someone provide me some suggestions.? (I also tried GetSystemTime function to get the time but i cannot get the microsecond detail like boost.)
MY Code
#pragma managed(push, off)
void GetSystemDateTime(SDateTime& stimeblock);
#pragma managed(pop)
int main()
{
c++/cli code
SDateTime stimestruct[1];
//call to the function having the boost code..
GetSystemDateTime(stimestruct[0]);
}
Function Definition
#pragma managed(push, off)
void GetSystemDateTime(SDateTime& timeblock)
{
// SYSTEMTIME time;
// GetSystemTime(&time);
// WORD millis = (time.wSecond * 1000) + time.wMilliseconds;
boost::posix_time::ptime now = boost::posix_time::microsec_clock::local_time();
std::tm pt_tm = to_tm(now);
std::cout << now << std::endl;
//std::cout << time.wYear<< time.wMonth<<time.wDay //<<time.wHour<<time.wMinute<<time.wSecond<<time.wMilliseconds << std::endl;
std::string timestring = to_iso_string(now);
std::string sYear = timestring.substr (0,4);
std::string sMonth = timestring.substr (4,2);
std::string sDay = timestring.substr (6,2);
std::string sHour = timestring.substr (9,2);
std::string sMinute = timestring.substr (11,2);
std::string sSecond = timestring.substr (13,2);
std::string sUSecond = timestring.substr (16);
istringstream isYear(sYear);
istringstream isMonth(sMonth);
istringstream isDay(sDay);
istringstream isHour(sHour);
istringstream isMinute(sMinute);
istringstream isSec(sSecond);
istringstream isUSec(sUSecond);
// use is like an input stream
int iYear,iMonth,iDay,iHour,iMinute,iSecond,iUSecond;
isYear >> iYear;
isMonth >>iMonth;
isDay >>iDay;
isHour >>iHour;
isMinute >>iMinute;
isSec >>iSecond;
isUSec >>iUSecond;
timeblock.uiYear = iYear;
timeblock.usiMonth = time.wMonth;
timeblock.usiDay = time.wDay;
timeblock.usiHour = time.wHour;
timeblock.usiMinute = time.wMinute;
timeblock.usiSec = time.wSecond;
timeblock.udiUSec = time.wMilliseconds;
// Display version information
}
I've seen this error caused by using a static variable in native code in a C++/CLI assembly.
The only workaround I found was to remove the static variable, e.g., by moving it to class or file scope.
However, if this static variable is in the boost code, doing so may not be easy/possible. In that case, you could create a separate C++ file that's compiled without /clr, use the boost function in that file, and link that into your C++/CLI assembly.
This error seems to be caused by the compiler generating incorrect code. I filed a bug with Microsoft, which was closed "won't fix", but the compiler team gave some other workarounds in their response.
Try using
#pragma managed(push, off)
#pragma managed(pop)
around the #include lines for all boost header files.
I'm on the same problem for a few days now.
this is the best workaround i have found. and also explains why this is happening.
look at the end (number 7 and 9)
hope this helps http://www.codeproject.com/Articles/442784/Best-gotchas-of-Cplusplus-CLI

stringstream manipulators & vstudio 2003

I am trying to use a stringstream object in VC++ (VStudio 2003) butI am getting an error when I use the overloaded << operator to try and set some manipulators.
I am trying the following:
int SomeInt = 1;
stringstream StrStream;
StrStream << std::setw(2) << SomeInt;
This will not compile (error C2593: 'operator <<' is ambiguous).
Does VStudio 2003 support using manipulators in this way?
I know that I can just set the width directly on the stringstream object e.g. StrStream.width(2);
I was wondering why the more usual method doesn't work?
Are you sure you included all of the right headers? The following compiles for me in VS2003:
#include <iostream>
#include <sstream>
#include <iomanip>
int main()
{
int SomeInt = 1;
std::stringstream StrStream;
StrStream << std::setw(2) << SomeInt;
return 0;
}
I love this reference site for stream questions like this.
/Allan
You probably just forgot to include iomanip, but I can't be sure because you didn't include code for a complete program there.
This complete program works fine over here using VS 2003:
#include <sstream>
#include <iomanip>
int main()
{
int SomeInt = 1;
std::stringstream StrStream;
StrStream << std::setw(2) << SomeInt;
}

Resources