MultiView
corbett5 opened this issue · 3 comments
Make something similar to the RAJA MultiView. Here's what I imagine it would look like.
template< int NARRAYS, typename T, int NDIM, int USD, typename INDEX_TYPE, template< typename > class BUFFER_TYPE >
class MultiView
{
public:
MultiView( CArray< ArrayView< T, NDIM, USD, INDEX_TYPE, BUFFER_TYPE > > && views ):
m_dims{ views[ 0 ].m_dims },
m_strides{ views[ 0 ].m_strides }
{
// Error checking
for( int i = 0; i < NARRAYS; ++i )
{
m_dataBuffers[ i ] = std::move( views[ i ].m_dataBuffer );
}
}
inline LVARRAY_HOST_DEVICE constexpr
ArraySlice< T, NDIM, USD, INDEX_TYPE >
toSlice( int const i ) const & noexcept
{ return ArraySlice< T, NDIM, USD, INDEX_TYPE >( m_dataBuffers[ i ].data(), m_dims.data, m_strides.data ); }
private:
CArray< INDEX_TYPE, NDIM > m_dims;
CArray< INDEX_TYPE, NDIM > m_strides;
CArray< BUFFER_TYPE< T >, NARRAYS > m_dataBuffers;
};
Would need to be a bit more complicated to ensure the same copy-semantics as ArrayView
.
With a little work it could be extended to support views with different types, which would be necessary if you want to mix T
with T const
.
Usage would look something like
void foo( ArrayView2d< int > const & xIn, ArrayView2d< int > const & yIn )
{
MultiView2d< 2, int > const multiView( { xIn, yIn } );
forAll< POLICY >( xIn.size( 0 ), [multiView] ( int const i )
{
ArraySlice2d< int > const x = multiView.toSlice( 0 );
ArraySlice2d< int > const y = multiView.toSlice( 1 );
bar( x, y );
} );
}
for( int i = 0; i < NDIM; ++i ) { m_dataBuffers[ i ] = std::move( views[ i ].m_dataBuffer ); }
}
That should be??
for( int i = 0; i < NARRAYS; ++i )
{
m_dataBuffers[ i ] = std::move( views[ i ].m_dataBuffer );
}
Looks pretty straight forward. The combination of different T
would be essential to general usage....which would make it much less straight forward I guess.
Nice catch, fixed.
Yeah internally it would be a bit more complicated using a tuple
instead of an array
for m_dataBuffers
. The usage would be pretty much the same. You'd have to call toSlice< 0 >()
instead of toSlice( 0 )
, but that's fine. As for construction we could create a
template< int NDIM, int USD, typename INDEX_TYPE, template< typename > class BUFFER_TYPE, typename ... TYPES >
MultiView<...> createMultiView( ArrayView< TYPES, NDIM, USD, INDEX_TYPE, BUFFER_TYPE > const & ... views );
So that users could just do
void foo( ArrayView2d< int > const & xIn, ArrayView2d< double > const & yIn )
{
auto const multiView = createMultiView( x, y );
...
}
OK. that looks nice. I guess we don't need anything to help with the creation of the multi view as the createMultiView
is pretty simple...but we can add a variadic macro to ease the definition of all the slices.