Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

MultiView #229

Open
corbett5 opened this issue Apr 1, 2021 · 3 comments
Open

MultiView #229

corbett5 opened this issue Apr 1, 2021 · 3 comments

Comments

@corbett5
Copy link
Collaborator

corbett5 commented Apr 1, 2021

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 );
  } );
}
@rrsettgast
Copy link
Member

rrsettgast commented Apr 1, 2021

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.

@corbett5
Copy link
Collaborator Author

corbett5 commented Apr 1, 2021

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 );
  ...
}

@rrsettgast
Copy link
Member

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.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

2 participants