Weird behaviour using thrust experimental::pinned_allocator in cuda - c++11

I am currently trying to delete part of the cumbersome cudaMallocHost/cudaFreeHost from my code. To do so, I am willing to use only std::vector, but I absolutely need that the underlying memory must be of pinned cuda memory type.
But, I am facing strange behaviour using the thrust::system::cuda::experimental::pinned_allocator<> from the thrust library:
//STL
#include <iostream>
#include <string>
#include <vector>
#include <algorithm>
//CUDA
#include <cuda_runtime.h>
#include <thrust/device_vector.h>
#include <thrust/transform.h>
#include <thrust/system/cuda/experimental/pinned_allocator.h>
#define SIZE 4
#define INITVAL 2
#define ENDVAL 4
//Compile using nvcc ./main.cu -o test -std=c++11
int main( int argc, char* argv[] )
{
// init host
std::vector<float,thrust::system::cuda::experimental::pinned_allocator<float> > hostVec(SIZE);
std::fill(hostVec.begin(),hostVec.end(),INITVAL);
//Init device
thrust::device_vector<float> thrustVec(hostVec.size());
//Copy
thrust::copy(hostVec.begin(), hostVec.end(), thrustVec.begin());
//std::cout << "Dereferencing values of the device, values should be "<< INITVAL << std::endl;
std::for_each(thrustVec.begin(),thrustVec.end(),[](float in){ std::cout <<"val is "<<in<<std::endl;} );
std::cout << "------------------------" << std::endl;
//Do Stuff
thrust::transform( thrustVec.begin(), thrustVec.end(), thrust::make_constant_iterator(2), thrustVec.begin(), thrust::multiplies<float>() );
//std::cout << "Dereferencing values of the device, values should now be "<< ENDVAL << std::endl;
std::for_each(thrustVec.begin(),thrustVec.end(),[](float in){ std::cout <<"val is "<<in<<std::endl;} );
std::cout << "------------------------" << std::endl;
//Copy back
thrust::copy(thrustVec.begin(), thrustVec.end(), hostVec.begin());
//Synchronize
//cudaDeviceSynchronize(); //makes the weird behaviour to go away
//Check result
//std::cout << "Dereferencing values on the host, values should now be "<< ENDVAL << std::endl;//Also makes the weird behaviour to go away
std::for_each(hostVec.begin(),hostVec.end(),[](float in){ std::cout <<"val is "<<in<<std::endl;} );
return EXIT_SUCCESS;
}
Which, in my setup, gives:
val is 2
val is 2
val is 2
val is 2
------------------------
val is 4
val is 4
val is 4
val is 4
------------------------
val is 2
val is 4
val is 4
val is 4
Why does the copy from device to host seems to fail ? Nvvp however shows a perfectly fine chronogram with the right values for copy.
By the way, I use NVCC/cuda/thrust from the 7.5 package, and gcc (GCC) 4.8.5 with a titanX card.
Thank you in advance for your help.

This was a real bug, and thrust developpers were already aware of it, see https://github.com/thrust/thrust/issues/775
Using the latest 1.8.3 version of thrust from the github repository solved the problem for me.

Related

serialize temporary into boost archive

