asherliu / thrust

Automatically exported from code.google.com/p/thrust
Apache License 2.0
0 stars 0 forks source link

Misuse of device_vector's copy constructor results in unhelpful error message #409

Closed GoogleCodeExporter closed 8 years ago

GoogleCodeExporter commented 8 years ago
Hi,

The copy constructor of a device vector with different types does not work:

thrust::device_vector<float> t1(10);
thrust::device_vector<double> t2(t1);

It does work for host vectors. I am using Thrust version from CUDA 4.0. Thanks 
for a great library.

/Stefan L. Glimberg

Original issue reported on code.google.com by stefangl...@gmail.com on 2 Nov 2011 at 4:03

GoogleCodeExporter commented 8 years ago
Thanks for the report Stefan.  I was able to reproduce your bug with the 
current development version of Thrust as well:

Error: calling a host function("thrust::detail::vector_base<double, 
thrust::device_malloc_allocator<double> > ::vector_base<float, 
thrust::device_malloc_allocator<float> > ") from a __device__/__global__ 
function("thrust::detail::vector_base<double, 
thrust::device_malloc_allocator<double> > ::vector_base<float, 
thrust::device_malloc_allocator<float> >  [subobject]") is not allowed

1 error detected in the compilation of 
"/tmp/tmpxft_00001c04_00000000-4_vector_copy.cpp1.ii".

However, I don't think this usage is valid.  For example, when I replace 
thrust::device_vector with std::vector I get the following error

vector_copy.cu(6): error: no instance of constructor "std::vector<_Tp, 
_Alloc>::vector [with _Tp=double, _Alloc=std::allocator<double>]" matches the 
argument list
            argument types are: (std::vector<float, std::allocator<float>>)

Admittedly, that's a more informative error message :)

Anyway, you can workaround the problem by constructing the second vector as 
follows:
  std::vector<double> t2(t1.begin(), t1.end());

Jared, what should we do here?

Original comment by wnbell on 2 Nov 2011 at 4:30

GoogleCodeExporter commented 8 years ago
Thank you. 

I also found that thrust::copy(t1.begin(),t1.end(),t2.begin()) will work.

/Stefan

Original comment by stefangl...@gmail.com on 2 Nov 2011 at 5:12

GoogleCodeExporter commented 8 years ago
I suppose we could use whatever strategy std::vector is using to remove the 
iterator-based constructor from the overload set.

Original comment by jaredhoberock on 2 Nov 2011 at 7:04

GoogleCodeExporter commented 8 years ago
I'm not sure what to do here.  Our vectors have a non-standard constructor from 
unrelated vector unlike std::vector, which only has a copy and move constructor.

I suspect that we could put an enable_if on the constructor, but it isn't 
immediately clear what would go inside the if. punting for now.

Original comment by jaredhoberock on 30 Jan 2012 at 7:59

GoogleCodeExporter commented 8 years ago
Forwarded to https://github.com/thrust/thrust/issues/37

Original comment by jaredhoberock on 7 May 2012 at 8:38