void free_operator(struct Operator *c) { ref_dec(c->args); ref_dec(c->body); ref_dec(c->env); deallocate(c, sizeof(struct Operator)); }
void free_closure(struct Closure *c) { ref_dec(c->args); ref_dec(c->body); ref_dec(c->env); deallocate(c, sizeof(struct Closure)); }
/* * Fills the arrays / queues with the states from the trace file and updates * counters. Assumes everything passed (except the filename) to be NULL/0. */ static void read_events(char const *filename, size_t *ranks, struct State_q **state_q, struct Link_q ***links, outter_t *sends, struct State_q ***recvs, uint64_t **slens, double **last, double **clast, struct State_q ***scattersS, struct State_q ***scattersR, struct State_q ***gathersS, struct State_q ***gathersR) { /* Important for some (size_t) conversions from marks registered as uint64 */ assert(SIZE_MAX <= UINT64_MAX); FILE *f = fopen(filename, "r"); if (!f) LOG_AND_EXIT("Could not open %s: %s\n", filename, strerror(errno)); char *line = mygetline(f); if (!line) REPORT_AND_EXIT; uint64_t *scaps = NULL; uint64_t const ocap = 10; /* Initialize all arrs/queues with one rank each */ grow_outer(ranks, 1, links, sends, recvs, scattersS, scattersR, gathersS, gathersR, last, clast, slens, &scaps, ocap); do { /* strtok shenanigans */ char *state_line = strdup(line), *link_line = strdup(line), *etc_line = strdup(line); free(line); if (!state_line || !link_line || !etc_line) REPORT_AND_EXIT; struct State *state = state_from_line(state_line); if (!state) { struct Link *link = link_from_line(link_line); if (!link) { LOG_DEBUG("Line is not a State nor a Link\n");//: %s", etc_line); printf("%s", etc_line); } else { size_t rank = (size_t)(link->to + 1); if (rank > *ranks) grow_outer(ranks, rank, links, sends, recvs, scattersS, scattersR, gathersS, gathersR, last, clast, slens, &scaps, ocap); /* (grow outer aborts on failure) */ link_q_push_ref((*links) + link->to, link); /* Toss away our local ref obtained on allocation */ ref_dec(&(link->ref)); } } else { size_t rank = (size_t)(state->rank + 1); if (rank > *ranks) grow_outer(ranks, rank, links, sends, recvs, scattersS, scattersR, gathersS, gathersR, last, clast, slens, &scaps, ocap); if ((*last)[state->rank] < 0) (*last)[state->rank] = state->start; state_q_push_ref(state_q, state); if (state_is_send(state)) { (*sends)[state->rank][(*slens)[state->rank]] = state; ref_inc(&(state->ref)); if (++((*slens)[state->rank]) >= scaps[state->rank]) grow_inner((*sends) + state->rank, scaps + state->rank); } else if (state_is_recv(state)) { state_q_push_ref((*recvs) + state->rank, state); } else if (state_is_wait(state)) { /* * For now we only support MPI_Wait for MPI_Isend (->mark). Thus, * MPI_Wait is always in the same rank as the matching MPI_Isend and * always comes after it, so we can assume the matching send has * already been processed and create a temporary comm in here, to be * used later to link the MPI_Wait to the MPI_Recv it is actually * waiting for (we assume MPI_Isend was synchronous, albeit * instantaneous, and we assert for that). */ if ((*slens)[state->rank] <= state->mark) { LOG_CRITICAL("There is no Send for the Wait. Did you call MPI_Wait " "without (or before) a matching MPI_Isend? This is not " "supported.\n"); exit(EXIT_FAILURE); } // TODO can this be moved to pj_compensate.c with the rest? struct State *send = (*sends)[state->rank][state->mark]; assert(send->mark == state->mark); send->comm.c = comm_new(state, NULL, 0); // TODO dont use a separate queue for scatter/gather } else if (state_is_1tn(state)) { if (state_is_1tns(state)) state_q_push_ref((*scattersS) + state->rank, state); else state_q_push_ref((*scattersR) + state->rank, state); } else if (state_is_nt1(state)) { if (state_is_nt1s(state)) state_q_push_ref((*gathersS) + state->rank, state); else state_q_push_ref((*gathersR) + state->rank, state); } ref_dec(&(state->ref)); } free(state_line); free(link_line); free(etc_line); line = mygetline(f); } while (line); fclose(f); free(scaps); for (size_t i = 0; i < *ranks; i++) if ((*last)[i] < 0) LOG_WARNING("Empty rank %zu or initial timestamp < 0\n", i); }