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

Rank 1 custom layouts don't work as expected. #2840

Closed
jeffmiles63 opened this issue Mar 5, 2020 · 1 comment
Closed

Rank 1 custom layouts don't work as expected. #2840

jeffmiles63 opened this issue Mar 5, 2020 · 1 comment
Assignees
Labels
Bug Broken / incorrect code; it could be Kokkos' responsibility, or others’ (e.g., Trilinos)

Comments

@jeffmiles63
Copy link
Contributor

consider the following example:

#include <limits>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <sys/time.h>

#include <Kokkos_Core.hpp>
#define OFFSET_LIST_MAX_SIZE 100
//----------------------------------------------------------------------------
namespace Kokkos {
struct LayoutSelective {
  //! Tag this class as a kokkos array layout
  typedef LayoutSelective array_layout;

  size_t offset_list[OFFSET_LIST_MAX_SIZE];
  size_t list_size;

  enum { is_extent_constructible = false };

  LayoutSelective() {
     for (int i = 0; i < OFFSET_LIST_MAX_SIZE; i++) {
        offset_list[i] = i;
     }  
  }
  LayoutSelective(LayoutSelective const& rhs)  {   
     list_size = rhs.list_size;
     for (int i = 0; i < list_size; i++) {
        offset_list[i] = rhs.offset_list[i];
     }  
  }
  LayoutSelective(LayoutSelective&&)      = default;
  LayoutSelective& operator=(LayoutSelective const&) = default;
  LayoutSelective& operator=(LayoutSelective&&) = default;


  KOKKOS_INLINE_FUNCTION
  explicit LayoutSelective(const size_t ol_ [], const size_t size_) {
     list_size = size_;
     for (int i = 0; i < list_size; i++) {
        offset_list[i] = ol_[i];
     }  
  }

  size_t offset( size_t ndx ) const {
     KOKKOS_ASSERT( ndx >= 0 && ndx < list_size);
     return offset_list[ndx];
  }
};

namespace Impl {
template <class Dimension>
struct ViewOffset<Dimension, Kokkos::LayoutSelective, void> {
 public:
  using is_mapping_plugin = std::true_type;
  using is_regular        = std::false_type;

  typedef size_t size_type;
  typedef Dimension dimension_type;
  typedef Kokkos::LayoutSelective array_layout;

  //----------------------------------------
  dimension_type m_dim;
  array_layout m_selective;

  // rank 1
  template <typename I0>
  KOKKOS_INLINE_FUNCTION constexpr size_type operator()(I0 const& i0) const {
    return m_selective.offset(i0);
  }
 
  // This ViewOffset and the underlying layout only supports rank 1 Views

  //----------------------------------------

  KOKKOS_INLINE_FUNCTION
  constexpr array_layout layout() const {
    return array_layout();
  }

  KOKKOS_INLINE_FUNCTION constexpr size_type dimension_0() const {
    return m_dim.N0;
  }
  
  /* Cardinality of the domain index space */
  KOKKOS_INLINE_FUNCTION
  constexpr size_type size() const {
    return m_dim.N0;
  }

 public:
  /* Span of the range space, largest stride * dimension */
  KOKKOS_INLINE_FUNCTION
  constexpr size_type span() const {
    return m_dim.N0;
  }

  KOKKOS_INLINE_FUNCTION constexpr bool span_is_contiguous() const {
    return false;
  }

  /* Strides of dimensions */
  KOKKOS_INLINE_FUNCTION constexpr size_type stride_0() const {
    return 1;
  }

  // Stride with [ rank ] value is the total length
  template <typename iType>
  KOKKOS_INLINE_FUNCTION void stride(iType* const s) const {
    if (0 < dimension_type::rank) {
      s[0] = 1;
    }
    for (int i = 1; i < 8; i++) s[i] = 0;
    s[dimension_type::rank] = span();
  }

  //----------------------------------------
  ViewOffset()                  {
     printf("constructing empty offset\n");
  }
  ViewOffset(const ViewOffset&) = default;
  ViewOffset& operator=(const ViewOffset&) = default;

  ViewOffset(std::integral_constant<unsigned, 0> const&,
             Kokkos::LayoutSelective const& rhs)
      : m_dim(rhs.list_size, 0, 0, 0, 0, 0, 0, 0),
        m_selective(rhs) {
      printf("constructing new offset: %d \n", rhs.list_size);
   }
};

} // namespace Impl
} // namespace Kokkos

class InnerClass {
public:
  double data[100];

  InnerClass() {
    for (int i = 0; i < 100; i++) {
        data[i] = (double)i;
     }
  }
  void update( double d ) {
     for (int i = 0; i < 100; i++) {
        data[i] += d;
     }
  }

};

  typedef Kokkos::LayoutRight  Layout;
  typedef Kokkos::LayoutSelective  SubLayout;

  // Allocate y, x vectors and Matrix A on device.
  typedef Kokkos::View<InnerClass*, Layout>   ViewVectorType;
  typedef Kokkos::View<InnerClass*, SubLayout, Kokkos::MemoryUnmanaged>   SubViewVectorType;

int main( int argc, char* argv[] )
{
  Kokkos::initialize( argc, argv );
  {
     ViewVectorType a("a", 100);
     for (int i = 0; i < 100; i++) {
        a(i).update((double)i);
     }
     size_t offsets [] = {20,40};
     SubLayout sl(offsets, 2);
     SubViewVectorType b(a.data(), sl ); 
    
     printf("b0 value at 16: %g a20 at 16: %g \n", b(0).data[16], a(20).data[16]);
     printf("b1 value at 16: %g a40 at 16: %g \n", b(1).data[16], a(40).data[16]);
     printf("a20 prt: %lx b20 ptr: %lx \n", (unsigned long)(a(20).data), (unsigned long)(b(0).data));

  }
  Kokkos::finalize();

  return 0;
}

This doesn't work because the ViewMapping function reference_type reference( I0 i0 ); skips the offset and goes straight to the handle if the layout isn't LayoutStride. These templates should also look offset_type::is_regular to make this decision because an irregular layout needs to use the offset to get the proper index.

@jeffmiles63
Copy link
Contributor Author

PR #2841 has proposed fix

@crtrott crtrott added Bug Broken / incorrect code; it could be Kokkos' responsibility, or others’ (e.g., Trilinos) InDevelop labels Jul 3, 2020
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Bug Broken / incorrect code; it could be Kokkos' responsibility, or others’ (e.g., Trilinos)
Projects
None yet
Development

No branches or pull requests

4 participants