ECP-copa / Cabana

Performance-portable library for particle-based simulations
Other
188 stars 51 forks source link

ArborX neighborlist interface compile error #726

Closed streeve closed 4 months ago

streeve commented 4 months ago

Nightly build fails using ArborX master

/__w/Cabana/Cabana/core/unit_test/tstNeighborListArborX.hpp:96:66:   required from here
/github/home/arborx/include/ArborX/details/ArborX_Callbacks.hpp:90:9: error: no type named 'Tag' in 'using Predicate = using value_type = std::decay_t<Kokkos::nonesuch>' {aka 'std::decay<Kokkos::nonesuch>::type'}
   90 |   using PredicateTag = typename Predicate::Tag;
      |         ^~~~~~~~~~~~
/github/home/arborx/include/ArborX/details/ArborX_Callbacks.hpp:99:55: error: no type named 'Tag' in 'using value_type = std::decay_t<Kokkos::nonesuch>' {aka 'std::decay<Kokkos::nonesuch>::type'}
   99 |   static_assert(is_valid_predicate_tag<PredicateTag>::value &&
      |                                                       ^~~~~
streeve commented 4 months ago

@aprokop is this is an easy fix?

aprokop commented 4 months ago

@streeve Where can I see the full log?

streeve commented 4 months ago

https://github.com/ECP-copa/Cabana/actions/runs/7381454600/job/20080001545

aprokop commented 4 months ago

The problem is this part: https://github.com/ECP-copa/Cabana/blob/973e7d0722ddb2503a3c5cb9220410a7666768e4/core/src/Cabana_Experimental_NeighborList.hpp#L99-L100

Users are only allowed to specialize AccessTraits for their own data. As the code in question is templated on any template Slice, it spreads to ArborX internals resulting in a conflict.

The way to fix it is to template on something Cabana. I'm not sure what the general Cabana slice template slice is. Would probably need something like

template<typename... Args>
struct AccessTraits<Cabana::Slice<Args...>

I'm trying it out, but something isn't working right now:

diff --git a/core/src/Cabana_Experimental_NeighborList.hpp b/core/src/Cabana_Experimental_NeighborList.hpp
index a5d9aa3b..52d4e048 100644
--- a/core/src/Cabana_Experimental_NeighborList.hpp
+++ b/core/src/Cabana_Experimental_NeighborList.hpp
@@ -74,13 +74,12 @@ auto makePredicates(
 } // namespace Experimental
 } // namespace Cabana

-namespace ArborX
-{
 //! Neighbor access trait for Cabana slice.
-template <typename Slice>
-struct AccessTraits<Slice, PrimitivesTag,
-                    std::enable_if_t<Cabana::is_slice<Slice>{}>>
+template <typename... Args>
+struct ArborX::AccessTraits<Cabana::Slice<Args...>, ArborX::PrimitivesTag>
 {
+    using Slice = Cabana::Slice<Args...>;
+
     //! Kokkos memory space.
     using memory_space = typename Slice::memory_space;
     //! Size type.
@@ -96,9 +95,12 @@ struct AccessTraits<Slice, PrimitivesTag,
     }
 };
 //! Neighbor access trait.
-template <typename SliceLike>
-struct AccessTraits<SliceLike, PredicatesTag>
+template <typename Slice>
+struct ArborX::AccessTraits<
+    Cabana::Experimental::Impl::SubsliceAndRadius<Slice>, ArborX::PredicatesTag>
 {
+    using SliceLike = Cabana::Experimental::Impl::SubsliceAndRadius<Slice>;
+
     //! Kokkos memory space.
     using memory_space = typename SliceLike::memory_space;
     //! Size type.
@@ -113,12 +115,11 @@ struct AccessTraits<SliceLike, PredicatesTag>
     {
         assert( i < size( x ) );
         auto const point =
-            AccessTraits<typename SliceLike::slice_type, PrimitivesTag>::get(
-                x.slice, x.first + i );
+            AccessTraits<std::decay_t<typename SliceLike::slice_type>,
+                         PrimitivesTag>::get( x.slice, x.first + i );
         return attach( intersects( Sphere{ point, x.radius } ), (int)i );
     }
 };
-} // namespace ArborX

 namespace Cabana
 {
@@ -413,7 +414,7 @@ auto make2DNeighborList( ExecutionSpace space, Tag,
         Impl::makePredicates( coordinate_slice, first, last, radius );

     auto const n_queries =
-        ArborX::AccessTraits<decltype( predicates ),
+        ArborX::AccessTraits<std::decay_t<decltype( predicates )>,
                              ArborX::PredicatesTag>::size( predicates );

     Kokkos::View<int**, memory_space> neighbors;
dalg24 commented 4 months ago

I suppose I should have read this before I opened #728 The predicate access traits are to blame. The primitive ones are fine. Essentially doing the same thing as Andrey. I like better his calling the alias SliceLike rather than Self. The decay_t in the get member function in unnecessary. I went for a remove_const_t for the one computing n_queries but that gives the same thing,