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>
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
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 if (&rhs == this) return *this;
216 m_track = rhs.m_track;
217 m_queue = rhs.m_queue;
218 return *this;
219 }
220
221 explicit BasicTaskScheduler(memory_pool const& arg_memory_pool) noexcept
222 : m_track(), m_queue(nullptr) {
223 using record_type =
224 Kokkos::Impl::SharedAllocationRecord<memory_space,
225 typename queue_type::Destroy>;
226
227 record_type* record = record_type::allocate(
228 memory_space(), "Kokkos::TaskQueue", sizeof(queue_type));
229
230 m_queue = new (record->data()) queue_type(arg_memory_pool);
231
232 record->m_destroy.m_queue = m_queue;
233
234 m_track.assign_allocated_record_to_uninitialized(record);
235 }
236
237 BasicTaskScheduler(memory_space const& arg_memory_space,
238 size_t const mempool_capacity,
239 unsigned const mempool_min_block_size // = 1u << 6
240 ,
241 unsigned const mempool_max_block_size // = 1u << 10
242 ,
243 unsigned const mempool_superblock_size // = 1u << 12
244 )
245 : BasicTaskScheduler(memory_pool(
246 arg_memory_space, mempool_capacity, mempool_min_block_size,
247 mempool_max_block_size, mempool_superblock_size)) {}
248
249 //----------------------------------------
250
251 KOKKOS_INLINE_FUNCTION
252 queue_type& queue() const noexcept {
253 KOKKOS_EXPECTS(m_queue != nullptr);
254 return *m_queue;
255 }
256
257 KOKKOS_INLINE_FUNCTION
258 memory_pool* memory() const noexcept {
259 return m_queue ? &(m_queue->m_memory) : (memory_pool*)0;
260 }
261
262 //----------------------------------------
264 template <typename FunctorType>
265 KOKKOS_FUNCTION size_t spawn_allocation_size() const {
266 return m_queue->template spawn_allocation_size<FunctorType>();
267 }
268
270 KOKKOS_FUNCTION
271 size_t when_all_allocation_size(int narg) const {
272 return m_queue->when_all_allocation_size(narg);
273 }
274
275 //----------------------------------------
276
277 template <int TaskEnum, typename DepFutureType, typename FunctorType>
278 KOKKOS_FUNCTION static Kokkos::BasicFuture<typename FunctorType::value_type,
279 scheduler_type>
280 spawn(Impl::TaskPolicyWithScheduler<TaskEnum, scheduler_type, DepFutureType>&&
281 arg_policy,
282 typename task_base::function_type arg_function,
283 typename task_base::destroy_type arg_destroy,
284 FunctorType&& arg_functor) {
285 return std::move(arg_policy.scheduler())
286 .template _spawn_impl<TaskEnum>(
287 _get_task_ptr(std::move(arg_policy.predecessor())),
288 arg_policy.priority(), arg_function, arg_destroy,
289 std::forward<FunctorType>(arg_functor));
290 }
291
292 template <int TaskEnum, typename DepFutureType, typename FunctorType>
293 KOKKOS_FUNCTION future_type_for_functor<std::decay_t<FunctorType>> spawn(
294 Impl::TaskPolicyWithPredecessor<TaskEnum, DepFutureType>&& arg_policy,
295 FunctorType&& arg_functor) {
296 using task_type = runnable_task_type<FunctorType>;
297 typename task_type::function_type const ptr = task_type::apply;
298 typename task_type::destroy_type const dtor = task_type::destroy;
299
300 auto const priority = arg_policy.priority();
301 return _spawn_impl<TaskEnum>(
302 _get_task_ptr(std::move(arg_policy).predecessor()), priority, ptr, dtor,
303 std::forward<FunctorType>(arg_functor));
304 }
305
306 template <typename FunctorType, typename ValueType, typename Scheduler>
307 KOKKOS_FUNCTION static void respawn(
308 FunctorType* arg_self,
309 BasicFuture<ValueType, Scheduler> const& arg_dependence,
310 TaskPriority const& arg_priority) {
311 // Precondition: task is in Executing state
312
313 using value_type = typename FunctorType::value_type;
314 using task_type = Impl::Task<BasicTaskScheduler, value_type, FunctorType>;
315
316 task_type* const task = static_cast<task_type*>(arg_self);
317
318 task->m_priority = static_cast<int>(arg_priority);
319
320 task->add_dependence(arg_dependence.m_task);
321
322 // Postcondition: task is in Executing-Respawn state
323 }
324
325 template <typename FunctorType>
326 KOKKOS_FUNCTION static void respawn(FunctorType* arg_self,
327 BasicTaskScheduler const&,
328 TaskPriority const& arg_priority) {
329 // Precondition: task is in Executing state
330
331 using value_type = typename FunctorType::value_type;
332 using task_type = Impl::Task<BasicTaskScheduler, value_type, FunctorType>;
333
334 task_type* const task = static_cast<task_type*>(arg_self);
335
336 task->m_priority = static_cast<int>(arg_priority);
337
338 task->add_dependence(nullptr);
339
340 // Postcondition: task is in Executing-Respawn state
341 }
342
343 //----------------------------------------
347 template <typename ValueType>
348 KOKKOS_FUNCTION BasicFuture<void, scheduler_type> when_all(
349 BasicFuture<ValueType, BasicTaskScheduler> const arg[], int narg) {
350 future_type<void> f;
351
352 if (narg) {
353 queue_type* q = m_queue;
354
355 // BasicTaskScheduler const* scheduler_ptr = nullptr;
356
357 for (int i = 0; i < narg; ++i) {
358 task_base* const t = arg[i].m_task;
359 if (nullptr != t) {
360 // Increment reference count to track subsequent assignment.
361 // This likely has to be SeqCst
362 desul::atomic_inc(&(t->m_ref_count), desul::MemoryOrderSeqCst(),
363 desul::MemoryScopeDevice());
364 if (q != static_cast<queue_type const*>(t->m_queue)) {
365 Kokkos::abort(
366 "Kokkos when_all Futures must be in the same scheduler");
367 }
368 }
369 }
370
371 if (q != nullptr) { // this should probably handle the queue == 0 case,
372 // but this is deprecated code anyway
373
374 size_t const alloc_size = q->when_all_allocation_size(narg);
375
376 f.m_task = reinterpret_cast<task_base*>(q->allocate(alloc_size));
377 // f.m_scheduler = *scheduler_ptr;
378
379 if (f.m_task) {
380 // Reference count starts at two:
381 // +1 to match decrement when task completes
382 // +1 for the future
383
384 new (f.m_task) task_base();
385
386 f.m_task->m_queue = q;
387 f.m_task->m_ref_count = 2;
388 f.m_task->m_alloc_size = static_cast<int32_t>(alloc_size);
389 f.m_task->m_dep_count = narg;
390 f.m_task->m_task_type = task_base::Aggregate;
391
392 // Assign dependences, reference counts were already incremented
393
394 task_base* volatile* const dep = f.m_task->aggregate_dependences();
395
396 for (int i = 0; i < narg; ++i) {
397 dep[i] = arg[i].m_task;
398 }
399
400 Kokkos::memory_fence();
401
402 q->schedule_aggregate(f.m_task);
403 // this when_all may be processed at any moment
404 }
405 }
406 }
407
408 return f;
409 }
410
411 template <class F>
412 KOKKOS_FUNCTION BasicFuture<void, scheduler_type> when_all(int narg,
413 F const func) {
414 using input_type = decltype(func(0));
415
416 static_assert(is_future<input_type>::value,
417 "Functor must return a Kokkos::Future");
418
419 future_type<void> f;
420
421 if (0 == narg) return f;
422
423 size_t const alloc_size = m_queue->when_all_allocation_size(narg);
424
425 f.m_task = reinterpret_cast<task_base*>(m_queue->allocate(alloc_size));
426
427 if (f.m_task) {
428 // Reference count starts at two:
429 // +1 to match decrement when task completes
430 // +1 for the future
431
432 new (f.m_task) task_base();
433 // f.m_scheduler = *this;
434
435 // f.m_task->m_scheduler = &f.m_scheduler;
436 f.m_task->m_queue = m_queue;
437 f.m_task->m_ref_count = 2;
438 f.m_task->m_alloc_size = static_cast<int32_t>(alloc_size);
439 f.m_task->m_dep_count = narg;
440 f.m_task->m_task_type = task_base::Aggregate;
441 // f.m_task->m_apply = nullptr;
442 // f.m_task->m_destroy = nullptr;
443
444 // Assign dependences, reference counts were already incremented
445
446 task_base* volatile* const dep = f.m_task->aggregate_dependences();
447
448 for (int i = 0; i < narg; ++i) {
449 const input_type arg_f = func(i);
450 if (nullptr != arg_f.m_task) {
451 // Not scheduled, so task scheduler is not yet set
452 // if ( m_queue != static_cast< BasicTaskScheduler const * >(
453 // arg_f.m_task->m_scheduler )->m_queue ) {
454 // Kokkos::abort("Kokkos when_all Futures must be in the same
455 // scheduler" );
456 //}
457 // Increment reference count to track subsequent assignment.
458 // This increment likely has to be SeqCst
459 desul::atomic_inc(&(arg_f.m_task->m_ref_count),
460 desul::MemoryOrderSeqCst(),
461 desul::MemoryScopeDevice());
462 dep[i] = arg_f.m_task;
463 }
464 }
465
466 Kokkos::memory_fence();
467
468 m_queue->schedule_aggregate(f.m_task);
469 // this when_all may be processed at any moment
470 }
471 return f;
472 }
473
474 //----------------------------------------
475
476 KOKKOS_INLINE_FUNCTION
477 int allocation_capacity() const noexcept {
478 return m_queue->m_memory.capacity();
479 }
480
481 KOKKOS_INLINE_FUNCTION
482 int allocated_task_count() const noexcept { return m_queue->m_count_alloc; }
483
484 KOKKOS_INLINE_FUNCTION
485 int allocated_task_count_max() const noexcept { return m_queue->m_max_alloc; }
486
487 KOKKOS_INLINE_FUNCTION
488 long allocated_task_count_accum() const noexcept {
489 return m_queue->m_accum_alloc;
490 }
491
492 //----------------------------------------
493
494 template <class S, class Q>
495 friend void wait(Kokkos::BasicTaskScheduler<S, Q> const&);
496};
497
498} // namespace Kokkos
499
500//----------------------------------------------------------------------------
501//----------------------------------------------------------------------------
502
503namespace Kokkos {
504
505//----------------------------------------------------------------------------
506// Construct a TaskTeam execution policy
507
508template <class T, class Scheduler>
509KOKKOS_DEPRECATED Impl::TaskPolicyWithPredecessor<
510 Impl::TaskType::TaskTeam, Kokkos::BasicFuture<T, Scheduler>>
511 KOKKOS_INLINE_FUNCTION
512 TaskTeam(Kokkos::BasicFuture<T, Scheduler> arg_future,
513 TaskPriority arg_priority = TaskPriority::Regular) {
514 return {std::move(arg_future), arg_priority};
515}
516
517template <class Scheduler>
518KOKKOS_DEPRECATED Impl::TaskPolicyWithScheduler<Impl::TaskType::TaskTeam,
519 Scheduler>
520 KOKKOS_INLINE_FUNCTION TaskTeam(
521 Scheduler arg_scheduler,
522 std::enable_if_t<Kokkos::is_scheduler<Scheduler>::value, TaskPriority>
523 arg_priority = TaskPriority::Regular) {
524 return {std::move(arg_scheduler), arg_priority};
525}
526
527template <class Scheduler, class PredecessorFuture>
528KOKKOS_DEPRECATED Impl::TaskPolicyWithScheduler<
529 Kokkos::Impl::TaskType::TaskTeam, Scheduler, PredecessorFuture>
530 KOKKOS_INLINE_FUNCTION
531 TaskTeam(Scheduler arg_scheduler, PredecessorFuture arg_future,
534 TaskPriority>
535 arg_priority = TaskPriority::Regular) {
536 static_assert(
537 std::is_same_v<typename PredecessorFuture::scheduler_type, Scheduler>,
538 "Can't create a task policy from a scheduler and a future from "
539 "a different scheduler");
540
541 return {std::move(arg_scheduler), std::move(arg_future), arg_priority};
542}
543
544// Construct a TaskSingle execution policy
545
546template <class T, class Scheduler>
547KOKKOS_DEPRECATED Impl::TaskPolicyWithPredecessor<
548 Impl::TaskType::TaskSingle, Kokkos::BasicFuture<T, Scheduler>>
549 KOKKOS_INLINE_FUNCTION
550 TaskSingle(Kokkos::BasicFuture<T, Scheduler> arg_future,
551 TaskPriority arg_priority = TaskPriority::Regular) {
552 return {std::move(arg_future), arg_priority};
553}
554
555template <class Scheduler>
556KOKKOS_DEPRECATED Impl::TaskPolicyWithScheduler<Impl::TaskType::TaskSingle,
557 Scheduler>
558 KOKKOS_INLINE_FUNCTION TaskSingle(
559 Scheduler arg_scheduler,
560 std::enable_if_t<Kokkos::is_scheduler<Scheduler>::value, TaskPriority>
561 arg_priority = TaskPriority::Regular) {
562 return {std::move(arg_scheduler), arg_priority};
563}
564
565template <class Scheduler, class PredecessorFuture>
566KOKKOS_DEPRECATED Impl::TaskPolicyWithScheduler<
567 Kokkos::Impl::TaskType::TaskSingle, Scheduler, PredecessorFuture>
568 KOKKOS_INLINE_FUNCTION
569 TaskSingle(Scheduler arg_scheduler, PredecessorFuture arg_future,
572 TaskPriority>
573 arg_priority = TaskPriority::Regular) {
574 static_assert(
575 std::is_same_v<typename PredecessorFuture::scheduler_type, Scheduler>,
576 "Can't create a task policy from a scheduler and a future from "
577 "a different scheduler");
578
579 return {std::move(arg_scheduler), std::move(arg_future), arg_priority};
580}
581
582//----------------------------------------------------------------------------
583
590template <int TaskEnum, typename Scheduler, typename DepFutureType,
591 typename FunctorType>
592KOKKOS_DEPRECATED typename Scheduler::template future_type_for_functor<
593 std::decay_t<FunctorType>>
594host_spawn(Impl::TaskPolicyWithScheduler<TaskEnum, Scheduler, DepFutureType>
595 arg_policy,
596 FunctorType&& arg_functor) {
597 using scheduler_type = Scheduler;
598 using task_type =
599 typename scheduler_type::template runnable_task_type<FunctorType>;
600
601 static_assert(TaskEnum == Impl::TaskType::TaskTeam ||
602 TaskEnum == Impl::TaskType::TaskSingle,
603 "Kokkos host_spawn requires TaskTeam or TaskSingle");
604
605 // May be spawning a Cuda task, must use the specialization
606 // to query on-device function pointer.
607 typename task_type::function_type ptr;
608 typename task_type::destroy_type dtor;
609 Kokkos::Impl::TaskQueueSpecialization<
610 scheduler_type>::template get_function_pointer<task_type>(ptr, dtor);
611
612 return scheduler_type::spawn(std::move(arg_policy), ptr, dtor,
613 std::forward<FunctorType>(arg_functor));
614}
615
622template <int TaskEnum, typename Scheduler, typename DepFutureType,
623 typename FunctorType>
624KOKKOS_DEPRECATED typename Scheduler::template future_type_for_functor<
625 std::decay_t<FunctorType>>
626 KOKKOS_INLINE_FUNCTION
627 task_spawn(Impl::TaskPolicyWithScheduler<TaskEnum, Scheduler, DepFutureType>
628 arg_policy,
629 FunctorType&& arg_functor) {
630 using scheduler_type = Scheduler;
631
632 using task_type =
633 typename scheduler_type::template runnable_task_type<FunctorType>;
634
635 static_assert(TaskEnum == Impl::TaskType::TaskTeam ||
636 TaskEnum == Impl::TaskType::TaskSingle,
637 "Kokkos task_spawn requires TaskTeam or TaskSingle");
638
639 typename task_type::function_type const ptr = task_type::apply;
640 typename task_type::destroy_type const dtor = task_type::destroy;
641
642 return scheduler_type::spawn(std::move(arg_policy), ptr, dtor,
643 std::forward<FunctorType>(arg_functor));
644}
645
651template <typename FunctorType, typename T>
652KOKKOS_DEPRECATED void KOKKOS_INLINE_FUNCTION
653respawn(FunctorType* arg_self, T const& arg,
654 TaskPriority const& arg_priority = TaskPriority::Regular) {
656 "Kokkos respawn argument must be Future or TaskScheduler");
657
658 T::scheduler_type::respawn(arg_self, arg, arg_priority);
659}
660
661//----------------------------------------------------------------------------
662
663// template<typename ValueType, typename Scheduler>
664// KOKKOS_INLINE_FUNCTION
665// BasicFuture<void, Scheduler>
666// when_all(BasicFuture<ValueType, Scheduler> const arg[], int narg)
667//{
668// return BasicFuture<void, Scheduler>::scheduler_type::when_all(arg, narg);
669//}
670
671//----------------------------------------------------------------------------
672// Wait for all runnable tasks to complete
673
674template <class ExecSpace, class QueueType>
675KOKKOS_DEPRECATED inline void wait(
676 BasicTaskScheduler<ExecSpace, QueueType> const& scheduler) {
677 using scheduler_type = BasicTaskScheduler<ExecSpace, QueueType>;
678 scheduler_type::specialization::execute(scheduler);
679 // scheduler.m_queue->execute();
680}
681
682} // namespace Kokkos
683
684#ifdef KOKKOS_ENABLE_DEPRECATION_WARNINGS
685KOKKOS_IMPL_DISABLE_DEPRECATED_WARNINGS_POP()
686#endif
687
688//----------------------------------------------------------------------------
689//----------------------------------------------------------------------------
690
692// END OLD CODE
694
695#endif /* #if defined( KOKKOS_ENABLE_TASKDAG ) */
696#endif /* #ifndef KOKKOS_TASKSCHEDULER_HPP */
A thread safe view to a bitset.