Kokkos Core Kernels Package Version of the Day
Loading...
Searching...
No Matches
Kokkos_TaskScheduler.hpp
1//@HEADER
2// ************************************************************************
3//
4// Kokkos v. 4.0
5// Copyright (2022) National Technology & Engineering
6// Solutions of Sandia, LLC (NTESS).
7//
8// Under the terms of Contract DE-NA0003525 with NTESS,
9// the U.S. Government retains certain rights in this software.
10//
11// Part of Kokkos, under the Apache License v2.0 with LLVM Exceptions.
12// See https://kokkos.org/LICENSE for license information.
13// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
14//
15//@HEADER
16
17#include <Kokkos_Macros.hpp>
18
19#ifndef KOKKOS_IMPL_PUBLIC_INCLUDE
20static_assert(false,
21 "Including non-public Kokkos header files is not allowed.");
22#endif
23
24#ifndef KOKKOS_ENABLE_DEPRECATED_CODE_4
25#error "The tasking framework is deprecated"
26#endif
27
28#ifndef KOKKOS_TASKSCHEDULER_HPP
29#define KOKKOS_TASKSCHEDULER_HPP
30
31//----------------------------------------------------------------------------
32
33#include <Kokkos_Macros.hpp>
34#if defined(KOKKOS_ENABLE_TASKDAG)
35
36#include <Kokkos_Core_fwd.hpp>
37#include <Kokkos_TaskScheduler_fwd.hpp>
38//----------------------------------------------------------------------------
39
40#include <Kokkos_MemoryPool.hpp>
41
42#include <Kokkos_Future.hpp>
43#include <impl/Kokkos_TaskQueue.hpp>
44#include <impl/Kokkos_SingleTaskQueue.hpp>
45#include <impl/Kokkos_TaskQueueMultiple.hpp>
46#include <impl/Kokkos_TaskPolicyData.hpp>
47#include <impl/Kokkos_TaskTeamMember.hpp>
48#include <impl/Kokkos_SimpleTaskScheduler.hpp>
49
50//----------------------------------------------------------------------------
51//----------------------------------------------------------------------------
52
53#ifdef KOKKOS_ENABLE_DEPRECATION_WARNINGS
54// We allow using deprecated classes in this file
55KOKKOS_IMPL_DISABLE_DEPRECATED_WARNINGS_PUSH()
56#endif
57
58namespace Kokkos {
59
60namespace Impl {
61
62template <class, class>
63class TaskExec;
64
65} // end namespace Impl
66
67template <class ExecSpace, class QueueType>
68class KOKKOS_DEPRECATED BasicTaskScheduler : public Impl::TaskSchedulerBase {
69 public:
70 using scheduler_type = BasicTaskScheduler;
71 using execution_space = ExecSpace;
72 using queue_type = QueueType;
73 using memory_space = typename queue_type::memory_space;
74 using memory_pool = typename queue_type::memory_pool;
75 using specialization = Impl::TaskQueueSpecialization<BasicTaskScheduler>;
76 using member_type = typename specialization::member_type;
77 using team_scheduler_type = BasicTaskScheduler;
78 template <class Functor>
79 using runnable_task_type =
80 Impl::Task<scheduler_type, typename Functor::value_type, Functor>;
81 template <class ValueType>
82 using future_type = Kokkos::BasicFuture<ValueType, BasicTaskScheduler>;
83 template <class FunctorType>
84 using future_type_for_functor = future_type<typename FunctorType::value_type>;
85
86 private:
87 using track_type = Kokkos::Impl::SharedAllocationTracker;
88 using task_base = Impl::TaskBase;
89
90 track_type m_track;
91 queue_type* m_queue;
92
93 //----------------------------------------
94
95 template <typename, typename>
96 friend class Impl::TaskQueue;
97 template <typename>
98 friend struct Impl::TaskQueueSpecialization;
99 template <typename, typename>
100 friend class Impl::TaskQueueSpecializationConstrained;
101 template <typename, typename>
102 friend class Impl::TaskTeamMemberAdapter;
103 template <typename, typename>
104 friend class Impl::TaskExec;
105
106 //----------------------------------------
107
108 KOKKOS_INLINE_FUNCTION
109 BasicTaskScheduler(track_type arg_track, queue_type* arg_queue)
110 : m_track(std::move(arg_track)), m_queue(std::move(arg_queue)) {}
111
112 KOKKOS_INLINE_FUNCTION
113 team_scheduler_type get_team_scheduler(int team_rank) const {
114 return {m_track, &m_queue->get_team_queue(team_rank)};
115 }
116
117 //----------------------------------------
118
119 KOKKOS_INLINE_FUNCTION
120 static constexpr task_base* _get_task_ptr(std::nullptr_t) { return nullptr; }
121
122 template <class ValueType>
123 KOKKOS_INLINE_FUNCTION static constexpr task_base* _get_task_ptr(
124 future_type<ValueType>&& f) {
125 return f.m_task;
126 }
127
128 template <int TaskEnum, typename DepTaskType, typename FunctorType>
129 KOKKOS_FUNCTION
130 Kokkos::BasicFuture<typename FunctorType::value_type, scheduler_type>
131 _spawn_impl(DepTaskType* arg_predecessor_task, TaskPriority arg_priority,
132 typename task_base::function_type arg_function,
133 typename task_base::destroy_type /*arg_destroy*/,
134 FunctorType&& arg_functor) {
135 using functor_future_type =
136 future_type_for_functor<std::decay_t<FunctorType>>;
137 using task_type =
138 Impl::Task<BasicTaskScheduler, typename functor_future_type::value_type,
139 FunctorType>;
140
141 //----------------------------------------
142 // Give single-thread back-ends an opportunity to clear
143 // queue of ready tasks before allocating a new task
144
145 // TODO @tasking @optimization DSH re-enable this, maybe?
146 // specialization::iff_single_thread_recursive_execute(scheduler);
147
148 //----------------------------------------
149
150 functor_future_type f;
151
152 // Allocate task from memory pool
153
154 const size_t alloc_size =
155 m_queue->template spawn_allocation_size<FunctorType>();
156
157 void* task_storage = m_queue->allocate(alloc_size);
158
159 if (task_storage) {
160 // Placement new construction
161 // Reference count starts at two:
162 // +1 for the matching decrement when task is complete
163 // +1 for the future
164 f.m_task =
165 new (task_storage) task_type(std::forward<FunctorType>(arg_functor));
166
167 f.m_task->m_apply = arg_function;
168 // f.m_task->m_destroy = arg_destroy;
169 f.m_task->m_queue = m_queue;
170 f.m_task->m_next = arg_predecessor_task;
171 f.m_task->m_ref_count = 2;
172 f.m_task->m_alloc_size = alloc_size;
173 f.m_task->m_task_type = TaskEnum;
174 f.m_task->m_priority = (int16_t)arg_priority;
175
176 Kokkos::memory_fence();
177
178 // The dependence (if any) is processed immediately
179 // within the schedule function, as such the dependence's
180 // reference count does not need to be incremented for
181 // the assignment.
182
183 m_queue->schedule_runnable(f.m_task);
184 // This task may be updated or executed at any moment,
185 // even during the call to 'schedule'.
186 }
187
188 return f;
189 }
190
191 public:
192 KOKKOS_INLINE_FUNCTION
193 BasicTaskScheduler() : m_track(), m_queue(nullptr) {}
194
195 KOKKOS_INLINE_FUNCTION
196 BasicTaskScheduler(BasicTaskScheduler&& rhs) noexcept
197 : m_track(rhs.m_track), // probably should be a move, but this is
198 // deprecated code anyway
199 m_queue(std::move(rhs.m_queue)) {}
200
201 KOKKOS_INLINE_FUNCTION
202 BasicTaskScheduler(BasicTaskScheduler const& rhs)
203 : m_track(rhs.m_track), m_queue(rhs.m_queue) {}
204
205 KOKKOS_INLINE_FUNCTION
206 BasicTaskScheduler& operator=(BasicTaskScheduler&& rhs) noexcept {
207 m_track = rhs.m_track; // probably should be a move, but this is deprecated
208 // code anyway
209 m_queue = std::move(rhs.m_queue);
210 return *this;
211 }
212
213 KOKKOS_INLINE_FUNCTION
214 BasicTaskScheduler& operator=(BasicTaskScheduler const& rhs) {
215 m_track = rhs.m_track;
216 m_queue = rhs.m_queue;
217 return *this;
218 }
219
220 explicit BasicTaskScheduler(memory_pool const& arg_memory_pool) noexcept
221 : m_track(), m_queue(nullptr) {
222 using record_type =
223 Kokkos::Impl::SharedAllocationRecord<memory_space,
224 typename queue_type::Destroy>;
225
226 record_type* record = record_type::allocate(
227 memory_space(), "Kokkos::TaskQueue", sizeof(queue_type));
228
229 m_queue = new (record->data()) queue_type(arg_memory_pool);
230
231 record->m_destroy.m_queue = m_queue;
232
233 m_track.assign_allocated_record_to_uninitialized(record);
234 }
235
236 BasicTaskScheduler(memory_space const& arg_memory_space,
237 size_t const mempool_capacity,
238 unsigned const mempool_min_block_size // = 1u << 6
239 ,
240 unsigned const mempool_max_block_size // = 1u << 10
241 ,
242 unsigned const mempool_superblock_size // = 1u << 12
243 )
244 : BasicTaskScheduler(memory_pool(
245 arg_memory_space, mempool_capacity, mempool_min_block_size,
246 mempool_max_block_size, mempool_superblock_size)) {}
247
248 //----------------------------------------
249
250 KOKKOS_INLINE_FUNCTION
251 queue_type& queue() const noexcept {
252 KOKKOS_EXPECTS(m_queue != nullptr);
253 return *m_queue;
254 }
255
256 KOKKOS_INLINE_FUNCTION
257 memory_pool* memory() const noexcept {
258 return m_queue ? &(m_queue->m_memory) : (memory_pool*)0;
259 }
260
261 //----------------------------------------
263 template <typename FunctorType>
264 KOKKOS_FUNCTION size_t spawn_allocation_size() const {
265 return m_queue->template spawn_allocation_size<FunctorType>();
266 }
267
269 KOKKOS_FUNCTION
270 size_t when_all_allocation_size(int narg) const {
271 return m_queue->when_all_allocation_size(narg);
272 }
273
274 //----------------------------------------
275
276 template <int TaskEnum, typename DepFutureType, typename FunctorType>
277 KOKKOS_FUNCTION static Kokkos::BasicFuture<typename FunctorType::value_type,
278 scheduler_type>
279 spawn(Impl::TaskPolicyWithScheduler<TaskEnum, scheduler_type, DepFutureType>&&
280 arg_policy,
281 typename task_base::function_type arg_function,
282 typename task_base::destroy_type arg_destroy,
283 FunctorType&& arg_functor) {
284 return std::move(arg_policy.scheduler())
285 .template _spawn_impl<TaskEnum>(
286 _get_task_ptr(std::move(arg_policy.predecessor())),
287 arg_policy.priority(), arg_function, arg_destroy,
288 std::forward<FunctorType>(arg_functor));
289 }
290
291 template <int TaskEnum, typename DepFutureType, typename FunctorType>
292 KOKKOS_FUNCTION future_type_for_functor<std::decay_t<FunctorType>> spawn(
293 Impl::TaskPolicyWithPredecessor<TaskEnum, DepFutureType>&& arg_policy,
294 FunctorType&& arg_functor) {
295 using task_type = runnable_task_type<FunctorType>;
296 typename task_type::function_type const ptr = task_type::apply;
297 typename task_type::destroy_type const dtor = task_type::destroy;
298
299 return _spawn_impl<TaskEnum>(
300 _get_task_ptr(std::move(arg_policy).predecessor()),
301 arg_policy.priority(), ptr, dtor,
302 std::forward<FunctorType>(arg_functor));
303 }
304
305 template <typename FunctorType, typename ValueType, typename Scheduler>
306 KOKKOS_FUNCTION static void respawn(
307 FunctorType* arg_self,
308 BasicFuture<ValueType, Scheduler> const& arg_dependence,
309 TaskPriority const& arg_priority) {
310 // Precondition: task is in Executing state
311
312 using value_type = typename FunctorType::value_type;
313 using task_type = Impl::Task<BasicTaskScheduler, value_type, FunctorType>;
314
315 task_type* const task = static_cast<task_type*>(arg_self);
316
317 task->m_priority = static_cast<int>(arg_priority);
318
319 task->add_dependence(arg_dependence.m_task);
320
321 // Postcondition: task is in Executing-Respawn state
322 }
323
324 template <typename FunctorType>
325 KOKKOS_FUNCTION static void respawn(FunctorType* arg_self,
326 BasicTaskScheduler const&,
327 TaskPriority const& arg_priority) {
328 // Precondition: task is in Executing state
329
330 using value_type = typename FunctorType::value_type;
331 using task_type = Impl::Task<BasicTaskScheduler, value_type, FunctorType>;
332
333 task_type* const task = static_cast<task_type*>(arg_self);
334
335 task->m_priority = static_cast<int>(arg_priority);
336
337 task->add_dependence(nullptr);
338
339 // Postcondition: task is in Executing-Respawn state
340 }
341
342 //----------------------------------------
346 template <typename ValueType>
347 KOKKOS_FUNCTION BasicFuture<void, scheduler_type> when_all(
348 BasicFuture<ValueType, BasicTaskScheduler> const arg[], int narg) {
349 future_type<void> f;
350
351 if (narg) {
352 queue_type* q = m_queue;
353
354 // BasicTaskScheduler const* scheduler_ptr = nullptr;
355
356 for (int i = 0; i < narg; ++i) {
357 task_base* const t = arg[i].m_task;
358 if (nullptr != t) {
359 // Increment reference count to track subsequent assignment.
360 // This likely has to be SeqCst
361 desul::atomic_inc(&(t->m_ref_count), desul::MemoryOrderSeqCst(),
362 desul::MemoryScopeDevice());
363 if (q != static_cast<queue_type const*>(t->m_queue)) {
364 Kokkos::abort(
365 "Kokkos when_all Futures must be in the same scheduler");
366 }
367 }
368 }
369
370 if (q != nullptr) { // this should probably handle the queue == 0 case,
371 // but this is deprecated code anyway
372
373 size_t const alloc_size = q->when_all_allocation_size(narg);
374
375 f.m_task = reinterpret_cast<task_base*>(q->allocate(alloc_size));
376 // f.m_scheduler = *scheduler_ptr;
377
378 if (f.m_task) {
379 // Reference count starts at two:
380 // +1 to match decrement when task completes
381 // +1 for the future
382
383 new (f.m_task) task_base();
384
385 f.m_task->m_queue = q;
386 f.m_task->m_ref_count = 2;
387 f.m_task->m_alloc_size = static_cast<int32_t>(alloc_size);
388 f.m_task->m_dep_count = narg;
389 f.m_task->m_task_type = task_base::Aggregate;
390
391 // Assign dependences, reference counts were already incremented
392
393 task_base* volatile* const dep = f.m_task->aggregate_dependences();
394
395 for (int i = 0; i < narg; ++i) {
396 dep[i] = arg[i].m_task;
397 }
398
399 Kokkos::memory_fence();
400
401 q->schedule_aggregate(f.m_task);
402 // this when_all may be processed at any moment
403 }
404 }
405 }
406
407 return f;
408 }
409
410 template <class F>
411 KOKKOS_FUNCTION BasicFuture<void, scheduler_type> when_all(int narg,
412 F const func) {
413 using input_type = decltype(func(0));
414
415 static_assert(is_future<input_type>::value,
416 "Functor must return a Kokkos::Future");
417
418 future_type<void> f;
419
420 if (0 == narg) return f;
421
422 size_t const alloc_size = m_queue->when_all_allocation_size(narg);
423
424 f.m_task = reinterpret_cast<task_base*>(m_queue->allocate(alloc_size));
425
426 if (f.m_task) {
427 // Reference count starts at two:
428 // +1 to match decrement when task completes
429 // +1 for the future
430
431 new (f.m_task) task_base();
432 // f.m_scheduler = *this;
433
434 // f.m_task->m_scheduler = &f.m_scheduler;
435 f.m_task->m_queue = m_queue;
436 f.m_task->m_ref_count = 2;
437 f.m_task->m_alloc_size = static_cast<int32_t>(alloc_size);
438 f.m_task->m_dep_count = narg;
439 f.m_task->m_task_type = task_base::Aggregate;
440 // f.m_task->m_apply = nullptr;
441 // f.m_task->m_destroy = nullptr;
442
443 // Assign dependences, reference counts were already incremented
444
445 task_base* volatile* const dep = f.m_task->aggregate_dependences();
446
447 for (int i = 0; i < narg; ++i) {
448 const input_type arg_f = func(i);
449 if (nullptr != arg_f.m_task) {
450 // Not scheduled, so task scheduler is not yet set
451 // if ( m_queue != static_cast< BasicTaskScheduler const * >(
452 // arg_f.m_task->m_scheduler )->m_queue ) {
453 // Kokkos::abort("Kokkos when_all Futures must be in the same
454 // scheduler" );
455 //}
456 // Increment reference count to track subsequent assignment.
457 // This increment likely has to be SeqCst
458 desul::atomic_inc(&(arg_f.m_task->m_ref_count),
459 desul::MemoryOrderSeqCst(),
460 desul::MemoryScopeDevice());
461 dep[i] = arg_f.m_task;
462 }
463 }
464
465 Kokkos::memory_fence();
466
467 m_queue->schedule_aggregate(f.m_task);
468 // this when_all may be processed at any moment
469 }
470 return f;
471 }
472
473 //----------------------------------------
474
475 KOKKOS_INLINE_FUNCTION
476 int allocation_capacity() const noexcept {
477 return m_queue->m_memory.capacity();
478 }
479
480 KOKKOS_INLINE_FUNCTION
481 int allocated_task_count() const noexcept { return m_queue->m_count_alloc; }
482
483 KOKKOS_INLINE_FUNCTION
484 int allocated_task_count_max() const noexcept { return m_queue->m_max_alloc; }
485
486 KOKKOS_INLINE_FUNCTION
487 long allocated_task_count_accum() const noexcept {
488 return m_queue->m_accum_alloc;
489 }
490
491 //----------------------------------------
492
493 template <class S, class Q>
494 friend void wait(Kokkos::BasicTaskScheduler<S, Q> const&);
495};
496
497} // namespace Kokkos
498
499//----------------------------------------------------------------------------
500//----------------------------------------------------------------------------
501
502namespace Kokkos {
503
504//----------------------------------------------------------------------------
505// Construct a TaskTeam execution policy
506
507template <class T, class Scheduler>
508KOKKOS_DEPRECATED Impl::TaskPolicyWithPredecessor<
509 Impl::TaskType::TaskTeam, Kokkos::BasicFuture<T, Scheduler>>
510 KOKKOS_INLINE_FUNCTION
511 TaskTeam(Kokkos::BasicFuture<T, Scheduler> arg_future,
512 TaskPriority arg_priority = TaskPriority::Regular) {
513 return {std::move(arg_future), arg_priority};
514}
515
516template <class Scheduler>
517KOKKOS_DEPRECATED Impl::TaskPolicyWithScheduler<Impl::TaskType::TaskTeam,
518 Scheduler>
519 KOKKOS_INLINE_FUNCTION TaskTeam(
520 Scheduler arg_scheduler,
521 std::enable_if_t<Kokkos::is_scheduler<Scheduler>::value, TaskPriority>
522 arg_priority = TaskPriority::Regular) {
523 return {std::move(arg_scheduler), arg_priority};
524}
525
526template <class Scheduler, class PredecessorFuture>
527KOKKOS_DEPRECATED Impl::TaskPolicyWithScheduler<
528 Kokkos::Impl::TaskType::TaskTeam, Scheduler, PredecessorFuture>
529 KOKKOS_INLINE_FUNCTION
530 TaskTeam(Scheduler arg_scheduler, PredecessorFuture arg_future,
531 std::enable_if_t<Kokkos::is_scheduler<Scheduler>::value &&
532 Kokkos::is_future<PredecessorFuture>::value,
533 TaskPriority>
534 arg_priority = TaskPriority::Regular) {
535 static_assert(
536 std::is_same_v<typename PredecessorFuture::scheduler_type, Scheduler>,
537 "Can't create a task policy from a scheduler and a future from "
538 "a different scheduler");
539
540 return {std::move(arg_scheduler), std::move(arg_future), arg_priority};
541}
542
543// Construct a TaskSingle execution policy
544
545template <class T, class Scheduler>
546KOKKOS_DEPRECATED Impl::TaskPolicyWithPredecessor<
547 Impl::TaskType::TaskSingle, Kokkos::BasicFuture<T, Scheduler>>
548 KOKKOS_INLINE_FUNCTION
549 TaskSingle(Kokkos::BasicFuture<T, Scheduler> arg_future,
550 TaskPriority arg_priority = TaskPriority::Regular) {
551 return {std::move(arg_future), arg_priority};
552}
553
554template <class Scheduler>
555KOKKOS_DEPRECATED Impl::TaskPolicyWithScheduler<Impl::TaskType::TaskSingle,
556 Scheduler>
557 KOKKOS_INLINE_FUNCTION TaskSingle(
558 Scheduler arg_scheduler,
559 std::enable_if_t<Kokkos::is_scheduler<Scheduler>::value, TaskPriority>
560 arg_priority = TaskPriority::Regular) {
561 return {std::move(arg_scheduler), arg_priority};
562}
563
564template <class Scheduler, class PredecessorFuture>
565KOKKOS_DEPRECATED Impl::TaskPolicyWithScheduler<
566 Kokkos::Impl::TaskType::TaskSingle, Scheduler, PredecessorFuture>
567 KOKKOS_INLINE_FUNCTION
568 TaskSingle(Scheduler arg_scheduler, PredecessorFuture arg_future,
569 std::enable_if_t<Kokkos::is_scheduler<Scheduler>::value &&
570 Kokkos::is_future<PredecessorFuture>::value,
571 TaskPriority>
572 arg_priority = TaskPriority::Regular) {
573 static_assert(
574 std::is_same_v<typename PredecessorFuture::scheduler_type, Scheduler>,
575 "Can't create a task policy from a scheduler and a future from "
576 "a different scheduler");
577
578 return {std::move(arg_scheduler), std::move(arg_future), arg_priority};
579}
580
581//----------------------------------------------------------------------------
582
589template <int TaskEnum, typename Scheduler, typename DepFutureType,
590 typename FunctorType>
591KOKKOS_DEPRECATED typename Scheduler::template future_type_for_functor<
592 std::decay_t<FunctorType>>
593host_spawn(Impl::TaskPolicyWithScheduler<TaskEnum, Scheduler, DepFutureType>
594 arg_policy,
595 FunctorType&& arg_functor) {
596 using scheduler_type = Scheduler;
597 using task_type =
598 typename scheduler_type::template runnable_task_type<FunctorType>;
599
600 static_assert(TaskEnum == Impl::TaskType::TaskTeam ||
601 TaskEnum == Impl::TaskType::TaskSingle,
602 "Kokkos host_spawn requires TaskTeam or TaskSingle");
603
604 // May be spawning a Cuda task, must use the specialization
605 // to query on-device function pointer.
606 typename task_type::function_type ptr;
607 typename task_type::destroy_type dtor;
608 Kokkos::Impl::TaskQueueSpecialization<
609 scheduler_type>::template get_function_pointer<task_type>(ptr, dtor);
610
611 return scheduler_type::spawn(std::move(arg_policy), ptr, dtor,
612 std::forward<FunctorType>(arg_functor));
613}
614
621template <int TaskEnum, typename Scheduler, typename DepFutureType,
622 typename FunctorType>
623KOKKOS_DEPRECATED typename Scheduler::template future_type_for_functor<
624 std::decay_t<FunctorType>>
625 KOKKOS_INLINE_FUNCTION
626 task_spawn(Impl::TaskPolicyWithScheduler<TaskEnum, Scheduler, DepFutureType>
627 arg_policy,
628 FunctorType&& arg_functor) {
629 using scheduler_type = Scheduler;
630
631 using task_type =
632 typename scheduler_type::template runnable_task_type<FunctorType>;
633
634 static_assert(TaskEnum == Impl::TaskType::TaskTeam ||
635 TaskEnum == Impl::TaskType::TaskSingle,
636 "Kokkos task_spawn requires TaskTeam or TaskSingle");
637
638 typename task_type::function_type const ptr = task_type::apply;
639 typename task_type::destroy_type const dtor = task_type::destroy;
640
641 return scheduler_type::spawn(std::move(arg_policy), ptr, dtor,
642 std::forward<FunctorType>(arg_functor));
643}
644
650template <typename FunctorType, typename T>
651KOKKOS_DEPRECATED void KOKKOS_INLINE_FUNCTION
652respawn(FunctorType* arg_self, T const& arg,
653 TaskPriority const& arg_priority = TaskPriority::Regular) {
654 static_assert(Kokkos::is_future<T>::value || Kokkos::is_scheduler<T>::value,
655 "Kokkos respawn argument must be Future or TaskScheduler");
656
657 T::scheduler_type::respawn(arg_self, arg, arg_priority);
658}
659
660//----------------------------------------------------------------------------
661
662// template<typename ValueType, typename Scheduler>
663// KOKKOS_INLINE_FUNCTION
664// BasicFuture<void, Scheduler>
665// when_all(BasicFuture<ValueType, Scheduler> const arg[], int narg)
666//{
667// return BasicFuture<void, Scheduler>::scheduler_type::when_all(arg, narg);
668//}
669
670//----------------------------------------------------------------------------
671// Wait for all runnable tasks to complete
672
673template <class ExecSpace, class QueueType>
674KOKKOS_DEPRECATED inline void wait(
675 BasicTaskScheduler<ExecSpace, QueueType> const& scheduler) {
676 using scheduler_type = BasicTaskScheduler<ExecSpace, QueueType>;
677 scheduler_type::specialization::execute(scheduler);
678 // scheduler.m_queue->execute();
679}
680
681} // namespace Kokkos
682
683#ifdef KOKKOS_ENABLE_DEPRECATION_WARNINGS
684KOKKOS_IMPL_DISABLE_DEPRECATED_WARNINGS_POP()
685#endif
686
687//----------------------------------------------------------------------------
688//----------------------------------------------------------------------------
689
691// END OLD CODE
693
694#endif /* #if defined( KOKKOS_ENABLE_TASKDAG ) */
695#endif /* #ifndef KOKKOS_TASKSCHEDULER_HPP */
ScopeGuard Some user scope issues have been identified with some Kokkos::finalize calls; ScopeGuard a...