Fenix @develop
 
Loading...
Searching...
No Matches
fenix.hpp
1/*
2//@HEADER
3// ************************************************************************
4//
5//
6// _|_|_|_| _|_|_|_| _| _| _|_|_| _| _|
7// _| _| _|_| _| _| _| _|
8// _|_|_| _|_|_| _| _| _| _| _|
9// _| _| _| _|_| _| _| _|
10// _| _|_|_|_| _| _| _|_|_| _| _|
11//
12//
13//
14//
15// Copyright (C) 2016 Rutgers University and Sandia Corporation
16//
17// Under the terms of Contract DE-AC04-94AL85000 with Sandia Corporation,
18// the U.S. Government retains certain rights in this software.
19//
20// Redistribution and use in source and binary forms, with or without
21// modification, are permitted provided that the following conditions are
22// met:
23//
24// 1. Redistributions of source code must retain the above copyright
25// notice, this list of conditions and the following disclaimer.
26//
27// 2. Redistributions in binary form must reproduce the above copyright
28// notice, this list of conditions and the following disclaimer in the
29// documentation and/or other materials provided with the distribution.
30//
31// 3. Neither the name of the Corporation nor the names of the
32// contributors may be used to endorse or promote products derived from
33// this software without specific prior written permission.
34//
35// THIS SOFTWARE IS PROVIDED BY SANDIA CORPORATION "AS IS" AND ANY
36// EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
37// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
38// PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL SANDIA CORPORATION OR THE
39// CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
40// EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
41// PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
42// PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
43// LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
44// NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
45// SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
46//
47// Author Marc Gamell, Eric Valenzuela, Keita Teranishi, Manish Parashar,
48// Rob Van der Wijngaart, Michael Heroux, and Matthew Whitlock
49//
50// Questions? Contact Keita Teranishi (knteran@sandia.gov) and
51// Marc Gamell (mgamell@cac.rutgers.edu)
52//
53// ************************************************************************
54//@HEADER
55*/
56
57#ifndef __FENIX_HPP__
58#define __FENIX_HPP__
59
60#include <mpi.h>
61#include <functional>
62#include <vector>
63#include <optional>
64#include <variant>
65
66#include "fenix.h"
67#include "fenix_exception.hpp"
68#include "fenix/data/subset.hpp"
69
70namespace fenix {
71
72using Role = Fenix_Rank_role;
73constexpr Role INITIAL_RANK = FENIX_ROLE_INITIAL_RANK;
74constexpr Role RECOVERED_RANK = FENIX_ROLE_RECOVERED_RANK;
75constexpr Role SURVIVOR_RANK = FENIX_ROLE_SURVIVOR_RANK;
76constexpr Role SPARE_RANK = FENIX_ROLE_SPARE_RANK;
77constexpr Role FAILED_RANK = FENIX_ROLE_FAILED_RANK;
78
79using SettingName = Fenix_Setting_name;
80constexpr SettingName RECOVERY_MODE = FENIX_RECOVERY_MODE;
81constexpr SettingName RESUME_MODE = FENIX_RESUME_MODE;
82constexpr SettingName UNHANDLED_MODE = FENIX_UNHANDLED_MODE;
83constexpr SettingName CALLBACK_EXCEPTION_MODE = FENIX_CALLBACK_EXCEPTION_MODE;
84constexpr SettingName MLOG_RECOVERY_MODE = FENIX_MLOG_RECOVERY_MODE;
85constexpr SettingName SPARE_WAIT_MODE = FENIX_SPARE_WAIT_MODE;
86constexpr SettingName SPARE_FINALIZE_MODE = FENIX_SPARE_FINALIZE_MODE;
87
88using RecoveryMode = Fenix_Recovery_mode;
89constexpr RecoveryMode IGNORE = FENIX_RECOVERY_IGNORE;
90constexpr RecoveryMode NOOP = FENIX_RECOVERY_NOOP;
91constexpr RecoveryMode REPAIR = FENIX_RECOVERY_REPAIR;
92constexpr RecoveryMode SPAWN = FENIX_RECOVERY_SPAWN;
93
94using ResumeMode = Fenix_Resume_mode;
95constexpr ResumeMode JUMP = FENIX_RESUME_JUMP;
96constexpr ResumeMode RETURN = FENIX_RESUME_RETURN;
97constexpr ResumeMode THROW = FENIX_RESUME_THROW;
98
99using UnhandledMode = Fenix_Unhandled_mode;
100constexpr UnhandledMode SILENT = FENIX_UNHANDLED_SILENT;
101constexpr UnhandledMode PRINT = FENIX_UNHANDLED_PRINT;
102constexpr UnhandledMode ABORT = FENIX_UNHANDLED_ABORT;
103
104using CallbackExceptionMode = Fenix_Callback_exception_mode;
105constexpr CallbackExceptionMode RETHROW = FENIX_CALLBACK_EXCEPTION_RETHROW;
106constexpr CallbackExceptionMode SQUASH = FENIX_CALLBACK_EXCEPTION_SQUASH;
107
108using MlogRecoveryMode = Fenix_Mlog_recovery_mode;
109constexpr MlogRecoveryMode MANUAL = FENIX_MLOG_RECOVERY_MANUAL;
110constexpr MlogRecoveryMode INLINE = FENIX_MLOG_RECOVERY_INLINE;
111constexpr MlogRecoveryMode INLINE_AUTOSYNC =
113
114using SpareWaitMode = Fenix_Spare_wait_mode;
115constexpr SpareWaitMode BUSY = FENIX_SPARE_WAIT_BUSY;
116constexpr SpareWaitMode YIELD = FENIX_SPARE_WAIT_YIELD;
117constexpr SpareWaitMode SLEEP = FENIX_SPARE_WAIT_SLEEP;
118
119using SpareFinalizeMode = Fenix_Spare_finalize_mode;
120constexpr SpareFinalizeMode RELEASE = FENIX_SPARE_FINALIZE_RELEASE;
121constexpr SpareFinalizeMode EXIT = FENIX_SPARE_FINALIZE_EXIT;
122
123constexpr int STOREV_ALL = FENIX_STOREV_ALL;
124
125enum CallbackLocation { PRE_RECOVERY, POST_RECOVERY };
126
127namespace args {
129 int* role = nullptr;
130 MPI_Comm in_comm = MPI_COMM_WORLD;
131 MPI_Comm* out_comm = nullptr;
132 int* argc = nullptr;
133 char*** argv = nullptr;
134 int spares = 0;
135 int* err = nullptr;
136};
137}
138
139void init(const args::FenixInitArgs args);
140
142void set_option(SettingName setting, unsigned option);
143
145unsigned get_option(SettingName setting);
146
148void throw_exception();
149
151Role role();
152
154Role role(MPI_Comm comm, int rank);
155
157int n_ranks_with_role(Role role);
158
160int error();
161
163int nspare();
164
165using FenixCallbackFunc = std::function<void(MPI_Comm, int)>;
166
168int callback_register(
169 FenixCallbackFunc callback, CallbackLocation loc = POST_RECOVERY
170);
171
172//@!brief Overload of #Fenix_Callback_pop
173int callback_pop(CallbackLocation loc = POST_RECOVERY);
174
175//@!brief Overload of #Fenix_Callback_invoke_all
176int callback_invoke_all(CallbackLocation loc = POST_RECOVERY);
177
182std::vector<int> fail_list();
183
185int detect_failures(bool recover = true);
186
188bool initialized();
189
191bool finalized();
192
194int comm_revoke(MPI_Comm comm);
195
196} // namespace fenix
197
198namespace fenix::data {
199
200extern const DataSubset& SUBSET_FULL;
201extern const DataSubset& SUBSET_EMPTY;
202extern const DataSubset& SUBSET_PRESTAGED;
203extern DataSubset SUBSET_IGNORE;
204
205//@!brief Overload of #Fenix_Data_group_create
206int group_create(
207 int group_id, MPI_Comm comm, int start_time_stamp, int depth, int policy_name,
208 void* policy_value, int* flag
209);
210
212 // MPI_COMM_NULL defaults to the resilient communicator
213 MPI_Comm comm = MPI_COMM_NULL;
214 int start_time_stamp = 0;
215 int depth = 1;
216 int policy_name = FENIX_DATA_POLICY_IMR;
217 void* policy_value = nullptr;
218 int* flag = nullptr;
219};
220int group_create(int group_id, GroupCreateArgs args = {});
221
222//@!brief Overload of #Fenix_Data_group_created
223bool group_created(int group_id);
224
225//@!brief Overload of #Fenix_Data_member_create
226int member_create(
227 int group_id, int member_id, void* buffer, int count, MPI_Datatype datatype
228);
229
231using SerializeFileFunc = std::function<void(FILE*, int, void*, int, int)>;
233using SerializeStreamFunc =
234 std::function<void(std::iostream&, int, void*, int, int)>;
235
236using SerializeFunc = std::variant<SerializeFileFunc, SerializeStreamFunc>;
237
239int member_create(
240 int group_id, int member_id, void* buffer, int count, MPI_Datatype datatype,
241 SerializeFunc serializer
242);
243
245int member_define(
246 int group_id, int member_id, void* buffer, int count, MPI_Datatype datatype
247);
249int member_define(
250 int group_id, int member_id, void* buffer, int count, MPI_Datatype datatype,
251 SerializeFunc serializer
252);
253
254//@!brief Overload of #Fenix_Data_member_created
255bool member_created(int group_id, int member_id);
256
257int member_attr_set(
258 int group_id, int member_id, int attr, void* value, int* flag
259);
260
261int member_attr_get(
262 int group_id, int member_id, int attr, void* value, int* flag
263);
264
266int member_stage(
267 int group_id, int member_id, const DataSubset& subset = SUBSET_FULL
268);
269
271int member_stage_inplace(
272 int group_id, int member_id, void* buf, const DataSubset& subset = SUBSET_FULL
273);
274
276int member_stage_begin(int group_id, int member_id, FILE** fp);
278int member_stage_begin(int group_id, int member_id, std::iostream** stream);
279
281int member_stage_end(int group_id, int member_id);
282
284int member_store(
285 int group_id, int member_id, const DataSubset& subset = SUBSET_FULL
286);
288inline int member_store(int group_id, const DataSubset& subset = SUBSET_FULL) {
289 return member_store(group_id, FENIX_DATA_MEMBER_ALL, subset);
290}
291
293int member_storev(int group_id, int member_id, const DataSubset& subset);
295inline int member_storev(int group_id, const DataSubset& subset) {
296 return member_storev(group_id, FENIX_DATA_MEMBER_ALL, subset);
297}
298
300int member_istore(
301 int group_id, int member_id, const DataSubset& subset, Fenix_Request* request
302);
303
305 int member_id = FENIX_DATA_MEMBER_ALL;
306 const DataSubset& subset = SUBSET_FULL;
307};
309inline int member_istore(
310 int group_id, Fenix_Request* request, MemberIstoreArgs args = {}
311) {
312 return member_istore(group_id, args.member_id, args.subset, request);
313}
314
316int member_istorev(
317 int group_id, int member_id, const DataSubset& subset, Fenix_Request* request
318);
320inline int member_istorev(
321 int group_id, const DataSubset& subset, Fenix_Request* request
322) {
323 return member_istorev(group_id, FENIX_DATA_MEMBER_ALL, subset, request);
324}
325
327int member_repair(int group_id, int member_id);
328
330int member_load(
331 int group_id, int member_id, int time_stamp = FENIX_DATA_SNAPSHOT_ALL,
332 DataSubset& data_found = SUBSET_IGNORE
333);
334
336int member_load(
337 int group_id, int member_id, void* target,
338 int target_count = FENIX_DATA_RESTORE_FULL,
339 int time_stamp = FENIX_DATA_SNAPSHOT_ALL,
340 DataSubset& data_found = SUBSET_IGNORE
341);
342
344int member_load_begin(
345 int group_id, int member_id, FILE** fp,
346 int time_stamp = FENIX_DATA_SNAPSHOT_LATEST,
347 DataSubset& data_found = SUBSET_IGNORE
348);
349
351int member_load_begin(
352 int group_id, int member_id, std::iostream** strm,
353 int time_stamp = FENIX_DATA_SNAPSHOT_LATEST,
354 DataSubset& data_found = SUBSET_IGNORE
355);
356
357//@!brief Overload of #Fenix_Data_member_load_end
358int member_load_end(int group_id, int member_id);
359
361int member_restore(
362 int group_id, int member_id, void* target_buffer = FENIX_DATA_RESTORE_INPLACE,
363 int max_length = FENIX_DATA_RESTORE_FULL,
364 int time_stamp = FENIX_DATA_SNAPSHOT_ALL,
365 DataSubset& data_found = SUBSET_IGNORE
366);
367
369[[deprecated("Use member_load functions instead")]]
370int member_lrestore(
371 int group_id, int member_id, void* target_buffer = FENIX_DATA_RESTORE_INPLACE,
372 int max_length = FENIX_DATA_RESTORE_FULL,
373 int time_stamp = FENIX_DATA_SNAPSHOT_ALL,
374 DataSubset& data_found = SUBSET_IGNORE
375);
376
378int commit(int group_id, int* time_stamp = nullptr);
379
381int commit_barrier(int group_id, int* time_stamp = nullptr);
382
384int checkpoint(
385 int group_id, const DataSubset& subset,
386 const std::vector<int>& storev_ids = {}, int* time_stamp = nullptr
387);
388
390int checkpointv(
391 int group_id, const DataSubset& subset, int* time_stamp = nullptr
392);
393
398std::optional<std::vector<int>> group_members(int group_id);
399
404std::optional<std::vector<int>> group_snapshots(int group_id);
405
406//@!brief Overload of #Fenix_Data_group_get_cohort
407MPI_Group group_cohort(int group_id);
408
409//@!brief Overload of #Fenix_Data_snapshot_delete
410int snapshot_delete(int group_id, int timestamp);
411
412//@!brief Overload of #Fenix_Data_group_delete
413int group_delete(int group_id);
414
415//@!brief Overload of #Fenix_Data_member_delete
416int member_delete(int group_id, int member_id);
417
418} // namespace fenix::data
419
420namespace fenix::mlog {
421
422//@brief Overload of #Fenix_Mlog_create
423int create(int mlog_id, MPI_Comm& comm, int depth);
424
425//@brief Overload of #Fenix_Mlog_activate
426int activate(int mlog_id);
427
428//@brief Overload of Fenix_Mlog_active, returns active log
429int active();
430
431//@brief Overload of #Fenix_Mlog_begin_region
432int begin_region(int mlog_id, int region_id);
433
434//@brief Overload of #Fenix_Mlog_activate_region
435int activate(int mlog_id, int region_id);
436
437//@brief Overload of #Fenix_Mlog_sync
438int sync(int mlog_id, int region_id = FENIX_MLOG_CONTINUE);
439
440//@brief Overload of #Fenix_Mlog_create_data_member
441int create_data_member(int mlog_id, int group_id, int member_id);
442
443//@brief Overload of #Fenix_Mlog_define_data_member
444int define_data_member(int mlog_id, int group_id, int member_id);
445
446//@brief Overload of #Fenix_Mlog_delete
447int mlog_delete(int mlog_id);
448
449} // namespace fenix::mlog
450
451#endif
Contains all API function calls and Fenix types. This is the only header file a user should include.
Fenix_Unhandled_mode
Options for dealing with 'unhandled' errors, e.g. invalid rank IDs.
Definition fenix.h:277
Fenix_Spare_finalize_mode
Options for what spare ranks should do when Fenix_Finalize is called. Must be set before Fenix_Init t...
Definition fenix.h:322
Fenix_Resume_mode
Options for passing control back to application after recovery.
Definition fenix.h:250
Fenix_Recovery_mode
Options for recovering after a failed rank is detected.
Definition fenix.h:208
Fenix_Spare_wait_mode
Options for how spare ranks wait to be needed. Must be set before Fenix_Init to take effect.
Definition fenix.h:293
Fenix_Callback_exception_mode
Options for dealing with CommExceptions generated in callbacks.
Definition fenix.h:308
Fenix_Setting_name
Global Fenix settings.
Definition fenix.h:185
Fenix_Mlog_recovery_mode
Definition fenix.h:226
Fenix_Rank_role
All possible roles returned by Fenix_Init.
Definition fenix.h:169
@ FENIX_UNHANDLED_PRINT
Print error and continue without handling.
Definition fenix.h:281
@ FENIX_UNHANDLED_SILENT
Ignore unhandled errors.
Definition fenix.h:279
@ FENIX_UNHANDLED_ABORT
Print error and abort Fenix's world (default)
Definition fenix.h:283
@ FENIX_SPARE_FINALIZE_EXIT
Finalize MPI and exit (default),.
Definition fenix.h:326
@ FENIX_SPARE_FINALIZE_RELEASE
Continue from Fenix_Init with Fenix_Rank_role FENIX_RANK_ROLE_SPARE.
Definition fenix.h:324
@ FENIX_RESUME_THROW
Throw a fenix::CommException.
Definition fenix.h:268
@ FENIX_RESUME_JUMP
Return to Fenix_Init via longjmp (default)
Definition fenix.h:264
@ FENIX_RESUME_RETURN
Return the error code inline.
Definition fenix.h:266
@ FENIX_RECOVERY_IGNORE
Do not repair communicator, immediately resume per FENIX_RESUME_MODE.
Definition fenix.h:210
@ FENIX_RECOVERY_REPAIR
Repair the communicator with spares or by shrinking.
Definition fenix.h:218
@ FENIX_RECOVERY_SPAWN
<span class="mlabel"> UNIMPLEMENTED </span> As REPAIR, but attempt to respawn failed processes
Definition fenix.h:220
@ FENIX_RECOVERY_NOOP
Do not repair communicator, otherwise behave normally.
Definition fenix.h:216
@ FENIX_SPARE_WAIT_YIELD
Tell MPI to yield this thread while waiting (if supported, else busy wait)
Definition fenix.h:297
@ FENIX_SPARE_WAIT_SLEEP
Sleep 100ms between checks to see if this thread is needed for recovery.
Definition fenix.h:299
@ FENIX_SPARE_WAIT_BUSY
Busy wait, consuming CPU time in exchange for faster response.
Definition fenix.h:295
@ FENIX_CALLBACK_EXCEPTION_SQUASH
CommExceptions from callbacks are squashed.
Definition fenix.h:312
@ FENIX_CALLBACK_EXCEPTION_RETHROW
CommExceptions are allowed to propagate out of callbacks.
Definition fenix.h:310
@ FENIX_RESUME_MODE
See Fenix_Resume_mode.
Definition fenix.h:189
@ FENIX_MLOG_RECOVERY_MODE
See Fenix_Mlog_recovery_mode.
Definition fenix.h:195
@ FENIX_SPARE_FINALIZE_MODE
See Fenix_Spare_finalize_mode.
Definition fenix.h:199
@ FENIX_SPARE_WAIT_MODE
See Fenix_Spare_wait_mode.
Definition fenix.h:197
@ FENIX_CALLBACK_EXCEPTION_MODE
See Fenix_Callback_exception_mode.
Definition fenix.h:193
@ FENIX_RECOVERY_MODE
See Fenix_Recovery_mode.
Definition fenix.h:187
@ FENIX_UNHANDLED_MODE
See Fenix_Unhandled_mode.
Definition fenix.h:191
@ FENIX_MLOG_RECOVERY_MANUAL
All message logging recovery is manual.
Definition fenix.h:228
@ FENIX_MLOG_RECOVERY_INLINE_AUTOSYNC
As INLINE, but automatically sync logs with FENIX_MLOG_CONTINUE.
Definition fenix.h:242
@ FENIX_MLOG_RECOVERY_INLINE
Automatically repeats failed, logged MPI operations without disrupting normal application control flo...
Definition fenix.h:235
@ FENIX_ROLE_SPARE_RANK
This rank was a spare when Fenix finalized.
Definition fenix.h:177
@ FENIX_ROLE_RECOVERED_RANK
This rank was a spare before the most recent failure, or was just spawned.
Definition fenix.h:173
@ FENIX_ROLE_INITIAL_RANK
No failures have occurred yet.
Definition fenix.h:171
@ FENIX_ROLE_SURVIVOR_RANK
This rank was not a spare before the most recent failure.
Definition fenix.h:175
@ FENIX_ROLE_FAILED_RANK
This rank no longer exists (process failed)
Definition fenix.h:179
<span class="mlabel"> UNIMPLEMENTED </span> As MPI_Request, but for Fenix asynchronous data recove...
Definition fenix.h:634
Definition subset.hpp:152
Definition fenix.hpp:128
Definition fenix.hpp:211
Definition fenix.hpp:304