42 #ifndef TPETRA_WITHLOCALACCESS_HPP
43 #define TPETRA_WITHLOCALACCESS_HPP
45 #include "TpetraCore_config.h"
47 #include <type_traits>
76 template<const EAccess accessMode>
86 template<
class T>
struct is_access_mode :
public std::false_type {};
88 struct is_access_mode<Access<am>> :
public std::true_type {};
90 using read_only = Access<EAccess::ReadOnly>;
91 using write_only = Access<EAccess::WriteOnly>;
92 using read_write = Access<EAccess::ReadWrite>;
100 template<
class GlobalObjectType>
102 using type =
typename GlobalObjectType::device_type::memory_space;
105 static type space (
const GlobalObjectType& ) {
119 template<
class GlobalObjectType>
121 using type =
typename GlobalObjectType::device_type::execution_space;
124 static type space (
const GlobalObjectType& ) {
132 #ifndef DOXYGEN_SHOULD_SKIP_THIS
133 template<
class GlobalObjectType,
class ... Args>
135 #endif // DOXYGEN_SHOULD_SKIP_THIS
154 template<
class LocalAccessType>
175 template<
class LocalAccessType>
177 master_local_object_type
206 template<
class LocalAccessType>
219 template<
class LocalAccessType>
221 nonowning_local_object_type
224 master_local_object_type& master)
227 return impl_type::get(LA, master);
245 template<
class LocalAccessType>
247 typename Details::GetNonowningLocalObject<LocalAccessType>::
248 nonowning_local_object_type;
257 template<
class GlobalObjectType>
266 template<
class GlobalObjectType>
274 template<
class GlobalObjectType>
282 template<
class GlobalObjectType>
304 template<
class ... Args>
318 template<
class ... Rest>
319 struct LocalAccessTraits<unspecified_type, Rest...> {
321 using rest_type = LocalAccessTraits<Rest...>;
323 using execution_space =
typename rest_type::execution_space;
324 using memory_space =
typename rest_type::memory_space;
325 using access_mode =
typename rest_type::access_mode;
328 template<
class First,
class ... Rest>
329 struct LocalAccessTraits<First, Rest...> {
331 using rest_type = LocalAccessTraits<Rest...>;
333 using execution_space =
typename std::conditional<
334 Kokkos::Impl::is_execution_space<First>::value,
336 typename rest_type::execution_space>::type;
337 using memory_space =
typename std::conditional<
338 Kokkos::Impl::is_memory_space<First>::value,
340 typename rest_type::memory_space>::type;
341 using access_mode =
typename std::conditional<
342 is_access_mode<First>::value,
344 typename rest_type::access_mode>::type;
347 template<
class GlobalObjectType,
349 bool is_execution_space_specified = ! std::is_same<
350 typename Traits::execution_space,
351 unspecified_type>::value,
352 bool is_memory_space_specified = ! std::is_same<
353 typename Traits::memory_space,
354 unspecified_type>::value>
355 struct SpaceTypes {};
357 template<
class GlobalObjectType,
class Traits>
358 struct SpaceTypes<GlobalObjectType, Traits, true, true> {
359 using execution_space =
typename Traits::execution_space;
360 using memory_space =
typename Traits::memory_space;
365 template<
class GlobalObjectType,
class Traits>
366 struct SpaceTypes<GlobalObjectType, Traits, false, true> {
367 using execution_space =
368 typename Traits::memory_space::execution_space;
369 using memory_space =
typename Traits::memory_space;
374 template<
class GlobalObjectType,
class Traits>
375 struct SpaceTypes<GlobalObjectType, Traits, true, false> {
376 using execution_space =
typename Traits::execution_space;
378 typename Traits::execution_space::memory_space;
384 template<
class GlobalObjectType,
class Traits>
385 struct SpaceTypes<GlobalObjectType, Traits, false, false> {
386 using execution_space =
387 typename DefaultExecutionSpace<GlobalObjectType>::type;
389 typename DefaultMemorySpace<GlobalObjectType>::type;
459 template<
class GlobalObjectType,
class ... Args>
464 static constexpr
bool is_execution_space_specified =
465 ! std::is_same<
typename traits::execution_space,
467 static constexpr
bool is_memory_space_specified =
468 ! std::is_same<
typename traits::memory_space,
470 static constexpr
bool is_access_mode_specified =
471 ! std::is_same<
typename traits::access_mode,
473 static_assert(is_access_mode_specified,
"LocalAccess requires "
474 "that you specify the access mode. You may do this by "
475 "always starting construction of a LocalAccess instance "
476 "with readOnly, writeOnly, or readWrite.");
479 using global_object_type = GlobalObjectType;
481 using execution_space =
482 typename SpaceTypes<global_object_type, traits>::execution_space;
483 static_assert(! is_execution_space_specified ||
484 Kokkos::Impl::is_execution_space<execution_space>::value,
485 "Specified execution space is not a Kokkos execution space.");
486 static_assert(is_execution_space_specified ||
487 Kokkos::Impl::is_execution_space<execution_space>::value,
488 "Default execution space is not a Kokkos execution space.");
491 typename SpaceTypes<global_object_type, traits>::memory_space;
492 static_assert(! is_memory_space_specified ||
493 Kokkos::Impl::is_memory_space<memory_space>::value,
494 "Specified memory space is not a Kokkos memory space.");
495 static_assert(is_memory_space_specified ||
496 Kokkos::Impl::is_memory_space<memory_space>::value,
497 "Default memory space is not a Kokkos memory space.");
499 using access_mode =
typename traits::access_mode;
517 const execution_space& execSpace,
518 const memory_space& memSpace,
519 const bool viewIsValid =
true) :
529 const bool viewIsValid =
true) :
540 const execution_space& execSpace,
541 const bool viewIsValid =
true) :
552 const memory_space& memSpace,
553 const bool viewIsValid =
true) :
589 valid (
const bool thisIsValid)
const {
596 template<
class NewMemorySpace>
597 typename std::conditional<
598 is_execution_space_specified,
600 NewMemorySpace, access_mode>,
603 on(
const NewMemorySpace& memSpace)
const {
604 using Kokkos::Impl::is_memory_space;
605 static_assert(is_memory_space<NewMemorySpace>::value,
606 "NewMemorySpace must be a Kokkos memory space.");
610 using alt_execution_space =
611 typename LocalAccess<global_object_type, NewMemorySpace,
612 access_mode>::execution_space;
613 auto execSpace = Kokkos::Impl::if_c<
614 is_execution_space_specified,
616 alt_execution_space>::select(
618 alt_execution_space());
619 return {
G_, execSpace, memSpace,
isValid()};
624 template<
class NewExecutionSpace>
625 typename std::conditional<
626 is_memory_space_specified,
628 memory_space, access_mode>,
631 at(
const NewExecutionSpace& execSpace)
const {
632 using Kokkos::Impl::is_execution_space;
633 static_assert(is_execution_space<NewExecutionSpace>::value,
634 "NewExecutionSpace must be a Kokkos execution space.");
638 using alt_memory_space =
639 typename LocalAccess<global_object_type, NewExecutionSpace,
640 access_mode>::memory_space;
641 auto memSpace = Kokkos::Impl::if_c<
642 is_memory_space_specified,
644 alt_memory_space>::select(
647 return {
G_, execSpace, memSpace,
isValid()};
656 global_object_type&
G_;
681 template<
class GlobalObjectType>
690 template<
class GlobalObjectType>
691 Details::LocalAccess<
696 GlobalObjectType& G_nc =
const_cast<GlobalObjectType&
> (G);
700 template<
class GlobalObjectType>
701 Details::LocalAccess<
709 template<
class GlobalObjectType>
710 Details::LocalAccess<
734 template<
class ...>
struct cons;
737 template<
class T,
template <
class ...>
class List>
738 struct cons<T, List<>> {
739 using type = List<T>;
743 template <
class T,
template <
class ...>
class List,
class ...Types>
744 struct cons<T, List<Types...>>
746 typedef List<T, Types...> type;
759 struct tuple_to_function_type { };
761 template<
typename... Ts>
762 struct tuple_to_function_type<std::tuple<Ts...> >
764 using type = std::function<void (Ts...)>;
770 template<
class ... Args>
771 struct ArgsToFunction {};
774 struct ArgsToFunction<> {
775 using arg_list_type = std::tuple<>;
778 using type = std::function<void ()>;
781 template<
class FirstLocalAccessType,
class ... Rest>
782 struct ArgsToFunction<FirstLocalAccessType, Rest...> {
783 using head_arg_type =
784 with_local_access_function_argument_type<FirstLocalAccessType>;
785 using tail_arg_list_type =
786 typename ArgsToFunction<Rest...>::arg_list_type;
787 using arg_list_type =
788 typename cons<head_arg_type, tail_arg_list_type>::type;
791 using type =
typename tuple_to_function_type<arg_list_type>::type;
798 template<
class ... LocalAccessTypes>
800 using current_user_function_type =
801 typename ArgsToFunction<LocalAccessTypes...>::type;
804 withLocalAccess (LocalAccessTypes...,
805 typename ArgsToFunction<LocalAccessTypes...>::type);
813 using current_user_function_type =
814 typename ArgsToFunction<>::type;
817 withLocalAccess (current_user_function_type userFunction)
829 template<
class FirstLocalAccessType,
class ... Rest>
831 using current_user_function_type =
832 typename ArgsToFunction<FirstLocalAccessType, Rest...>::type;
835 withLocalAccess (current_user_function_type userFunction,
836 FirstLocalAccessType first,
883 userFunction (first_lcl_view, args...);
926 template<
class ... LocalAccessTypes>
929 (
typename Details::ArgsToFunction<LocalAccessTypes...>::type userFunction,
930 LocalAccessTypes... localAccesses)
938 #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.
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.
Details::LocalAccess< GlobalObjectType, Details::write_only > writeOnly(GlobalObjectType &)
Declare that you want to access the given global object's local data in write-only mode...
Implementation of withLocalAccess.
EAccess
Enum for declaring access intent.
Details::LocalAccess< GlobalObjectType, Details::read_write > readWrite(GlobalObjectType &)
Declare that you want to access the given global object's local data in read-and-write mode...
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.
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?
Tag class for declaring access intent.
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)...
Details::LocalAccess< GlobalObjectType, Details::read_only > readOnly(GlobalObjectType &)
Declare that you want to access the given global object's local data in read-only mode...
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.