• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

celerity / celerity-runtime / 8329571092

18 Mar 2024 03:49PM UTC coverage: 94.63% (+0.7%) from 93.968%
8329571092

push

github

fknorr
Update benchmark results for IDAG generation

2907 of 3248 branches covered (89.5%)

Branch coverage included in aggregate %.

6574 of 6771 relevant lines covered (97.09%)

179871.27 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

96.72
/include/command.h
1
#pragma once
2

3
#include <cstddef>
4
#include <variant>
5

6
#include "intrusive_graph.h"
7
#include "mpi_support.h"
8
#include "ranges.h"
9
#include "task.h"
10
#include "types.h"
11

12
#include <matchbox.hh>
13

14
namespace celerity {
15
namespace detail {
16

17
        enum class command_type { epoch, horizon, execution, push, await_push, reduction, fence };
18

19
        // ----------------------------------------------------------------------------------------------------------------
20
        // ------------------------------------------------ COMMAND GRAPH -------------------------------------------------
21
        // ----------------------------------------------------------------------------------------------------------------
22

23
        class abstract_command : public intrusive_graph_node<abstract_command>,
24
                                 // Accept visitors to enable matchbox::match() on the command inheritance hierarchy
25
                                 public matchbox::acceptor<class epoch_command, class horizon_command, class execution_command, class push_command,
26
                                     class await_push_command, class reduction_command, class fence_command> {
27
                friend class command_graph;
28

29
          protected:
30
                abstract_command(command_id cid) : m_cid(cid) {}
8,371✔
31

32
          public:
33
                virtual command_type get_type() const = 0;
34

35
                command_id get_cid() const { return m_cid; }
130,636✔
36

37
                void mark_as_flushed() {
6,638✔
38
                        assert(!m_flushed);
6,638✔
39
                        m_flushed = true;
6,638✔
40
                }
6,638✔
41
                bool is_flushed() const { return m_flushed; }
15,002✔
42

43
          private:
44
                // Should only be possible to add/remove dependencies using command_graph.
45
                using parent_type = intrusive_graph_node<abstract_command>;
46
                using parent_type::add_dependency;
47
                using parent_type::remove_dependency;
48

49
                command_id m_cid;
50
                bool m_flushed = false;
51
        };
52

53
        class push_command final : public matchbox::implement_acceptor<abstract_command, push_command> {
54
                friend class command_graph;
55
                push_command(const command_id cid, const node_id target, const transfer_id& trid, const subrange<3>& push_range)
605✔
56
                    : acceptor_base(cid), m_target(target), m_trid(trid), m_push_range(push_range) {}
605✔
57

58
                command_type get_type() const override { return command_type::push; }
263✔
59

60
          public:
61
                node_id get_target() const { return m_target; }
779✔
62
                const transfer_id& get_transfer_id() const { return m_trid; }
1,674✔
63
                const subrange<3>& get_range() const { return m_push_range; }
1,270✔
64

65
          private:
66
                node_id m_target;
67
                transfer_id m_trid;
68
                subrange<3> m_push_range;
69
        };
70

71
        class await_push_command final : public matchbox::implement_acceptor<abstract_command, await_push_command> {
72
                friend class command_graph;
73
                await_push_command(const command_id cid, const transfer_id& trid, region<3> region) : acceptor_base(cid), m_trid(trid), m_region(std::move(region)) {}
393✔
74

75
                command_type get_type() const override { return command_type::await_push; }
210✔
76

77
          public:
78
                const transfer_id& get_transfer_id() const { return m_trid; }
674✔
79
                const region<3>& get_region() const { return m_region; }
498✔
80

81
          private:
82
                transfer_id m_trid;
83
                region<3> m_region;
84
        };
85

86
        class reduction_command final : public matchbox::implement_acceptor<abstract_command, reduction_command> {
87
                friend class command_graph;
88
                reduction_command(command_id cid, const reduction_info& info, const bool has_local_contribution)
61✔
89
                    : acceptor_base(cid), m_info(info), m_has_local_contribution(has_local_contribution) {}
61✔
90

91
                command_type get_type() const override { return command_type::reduction; }
70✔
92

93
          public:
94
                const reduction_info& get_reduction_info() const { return m_info; }
205✔
95
                bool has_local_contribution() const { return m_has_local_contribution; }
72✔
96

97
          private:
98
                reduction_info m_info;
99
                bool m_has_local_contribution;
100
        };
101

102
        class task_command : public abstract_command {
103
          protected:
104
                task_command(command_id cid, task_id tid) : abstract_command(cid), m_tid(tid) {}
7,312✔
105

106
          public:
107
                task_id get_tid() const { return m_tid; }
33,386✔
108

109
          private:
110
                task_id m_tid;
111
        };
112

113
        class epoch_command final : public matchbox::implement_acceptor<task_command, epoch_command> {
114
                friend class command_graph;
115
                epoch_command(const command_id cid, const task_id tid, const epoch_action action, std::vector<reduction_id> completed_reductions)
1,949✔
116
                    : acceptor_base(cid, tid), m_action(action), m_completed_reductions(std::move(completed_reductions)) {}
1,949✔
117

118
                command_type get_type() const override { return command_type::epoch; }
692✔
119

120
          public:
121
                epoch_action get_epoch_action() const { return m_action; }
1,946✔
122
                const std::vector<reduction_id>& get_completed_reductions() const { return m_completed_reductions; }
688✔
123

124
          private:
125
                epoch_action m_action;
126
                std::vector<reduction_id> m_completed_reductions;
127
        };
128

129
        class horizon_command final : public matchbox::implement_acceptor<task_command, horizon_command> {
130
                friend class command_graph;
131
                horizon_command(const command_id cid, const task_id tid, std::vector<reduction_id> completed_reductions)
563✔
132
                    : acceptor_base(cid, tid), m_completed_reductions(std::move(completed_reductions)) {}
563✔
133

134
                command_type get_type() const override { return command_type::horizon; }
1,011✔
135

136
          public:
137
                const std::vector<reduction_id>& get_completed_reductions() const { return m_completed_reductions; }
249✔
138

139
          private:
140
                std::vector<reduction_id> m_completed_reductions;
141
        };
142

143
        class execution_command final : public matchbox::implement_acceptor<task_command, execution_command> {
144
                friend class command_graph;
145

146
          protected:
147
                execution_command(command_id cid, task_id tid, subrange<3> execution_range) : acceptor_base(cid, tid), m_execution_range(execution_range) {}
4,740✔
148

149
          public:
150
                command_type get_type() const override { return command_type::execution; }
2,360✔
151

152
                const subrange<3>& get_execution_range() const { return m_execution_range; }
6,418✔
153

154
                void set_is_reduction_initializer(bool is_initializer) { m_initialize_reductions = is_initializer; }
14✔
155

156
                bool is_reduction_initializer() const { return m_initialize_reductions; }
5,020✔
157

158
          private:
159
                subrange<3> m_execution_range;
160
                bool m_initialize_reductions = false;
161
        };
162

163
        class fence_command final : public matchbox::implement_acceptor<task_command, fence_command> {
164
                friend class command_graph;
165
                using acceptor_base::acceptor_base;
166

167
                command_type get_type() const override { return command_type::fence; }
25✔
168
        };
169

170
        /// Hash function for `unordered_sets/maps` of `command *` that is deterministic even as allocation addresses change between application runs.
171
        struct command_hash_by_id {
172
                template <typename Pointer>
173
                constexpr size_t operator()(const Pointer instr) const {
35,325✔
174
                        return std::hash<command_id>()(instr->get_cid());
35,325✔
175
                }
176
        };
177

178
        using command_set = std::unordered_set<abstract_command*, command_hash_by_id>;
179

180
        // ----------------------------------------------------------------------------------------------------------------
181
        // -------------------------------------------- SERIALIZED COMMANDS -----------------------------------------------
182
        // ----------------------------------------------------------------------------------------------------------------
183

184
        // TODO: These are a holdover from the master/worker scheduling model. Remove at some point.
185
        // The only reason we keep them around for now is that they allow us to persist commands beyond graph pruning.
186
        // They no longer have to be network-serializable though.
187

188
        struct horizon_data {
189
                task_id tid;
190
        };
191

192
        struct epoch_data {
193
                task_id tid;
194
                epoch_action action;
195
        };
196

197
        struct execution_data {
198
                task_id tid;
199
                subrange<3> sr;
200
                bool initialize_reductions;
201
        };
202

203
        struct push_data {
204
                node_id target;
205
                transfer_id trid;
206
                subrange<3> sr;
207
        };
208

209
        struct await_push_data {
210
                transfer_id trid;
211
                detail::region<3> region;
212
        };
213

214
        struct reduction_data {
215
                reduction_id rid;
216
        };
217

218
        struct fence_data {
219
                task_id tid;
220
        };
221

222
        using command_data = std::variant<std::monostate, horizon_data, epoch_data, execution_data, push_data, await_push_data, reduction_data, fence_data>;
223

224
        struct command_pkg {
225
                command_id cid{};
226
                command_data data{};
227
                std::vector<command_id> dependencies;
228

229
                std::optional<task_id> get_tid() const {
15,859✔
230
                        // clang-format off
231
                        return matchbox::match(data,
31,718✔
232
                                [](const horizon_data& d) { return std::optional{d.tid}; },
690✔
233
                                [](const epoch_data& d) { return std::optional{d.tid}; },
2,516✔
234
                                [](const execution_data& d) { return std::optional{d.tid}; },
11,115✔
235
                                [](const fence_data& d) { return std::optional{d.tid}; },
82✔
236
                                [](const auto&) { return std::optional<task_id>{}; }
1,456✔
237
                        );
31,718✔
238
                        // clang-format on
239
                }
240

241
                command_type get_command_type() const {
19,083✔
242
                        // clang-format off
243
                        return matchbox::match(data,
19,083✔
244
                                [](const std::monostate&) -> command_type {
×
245
                                        assert(!"calling get_command_type() on an empty command_pkg");
×
246
                                        std::terminate();
247
                                },
248
                                [](const horizon_data&) { return command_type::horizon; },
1,047✔
249
                                [](const epoch_data&) { return command_type::epoch; },
3,792✔
250
                                [](const execution_data&) { return command_type::execution; },
11,142✔
251
                                [](const push_data&) { return command_type::push; },
1,803✔
252
                                [](const await_push_data&) { return command_type::await_push; },
1,120✔
253
                                [](const reduction_data&) { return command_type::reduction; },
48✔
254
                                [](const fence_data&) { return command_type::fence; }
131✔
255
                        );
38,166✔
256
                        // clang-format on
257
                }
258
        };
259

260
} // namespace detail
261
} // namespace celerity
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2026 Coveralls, Inc