5#define TW_GVT_COMPUTE 1
17#ifdef USE_RAND_TIEBREAKER
18MPI_Datatype event_sig_type;
20MPI_Aint event_sig_displacements[4];
21MPI_Datatype event_sig_types[4] = {MPI_DOUBLE, MPI_DOUBLE, MPI_DOUBLE, MPI_UNSIGNED};
22MPI_Aint event_sig_base_address;
23MPI_Op event_sig_min_op;
26void find_min_sig(
void *in,
void *inout,
int *len, MPI_Datatype *datatype) {
31 for (
int i=0; i < *len; i++) {
42 in_sig++; inout_sig++;
50 TWOPT_UINT(
"gvt-interval",
g_tw_gvt_interval,
"GVT Interval: Iterations through scheduling loop (synch=1,2,3,4), or ms between GVTs (synch=5)"),
71#ifdef USE_RAND_TIEBREAKER
72 MPI_Get_address(&dummy_event_sig, &event_sig_base_address);
73 MPI_Get_address(&dummy_event_sig.
recv_ts, &event_sig_displacements[0]);
74 MPI_Get_address(&dummy_event_sig.
priority, &event_sig_displacements[1]);
75 MPI_Get_address(&dummy_event_sig.
event_tiebreaker, &event_sig_displacements[2]);
78 for (
int i = 0; i < 4; i++) {
79 event_sig_displacements[i] = MPI_Aint_diff(event_sig_displacements[i], event_sig_base_address);
82 MPI_Type_create_struct(4, event_sig_blocklengths, event_sig_displacements, event_sig_types, &event_sig_type);
83 MPI_Type_commit(&event_sig_type);
84 MPI_Op_create(find_min_sig, 1, &event_sig_min_op);
91#ifdef USE_RAND_TIEBREAKER
92 MPI_Op_free(&event_sig_min_op);
93 MPI_Type_free(&event_sig_type);
114 fprintf(f,
"\nTW GVT Statistics: MPI AllReduce\n");
118 fprintf(f,
"\t%-50s %11d\n",
"Batch Size",
g_tw_mblock);
120 fprintf(f,
"\t%-50s %11d\n",
"Forced GVT",
gvt_force);
121 fprintf(f,
"\t%-50s %11d\n",
"Total GVT Computations",
g_tw_gvt_done);
122 fprintf(f,
"\t%-50s %11lld\n",
"Total All Reduce Calls",
all_reduce_cnt);
123 fprintf(f,
"\t%-50s %11.2lf\n",
"Average Reduction / GVT",
128#ifdef USE_RAND_TIEBREAKER
129#define NOT_PAST_LOOKAHEAD(pe) (TW_STIME_DBL(tw_pq_minimum_sig_ptr(pe->pq)->recv_ts) - TW_STIME_DBL(pe->GVT_sig.recv_ts) < g_tw_max_opt_lookahead)
130#define PAST_GVT_HOOK_ACTIVATION(pe) (\
131 g_tw_gvt_hook_trigger.status == GVT_HOOK_STATUS_timestamp \
132 && tw_event_sig_compare_ptr(tw_pq_minimum_sig_ptr(pe->pq), &g_tw_gvt_hook_trigger.sig_at) >= 0)
134#define NOT_PAST_LOOKAHEAD(pe) (TW_STIME_DBL(tw_pq_minimum(pe->pq)) - TW_STIME_DBL(pe->GVT) < g_tw_max_opt_lookahead)
135#define PAST_GVT_HOOK_ACTIVATION(pe) (\
136 g_tw_gvt_hook_trigger.status == GVT_HOOK_STATUS_timestamp \
137 && tw_pq_minimum(me->pq) >= g_tw_gvt_hook_trigger.at)
169#ifdef USE_RAND_TIEBREAKER
177 long long local_white = 0;
178 long long total_white = 0;
234 tw_error(
TW_LOC,
"MPI_Allreduce for GVT event signatures failed");
247 "GVT computed %d times in a row"
248 " without changing: GVT = %14.14lf, PREV %14.14lf"
249 " -- GLOBAL SYNCH -- out of memory!",
292 if (g_st_damaris_enabled)
294 st_damaris_expose_data(me, gvt,
GVT_COL);
295 st_damaris_end_iteration();
308 st_damaris_end_iteration();
327 long long local_white = 0;
328 long long total_white = 0;
393 "GVT computed %d times in a row"
394 " without changing: GVT = %14.14lf, PREV %14.14lf"
395 " -- GLOBAL SYNCH -- out of memory!",
403 me->
id, me->
GVT, gvt);
437 if (g_st_damaris_enabled)
439 st_damaris_expose_data(me, gvt,
GVT_COL);
440 st_damaris_end_iteration();
453 st_damaris_end_iteration();
471#ifdef USE_RAND_TIEBREAKER
477 .event_tiebreaker = {0.0},
478 .tie_lineage_length = 1};
481 tw_warning(
TW_LOC,
"Trying to schedule arbitrary function trigger at a time in the past %e, current GVT %e\n", time, now.
recv_ts);
492 tw_warning(
TW_LOC,
"Trying to schedule arbitrary function trigger at a time in the past %e, current GVT %e\n", time, now);
500#ifdef USE_RAND_TIEBREAKER
515 if (num_gvt_calls <= 0) {
516 tw_error(
TW_LOC,
"`tw_trigger_gvt_hook_every` has been called with a non-positive argument: %d", num_gvt_calls);
534 tw_error(
TW_LOC,
"`tw_trigger_gvt_hook_now` called but `g_tw_gvt_hook_trigger.status != GVT_HOOK_STATUS_model_call`. Either `tw_trigger_gvt_hook_when_model_calls` was not called or another trigger function has been");
static tw_clock tw_clock_read(void)
static double percent_complete
static double gvt_print_interval
static void gvt_print(tw_stime gvt)
void st_collect_engine_data(tw_pe *me, int col_type)
void st_collect_model_data(tw_pe *pe, double current_rt, int stats_type)
void tw_net_read(tw_pe *)
starts service_queues() to poll network
tw_event_sig const * tw_net_minimum_sig_ptr(void)
Obtain the event signature for the lowest ordered event inside the network buffers.
tw_stime tw_net_minimum(void)
Obtain the lowest timestamp inside the network buffers.
tw_stime tw_pq_minimum(tw_pq *)
#define MPI_TYPE_TW_STIME
#define TW_STIME_CMP(x, y)
void tw_pe_fossil_collect(void)
unsigned long long g_tw_clock_rate
unsigned long long g_tw_gvt_interval_start_cycles
void tw_error(const char *file, int line, const char *fmt,...)
unsigned int g_tw_gvt_done
void tw_warning(const char *file, int line, const char *fmt,...)
unsigned int g_tw_gvt_interval
unsigned long long g_tw_gvt_realtime_interval
tw_synch g_tw_synchronization_protocol
void tw_trigger_gvt_hook_at_event_sig(tw_event_sig time)
@ GVT_HOOK_STATUS_disabled
@ GVT_HOOK_STATUS_timestamp
@ GVT_HOOK_STATUS_every_n_gvt
struct gvt_hook_trigger g_tw_gvt_hook_trigger
void(* g_tw_gvt_hook)(tw_pe *pe, bool is_queue_empty)
static int tw_event_sig_compare_ptr(tw_event_sig const *e_sig, tw_event_sig const *n_sig)
tw_event_sig const g_tw_max_sig
static void tw_copy_event_sig(tw_event_sig *e, tw_event_sig const *sig)
unsigned long long tw_stat
#define TWOPT_UINT(n, v, h)
#define TWOPT_DOUBLE(n, v, h)
@ GVT_HOOK_STATUS_model_call
static const tw_optdef gvt_opts[]
static unsigned int gvt_force
void tw_gvt_stats(FILE *f)
#define PAST_GVT_HOOK_ACTIVATION(pe)
void tw_gvt_force_update(void)
static tw_stat all_reduce_cnt
void tw_trigger_gvt_hook_now_rev(tw_lp *lp)
void tw_trigger_gvt_hook_at(tw_stime time)
void tw_trigger_gvt_hook_now(tw_lp *lp)
static unsigned int gvt_cnt
void tw_gvt_step1_realtime(tw_pe *me)
void tw_gvt_force_update_realtime(void)
static unsigned int g_tw_gvt_max_no_change
void tw_trigger_gvt_hook_every(int num_gvt_calls)
void tw_trigger_gvt_hook_when_model_calls(void)
void tw_gvt_step1(tw_pe *me)
tw_stat st_get_allreduce_count()
#define NOT_PAST_LOOKAHEAD(pe)
const tw_optdef * tw_gvt_setup(void)
static unsigned int g_tw_gvt_no_change
void tw_gvt_step2(tw_pe *me)
double event_tiebreaker[20]
unsigned int tie_lineage_length
tw_event_sig last_sig
Event signature of the current event being processed.
tw_kp * kp
kp – Kernel process that we belong to (must match pe).
unsigned int triggered_gvt_hook
Holds the entire PE state.
tw_pq * pq
Priority queue used to sort events.
tw_event_sig trans_msg_sig
Last transient messages' time signature.
tw_stime GVT
Global Virtual Time.
tw_stime trans_msg_ts
Last transient messages' time stamp.
unsigned char gvt_status
Bits available for gvt computation.
tw_statistics stats
per PE counters
tw_event_sig GVT_sig
Global Virtual Time Signature.
tw_event_sig GVT_prev_sig
tw_clock s_fossil_collect