42 #ifndef TPETRA_WITHLOCALACCESS_HPP
43 #define TPETRA_WITHLOCALACCESS_HPP
45 #include "TpetraCore_config.h"
46 #include "Tpetra_Access.hpp"
48 #include <type_traits>
61 template<
class T>
struct is_access_mode :
public std::false_type {};
62 template<>
struct is_access_mode<Access::ReadOnly> :
public std::true_type {};
63 template<>
struct is_access_mode<Access::ReadWrite> :
public std::true_type {};
64 template<>
struct is_access_mode<Access::WriteOnly> :
public std::true_type {};
72 template<
class GlobalObjectType>
74 using type =
typename GlobalObjectType::device_type::memory_space;
77 static type space (
const GlobalObjectType& ) {
91 template<
class GlobalObjectType>
93 using type =
typename GlobalObjectType::device_type::execution_space;
96 static type space (
const GlobalObjectType& ) {
104 #ifndef DOXYGEN_SHOULD_SKIP_THIS
105 template<
class GlobalObjectType,
class ... Args>
107 #endif // DOXYGEN_SHOULD_SKIP_THIS
126 template<
class LocalAccessType>
147 template<
class LocalAccessType>
149 master_local_object_type
178 template<
class LocalAccessType>
191 template<
class LocalAccessType>
193 nonowning_local_object_type
196 master_local_object_type& master)
199 return impl_type::get(LA, master);
217 template<
class LocalAccessType>
219 typename Details::GetNonowningLocalObject<LocalAccessType>::
220 nonowning_local_object_type;
229 template<
class GlobalObjectType>
238 template<
class GlobalObjectType>
246 template<
class GlobalObjectType>
254 template<
class GlobalObjectType>
276 template<
class ... Args>
290 template<
class ... Rest>
291 struct LocalAccessTraits<unspecified_type, Rest...> {
293 using rest_type = LocalAccessTraits<Rest...>;
295 using execution_space =
typename rest_type::execution_space;
296 using memory_space =
typename rest_type::memory_space;
297 using access_mode =
typename rest_type::access_mode;
300 template<
class First,
class ... Rest>
301 struct LocalAccessTraits<First, Rest...> {
303 using rest_type = LocalAccessTraits<Rest...>;
305 using execution_space =
typename std::conditional<
306 Kokkos::Impl::is_execution_space<First>::value,
308 typename rest_type::execution_space>::type;
309 using memory_space =
typename std::conditional<
310 Kokkos::Impl::is_memory_space<First>::value,
312 typename rest_type::memory_space>::type;
313 using access_mode =
typename std::conditional<
314 is_access_mode<First>::value,
316 typename rest_type::access_mode>::type;
319 template<
class GlobalObjectType,
321 bool is_execution_space_specified = ! std::is_same<
322 typename Traits::execution_space,
323 unspecified_type>::value,
324 bool is_memory_space_specified = ! std::is_same<
325 typename Traits::memory_space,
326 unspecified_type>::value>
327 struct SpaceTypes {};
329 template<
class GlobalObjectType,
class Traits>
330 struct SpaceTypes<GlobalObjectType, Traits, true, true> {
331 using execution_space =
typename Traits::execution_space;
332 using memory_space =
typename Traits::memory_space;
337 template<
class GlobalObjectType,
class Traits>
338 struct SpaceTypes<GlobalObjectType, Traits, false, true> {
339 using execution_space =
340 typename Traits::memory_space::execution_space;
341 using memory_space =
typename Traits::memory_space;
346 template<
class GlobalObjectType,
class Traits>
347 struct SpaceTypes<GlobalObjectType, Traits, true, false> {
348 using execution_space =
typename Traits::execution_space;
350 typename Traits::execution_space::memory_space;
356 template<
class GlobalObjectType,
class Traits>
357 struct SpaceTypes<GlobalObjectType, Traits, false, false> {
358 using execution_space =
359 typename DefaultExecutionSpace<GlobalObjectType>::type;
361 typename DefaultMemorySpace<GlobalObjectType>::type;
431 template<
class GlobalObjectType,
class ... Args>
436 static constexpr
bool is_execution_space_specified =
437 ! std::is_same<
typename traits::execution_space,
439 static constexpr
bool is_memory_space_specified =
440 ! std::is_same<
typename traits::memory_space,
442 static constexpr
bool is_access_mode_specified =
443 ! std::is_same<
typename traits::access_mode,
445 static_assert(is_access_mode_specified,
"LocalAccess requires "
446 "that you specify the access mode. You may do this by "
447 "always starting construction of a LocalAccess instance "
448 "with readOnly, writeOnly, or readWrite.");
451 using global_object_type = GlobalObjectType;
453 using execution_space =
454 typename SpaceTypes<global_object_type, traits>::execution_space;
455 static_assert(! is_execution_space_specified ||
456 Kokkos::Impl::is_execution_space<execution_space>::value,
457 "Specified execution space is not a Kokkos execution space.");
458 static_assert(is_execution_space_specified ||
459 Kokkos::Impl::is_execution_space<execution_space>::value,
460 "Default execution space is not a Kokkos execution space.");
463 typename SpaceTypes<global_object_type, traits>::memory_space;
464 static_assert(! is_memory_space_specified ||
465 Kokkos::Impl::is_memory_space<memory_space>::value,
466 "Specified memory space is not a Kokkos memory space.");
467 static_assert(is_memory_space_specified ||
468 Kokkos::Impl::is_memory_space<memory_space>::value,
469 "Default memory space is not a Kokkos memory space.");
471 using access_mode =
typename traits::access_mode;
489 const execution_space& execSpace,
490 const memory_space& memSpace,
491 const bool viewIsValid =
true) :
501 const bool viewIsValid =
true) :
512 const execution_space& execSpace,
513 const bool viewIsValid =
true) :
524 const memory_space& memSpace,
525 const bool viewIsValid =
true) :
561 valid (
const bool thisIsValid)
const {
568 template<
class NewMemorySpace>
569 typename std::conditional<
570 is_execution_space_specified,
572 NewMemorySpace, access_mode>,
575 on(
const NewMemorySpace& memSpace)
const {
576 using Kokkos::Impl::is_memory_space;
577 static_assert(is_memory_space<NewMemorySpace>::value,
578 "NewMemorySpace must be a Kokkos memory space.");
582 using alt_execution_space =
583 typename LocalAccess<global_object_type, NewMemorySpace,
584 access_mode>::execution_space;
585 auto execSpace = Kokkos::Impl::if_c<
586 is_execution_space_specified,
588 alt_execution_space>::select(
590 alt_execution_space());
591 return {
G_, execSpace, memSpace,
isValid()};
596 template<
class NewExecutionSpace>
597 typename std::conditional<
598 is_memory_space_specified,
600 memory_space, access_mode>,
603 at(
const NewExecutionSpace& execSpace)
const {
604 using Kokkos::Impl::is_execution_space;
605 static_assert(is_execution_space<NewExecutionSpace>::value,
606 "NewExecutionSpace must be a Kokkos execution space.");
610 using alt_memory_space =
611 typename LocalAccess<global_object_type, NewExecutionSpace,
612 access_mode>::memory_space;
613 auto memSpace = Kokkos::Impl::if_c<
614 is_memory_space_specified,
616 alt_memory_space>::select(
619 return {
G_, execSpace, memSpace,
isValid()};
628 global_object_type&
G_;
653 template<
class GlobalObjectType>
662 template<
class GlobalObjectType>
663 Details::LocalAccess<
668 GlobalObjectType& G_nc =
const_cast<GlobalObjectType&
> (G);
672 template<
class GlobalObjectType>
673 Details::LocalAccess<
681 template<
class GlobalObjectType>
682 Details::LocalAccess<
706 template<
class ...>
struct cons;
709 template<
class T,
template <
class ...>
class List>
710 struct cons<T, List<>> {
711 using type = List<T>;
715 template <
class T,
template <
class ...>
class List,
class ...Types>
716 struct cons<T, List<Types...>>
718 typedef List<T, Types...> type;
731 struct tuple_to_function_type { };
733 template<
typename... Ts>
734 struct tuple_to_function_type<std::tuple<Ts...> >
736 using type = std::function<void (Ts...)>;
742 template<
class ... Args>
743 struct ArgsToFunction {};
746 struct ArgsToFunction<> {
747 using arg_list_type = std::tuple<>;
750 using type = std::function<void ()>;
753 template<
class FirstLocalAccessType,
class ... Rest>
754 struct ArgsToFunction<FirstLocalAccessType, Rest...> {
755 using head_arg_type =
756 with_local_access_function_argument_type<FirstLocalAccessType>;
757 using tail_arg_list_type =
758 typename ArgsToFunction<Rest...>::arg_list_type;
759 using arg_list_type =
760 typename cons<head_arg_type, tail_arg_list_type>::type;
763 using type =
typename tuple_to_function_type<arg_list_type>::type;
770 template<
class ... LocalAccessTypes>
772 using current_user_function_type =
773 typename ArgsToFunction<LocalAccessTypes...>::type;
776 withLocalAccess (LocalAccessTypes...,
777 typename ArgsToFunction<LocalAccessTypes...>::type);
785 using current_user_function_type =
786 typename ArgsToFunction<>::type;
789 withLocalAccess (current_user_function_type userFunction)
799 template<
class FirstLocalAccessType>
801 using current_user_function_type =
802 typename ArgsToFunction<FirstLocalAccessType>::type;
805 withLocalAccess (current_user_function_type userFunction,
806 FirstLocalAccessType first)
841 userFunction (first_lcl_view);
852 template<
class FirstLocalAccessType,
class ... Rest>
854 using current_user_function_type =
855 typename ArgsToFunction<FirstLocalAccessType, Rest...>::type;
858 withLocalAccess (current_user_function_type userFunction,
859 FirstLocalAccessType first,
895 userFunction (first_lcl_view, args...);
938 template<
class ... LocalAccessTypes>
941 (
typename Details::ArgsToFunction<LocalAccessTypes...>::type userFunction,
942 LocalAccessTypes... localAccesses)
950 #endif // TPETRA_WITHLOCALACCESS_HPP
Mapping from "master" local object type to the nonowning "local view" type that users see (as argumen...
bool valid_
Will I actually need to access this object?
memory_space getMemorySpace() const
Memory space instance, on which the user will access local data.
Declaration of access intent for a global object.
LocalAccess(global_object_type &G, const bool viewIsValid=true)
Constructor that specifies the global object and (optionally) whether it is valid.
global_object_type & G_
Reference to the global object whose data the user will access.
Details::LocalAccess< GlobalObjectType, Access::WriteOnly > writeOnly(GlobalObjectType &)
Declare that you want to access the given global object's local data in write-only mode...
Details::LocalAccess< GlobalObjectType, Access::ReadWrite > readWrite(GlobalObjectType &)
Declare that you want to access the given global object's local data in read-and-write mode...
this_type valid(const bool thisIsValid) const
Declare at run time whether you actually want to access the object.
std::conditional< is_memory_space_specified, LocalAccess< global_object_type, NewExecutionSpace, memory_space, access_mode >, LocalAccess< global_object_type, NewExecutionSpace, access_mode > >::type at(const NewExecutionSpace &execSpace) const
Declare intent to access this object's local data at a specific (Kokkos) execution space (instance)...
LocalAccess(global_object_type &G, const execution_space &execSpace, const memory_space &memSpace, const bool viewIsValid=true)
Constructor that specifies the global object, the execution memory space instance on which to view it...
GetNonowningLocalObject< LocalAccessType >::nonowning_local_object_type getNonowningLocalObject(LocalAccessType LA, const typename GetMasterLocalObject< LocalAccessType >::master_local_object_type &master)
Given a master local object, get an instance of a nonowning local object.
Implementation of withLocalAccess.
LocalAccess(global_object_type &G, const execution_space &execSpace, const bool viewIsValid=true)
Constructor that specifies the global object, the execution space instance at which to view its local...
execution_space execSpace_
Execution space instance, with which the user will access local data.
GetMasterLocalObject< LocalAccessType >::master_local_object_type getMasterLocalObject(LocalAccessType LA)
Given a LocalAccess instance (which has a reference to a global object), get an instance of its maste...
Deduce types from parameter pack of LocalAccess.
void withLocalAccess(typename Details::ArgsToFunction< LocalAccessTypes...>::type userFunction, LocalAccessTypes...localAccesses)
Get access to a Tpetra global object's local data.
Tag indicating an unspecified type in LocalAccessTraits.
LocalAccess(global_object_type &G, const memory_space &memSpace, const bool viewIsValid=true)
Constructor that specifies the global object, the memory space instance on which to view its local da...
memory_space memSpace_
Memory space instance, on which the user will access local data.
Details::LocalAccess< GlobalObjectType, Access::ReadOnly > readOnly(GlobalObjectType &)
Declare that you want to access the given global object's local data in read-only mode...
Given a global object, get its default execution space (both the type and the default instance thereo...
bool isValid() const
Is access supposed to be valid?
std::conditional< is_execution_space_specified, LocalAccess< global_object_type, execution_space, NewMemorySpace, access_mode >, LocalAccess< global_object_type, NewMemorySpace, access_mode > >::type on(const NewMemorySpace &memSpace) const
Declare intent to access this object's local data on a specific (Kokkos) memory space (instance)...
typename Details::GetNonowningLocalObject< LocalAccessType >::nonowning_local_object_type with_local_access_function_argument_type
Type of the local object, that is an argument to the function the user gives to withLocalAccess.
Given a global object, get its default memory space (both the type and the default instance thereof)...
Mapping from LocalAccess to the "master" local object type.
execution_space getExecutionSpace() const
Execution space instance, at which the user will access local data.