24 #if !defined( BOLT_AMP_DEVICE_VECTOR_H )
25 #define BOLT_AMP_DEVICE_VECTOR_H
28 #include <type_traits>
33 #include <boost/iterator/iterator_facade.hpp>
34 #include <boost/iterator/reverse_iterator.hpp>
35 #include <boost/shared_array.hpp>
57 :
public std::random_access_iterator_tag
68 static concurrency::array<T> getav() restrict(cpu)
70 static T type_default;
71 return concurrency::array<T>(1);
84 template<
typename T,
template <
typename,
int RANK = 1 >
class CONT= concurrency::array_view >
87 typedef T* naked_pointer;
88 typedef const T* const_naked_pointer;
93 typedef ptrdiff_t difference_type;
94 typedef difference_type distance_type;
95 typedef int size_type;
98 typedef concurrency::array_view< T > arrayview_type;
99 typedef concurrency::array< T > array_type;
101 typedef CONT< T > container_type;
103 typedef naked_pointer pointer;
104 typedef const_naked_pointer const_pointer;
114 template<
typename Container >
118 reference_base( Container& rhs, size_type index ): m_Container( rhs,
false ), m_Index( index )
122 operator value_type( )
const
124 arrayview_type av( m_Container.m_devMemory );
125 value_type &result = av[
static_cast< int >( m_Index )];
132 arrayview_type av( m_Container.m_devMemory );
133 av[
static_cast< int >( m_Index )] = rhs;
153 Container m_Container;
162 template<
typename Container >
166 const_reference_base(
const Container& rhs, size_type index ): m_Container( rhs,
false ), m_Index( index )
170 operator value_type( )
const
172 arrayview_type av( m_Container.m_devMemory );
173 value_type &result = av[
static_cast< int >( m_Index )];
180 arrayview_type av( m_Container.m_devMemory );
181 av[
static_cast< int >( m_Index )] = rhs;
201 const Container m_Container;
223 template<
typename Container >
224 class iterator_base:
public boost::iterator_facade< iterator_base< Container >,
225 value_type, device_vector_tag, typename device_vector::reference >
233 iterator_base( Container& rhs, size_type index ): m_Container( rhs,
false ), m_Index( static_cast<int>(index) )
237 template<
typename OtherContainer >
239 m_Container( rhs.m_Container,
false ), m_Index( rhs.m_Index )
242 m_Container( rhs.m_Container,
false ), m_Index( rhs.m_Index )
247 m_Container = rhs.m_Container;
248 m_Index = rhs.m_Index;
265 Container getContainer( )
const
270 size_type getIndex()
const
278 return ( rhs.m_Index - m_Index );
283 friend class boost::iterator_core_access;
291 void advance( difference_type n )
293 m_Index +=
static_cast<int>(n);
307 template<
typename OtherContainer >
310 bool sameIndex = rhs.m_Index == m_Index;
311 bool sameContainer = &m_Container.m_devMemory[m_Index] == &rhs.m_Container.m_devMemory[rhs.m_Index];
312 return ( sameIndex && sameContainer );
315 value_type& operator[](
int x)
const restrict(cpu,amp)
317 return m_Container[m_Index + x];
320 value_type& operator*()
const restrict(cpu,amp)
322 return m_Container[m_Index];
326 Container m_Container;
336 template<
typename Container >
338 value_type, std::random_access_iterator_tag, typename device_vector::reference >
346 reverse_iterator_base( Container& lhs,
int index ): m_Container( lhs,
false ), m_Index( static_cast<int>(index-1) )
350 template<
typename OtherContainer >
352 m_Container( lhs.m_Container,
false ), m_Index( lhs.m_Index )
356 m_Container( lhs.m_Container,
false ), m_Index( lhs.m_Index )
361 m_Container = lhs.m_Container;
362 m_Index = lhs.m_Index;
384 Container& getContainer( )
const
392 return static_cast< difference_type
>( m_Index - lhs.m_Index );
398 friend class boost::iterator_core_access;
406 void advance( difference_type n )
408 m_Index +=
static_cast<int>(n);
421 template<
typename OtherContainer >
424 bool sameIndex = lhs.m_Index == m_Index;
425 bool sameContainer = &m_Container.m_devMemory[m_Index] == &lhs.m_Container.m_devMemory[lhs.m_Index];
426 return ( sameIndex && sameContainer );
429 value_type& operator[](
int x)
const restrict(cpu,amp)
431 return m_Container[m_Index - x];
434 value_type& operator*()
const restrict(cpu,amp)
436 return m_Container[m_Index];
440 Container m_Container;
468 : m_Size( static_cast<int>(0) ), m_devMemory(
create_empty_array<value_type>::getav() )
481 device_vector( size_type newSize,
const value_type& initValue = value_type( ),
bool init =
true,
483 : m_Size( static_cast<int>(newSize) ), m_devMemory(
create_empty_array<value_type>::getav() )
487 concurrency::array<value_type> tmp = array_type( static_cast< int >( m_Size ), ctl.getAccelerator().default_view );
488 m_devMemory = tmp.view_as(tmp.get_extent());
491 arrayview_type m_devMemoryAV( m_devMemory );
492 Concurrency::parallel_for_each( m_devMemoryAV.extent, [=](Concurrency::index<1> idx) restrict(amp)
494 m_devMemoryAV[idx] = initValue;
508 template<
typename InputIterator >
510 typename std::enable_if< !std::is_integral< InputIterator >::value &&
511 std::is_same< arrayview_type, container_type >::value>::type* = 0 )
512 : m_Size( static_cast<int>(newSize) ), m_devMemory(
create_empty_array<value_type>::getav() )
516 concurrency::extent<1> ext( static_cast< int >( m_Size ) );
517 concurrency::array_view<value_type> tmp = arrayview_type( ext, reinterpret_cast< value_type* >(&begin[ 0 ]) );
521 m_devMemory.discard_data();
532 template<
typename InputIterator >
534 typename std::enable_if< !std::is_integral< InputIterator >::value &&
535 std::is_same< array_type, container_type >::value>::type* = 0 )
536 : m_Size( static_cast<int>(newSize) ), m_devMemory(
create_empty_array<value_type>::getav() )
540 concurrency::extent<1> ext( static_cast< int >( m_Size ) );
541 concurrency::array<value_type> tmp = array_type( ext, reinterpret_cast< value_type* >(&begin[ 0 ]) );
542 m_devMemory = tmp.view_as(tmp.get_extent());
552 template<
typename T >
554 m_devMemory( cont.m_devMemory.view_as(cont.m_devMemory.get_extent()))
560 concurrency::array<value_type> tmp = array_type( m_devMemory );
561 m_devMemory = tmp.view_as(tmp.get_extent());
576 device_vector( array_type &cont): m_Size(cont.get_extent().
size()), m_devMemory( cont.view_as(cont.get_extent()))
587 template<
typename InputIterator >
589 typename std::enable_if< std::is_same< arrayview_type, container_type >::value &&
590 !std::is_integral< InputIterator >::value>::type* = 0 )
593 m_Size =
static_cast<int>(std::distance( begin, end ));
597 concurrency::extent<1> ext( static_cast< int >( m_Size ) );
598 concurrency::array_view<value_type> tmp = arrayview_type( ext, reinterpret_cast< value_type* >(&begin[ 0 ]) );
602 m_devMemory.discard_data();
614 template<
typename InputIterator >
616 typename std::enable_if< std::is_same< array_type, container_type >::value &&
617 !std::is_integral< InputIterator >::value>::type* = 0 )
620 m_Size =
static_cast<int>(std::distance( begin, end ));
624 concurrency::extent<1> ext( static_cast< int >( m_Size ) );
625 concurrency::array<value_type> tmp = array_type( ext, reinterpret_cast< value_type* >(&begin[ 0 ]) );
626 m_devMemory = tmp.view_as(tmp.get_extent());
647 concurrency::extent<1> ext( static_cast< int >( m_Size ) );
648 return m_devMemory.view_as( ext );
662 if(size == static_cast<unsigned int>(m_Size))
664 concurrency::extent<1> ext( static_cast< int >( m_Size ) );
665 return m_devMemory.view_as( ext );
669 size_type offset = itr.getIndex();
670 concurrency::extent<1> ext( static_cast< int >( size ) );
671 return m_devMemory.section( Concurrency::index<1>(offset), ext );
678 if(size == static_cast<unsigned int>(m_Size))
680 concurrency::extent<1> ext( static_cast< int >( m_Size ) );
681 return m_devMemory.view_as( ext );
685 size_type offset = itr.getIndex();
686 concurrency::extent<1> ext( static_cast< int >( size ) );
687 return m_devMemory.section( Concurrency::index<1>(offset), ext );
703 void resize( size_type reqSize,
const value_type& val = value_type( ) )
711 array_type l_tmpArray = array_type(reqSize);
712 arrayview_type l_tmpBuffer = arrayview_type(l_tmpArray);
719 if( reqSize > m_Size )
721 m_devMemory.copy_to(l_tmpBuffer.section( 0, m_devMemory.get_extent().size() ) );
722 arrayview_type l_tmpBufferSectionAV =
723 l_tmpBuffer.section(m_Size, (reqSize - m_Size));
724 concurrency::parallel_for_each(l_tmpBufferSectionAV.extent, [=](Concurrency::index<1> idx) restrict(amp)
726 l_tmpBufferSectionAV[idx] = val;
731 arrayview_type l_devMemoryAV = m_devMemory.section(0, reqSize);
732 l_devMemoryAV.copy_to(l_tmpBuffer);
737 arrayview_type l_tmpBufferAV(l_tmpBuffer);
738 Concurrency::parallel_for_each(l_tmpBufferAV.extent, [=](Concurrency::index<1> idx) restrict(amp)
740 l_tmpBufferAV[idx] = val;
745 m_devMemory = l_tmpBuffer;
776 concurrency::array<value_type> tmp = array_type( static_cast< int >( reqSize ) );
777 arrayview_type l_tmpBuffer = arrayview_type( tmp );
782 arrayview_type l_tmpBuffer = arrayview_type( tmp );
783 m_devMemory.copy_to(l_tmpBuffer.section(0, m_devMemory.get_extent().size()));
786 m_devMemory = l_tmpBuffer;
797 Concurrency::extent<1> ext = m_devMemory.get_extent();
811 array_type l_tmpArray = array_type( static_cast< int >(
size( ) ) );
812 arrayview_type l_tmpBuffer = arrayview_type(l_tmpArray);
813 arrayview_type l_devMemoryAV = m_devMemory.section( 0,(
int)
size() );
814 arrayview_type l_tmpBufferAV = l_tmpBuffer.section( 0,(
int)
size() );
816 l_devMemoryAV.copy_to( l_tmpBufferAV );
817 m_devMemory = l_tmpBuffer;
823 value_type&
operator[]( size_type n ) restrict(cpu,amp)
825 return m_devMemory[n];
831 value_type&
operator[]( size_type ix )
const restrict(cpu,amp)
833 return m_devMemory[ix];
961 const value_type&
front(
void )
const
971 return (*(
end() - 1));
977 const value_type&
back(
void )
const
979 return ( *(
end() - 1) );
993 synchronize( *
this );
994 arrayview_type av( m_devMemory );
998 const_pointer
data(
void )
const
1004 synchronize( *
this );
1005 arrayview_type av( m_devMemory );
1023 return m_Size ?
false:
true;
1032 throw std::exception(
"device_vector size can not be greater than capacity( )" );
1041 arrayview_type av( m_devMemory );
1043 av[
static_cast<int>( m_Size )] = value;
1065 arrayview_type swapBuffer( m_devMemory );
1066 m_devMemory = vec.m_devMemory;
1067 vec.m_devMemory = swapBuffer;
1069 size_type sizeTmp = m_Size;
1070 m_Size = vec.m_Size;
1071 vec.m_Size =
static_cast<int>(sizeTmp);
1081 if( index.m_Index >= l_End.m_Index )
1082 throw std::exception(
"Iterator is pointing past the end of this container" );
1084 size_type sizeRegion = l_End.m_Index - index.m_Index;
1086 arrayview_type av( m_devMemory );
1087 naked_pointer ptrBuff = av.data();
1088 naked_pointer ptrBuffTemp = ptrBuff + index.m_Index;
1089 ::memmove( ptrBuffTemp, ptrBuffTemp + 1, (sizeRegion - 1)*
sizeof( value_type ) );
1093 size_type newIndex = (m_Size < index.m_Index) ? m_Size : index.m_Index;
1094 return iterator( *
this, newIndex );
1104 if( last.m_Index > m_Size )
1105 throw std::exception(
"Iterator is pointing past the end of this container" );
1107 if( (first ==
begin( )) && (last ==
end( )) )
1114 size_type sizeMap = l_End.m_Index - first.m_Index;
1116 arrayview_type av( m_devMemory );
1117 naked_pointer ptrBuff = av.data();
1118 ptrBuff = ptrBuff + first.m_Index;
1119 size_type sizeErase = last.m_Index - first.m_Index;
1120 ::memmove( ptrBuff, ptrBuff + sizeErase, (sizeMap - sizeErase)*
sizeof( value_type ) );
1122 m_Size -=
static_cast<int>(sizeErase);
1124 size_type newIndex = (m_Size < last.m_Index) ? m_Size : last.m_Index;
1125 return iterator( *
this, newIndex );
1137 if( index.m_Index > m_Size )
1138 throw std::exception(
"Iterator is pointing past the end of this container" );
1140 if( index.m_Index == m_Size )
1143 return iterator( *
this, index.m_Index );
1154 size_type sizeMap = (m_Size - index.m_Index) + 1;
1156 arrayview_type av( m_devMemory );
1157 naked_pointer ptrBuff = av.data();
1158 ptrBuff = ptrBuff + index.m_Index;
1161 ::memmove( ptrBuff + 1, ptrBuff, (sizeMap - 1)*
sizeof( value_type ) );
1168 return iterator( *
this, index.m_Index );
1180 if( index.m_Index > m_Size )
1181 throw std::exception(
"Iterator is pointing past the end of this container" );
1189 size_type sizeMap = (m_Size - index.m_Index) + n;
1191 arrayview_type av( m_devMemory );
1192 naked_pointer ptrBuff = av.data( );
1193 ptrBuff = ptrBuff + index.m_Index;
1196 ::memmove( ptrBuff + n, ptrBuff, (sizeMap - n)*
sizeof( value_type ) );
1199 for( size_type i = 0; i < n; ++i )
1201 ptrBuff[ i ] = value;
1207 template<
typename InputIterator >
1210 if( index.m_Index > m_Size )
1211 throw std::exception(
"Iterator is pointing past the end of this container" );
1214 size_type n =
static_cast<int>(std::distance( begin, end ));
1219 size_type sizeMap = (m_Size - index.m_Index) + n;
1221 arrayview_type av( m_devMemory );
1222 naked_pointer ptrBuff = av.data() + index.m_Index;
1225 ::memmove( ptrBuff + n, ptrBuff, (sizeMap - n)*
sizeof( value_type ) );
1228 std::copy( begin, end, stdext::checked_array_iterator< naked_pointer >( ptrBuff, n ) );
1233 m_Size +=
static_cast<int>(n);
1241 void assign( size_type newSize,
const value_type& value )
1243 if( newSize > m_Size )
1249 arrayview_type m_devMemoryAV( m_devMemory );
1250 Concurrency::parallel_for_each( m_devMemoryAV.extent, [=](Concurrency::index<1> idx) restrict(amp)
1252 m_devMemoryAV[idx] = value;
1262 template<
typename InputIterator>
1263 typename std::enable_if< std::_Is_iterator<InputIterator>::value,
void>::type
1264 assign( InputIterator begin, InputIterator end )
1266 size_type l_Count =
static_cast<int>(std::distance( begin, end ));
1268 if( l_Count > m_Size )
1272 m_Size =
static_cast<int>(l_Count);
1274 arrayview_type m_devMemoryAV( m_devMemory );
1275 naked_pointer ptrBuff = m_devMemoryAV.data();
1277 std::copy( begin, end, stdext::checked_array_iterator< naked_pointer >( ptrBuff, m_Size ) );
1292 void synchronize( device_vector< T, concurrency::array_view >& rhs )
1294 rhs.m_devMemory.synchronize( );
1298 concurrency::array_view<T, 1> m_devMemory;