alpaka
Abstraction Library for Parallel Kernel Acceleration
Loading...
Searching...
No Matches
executeForEach.hpp
Go to the documentation of this file.
1/* Copyright 2023 Jeffrey Kelling, Bernhard Manfred Gruber, Jan Stephan, Aurora Perego, Andrea Bocci, Tim Hanel
2 * SPDX-License-Identifier: MPL-2.0
3 */
4
5#include "alpaka/api/api.hpp"
8
9#include <functional>
10#include <tuple>
11#include <utility>
12
13#pragma once
14
15namespace alpaka::onHost
16{
17 /**! Execute a callable for each tuple entry.
18 *
19 * @attention: Execution is short-circuited and stops after the first error.
20 *
21 * @param callable Callable that can be invoked with each tuple entry and returns an execution status.
22 * A return value of zero (`EXIT_SUCCESS`) indicates success; any non-zero value indicates a failure.
23 * @param tuple Tuple like list of entries used to invoke the callable.
24 * @return The disjunction of all returned error codes. If false, the result is `EXIT_SUCCESS`;
25 * otherwise, at least a failure occurred.
26 */
27 template<template<typename...> class T_TupleLike, typename... T_Entries>
28 inline int executeForEach(auto&& callable, T_TupleLike<T_Entries...> const& tuple)
29 {
30 // Execute the callable once for each enabled accelerator.
31 // Pass the tag as first argument to the callable.
32 return std::apply(
33 [=](auto const&... tupleEntry)
34 {
35 static_assert(
36 (std::same_as<ALPAKA_TYPEOF(callable(tupleEntry)), int> && ...),
37 "The callable must return 'int'.");
38 return (static_cast<bool>(callable(tupleEntry)) || ...);
39 },
40 tuple)
41 == false
42 ? EXIT_SUCCESS
43 : EXIT_FAILURE;
44 }
45
46 /**! execute a callable for each device specification if there is a device available
47 *
48 * The function contains a runtime check if at least one device is available, if there is no device the callable
49 * will not be executed. Not executed combinations will return EXIT_SUCCESS.
50 *
51 * @attention: Execution is short-circuited and stops after the first error.
52 *
53 * @param callable Callable that can be invoked with device specification and returns an execution status.
54 * A return value of zero (`EXIT_SUCCESS`) indicates success; any non-zero value indicates a failure.
55 * @param tuple Tuple like list of device specifications used to invoke the callable.
56 * otherwise, at least one failure occurred.
57 * @return The disjunction of all returned error codes. If false, the result is `EXIT_SUCCESS`;
58 * otherwise, at least a failure occurred.
59 */
60 template<alpaka::concepts::DeviceSpec... T_DeviceSpecs>
61 inline int executeForEachIfHasDevice(auto&& callable, std::tuple<T_DeviceSpecs...> const& tupleOfDeviceSpecs)
62 {
63 auto exe = [=](auto const& devSpec)
64 {
65 auto devSelector = onHost::makeDeviceSelector(devSpec);
66 if(devSelector.isAvailable())
67 {
68 return callable(devSpec);
69 }
70 return EXIT_SUCCESS;
71 };
72 return executeForEach(exe, tupleOfDeviceSpecs);
73 }
74} // namespace alpaka::onHost
#define ALPAKA_TYPEOF(...)
Get the type of instance.
Definition common.hpp:154
Concept to check that a device specification with an API and device kind can be extracted.
Definition concepts.hpp:58
Functionality which is usable on the host CPU controller thread.
Definition api.hpp:40
int executeForEachIfHasDevice(auto &&callable, std::tuple< T_DeviceSpecs... > const &tupleOfDeviceSpecs)
!
auto makeDeviceSelector(T_DeviceSpec deviceSpec)
create an object to get access to devices
int executeForEach(auto &&callable, T_TupleLike< T_Entries... > const &tuple)
!