2#ifndef MADNESS_TTG_H_INCLUDED
3#define MADNESS_TTG_H_INCLUDED
6#if !defined(TTG_IMPL_NAME)
7#define TTG_USE_MADNESS 1
48#include <madness/world/MADworld.h>
49#include <madness/world/world_object.h>
50#include <madness/world/worldhashmap.h>
51#include <madness/world/worldtypes.h>
53#include <madness/world/world_task_queue.h>
64 world_ = default_execution_context();
66 Graph(World& w) : world_(w) {}
76 ::madness::World &m_impl;
77 bool m_allocated =
false;
85 :
WorldImplBase(comm.Get_size(), comm.Get_rank()), m_impl(*new ::madness::World(comm)), m_allocated(true) {}
101 virtual void fence_impl(
void)
override { m_impl.gop.fence(); }
120 ::madness::World &
impl() {
return m_impl; }
122 const ::madness::World &
impl()
const {
return m_impl; }
125 parsec_context_t *context() { return ::madness::ThreadPool::instance()->parsec; }
133 ::madness::World &madworld = ::madness::initialize(argc, argv, num_threads,
true);
137 ttg::detail::set_default_world(std::move(world));
141 ttg::detail::destroy_worlds<ttg_madness::WorldImpl>();
142 ::madness::finalize();
154 template <
typename T>
156 world.
impl().register_ptr(ptr);
159 template <
typename T>
161 world.
impl().register_ptr(std::move(ptr));
165 world.
impl().register_status(status_ptr);
168 template <
typename Callback>
170 world.
impl().register_callback(std::forward<Callback>(callback));
175 template <
typename T>
177 world.
impl().impl().gop.sum(value);
181 template <
typename T>
183 world.
impl().impl().gop.broadcast_serializable(data, source_rank);
194 template <
typename keyT,
typename output_terminalsT,
typename derivedT,
typename input_valueTs, ttg::ExecutionSpace Space>
195 class TT :
public ttg::TTBase,
public ::madness::WorldObject<TT<keyT, output_terminalsT, derivedT, input_valueTs, Space>> {
198 "The fourth template for ttg::TT must be a ttg::typelist containing the input types");
201 using actual_input_tuple_type = std::conditional_t<!ttg::meta::typelist_is_empty_v<input_valueTs>,
212 ttg::meta::detail::keymap_t<keyT> keymap;
213 ttg::meta::detail::keymap_t<keyT> priomap;
215 ttg::meta::detail::input_reducers_t<actual_input_tuple_type>
219 std::array<std::size_t, std::tuple_size_v<actual_input_tuple_type>> static_streamsize;
247 static constexpr int numinedges = std::tuple_size_v<input_tuple_type>;
248 static constexpr int numins = std::tuple_size_v<actual_input_tuple_type>;
249 static constexpr int numouts = std::tuple_size_v<output_terminalsT>;
262 "at most one void input can be handled, and it must come last");
279 template <std::
size_t i,
typename resultT,
typename InTuple>
281 return static_cast<resultT>(std::get<i>(std::forward<InTuple>(
intuple)));
283 template <std::
size_t i,
typename InTuple>
285 return std::get<i>(std::forward<InTuple>(
intuple));
296 struct TTArgs : ::madness::TaskInterface {
298 using TaskInterface = ::madness::TaskInterface;
302 std::array<std::int64_t, numins>
307 std::array<std::size_t, numins> stream_size;
311 bool pull_terminals_invoked =
false;
312 std::conditional_t<ttg::meta::is_void_v<keyT>,
ttg::Void,
keyT> key;
313#ifdef TTG_HAVE_COROUTINE
314 void *suspended_task_address =
nullptr;
319 template <
typename Tuple, std::size_t...
Is>
327 return make_input_refs_impl(this->input_values,
328 std::make_index_sequence<std::tuple_size_v<input_values_tuple_type>>{});
337 std::fill(nargs.begin(), nargs.end(), std::numeric_limits<std::int64_t>::max());
340 virtual void run(::madness::World &world)
override {
345 void *suspended_task_address =
346#ifdef TTG_HAVE_COROUTINE
347 this->suspended_task_address;
351 if (suspended_task_address ==
nullptr) {
355 suspended_task_address,
357 derived->op(key,
this->make_input_refs(),
358 derived->output_terminals));
363 suspended_task_address,
365 derived->op(
this->make_input_refs(),
366 derived->output_terminals));
372#ifdef TTG_HAVE_COROUTINE
376 if (
ret.completed()) {
378 suspended_task_address =
nullptr;
382 this->suspended_task_address = suspended_task_address;
394#ifdef TTG_HAVE_COROUTINE
395 if (suspended_task_address) {
415 if (
ret.completed()) {
417 suspended_task_address =
nullptr;
428 ::madness::Spinlock lock_;
430 void lock() { lock_.lock(); }
431 void unlock() { lock_.unlock(); }
434 using hashable_keyT = std::conditional_t<ttg::meta::is_void_v<keyT>,
int,
keyT>;
435 using cacheT = ::madness::ConcurrentHashMap<hashable_keyT, TTArgs *, ttg::hash<hashable_keyT>>;
436 using accessorT =
typename cacheT::accessor;
440 template <
typename terminalT, std::
size_t i,
typename Key>
442 if (
in.is_pull_terminal) {
445 owner =
in.container.owner(key);
450 if (
owner != world.rank()) {
454 auto value = (
in.container).
get(key);
455 if (args->nargs[
i] == 0) {
457 ": error argument is already finalized : ",
i);
458 throw std::runtime_error(
"Op::set_arg called for a finalized stream");
461 if (
typeid(value) !=
typeid(std::nullptr_t) &&
i < std::tuple_size_v<input_values_tuple_type>) {
462 this->
get<
i, std::decay_t<
decltype(value)> &>(args->input_values) = std::forward<decltype(value)>(value);
467 auto value = (
in.container).
get();
468 if (args->nargs[
i] == 0) {
470 ": error argument is already finalized : ",
i);
471 throw std::runtime_error(
"Op::set_arg called for a finalized stream");
474 if (
typeid(value) !=
typeid(std::nullptr_t) &&
i < std::tuple_size_v<input_values_tuple_type>) {
475 this->
get<
i, std::decay_t<
decltype(value)> &>(args->input_values) = std::forward<decltype(value)>(value);
484 template <std::
size_t i,
typename Key>
486 if (
owner != world.rank()) {
489 auto &
in = std::get<i>(input_terminals);
491 auto value = (
in.container).
get(key);
495 auto value = (
in.container).
get();
496 worldobjT::send(keymap(), &
ttT::template set_arg<
i,
void,
const std::remove_reference_t<
decltype(value)> &>,
502 template <std::size_t...
IS,
typename Key =
keyT>
505 std::get<IS>(input_terminals), key, args),
520 template <std::
size_t i,
typename Key,
typename Value>
522 using valueT = std::tuple_element_t<i, input_values_full_tuple_type>;
523 static_assert(std::is_same_v<std::decay_t<Value>, std::decay_t<valueT>>,
524 "TT::set_arg(key,value) given value of type incompatible with TT");
533 if (
owner != world.rank()) {
534 ttg::trace(world.rank(),
":",
get_name(),
" : ", key,
": forwarding setting argument : ",
i);
557 ttg::trace(world.rank(),
":",
get_name(),
" : ", key,
": received value for argument : ",
i);
564 prio = this->priomap(key);
565 if (cache.insert(
acc, key)) {
566 acc->second =
new TTArgs(
prio);
575 prio = this->priomap();
576 if (cache.insert(
acc, 0))
acc->second =
new TTArgs(
prio);
579 TTArgs *args =
acc->second;
582 if (args->nargs[
i] == 0) {
584 throw std::runtime_error(
"TT::set_arg called for a finalized stream");
587 const auto &
reducer = std::get<i>(input_reducers);
594 if (args->nargs[
i] == std::numeric_limits<std::int64_t>::max()) {
602 if (args->stream_size[
i] != 0) {
603 assert(args->stream_size[
i] <=
static_cast<std::size_t
>(std::numeric_limits<std::int64_t>::max()));
604 args->nargs[
i] = args->stream_size[
i];
605 }
else if (static_streamsize[
i] != 0) {
606 assert(static_streamsize[
i] <=
static_cast<std::size_t
>(std::numeric_limits<std::int64_t>::max()));
607 args->stream_size[
i] = static_streamsize[
i];
608 args->nargs[
i] = static_streamsize[
i];
618 reducer(this->
get<
i, std::decay_t<valueT> &>(args->input_values), value);
627 if (args->nargs[
i] == 0) args->counter--;
639 if (
numins - args->counter == num_pullins) {
642 invoke_pull_terminals(std::make_index_sequence<std::tuple_size_v<input_values_tuple_type>>{}, key, args);
647 if (args->counter == 0) {
649 args->derived =
static_cast<derivedT *
>(
this);
660 static_cast<derivedT *
>(
this)->op(key, args->make_input_refs(), output_terminals);
662 static_cast<derivedT *
>(
this)->op(key, output_terminals);
664 static_cast<derivedT *
>(
this)->op(args->make_input_refs(), output_terminals);
666 static_cast<derivedT *
>(
this)->op(output_terminals);
673 world.impl().impl().taskq.add(args);
682 template <std::
size_t i,
typename Key,
typename Value>
683 std::enable_if_t<!ttg::meta::is_void_v<Key> && std::is_void_v<Value>,
void>
set_arg(
const Key &key) {
688 template <std::
size_t i,
typename Key = keyT,
typename Value>
689 std::enable_if_t<ttg::meta::is_void_v<Key> && !std::is_void_v<std::decay_t<Value>>,
void>
set_arg(
Value &&value) {
694 template <std::
size_t i,
typename Key = keyT,
typename Value>
695 std::enable_if_t<ttg::meta::is_void_v<Key> && std::is_void_v<Value>,
void>
set_arg() {
702 template <
typename Key,
typename...
Ts,
size_t...
Is,
size_t...
Js>
703 std::enable_if_t<!ttg::meta::is_void_v<Key>,
void>
set_args(std::index_sequence<Is...>, std::index_sequence<Js...>,
704 const Key &key,
const std::tuple<Ts...> &args) {
705 static_assert(
sizeof...(Js) ==
sizeof...(
Is));
706 constexpr std::size_t
js[] = {
Js...};
713 template <
typename Key,
typename...
Ts,
size_t...
Is>
714 std::enable_if_t<!ttg::meta::is_void_v<Key>,
void>
set_args(std::index_sequence<Is...>
is,
const Key &key,
715 const std::tuple<Ts...> &args) {
716 set_args(std::index_sequence_for<Ts...>{},
is, key, args);
722 template <
typename Key =
keyT,
typename...
Ts,
size_t...
Is,
size_t...
Js>
723 std::enable_if_t<ttg::meta::is_void_v<Key>,
void>
set_args(std::index_sequence<Is...>, std::index_sequence<Js...>,
724 const std::tuple<Ts...> &args) {
725 static_assert(
sizeof...(Js) ==
sizeof...(
Is));
726 constexpr std::size_t
js[] = {
Js...};
733 template <
typename Key =
keyT,
typename...
Ts,
size_t...
Is>
734 std::enable_if_t<ttg::meta::is_void_v<Key>,
void>
set_args(std::index_sequence<Is...>
is,
735 const std::tuple<Ts...> &args) {
736 set_args(std::index_sequence_for<Ts...>{},
is, args);
742 template <std::
size_t i,
bool key_is_
void = ttg::meta::is_
void_v<keyT>>
745 assert(std::get<i>(input_reducers) &&
"TT::set_argstream_size called on nonstreaming input terminal");
746 assert(size > 0 &&
"TT::set_argstream_size(size) called with size=0");
749 const auto owner = keymap();
750 if (
owner != world.rank()) {
754 ttg::trace(world.rank(),
":",
get_name(),
" : setting stream size to ", size,
" for terminal ",
i);
757 if (cache.insert(
acc, 0))
acc->second =
new TTArgs();
758 TTArgs *args =
acc->second;
763 if (args->stream_size[
i] > 0) {
765 throw std::runtime_error(
"TT::set_argstream_size called for a bounded stream");
769 if (args->nargs[
i] == 0) {
771 throw std::runtime_error(
"TT::set_argstream_size called for a finalized stream");
775 args->stream_size[
i] = size;
780 if (-(args->nargs[
i]) > size) {
782 " : error stream received more messages than specified via set_argstream_size : ",
i);
783 throw std::runtime_error(
"TT::set_argstream_size(n): n less than the number of messages already received");
785 args->nargs[
i] += size;
788 if (args->nargs[
i] == 0) args->counter--;
792 if (args->counter == 0) {
794 args->derived =
static_cast<derivedT *
>(
this);
796 world.impl().impl().taskq.add(args);
803 template <std::
size_t i>
805 assert(std::get<i>(input_reducers) &&
"TT::set_argstream_size called on nonstreaming input terminal");
806 assert(size > 0 &&
"TT::set_static_argstream_size(key,size) called with size=0");
808 ttg::trace(world.rank(),
":",
get_name(),
": setting global stream size for terminal ",
i);
811 if (static_streamsize[
i] > 0) {
813 throw std::runtime_error(
"TT::set_static_argstream_size called for a bounded stream");
817 static_streamsize[
i] = size;
824 template <std::
size_t i,
typename Key = keyT,
bool key_is_
void = ttg::meta::is_
void_v<Key>>
827 assert(std::get<i>(input_reducers) &&
"TT::set_argstream_size called on nonstreaming input terminal");
828 assert(size > 0 &&
"TT::set_argstream_size(key,size) called with size=0");
831 const auto owner = keymap(key);
832 if (
owner != world.rank()) {
833 ttg::trace(world.rank(),
":",
get_name(),
" : ", key,
": forwarding stream size for terminal ",
i);
836 ttg::trace(world.rank(),
":",
get_name(),
" : ", key,
": setting stream size for terminal ",
i);
839 if (cache.insert(
acc, key))
acc->second =
new TTArgs(this->priomap(key));
840 TTArgs *args =
acc->second;
845 if (args->stream_size[
i] > 0) {
847 throw std::runtime_error(
"TT::set_argstream_size called for a bounded stream");
851 if (args->nargs[
i] == 0) {
853 throw std::runtime_error(
"TT::set_argstream_size called for a finalized stream");
857 args->stream_size[
i] = size;
862 if (args->nargs[
i] == 0) args->counter--;
867 if (args->counter == 0) {
869 args->derived =
static_cast<derivedT *
>(
this);
872 world.impl().impl().taskq.add(args);
880 template <std::
size_t i,
typename Key = keyT,
bool key_is_
void = ttg::meta::is_
void_v<Key>>
883 assert(std::get<i>(input_reducers) &&
"TT::finalize_argstream called on nonstreaming input terminal");
886 const auto owner = keymap(key);
887 if (
owner != world.rank()) {
888 ttg::trace(world.rank(),
":",
get_name(),
" : ", key,
": forwarding stream finalize for terminal ",
i);
891 ttg::trace(world.rank(),
":",
get_name(),
" : ", key,
": finalizing stream for terminal ",
i);
894 const auto found = cache.find(
acc, key);
895 assert(
found &&
"TT::finalize_argstream called but no values had been received yet for this key");
897 TTArgs *args =
acc->second;
900 if (args->stream_size[
i] > 0) {
902 throw std::runtime_error(
"TT::finalize called for a bounded stream");
906 if (args->nargs[
i] == 0) {
908 throw std::runtime_error(
"TT::finalize called for a finalized stream");
915 if (args->counter == 0) {
917 args->derived =
static_cast<derivedT *
>(
this);
920 world.impl().impl().taskq.add(args);
929 template <std::
size_t i,
bool key_is_
void = ttg::meta::is_
void_v<keyT>>
932 assert(std::get<i>(input_reducers) &&
"TT::finalize_argstream called on nonstreaming input terminal");
935 const int owner = keymap();
936 if (
owner != world.rank()) {
937 ttg::trace(world.rank(),
":",
get_name(),
" : forwarding stream finalize for terminal ",
i);
943 const auto found = cache.find(
acc, 0);
944 assert(
found &&
"TT::finalize_argstream called but no values had been received yet for this key");
946 TTArgs *args =
acc->second;
949 if (args->stream_size[
i] > 0) {
951 throw std::runtime_error(
"TT::finalize called for a bounded stream");
955 if (args->nargs[
i] == 0) {
957 throw std::runtime_error(
"TT::finalize called for a finalized stream");
964 if (args->counter == 0) {
966 args->derived =
static_cast<derivedT *
>(
this);
968 world.impl().impl().taskq.add(args);
992 template <
typename terminalT, std::
size_t i>
994 static_assert(std::is_same_v<keyT, typename terminalT::key_type>,
995 "TT::register_input_callback(terminalT) -- incompatible terminalT");
996 using valueT = std::decay_t<typename terminalT::value_type>;
998 if (
input.is_pull_terminal) {
1006 !std::is_void_v<valueT>) {
1007 auto move_callback = [
this](
const keyT &key,
valueT &&value) {
1010 auto send_callback = [
this](
const keyT &key,
const valueT &value) {
1015 input.set_callback(send_callback, move_callback, {}, setsize_callback, finalize_callback);
1021 !std::is_void_v<valueT>) {
1026 input.set_callback(send_callback, move_callback, {}, setsize_callback, finalize_callback);
1036 input.set_callback(send_callback, send_callback, {}, setsize_callback, finalize_callback);
1046 input.set_callback(send_callback, send_callback, {}, setsize_callback, finalize_callback);
1051 template <std::size_t...
IS>
1052 void register_input_callbacks(std::index_sequence<IS...>) {
1060 template <std::size_t...
IS,
typename inedgesT>
1061 void connect_my_inputs_to_incoming_edge_outputs(std::index_sequence<IS...>,
inedgesT &
inedges) {
1062 static_assert(
sizeof...(IS) == std::tuple_size_v<input_terminals_type>);
1063 static_assert(std::tuple_size_v<inedgesT> == std::tuple_size_v<input_terminals_type>);
1064 int junk[] = {0, (std::get<IS>(
inedges).set_out(&std::get<IS>(input_terminals)), 0)...};
1066 ttg::trace(world.rank(),
":",
get_name(),
" : connected ",
sizeof...(
IS),
" TT inputs to ",
sizeof...(
IS),
1071 void connect_my_outputs_to_outgoing_edge_inputs(std::index_sequence<IS...>,
outedgesT &
outedges) {
1072 static_assert(
sizeof...(IS) ==
numouts);
1073 static_assert(std::tuple_size_v<outedgesT> ==
numouts);
1074 int junk[] = {0, (std::get<IS>(
outedges).set_in(&std::get<IS>(output_terminals)), 0)...};
1076 ttg::trace(world.rank(),
":",
get_name(),
" : connected ",
sizeof...(
IS),
" TT outputs to ",
sizeof...(
IS),
1081 template <
typename keymapT = ttg::detail::default_keymap<keyT>,
1082 typename priomapT = ttg::detail::default_priomap<keyT>>
1083 TT(
const std::string &name,
const std::vector<std::string> &
innames,
const std::vector<std::string> &
outnames,
1086 , static_streamsize()
1098 throw this->
get_name() +
":madness::ttg::TT: #input names != #input terminals";
1100 if (outnames.size() !=
numouts)
throw this->
get_name() +
":madness::ttg::TT: #output names != #output terminals";
1105 register_input_callbacks(std::make_index_sequence<numinedges>{});
1108 template <
typename keymapT = ttg::detail::default_keymap<keyT>,
1109 typename priomapT = ttg::detail::default_priomap<keyT>>
1110 TT(
const std::string &name,
const std::vector<std::string> &
innames,
const std::vector<std::string> &
outnames,
1115 template <
typename keymapT = ttg::detail::default_keymap<keyT>,
1116 typename priomapT = ttg::detail::default_priomap<keyT>>
1121 , static_streamsize()
1122 ,
worldobjT(
ttg::default_execution_context().impl().impl())
1123 , world(
ttg::default_execution_context())
1133 throw this->
get_name() +
":madness::ttg::TT: #input names != #input terminals";
1135 if (outnames.size() !=
numouts)
throw this->
get_name() +
":madness::ttg::T: #output names != #output terminals";
1140 connect_my_inputs_to_incoming_edge_outputs(std::make_index_sequence<numinedges>{},
inedges);
1141 connect_my_outputs_to_outgoing_edge_inputs(std::make_index_sequence<numouts>{},
outedges);
1143 register_input_callbacks(std::make_index_sequence<numinedges>{});
1146 template <
typename keymapT = ttg::detail::default_keymap<keyT>,
1147 typename priomapT = ttg::detail::default_priomap<keyT>>
1149 const std::vector<std::string> &
innames,
const std::vector<std::string> &
outnames,
1156 if (cache.size() != 0) {
1157 std::cerr << world.
rank() <<
":"
1158 <<
"warning: unprocessed tasks in destructor of operation '" <<
get_name()
1160 std::cerr << world.
rank() <<
":"
1161 <<
" T => argument assigned F => argument unassigned" << std::endl;
1163 for (
auto item : cache) {
1165 std::cerr <<
" etc." << std::endl;
1168 using ::madness::operators::operator<<;
1169 std::cerr << world.
rank() <<
":"
1170 <<
" unused: " <<
item.first <<
" : ( ";
1171 for (std::size_t
i = 0;
i <
numins;
i++) std::cerr << (
item.second->nargs[
i] == 0 ?
"T" :
"F") <<
" ";
1172 std::cerr <<
")" << std::endl;
1183 template <std::
size_t i,
typename Reducer>
1186 std::get<i>(input_reducers) =
reducer;
1196 template <std::
size_t i,
typename Reducer>
1202 template <
typename Keymap>
1212 template <
typename Priomap>
1214 priomap = std::forward<Priomap>(
pm);
1219 template<
typename Constra
int>
1224 template<
typename Constra
int,
typename Mapper>
1229 template<
typename Constra
int,
typename Mapper>
1236 TTBase::make_executable();
1249 template <std::
size_t i>
1250 std::tuple_element_t<i, input_terminals_type> *
in() {
1251 return &std::get<i>(input_terminals);
1255 template <std::
size_t i>
1256 std::tuple_element_t<i, output_terminalsT> *
out() {
1257 return &std::get<i>(output_terminals);
1261 template <
typename Key = keyT>
1265 if constexpr(!std::is_same_v<Key, key_type>) {
1278 template <
typename Key = keyT>
1290 template <
typename Key = keyT>
1294 if constexpr(!std::is_same_v<Key, key_type>) {
1305 template <
typename Key = keyT>
1331 template <
typename Key>
1332 std::enable_if_t<!ttg::meta::is_void_v<Key>,
int>
owner(
const Key &key)
const {
1338 template <
typename Key>
1339 std::enable_if_t<ttg::meta::is_void_v<Key>,
int>
owner()
const {
#define TTG_OP_ASSERT_EXECUTABLE()
Edge is used to connect In and Out terminals.
A base class for all template tasks.
std::string get_class_name() const
Gets the demangled class name (uses RTTI)
void register_input_terminals(terminalsT &terms, const namesT &names)
const std::string & get_name() const
Gets the name of this operation.
void register_output_terminals(terminalsT &terms, const namesT &names)
A complete version of void.
Base class for implementation-specific Worlds.
WorldImplBase(int size, int rank)
bool is_valid(void) const
void set_keymap(Keymap &&km)
ttg::detail::input_terminals_tuple_t< keyT, input_tuple_type > input_terminals_type
actual_input_tuple_type input_args_type
std::enable_if_t< ttg::meta::is_void_v< Key > &&std::is_void_v< Value >, void > set_arg()
void set_priomap(Priomap &&pm)
void set_defer_writer(bool _)
void set_arg(const Key &key, Value &&value)
void fence() override
Waits for the entire TTG associated with this TT to be completed (collective)
void set_input_reducer(Reducer &&reducer, std::size_t size)
void add_constraint(Constraint c, Mapper &&map)
std::enable_if_t< ttg::meta::is_void_v< Key > &&!std::is_void_v< std::decay_t< Value > >, void > set_arg(Value &&value)
TT(const std::string &name, const std::vector< std::string > &innames, const std::vector< std::string > &outnames, ttg::World world, keymapT &&keymap_=keymapT(), priomapT &&priomap_=priomapT())
ttg::detail::edges_tuple_t< keyT, ttg::meta::decayed_typelist_t< input_tuple_type > > input_edges_type
static resultT get(InTuple &&intuple)
void add_constraint(std::shared_ptr< Constraint > c, Mapper &&map)
std::tuple_element_t< i, output_terminalsT > * out()
Returns pointer to output terminal for purpose of connection — terminal cannot be copied,...
static constexpr bool derived_has_cuda_op()
static constexpr bool derived_has_level_zero_op()
std::enable_if_t<!ttg::meta::is_void_v< Key > &&std::is_void_v< Value >, void > set_arg(const Key &key)
const auto & get_output_terminals() const
std::tuple_element_t< i, input_terminals_type > * in()
Returns pointer to input terminal i to facilitate connection — terminal cannot be copied,...
std::enable_if_t< ttg::meta::is_void_v< Key > &&ttg::meta::is_empty_tuple_v< input_values_tuple_type >, void > invoke()
Manual injection of a task that has no key or arguments.
TT(const input_edges_type &inedges, const output_edges_type &outedges, const std::string &name, const std::vector< std::string > &innames, const std::vector< std::string > &outnames, ttg::World world, keymapT &&keymap_=keymapT(), priomapT &&priomap_=priomapT())
static constexpr int numouts
static auto & get(InTuple &&intuple)
TT(const input_edges_type &inedges, const output_edges_type &outedges, const std::string &name, const std::vector< std::string > &innames, const std::vector< std::string > &outnames, keymapT &&keymap=keymapT(ttg::default_execution_context()), priomapT &&priomap=priomapT())
void get_terminal_data(const int owner, const Key &key)
ttg::meta::add_glvalue_reference_tuple_t< ttg::meta::void_to_Void_tuple_t< actual_input_tuple_type > > input_refs_full_tuple_type
void set_input_reducer(Reducer &&reducer)
std::enable_if_t<!ttg::meta::is_void_v< Key > &&!ttg::meta::is_empty_tuple_v< input_values_tuple_type >, void > invoke(const Key &key, const input_values_tuple_type &args)
Manual injection of a task with all input arguments specified as a tuple.
std::enable_if_t< ttg::meta::is_void_v< Key > &&!ttg::meta::is_empty_tuple_v< input_values_tuple_type >, void > invoke(const input_values_tuple_type &args)
Manual injection of a key-free task with all input arguments specified as a tuple.
static constexpr int numinedges
ttg::meta::void_to_Void_tuple_t< ttg::meta::decayed_typelist_t< actual_input_tuple_type > > input_values_full_tuple_type
std::enable_if_t<!ttg::meta::is_void_v< Key >, void > set_args(std::index_sequence< Is... > is, const Key &key, const std::tuple< Ts... > &args)
std::enable_if_t< ttg::meta::is_void_v< Key >, void > set_args(std::index_sequence< Is... >, std::index_sequence< Js... >, const std::tuple< Ts... > &args)
output_terminalsT output_terminals_type
std::enable_if_t< key_is_void, void > finalize_argstream()
finalizes stream for input i
ttg::meta::drop_void_t< ttg::meta::decayed_typelist_t< input_tuple_type > > input_values_tuple_type
typename ttg::terminals_to_edges< output_terminalsT >::type output_edges_type
static constexpr bool derived_has_hip_op()
ttg::meta::drop_void_t< ttg::meta::add_glvalue_reference_tuple_t< input_tuple_type > > input_refs_tuple_type
std::enable_if_t< ttg::meta::is_void_v< Key >, int > owner() const
std::enable_if_t< key_is_void, void > set_argstream_size(std::size_t size)
TT(const std::string &name, const std::vector< std::string > &innames, const std::vector< std::string > &outnames, keymapT &&keymap=keymapT(ttg::default_execution_context()), priomapT &&priomap=priomapT())
void invoke_pull_terminals(std::index_sequence< IS... >, const Key &key, TTArgs *args)
void set_static_argstream_size(std::size_t size)
void make_executable() override
implementation of TTBase::make_executable()
std::enable_if_t<!ttg::meta::is_void_v< Key > &&ttg::meta::is_empty_tuple_v< input_values_tuple_type >, void > invoke(const Key &key)
Manual injection of a task that has no arguments.
std::enable_if_t< ttg::meta::is_void_v< Key >, void > set_args(std::index_sequence< Is... > is, const std::tuple< Ts... > &args)
static constexpr bool derived_has_device_op()
::madness::WorldObject< ttT > worldobjT
auto get_priomap(void) const
const decltype(keymap) & get_keymap() const
void add_constraint(Constraint &&c)
std::enable_if_t<!key_is_void, void > finalize_argstream(const Key &key)
finalizes stream for input i
ttg::World get_world() const override final
std::enable_if_t<!ttg::meta::is_void_v< Key >, int > owner(const Key &key) const
static __thread struct ttg_madness::TT::@0 threaddata
void invoke_pull_terminal(terminalT &in, const Key &key, TTArgs *args)
static constexpr int numins
bool get_defer_writer(bool _)
std::enable_if_t<!key_is_void, void > set_argstream_size(const Key &key, std::size_t size)
std::enable_if_t<!ttg::meta::is_void_v< Key >, void > set_args(std::index_sequence< Is... >, std::index_sequence< Js... >, const Key &key, const std::tuple< Ts... > &args)
WorldImpl(const WorldImpl &other)=delete
WorldImpl & operator=(const WorldImpl &other)=delete
const ttg::Edge & ctl_edge() const
virtual void fence_impl(void) override
::madness::World & impl()
WorldImpl & operator=(WorldImpl &&other)=delete
virtual ~WorldImpl() override
WorldImpl(WorldImpl &&other)=delete
WorldImpl(::madness::World &world)
const ::madness::World & impl() const
virtual void destroy(void) override
WorldImpl(const SafeMPI::Intracomm &comm)
void deregister_world(ttg::base::WorldImplBase &world)
typename input_terminals_tuple< keyT, valuesT... >::type input_terminals_tuple_t
int num_threads()
Determine the number of compute threads to use by TTG when not given to ttg::initialize
typename edges_tuple< keyT, valuesT >::type edges_tuple_t
this contains MADNESS-based TTG functionality
void ttg_register_ptr(ttg::World world, const std::shared_ptr< T > &ptr)
void ttg_initialize(int argc, char **argv, int num_threads=-1)
void ttg_execute(ttg::World world)
ttg::Edge & ttg_ctl_edge(ttg::World world)
void ttg_register_status(ttg::World world, const std::shared_ptr< std::promise< void > > &status_ptr)
void ttg_sum(ttg::World world, T &value)
void ttg_fence(ttg::World world)
void make_executable_hook(ttg::World &)
void ttg_register_callback(ttg::World world, Callback &&callback)
void ttg_broadcast(ttg::World world, T &data, int source_rank)
ttg::World ttg_default_execution_context()
top-level TTG namespace contains runtime-neutral functionality
int size(World world=default_execution_context())
void abort()
Aborts the TTG program using the default backend's ttg_abort method.
ttg::World & get_default_world()
World default_execution_context()
Accesses the default backend's default execution context.
TTG_CXX_COROUTINE_NAMESPACE::coroutine_handle< Promise > coroutine_handle
void print_error(const T &t, const Ts &... ts)
atomically prints to std::cerr a sequence of items (separated by ttg::print_separator) followed by st...
void trace(const T &t, const Ts &... ts)
@ ResumableTask
-> ttg::resumable_task
@ Invalid
not a coroutine, i.e. a standard task function, -> void
Computes hash values for objects of type T.
task that can be resumed after some events occur
#define TTG_PROCESS_TT_OP_RETURN(result, id, invoke)