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>
58 :
public std::random_access_iterator_tag
70 template<
typename T,
template <
typename,
int RANK = 1 >
class CONT= concurrency::array >
73 typedef T* naked_pointer;
74 typedef const T* const_naked_pointer;
79 typedef ptrdiff_t difference_type;
80 typedef difference_type distance_type;
81 typedef size_t size_type;
84 typedef CONT< T > container_type;
85 typedef concurrency::array_view< T > arrayview_type;
86 typedef concurrency::array< T > array_type;
88 typedef naked_pointer pointer;
89 typedef const_naked_pointer const_pointer;
99 template<
typename Container >
103 reference_base( Container& rhs, size_type index ): m_Container( rhs ), m_Index( index )
107 operator value_type( )
const
109 arrayview_type av( *m_Container.m_devMemory );
110 value_type &result = av[
static_cast< int >( m_Index )];
117 arrayview_type av( *m_Container.m_devMemory );
118 av[
static_cast< int >( m_Index )] = rhs;
138 Container& m_Container;
147 template<
typename Container >
151 const_reference_base(
const Container& rhs, size_type index ): m_Container( rhs ), m_Index( index )
155 operator value_type( )
const
157 arrayview_type av( *m_Container.m_devMemory );
158 value_type &result = av[
static_cast< int >( m_Index )];
165 arrayview_type av( *m_Container.m_devMemory );
166 av[
static_cast< int >( m_Index )] = rhs;
186 const Container& m_Container;
208 template<
typename Container >
209 class iterator_base:
public boost::iterator_facade< iterator_base< Container >,
210 value_type, device_vector_tag, typename device_vector::reference >
215 iterator_base( Container& rhs, size_type index ): m_Container( rhs ), m_Index( index )
219 template<
typename OtherContainer >
221 m_Container( rhs.m_Container ), m_Index( rhs.m_Index )
228 m_Container = rhs.m_Container;
229 m_Index = rhs.m_Index;
246 Container& getContainer( )
const
251 size_type getIndex()
const
260 return ( rhs.m_Index - m_Index );
265 friend class boost::iterator_core_access;
273 void advance( difference_type n )
290 template<
typename OtherContainer >
293 bool sameIndex = rhs.m_Index == m_Index;
294 bool sameContainer = (&m_Container == &rhs.m_Container );
296 return ( sameIndex && sameContainer );
301 return m_Container[ m_Index ];
304 Container& m_Container;
314 template<
typename Container >
316 value_type, std::random_access_iterator_tag, typename device_vector::reference >
325 template<
typename OtherContainer >
327 m_Container( lhs.m_Container ), m_Index( lhs.m_Index-1 )
334 m_Container = lhs.m_Container;
335 m_Index = lhs.m_Index;
352 size_type getIndex()
const
357 Container& getContainer( )
const
365 return static_cast< difference_type
>( m_Index - lhs.m_Index );
370 friend class boost::iterator_core_access;
378 void advance( difference_type n )
395 template<
typename OtherContainer >
398 bool sameIndex = lhs.m_Index == m_Index;
399 bool sameContainer = (&m_Container == &lhs.m_Container );
401 return ( sameIndex && sameContainer );
406 return m_Container[ m_Index ];
409 Container& m_Container;
450 device_vector( size_type newSize,
const value_type& initValue = value_type( ),
bool init =
true,
453 static_assert( std::is_same< array_type, container_type >::value,
454 "This constructor is only valid for concurrency::array types. concurrency::array_views should use a "
455 "constructor that accepts host backing store" );
459 m_devMemory =
new container_type( static_cast< int >( m_Size ) );
463 arrayview_type m_devMemoryAV( *m_devMemory );
464 Concurrency::parallel_for_each( m_devMemoryAV.extent, [=](Concurrency::index<1> idx) restrict(amp)
466 m_devMemoryAV[idx] = initValue;
486 template<
typename InputIterator >
488 typename std::enable_if< !std::is_integral< InputIterator >::value &&
489 std::is_same< array_type, container_type >::value>::type* = 0 ) : m_Size( newSize )
491 static_assert( std::is_same< array_type, container_type >::value,
492 "This constructor is only valid for concurrency::array types. concurrency::array_views should use a "
493 "constructor that accepts containers" );
495 concurrency::extent<1> ext( static_cast< int >( m_Size ) );
496 m_devMemory =
new container_type( ext, begin, ctl.getAccelerator( ).default_view );
509 template<
typename InputIterator >
511 typename std::enable_if< !std::is_integral< InputIterator >::value &&
512 std::is_same< arrayview_type, container_type >::value>::type* = 0 ) : m_Size( newSize )
514 concurrency::extent<1> ext( static_cast< int >( m_Size ) );
515 m_devMemory =
new container_type( ext, &begin[ 0 ] );
524 template<
typename Container >
527 static_assert( std::is_same< arrayview_type, container_type >::value,
528 "This constructor is only valid for concurrency::array_view types" );
530 concurrency::extent<1> ext( static_cast< int >( m_Size ) );
531 m_devMemory =
new container_type( ext, cont );
543 template<
typename InputIterator >
545 typename std::enable_if< !std::is_integral< InputIterator >::value &&
546 std::is_same< array_type, container_type >::value>::type* = 0 )
548 static_assert( std::is_same< array_type, container_type >::value,
549 "This constructor is only valid for concurrency::array types. concurrency::array_views should use a "
550 "constructor that accepts containers" );
552 m_Size = std::distance( begin, end );
554 concurrency::extent<1> ext( static_cast< int >( m_Size ) );
556 m_devMemory =
new container_type( ext, begin, end, ctl.getAccelerator().default_view );
565 template<
typename InputIterator >
567 typename std::enable_if< !std::is_integral< InputIterator >::value &&
568 std::is_same< arrayview_type, container_type >::value>::type* = 0 )
570 m_Size = std::distance( begin, end );
572 concurrency::extent<1> ext( static_cast< int >( m_Size ) );
574 m_devMemory =
new container_type( ext, &begin[ 0 ] );
589 if (m_devMemory != NULL)
591 delete( m_devMemory );
607 concurrency::extent<1> ext( static_cast< int >( m_Size ) );
608 return m_devMemory->view_as( ext );
623 void resize( size_type reqSize,
const value_type& val = value_type( ) )
625 static_assert( std::is_same< array_type, container_type >::value,
626 "This member function is only valid for concurrency::array types.");
633 container_type* l_tmpBuffer =
new container_type((
int)reqSize);
640 if( reqSize > m_Size )
642 m_devMemory->copy_to(*l_tmpBuffer);
643 arrayview_type l_tmpBufferSectionAV =
644 l_tmpBuffer->section((
int)m_Size, (
int)(reqSize - m_Size));
645 concurrency::parallel_for_each(l_tmpBufferSectionAV.extent, [=](Concurrency::index<1> idx) restrict(amp)
647 l_tmpBufferSectionAV[idx] = val;
652 arrayview_type l_devMemoryAV = m_devMemory->section(0, (
int)reqSize);
653 arrayview_type l_tmpBufferAV = l_tmpBuffer->section(0, (
int)reqSize);
654 l_devMemoryAV.copy_to(l_tmpBufferAV);
659 arrayview_type l_tmpBufferAV(*l_tmpBuffer);
660 Concurrency::parallel_for_each(l_tmpBufferAV.extent, [=](Concurrency::index<1> idx) restrict(amp)
662 l_tmpBufferAV[idx] = val;
670 m_devMemory = l_tmpBuffer;
712 static_assert( std::is_same< array_type, container_type >::value,
713 "This member function is only valid for concurrency::array types.");
719 m_devMemory =
new container_type((
int)reqSize);
723 container_type* l_tmpBuffer =
new container_type((
int)reqSize);
726 m_devMemory->copy_to(*l_tmpBuffer);
728 m_devMemory = l_tmpBuffer;
738 if( m_devMemory != NULL )
740 Concurrency::extent<1> ext = m_devMemory->get_extent();
753 static_assert( std::is_same< array_type, container_type >::value,
754 "This member function is only valid for concurrency::array types.");
758 container_type* l_tmpBuffer =
new container_type( static_cast< int >(
size( ) ) );
759 arrayview_type l_devMemoryAV = m_devMemory->section( 0,(
int)
size() );
760 arrayview_type l_tmpBufferAV = l_tmpBuffer->section( 0,(
int)
size() );
762 l_devMemoryAV.copy_to( l_tmpBufferAV );
764 delete( m_devMemory );
766 m_devMemory = l_tmpBuffer;
927 return ( *(
end() - 1) );
935 return ( *(
end() - 1) );
945 synchronize( *
this );
947 arrayview_type av( *m_devMemory );
951 const_pointer
data(
void )
const
953 synchronize( *
this );
955 arrayview_type av( *m_devMemory );
964 delete( m_devMemory );
974 return m_Size ?
false:
true;
983 throw std::exception(
"device_vector size can not be greater than capacity( )" );
992 arrayview_type av( *m_devMemory );
994 av[
static_cast<int>( m_Size )] = value;
1016 container_type* swapBuffer( m_devMemory );
1017 m_devMemory = vec.m_devMemory;
1018 vec.m_devMemory = swapBuffer;
1020 size_type sizeTmp = m_Size;
1021 m_Size = vec.m_Size;
1022 vec.m_Size = sizeTmp;
1031 if( &index.m_Container !=
this )
1032 throw std::exception(
"Iterator is not from this container" );
1035 if( index.m_Index >= l_End.m_Index )
1036 throw std::exception(
"Iterator is pointing past the end of this container" );
1038 size_type sizeRegion = l_End.m_Index - index.m_Index;
1040 arrayview_type av( *m_devMemory );
1041 naked_pointer ptrBuff = av.data();
1042 naked_pointer ptrBuffTemp = ptrBuff + index.m_Index;
1043 ::memmove( ptrBuffTemp, ptrBuffTemp + 1, (sizeRegion - 1)*
sizeof( value_type ) );
1047 size_type newIndex = (m_Size < index.m_Index) ? m_Size : index.m_Index;
1048 return iterator( *
this, newIndex );
1058 if(( &first.m_Container !=
this ) && ( &last.m_Container !=
this ) )
1059 throw std::exception(
"Iterator is not from this container" );
1061 if( last.m_Index > m_Size )
1062 throw std::exception(
"Iterator is pointing past the end of this container" );
1064 if( (first ==
begin( )) && (last ==
end( )) )
1071 size_type sizeMap = l_End.m_Index - first.m_Index;
1073 arrayview_type av( *m_devMemory );
1074 naked_pointer ptrBuff = av.data();
1075 ptrBuff = ptrBuff + first.m_Index;
1076 size_type sizeErase = last.m_Index - first.m_Index;
1077 ::memmove( ptrBuff, ptrBuff + sizeErase, (sizeMap - sizeErase)*
sizeof( value_type ) );
1079 m_Size -= sizeErase;
1081 size_type newIndex = (m_Size < last.m_Index) ? m_Size : last.m_Index;
1082 return iterator( *
this, newIndex );
1094 if( &index.m_Container !=
this )
1095 throw std::exception(
"Iterator is not from this container" );
1097 if( index.m_Index > m_Size )
1098 throw std::exception(
"Iterator is pointing past the end of this container" );
1100 if( index.m_Index == m_Size )
1103 return iterator( *
this, index.m_Index );
1114 size_type sizeMap = (m_Size - index.m_Index) + 1;
1116 arrayview_type av( *m_devMemory );
1117 naked_pointer ptrBuff = av.data();
1118 ptrBuff = ptrBuff + index.m_Index;
1121 ::memmove( ptrBuff + 1, ptrBuff, (sizeMap - 1)*
sizeof( value_type ) );
1128 return iterator( *
this, index.m_Index );
1140 static_assert( std::is_same< array_type, container_type >::value,
1141 "This member function is only valid for concurrency::array types.");
1142 if( &index.m_Container !=
this )
1143 throw std::exception(
"Iterator is not from this container" );
1145 if( index.m_Index > m_Size )
1146 throw std::exception(
"Iterator is pointing past the end of this container" );
1154 size_type sizeMap = (m_Size - index.m_Index) + n;
1156 arrayview_type av( *m_devMemory );
1157 naked_pointer ptrBuff = av.data( );
1158 ptrBuff = ptrBuff + index.m_Index;
1161 ::memmove( ptrBuff + n, ptrBuff, (sizeMap - n)*
sizeof( value_type ) );
1164 for( size_type i = 0; i < n; ++i )
1166 ptrBuff[ i ] = value;
1172 template<
typename InputIterator >
1175 if( &index.m_Container !=
this )
1176 throw std::exception(
"Iterator is not from this container" );
1178 if( index.m_Index > m_Size )
1179 throw std::exception(
"Iterator is pointing past the end of this container" );
1182 size_type n = std::distance( begin, end );
1187 size_type sizeMap = (m_Size - index.m_Index) + n;
1189 arrayview_type av( *m_devMemory );
1190 naked_pointer ptrBuff = av.data() + index.m_Index;
1193 ::memmove( ptrBuff + n, ptrBuff, (sizeMap - n)*
sizeof( value_type ) );
1196 std::copy( begin, end, stdext::checked_array_iterator< naked_pointer >( ptrBuff, n ) );
1209 void assign( size_type newSize,
const value_type& value )
1211 if( newSize > m_Size )
1217 arrayview_type m_devMemoryAV( *m_devMemory );
1218 Concurrency::parallel_for_each( m_devMemoryAV.extent, [=](Concurrency::index<1> idx) restrict(amp)
1220 m_devMemoryAV[idx] = value;
1230 template<
typename InputIterator>
1231 typename std::enable_if< std::_Is_iterator<InputIterator>::value,
void>::type
1232 assign( InputIterator begin, InputIterator end )
1234 size_type l_Count = std::distance( begin, end );
1236 if( l_Count > m_Size )
1241 arrayview_type m_devMemoryAV( *m_devMemory );
1242 naked_pointer ptrBuff = m_devMemoryAV.data();
1244 std::copy( begin, end, stdext::checked_array_iterator< naked_pointer >( ptrBuff, m_Size ) );
1260 void synchronize( device_vector< T, concurrency::array_view >& rhs )
1262 rhs.m_devMemory->synchronize( );
1266 container_type* m_devMemory;