The following is not possible for any boost output archive:
int foo(){
return 4;
}
ar << static_cast<unsigned int>(foo());
Is there an alternative without out creating a local temporary x=foo().
and why is the underlying archive operator <<(T & t) not const reference , for an output archive such that the above would work?
This seems to work, and I think this is why:
... To help detect such cases, output archive operators expect to be
passed const reference arguments.
It seems worth noting that in your example ar << foo(); does not work either (i.e. it doesn't have to do with your cast).
#include <fstream>
#include <iostream>
#include <boost/serialization/serialization.hpp>
#include <boost/archive/text_iarchive.hpp>
#include <boost/archive/text_oarchive.hpp>
unsigned int foo(){
return 4;
}
int main()
{
{
std::ofstream outputStream("someFile.txt");
boost::archive::text_oarchive outputArchive(outputStream);
outputArchive << static_cast<const int&>(foo());
}
std::ifstream inputStream("someFile.txt");
boost::archive::text_iarchive inputArchive(inputStream);
int readBack;
inputArchive >> readBack;
std::cout << "Read back: " << readBack << std::endl;
return 0;
}

C++ gettid() was not declared in this scope

A simple program is:
I would like to get the thread ID of both of the threads using this gettid function. I do not want to do the sysCall directly. I want to use this function.
#include <iostream>
#include <boost/thread/thread.hpp>
#include <boost/date_time/date.hpp>
#include <unistd.h>
#include <sys/types.h>
using namespace boost;
using namespace std;
boost::thread thread_obj;
boost::thread thread_obj1;
void func(void)
{
char x;
cout << "enter y to interrupt" << endl;
cin >> x;
pid_t tid = gettid();
cout << "tid:" << tid << endl;
if (x == 'y') {
cout << "x = 'y'" << endl;
cout << "thread interrupt" << endl;
}
}
void real_main() {
cout << "real main thread" << endl;
pid_t tid = gettid();
cout << "tid:" << tid << endl;
boost::system_time const timeout = boost::get_system_time() + boost::posix_time::seconds(3);
try {
boost::this_thread::sleep(timeout);
}
catch (boost::thread_interrupted &) {
cout << "thread interrupted" << endl;
}
}
int main()
{
thread_obj1 = boost::thread(&func);
thread_obj = boost::thread(&real_main);
thread_obj.join();
}
It gives Error on compilation; The use of gettid() has been done according to the man page:
$g++ -std=c++11 -o Intrpt Interrupt.cpp -lboost_system -lboost_thread
Interrupt.cpp: In function ‘void func()’:
Interrupt.cpp:17:25: error: ‘gettid’ was not declared in this scope
pid_t tid = gettid();
This is a silly glibc bug. Work around it like this:
#include <unistd.h>
#include <sys/syscall.h>
#define gettid() syscall(SYS_gettid)
The man page you refer to can be read online here. It clearly states:
Note: There is no glibc wrapper for this system call; see NOTES.
and
NOTES
Glibc does not provide a wrapper for this system call; call it using syscall(2).
The thread ID returned by this call is not the same thing as a POSIX thread ID (i.e., the opaque value returned by pthread_self(3)).
So you can't. The only way to use this function is through the syscall.
But you probably shouldn't anyway. You can use pthread_self() (and compare using pthread_equal(t1, t2)) instead. It's possible that boost::thread has its own equivalent too.
Additional to the solution provided by Glenn Maynard it might be appropriate to check the glibc version and only if it is lower than 2.30 define the suggested macro for gettid().
#if __GLIBC__ == 2 && __GLIBC_MINOR__ < 30
#include <sys/syscall.h>
#define gettid() syscall(SYS_gettid)
#endif

Move or swap a stringstream

I want to move a stringstream, in the real world application I have some stringstream class data member, which I want to reuse for different string's during operation.
stringstream does not have a copy-assignment or copy constructor, which makes sense. However, according to cppreference.com and cplusplus.com std::stringstream should have a move assignment and swap operation defined. I tried both, and both fail.
Move assignment
#include <string> // std::string
#include <iostream> // std::cout
#include <sstream> // std::stringstream
int main () {
std::stringstream stream("1234");
//stream = std::move(std::stringstream("5678"));
stream.operator=(std::move(std::stringstream("5678")));
//stream.operator=(std::stringstream("5678"));
return 0;
}
source: http://ideone.com/Izyanb
prog.cpp:11:56: error: use of deleted function ‘std::basic_stringstream<char>& std::basic_stringstream<char>::operator=(const std::basic_stringstream<char>&)’
stream.operator=(std::move(std::stringstream("5678")));
The compiler states that there is no copy assignment for all three statements, which is true. However, I fail to see why it is not using the move-assignment, especially since std::move is supposed to return a rvalue reference. Stringstream should have a move assignment, as shown here: http://en.cppreference.com/w/cpp/io/basic_stringstream/operator%3D
PS: I'm working with c++11, hence rvalue-references are part of the 'world'.
Swap
This I found really strange, I copied example code from cplusplus.com and it failed:
// swapping stringstream objects
#include <string> // std::string
#include <iostream> // std::cout
#include <sstream> // std::stringstream
int main () {
std::stringstream foo;
std::stringstream bar;
foo << 100;
bar << 200;
foo.swap(bar);
int val;
foo >> val; std::cout << "foo: " << val << '\n';
bar >> val; std::cout << "bar: " << val << '\n';
return 0;
}
source: http://ideone.com/NI0xMS
cplusplus.com source: http://www.cplusplus.com/reference/sstream/stringstream/swap/
prog.cpp: In function ‘int main()’:
prog.cpp:14:7: error: ‘std::stringstream’ has no member named ‘swap’
foo.swap(bar);
What am I missing? Why can't I move or swap a stringstream? How should I swap or move a stringstream?
This is a missing feature on GCC : see bug 54316 , it has been fixed (you can thank Jonathan Wakely) for the next versions (gcc 5)
Clang with libc++ compiles this code :
int main () {
std::stringstream stream("1234");
std::stringstream stream2 = std::move(std::stringstream("5678"));
return 0;
}
Live demo
And it also compiles the example with std::stringstream::swap
I have an alternative to moving or swapping, one can also clear and set a stringstream to a new string:
#include <string> // std::string
#include <iostream> // std::cout
#include <sstream> // std::stringstream
int main () {
std::stringstream ss("1234");
ss.clear();
ss.str("5678");
int val;
ss >> val; std::cout << "val: " << val << '\n';
return 0;
}
It's a clean work around that does not require one to refactor code, except for the localized section where the swap is changed to a clear() and str().

Different behavior of boost::serialization of strings on text archive

I'm having some issue serializing a std::string with boost::serialization on a text_oarchive. AFAICT, I have two identical pieces of code that behaves differently in two different programs.
This is the program that I believe is behaving correctly:
#include <iostream>
#include <string>
#include <sstream>
#include <boost/archive/text_iarchive.hpp>
#include <boost/archive/text_oarchive.hpp>
template <typename T>
void serialize_deserialize(const T & src, T & dst)
{
std::string serialized_data_str;
std::cout << "original data: " << src << std::endl;
std::ostringstream archive_ostream;
boost::archive::text_oarchive oarchive(archive_ostream);
oarchive << src;
serialized_data_str = archive_ostream.str();
std::cout << "serialized data: " << serialized_data_str << std::endl;
std::istringstream archive_istream(serialized_data_str);
boost::archive::text_iarchive iarchive(archive_istream);
iarchive >> dst;
}
int main()
{
std::string archived_data_str = "abcd";
std::string restored_data_str;
serialize_deserialize<std::string>(archived_data_str, restored_data_str);
std::cout << "restored data: " << restored_data_str << std::endl;
return 0;
}
And this is its output:
original data: abcd
serialized data: 22 serialization::archive 10 4 abcd
restored data: abcd
(You can compile it with: g++ boost-serialization-string.cpp -o boost-serialization-string -lboost_serialization)
This one, on the other hand, is an excerpt of the program I'm writing (derived from boost_asio/example/serialization/connection.hpp) that serializes std::string data converting each character in its hex representation:
/// Asynchronously write a data structure to the socket.
template <typename T, typename Handler>
void async_write(const T& t, Handler handler)
{
// Serialize the data first so we know how large it is.
std::cout << "original data: " << t << std::endl;
std::ostringstream archive_stream;
boost::archive::text_oarchive archive(archive_stream);
archive << t;
outbound_data_ = archive_stream.str();
std::cout << "serialized data: " << outbound_data_ << std::endl;
[...]
And this is an excerpt of its output:
original data: abcd
serialized data: 22 serialization::archive 10 5 97 98 99 100 0
The version (10) is the same, right? So that should be the proof that I'm using the same serialization library in both programs.
However, I really can't figure out what's going on here. I've been trying to solve this puzzle for almost an entire work day now, and I'm out of ideas.
For anyone that may want to reproduce this result, it should be sufficient to download the Boost serialization example, add the following line
connection_.async_write("abcd", boost::bind(&client::handle_write, this, boost::asio::placeholders::error));
at line 50 of client.cpp, add the following member function in client.cpp
/// Handle completion of a write operation.
void handle_write(const boost::system::error_code& e)
{
// Nothing to do. The socket will be closed automatically when the last
// reference to the connection object goes away.
}
add this cout:
std::cout << "serialized data: " << outbound_data_ << std::endl;
at connection.hpp:59
and compile with:
g++ -O0 -g3 client.cpp -o client -lboost_serialization -lboost_system
g++ -O0 -g3 server.cpp -o server -lboost_serialization -lboost_system
I'm using g++ 4.8.1 under Ubuntu 13.04 64bit with Boost 1.53
Any help would be greatly appreciated.
P.s. I'm posting this because the deserialization of the std::strings isn't working at all! :)
I see two causes of such behavior.
The compiler does not explicitly converts "abcd" from const char * to std::string and the serialization handles it as a vector of "bytes" and not as an ASCII string. Changing the code to the connection_.async_write(std::string("abcd"), boost::bind(&client::handle_write, this, boost::asio::placeholders::error)); should fix the problem.
Probably, the string type passed as the t argument of the async_write template method is not std::string but std::wstring and it is serialized not as an ASCII string ("abcd") but as an unsigned short vector and 97 98 99 100 is a decimal representation of the ASCII characters a, b, c and d.

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