ttg 1.0.0
Template Task Graph (TTG): flowgraph-based programming model for high-performance distributed-memory algorithms
Loading...
Searching...
No Matches
callable.h
Go to the documentation of this file.
1// SPDX-License-Identifier: BSD-3-Clause
2//
3// Created by Eduard Valeyev on 3/1/22.
4//
5
6#ifndef TTG_META_CALLABLE_H
7#define TTG_META_CALLABLE_H
8
9#include "ttg/util/meta.h"
10#include "ttg/util/typelist.h"
11
12#ifdef TTG_USE_BUNDLED_BOOST_CALLABLE_TRAITS
14#else
16#endif
17
18namespace ttg::meta {
19
21 // nongeneric callables
23 // handled using Boost.CallableTraits ... to detect whether a callable is generic or not detect existence of
24 // boost::callable_traits::args_t
25 template <typename Callable, typename = void>
26 struct is_generic_callable : std::true_type {};
27
28 template <typename Callable>
29 struct is_generic_callable<Callable, ttg::meta::void_t<boost::callable_traits::args_t<Callable, ttg::typelist>>>
30 : std::false_type {};
31
32 template <typename Callable>
34
44 template <typename Callable, typename Enabler = void>
45 constexpr std::pair<bool, std::pair<ttg::typelist<>, ttg::typelist<>>> callable_args = {true, {}};
46
47 template <typename Callable>
49 std::pair<bool, std::pair<ttg::typelist<boost::callable_traits::return_type_t<Callable>>,
51
53 // generic callables
55
57
61 template <std::size_t N>
62 constexpr auto ordinal2index(std::size_t ordinal, std::array<std::size_t, N> extents) {
63 std::array<std::size_t, N> idx = {};
64 for (size_t d = 0; d < N; ++d) {
65 idx[d] = ordinal % extents[d];
66 ordinal /= extents[d];
67 }
68 return idx;
69 }
70
84 template <std::size_t Ordinal, typename Func, typename... Typelists, std::size_t... ArgIdx>
86 std::index_sequence<ArgIdx...> arg_idx = {}) {
88 constexpr auto Order = sizeof...(Typelists);
89 constexpr std::array<std::size_t, Order> extents = {
90 std::tuple_size_v<std::tuple_element_t<ArgIdx, arg_typelists_t>>...};
91 constexpr auto tensor_size = (extents[ArgIdx] * ...);
92 static_assert(tensor_size >= Ordinal);
93 if constexpr (tensor_size == Ordinal) {
95 } else {
96 constexpr auto idx = ordinal2index(Ordinal, extents);
98 using args_sans_void_t = drop_void_t<decltype(args)>;
101 return ttg::typelist<ttg::typelist<return_type>, decltype(args)>{};
102 } else {
104 }
105 }
106 }
107
122 template <std::size_t Ordinal, typename ReturnType, typename Func, typename... Typelists, std::size_t... ArgIdx>
124 std::index_sequence<ArgIdx...> arg_idx = {}) {
126 constexpr auto Order = sizeof...(Typelists);
127 constexpr std::array<std::size_t, Order> extents = {
128 std::tuple_size_v<std::tuple_element_t<ArgIdx, arg_typelists_t>>...};
129 constexpr auto tensor_size = (extents[ArgIdx] * ...);
130 static_assert(tensor_size >= Ordinal);
131 if constexpr (tensor_size == Ordinal) {
132 return typelist<>{};
133 } else {
134 constexpr auto idx = ordinal2index(Ordinal, extents);
136 if constexpr (is_invocable_typelist_r_v<ReturnType, Func, drop_void_t<decltype(args)>>) {
137 return args;
138 } else {
140 }
141 }
142 }
143
154 template <typename Func, typename... Typelists>
156 constexpr auto is_generic__args = callable_args<Func&>;
157 constexpr bool is_generic = is_generic__args.first;
158 if constexpr (is_generic) {
160 std::make_index_sequence<sizeof...(Typelists)>{});
161 } else {
162 return is_generic__args.second;
163 }
164 }
165
175 template <typename ReturnType, typename Func, typename... Typelists>
177 constexpr auto is_generic__args = callable_args<Func&>;
178 constexpr bool is_generic = is_generic__args.first;
179 if constexpr (is_generic) {
181 std::make_index_sequence<sizeof...(Typelists)>{});
182 } else {
183 return is_generic__args.second.second;
184 }
185 }
186
189 template <typename T, typename = void>
191
192 template <typename T>
193 struct candidate_argument_bindings<T, std::enable_if_t<!std::is_reference_v<T> && !std::is_void_v<T>>> {
194 using type = std::conditional_t<std::is_const_v<T>, typelist<const T&>,
195 typelist<
196 // RATIONALE for this order of binding detection tries:
197 // - to be able to distinguish arguments declared as auto& vs auto&& should try
198 // binding to T&& first since auto& won't bind to it
199 // - HOWEVER argument declared as const T& will bind to either T&& or const T&,
200 // so this order will detect such argument as binding to T&&, which will
201 // indicate to the runtime that the argument is CONSUMABLE and may cause
202 // creation of extra copies. Thus you should not try to use nongeneric
203 // data arguments in generic task functions; for purely nongeneric functions
204 // a different introspection mechanism (Boost.CallableTraits) is used
205 T&&, const T&
206 // - no need to check T& since auto& and auto&& both bind to it
207 //, T&
208 >>;
209 };
210
211 template <>
215
216 template <>
220
221 template <typename T>
223} // namespace ttg::meta
224
225#endif // TTG_META_CALLABLE_H
detail::try_but_fail_if_invalid< typename detail::traits< detail::shallow_decay< T > >::template expand_args< Container >, cannot_expand_the_parameter_list_of_first_template_argument > args_t
Definition args.hpp:29
STL namespace.
auto compute_arg_binding_types_r(Func &func, typelist< Typelists... > argument_type_lists)
Definition callable.h:176
auto compute_arg_binding_types_impl(Func &func, typelist< Typelists... > argument_type_lists, std::index_sequence< ArgIdx... > arg_idx={})
Definition callable.h:85
auto compute_arg_binding_types(Func &func, typelist< Typelists... > argument_type_lists)
Definition callable.h:155
constexpr std::pair< bool, std::pair< ttg::typelist<>, ttg::typelist<> > > callable_args
Definition callable.h:45
void void_t
Definition meta.h:21
constexpr bool is_generic_callable_v
Definition callable.h:33
constexpr auto ordinal2index(std::size_t ordinal, std::array< std::size_t, N > extents)
Definition callable.h:62
auto compute_arg_binding_types_r_impl(Func &func, typelist< Typelists... > argument_type_lists, std::index_sequence< ArgIdx... > arg_idx={})
Definition callable.h:123
typename candidate_argument_bindings< T >::type candidate_argument_bindings_t
Definition callable.h:222
constexpr auto get(typelist< T, RestOfTs... >)
Definition typelist.h:102
top-level TTG namespace contains runtime-neutral functionality
Definition keymap.h:9
std::conditional_t< std::is_const_v< T >, typelist< const T & >, typelist< T &&, const T & > > type
Definition callable.h:208
A container for types.
Definition typelist.h:25