/* * map: map LPs->KPs->PEs linearly */ void map_linear(void) { tw_pe *pe; int nlp_per_kp; int lpid; int kpid; int i; int j; // may end up wasting last KP, but guaranteed each KP has == nLPs nlp_per_kp = (int)ceil((double) g_tw_nlp / (double) g_tw_nkp); if(!nlp_per_kp) { tw_error(TW_LOC, "Not enough KPs defined: %d", g_tw_nkp); } g_tw_lp_offset = g_tw_mynode * g_tw_nlp; #if VERIFY_MAPPING printf("NODE %d: nlp %lld, offset %lld\n", g_tw_mynode, g_tw_nlp, g_tw_lp_offset); #endif for(kpid = 0, lpid = 0, pe = NULL; (pe = tw_pe_next(pe)); ) { #if VERIFY_MAPPING printf("\tPE %d\n", pe->id); #endif for(i = 0; i < nkp_per_pe; i++, kpid++) { tw_kp_onpe(kpid, pe); #if VERIFY_MAPPING printf("\t\tKP %d", kpid); #endif for(j = 0; j < nlp_per_kp && lpid < g_tw_nlp; j++, lpid++) { tw_lp_onpe(lpid, pe, g_tw_lp_offset+lpid); tw_lp_onkp(g_tw_lp[lpid], g_tw_kp[kpid]); #if VERIFY_MAPPING if(0 == j % 20) { printf("\n\t\t\t"); } printf("%lld ", lpid+g_tw_lp_offset); #endif } #if VERIFY_MAPPING printf("\n"); #endif } } if(!g_tw_lp[g_tw_nlp-1]) { tw_error(TW_LOC, "Not all LPs defined! (g_tw_nlp=%d)", g_tw_nlp); } if(g_tw_lp[g_tw_nlp-1]->gid != g_tw_lp_offset + g_tw_nlp - 1) { tw_error(TW_LOC, "LPs not sequentially enumerated!"); } }
static void tw_gvt_compute(tw_pe * pe) { tw_stime gvt_temp; tw_stime trans_temp; tw_pe *p; pe->LVT = min(tw_pq_minimum(pe->pq), pe->trans_msg_ts); #if 0 printf("%d pq %lf, trans %lf \n", pe->id, tw_pq_minimum(pe->pq), pe->trans_msg_ts); #endif if (pe->LVT < sim_gvt) tw_error( TW_LOC, "%d: LVT < GVT!!! gvt: %f lvt: %f t_msg: %f", pe->id, sim_gvt, pe->LVT, pe->trans_msg_ts); tw_mutex_lock(&g_tw_gvt_lck); if (g_tw_7oclock_node_flag != 1) { g_tw_7oclock_node_flag--; tw_mutex_unlock(&g_tw_gvt_lck); pe->gvt_status = TW_GVT_WAIT_REMOTE; return; } /* Last to compute GVT for this node (LGVT) */ gvt_temp = pe->LVT; trans_temp = pe->trans_msg_ts; p = NULL; while ((p = tw_pe_next(p))) { if (gvt_temp > p->LVT) gvt_temp = p->LVT; if (trans_temp > p->trans_msg_ts) trans_temp = p->trans_msg_ts; } if (trans_temp < gvt_temp) gvt_temp = trans_temp; if(TW_DISTRIBUTED) { node_lvt = gvt_temp; g_tw_7oclock_node_flag--; } else { g_tw_gvt_done++; sim_gvt = gvt_temp; g_tw_7oclock_node_flag = -1; } tw_mutex_unlock(&g_tw_gvt_lck); #if VERIFY_GVT || 0 if(!TW_DISTRIBUTED) { printf("%d %d new GVT %f in gvt_compute\n", pe->id, (int) *tw_net_onnode(pe->id), pe->GVT); } else printf("%d %d new LVT %f in gvt_compute\n", pe->id, (int) *tw_net_onnode(pe->id), pe->LVT); printf("%d %d sets gvt flag = %d in gvt_compute \n", pe->id, (int) *tw_net_onnode(pe->id), g_tw_7oclock_node_flag); #endif /* Send LVT to master node on network */ if (!tw_node_eq(&pe->node, &g_tw_masternode)) tw_net_send_lvt(pe, node_lvt); pe->gvt_status = TW_GVT_WAIT_REMOTE; pe->trans_msg_ts = DBL_MAX; if(TW_PARALLEL) { if (sim_gvt != pe->GVT) { g_tw_gvt_no_change = 0; } else { g_tw_gvt_no_change++; if (g_tw_gvt_no_change >= g_tw_gvt_max_no_change) { tw_error( TW_LOC, "GVT computed %d times in a row" " without changing: GVT = %g" " -- GLOBAL SYNCH -- out of memory!", g_tw_gvt_no_change, sim_gvt); } } pe->GVT = sim_gvt; if (sim_gvt > g_tw_ts_end) return; tw_pe_fossil_collect(pe); pe->gvt_status = TW_GVT_NORMAL; pe->trans_msg_ts = DBL_MAX; } }