@@ -13,6 +13,7 @@ use std::ops::{
1313 Index , IndexMut , Range , RangeFrom , RangeFull , RangeInclusive , RangeTo , RangeToInclusive ,
1414} ;
1515use std:: os:: raw:: c_void;
16+ use std:: slice;
1617use std:: ptr:: { slice_from_raw_parts, slice_from_raw_parts_mut} ;
1718
1819/// Fixed-size device-side slice.
@@ -35,14 +36,6 @@ impl<T: DeviceCopy> Debug for DeviceSlice<T> {
3536 }
3637}
3738
38- impl < T : DeviceCopy + Default + Clone > DeviceSlice < T > {
39- pub fn as_host_vec ( & self ) -> CudaResult < Vec < T > > {
40- let mut vec = vec ! [ T :: default ( ) ; self . len( ) ] ;
41- self . copy_to ( & mut vec) ?;
42- Ok ( vec)
43- }
44- }
45-
4639// This works by faking a regular slice out of the device raw-pointer and the length and transmuting
4740// I have no idea if this is safe or not. Probably not, though I can't imagine how the compiler
4841// could possibly know that the pointer is not de-referenceable. I'm banking that we get proper
@@ -94,6 +87,17 @@ impl<T: DeviceCopy> DeviceSlice<T> {
9487 DevicePointer :: from_raw ( self as * const _ as * const ( ) as usize as u64 )
9588 }
9689
90+ pub fn as_host_vec ( & self ) -> CudaResult < Vec < T > > {
91+ let mut vec = Vec :: with_capacity ( self . len ( ) ) ;
92+ // SAFETY: The slice points to uninitialized memory, but we only write to it. Once it is
93+ // written, all values are valid, so we can (and must) change the length of the vector.
94+ unsafe {
95+ self . copy_to ( slice:: from_raw_parts_mut ( vec. as_mut_ptr ( ) , self . len ( ) ) ) ?;
96+ vec. set_len ( self . len ( ) )
97+ }
98+ Ok ( vec)
99+ }
100+
97101 /* TODO (AL): keep these?
98102 /// Divides one DeviceSlice into two at a given index.
99103 ///
0 commit comments