I am trying to simplify some code that make improper use of std::shared_ptr for handling objects returned by methods.
To do so, I want to rely on std::move, but I am afraid of the fact that thrust does not seem to handle the move construction properly. I wrote a small piece of code that intend to demonstrate this fact.
Could you tell me if the return value of this code is the one that we should expect from a proper implementation of move construction in thrust::device_vector ?
#include <thrust/device_vector.h>
#include <thrust/fill.h>
#include <iostream>
#include <cstdlib>
#include <vector>
#include <string>
#include <utility>
#include <algorithm>
class Foo
{
public:
Foo() : m_v(1,5555)
{
std::cout <<"This is the normal constructor with addr "<<
thrust::raw_pointer_cast( m_v.data() )<<std::endl;
}
virtual ~Foo()=default;
//Copy constructor
Foo( const Foo& other) : m_v(other.m_v)
{
std::cout <<"This is the copy constructor with addr "<<
thrust::raw_pointer_cast( m_v.data() )<<std::endl;
}
//Move constructor
Foo( Foo&& other) : m_v(std::move(other.m_v))
{
std::cout <<"This is the move constructor with addr "<<
thrust::raw_pointer_cast( m_v.data() )<<std::endl;
}
//Move assignment
Foo& operator=(Foo&& other)
{
m_v = std::move(other.m_v);
std::cout <<"This is the move assignment operator with addr "<<
thrust::raw_pointer_cast( m_v.data() )<<std::endl;
return *this;
}
//Assignment operator
Foo& operator=(const Foo& other)
{
m_v = other.m_v;
std::cout <<"This is the assignment operator with addr "<<
thrust::raw_pointer_cast( m_v.data() )<<std::endl;
return *this;
}
void fillWithVal( int val )
{
thrust::fill(m_v.begin(), m_v.end(), val);
}
void printValue() const
{
std::for_each(m_v.cbegin(), m_v.cend(), [](int in){std::cout<<in<<std::endl;});
}
protected:
thrust::device_vector<int> m_v;
};
Foo GetFoo()
{
Foo f;
f.fillWithVal( 255 );
return std::move(f);
}
//Compile using nvcc -std=c++11 ./main.cu -o ./test
//eventually with -fno-elide-constructors
int main()
{
std::cout <<"test 0 "<<std::endl;
Foo f = GetFoo();
f.printValue();
return EXIT_SUCCESS;
}
The return value is:
test 0
This is the normal constructor with addr 0xd06c00000
This is the move constructor with addr 0xd06c00200
255
Why do I get two different addresses ? It looks like there is a new allocation of device_vector, and that the pointer to the raw data is not the same anymore.
I tested a very similar code of pure c++11 host code that make use of std::vector (not shown here) and I got the same value printed out for the raw pointer.
Thank you in advance for your help
Aucun commentaire:
Enregistrer un commentaire