Esempio n. 1
0
void
tw_gvt_wait(tw_pe * pe)
{
	/*
	 * If new GVT is available grab it and store in
	 * our PE.  Also decrement the global flag so that
	 * it is known that we have finished doing GVT work.
	 * Then cleanup our lists by doing a fossil collection.
	 */
	pe->GVT = sim_gvt;
	pe->trans_msg_ts = DBL_MAX;

	tw_mutex_lock(&g_tw_gvt_lck);
	g_tw_7oclock_node_flag--;
	tw_mutex_unlock(&g_tw_gvt_lck);

	tw_pe_fossil_collect(pe);
	pe->gvt_status = TW_GVT_NORMAL;

#if VERIFY_GVT
	printf("%d %d new GVT %lf (gvt_wait)\n",
		pe->id, (int) *tw_net_onnode(pe->id), sim_gvt);
	printf("%d %d set gvt_flag = %d in gvt_wait\n",
		pe->id, (int) *tw_net_onnode(pe->id), g_tw_7oclock_node_flag);
#endif
}
Esempio n. 2
0
int
tw_gvt_set(tw_pe * pe, tw_stime GVT)
{
	tw_mutex_lock(&g_tw_gvt_lck);

	sim_gvt = GVT;
	g_tw_7oclock_node_flag--;

	tw_mutex_unlock(&g_tw_gvt_lck);

	if(0 == g_tw_mynode && 0 == pe->id && sim_gvt == pe->GVT)
	{
		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!\n",
					 g_tw_gvt_no_change, sim_gvt);
		}
	} else
	{
		g_tw_gvt_no_change = 0;
	}

	g_tw_gvt_done++;
	if(sim_gvt / g_tw_ts_end > percent_complete)
		gvt_print(sim_gvt);

	if (sim_gvt < pe->GVT)
		tw_error(TW_LOC, "GVT DECREASE from %f to %f\n", pe->GVT, sim_gvt);

	pe->GVT = sim_gvt;
	pe->gvt_status = TW_GVT_NORMAL;
	pe->trans_msg_ts = DBL_MAX;
	pe->s_ngvts = 0;

	tw_pe_fossil_collect(pe);

	return 0;
}
Esempio n. 3
0
void
tw_gvt_step2(tw_pe *me)
{
	tw_stat local_white = 0;
	tw_stat total_white = 0;
	
	tw_stime pq_min = DBL_MAX;
	tw_stime net_min = DBL_MAX;
	
	tw_stime lvt;
	tw_stime gvt;
	
	tw_clock start = tw_clock_read();
	
	if(me->gvt_status != TW_GVT_COMPUTE)
		return;
	
	while(1)
	{
	    tw_net_read(me);
		
	    // send message counts to create consistent cut
	    local_white = me->s_nwhite_sent - me->s_nwhite_recv;
	    all_reduce_cnt++;
	    if(MPI_Allreduce(
						 &local_white,
						 &total_white,
						 1,
						 MPI_LONG_LONG,
						 MPI_SUM,
						 MPI_COMM_WORLD) != MPI_SUCCESS)
			tw_error(TW_LOC, "MPI_Allreduce for GVT failed");
	    
	    if(total_white == 0)
			break;
	}
	
	pq_min = tw_pq_minimum(me->pq);
	net_min = tw_net_minimum(me);
	
	lvt = me->trans_msg_ts;
	if(lvt > pq_min)
		lvt = pq_min;
	if(lvt > net_min)
		lvt = net_min;
	
	all_reduce_cnt++;
	if(MPI_Allreduce(
					 &lvt,
					 &gvt,
					 1,
					 MPI_DOUBLE,
					 MPI_MIN,
					 MPI_COMM_WORLD) != MPI_SUCCESS)
		tw_error(TW_LOC, "MPI_Allreduce for GVT failed");
	
	gvt = min(gvt, me->GVT_prev);
	
	if(gvt != me->GVT_prev)
	{
		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 = %14.14lf, PREV %14.14lf"
					 " -- GLOBAL SYNCH -- out of memory!",
					 g_tw_gvt_no_change, gvt, me->GVT_prev);
		}
	}
	
	if (me->GVT > gvt)
	{
		tw_error(TW_LOC, "PE %u GVT decreased %g -> %g",
				 me->id, me->GVT, gvt);
	}
	
	if(gvt / g_tw_ts_end > percent_complete &&
	   tw_node_eq(&g_tw_mynode, &g_tw_masternode))
	{
		gvt_print(gvt);
	}
	
	me->s_nwhite_sent = 0;
	me->s_nwhite_recv = 0;
	me->trans_msg_ts = DBL_MAX;
	me->GVT_prev = DBL_MAX; // me->GVT;
	me->GVT = gvt;
	me->gvt_status = TW_GVT_NORMAL;
	
//	printf("gvt before fossil %14.14lf\n", gvt);
	
	gvt_cnt = 0;
	
	// update GVT timing stats
	me->stats.s_gvt += tw_clock_read() - start;
	
	// only FC if OPTIMISTIC
	if( g_tw_synchronization_protocol == OPTIMISTIC )
	{
	    start = tw_clock_read();
		
	//	printf("ROSS fossil collect at gvt %14.14lf\n", gvt);
		
	    tw_pe_fossil_collect(me);
		fossil_collected = 1;
	    me->stats.s_fossil_collect += tw_clock_read() - start;
	}
	
	g_tw_gvt_done++;
}
Esempio n. 4
0
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;
	}
}
Esempio n. 5
0
void
tw_gvt_step2(tw_pe *me)
{
	long long local_white = 0;
	long long total_white = 0;

	tw_stime pq_min = DBL_MAX;
	tw_stime net_min = DBL_MAX;

	tw_stime lvt;
	tw_stime gvt;

    tw_clock net_start;
	tw_clock start = tw_clock_read();

	if(me->gvt_status != TW_GVT_COMPUTE)
		return;
	while(1)
	  {
        net_start = tw_clock_read();
	    tw_net_read(me);
        me->stats.s_net_read += tw_clock_read() - net_start;

	    // send message counts to create consistent cut
	    local_white = me->s_nwhite_sent - me->s_nwhite_recv;
	    all_reduce_cnt++;
	    if(MPI_Allreduce(
			     &local_white,
			     &total_white,
			     1,
			     MPI_LONG_LONG,
			     MPI_SUM,
			     MPI_COMM_ROSS) != MPI_SUCCESS)
	      tw_error(TW_LOC, "MPI_Allreduce for GVT failed");

	    if(total_white == 0)
	      break;
	  }

	pq_min = tw_pq_minimum(me->pq);
	net_min = tw_net_minimum(me);

	lvt = me->trans_msg_ts;
	if(lvt > pq_min)
	  lvt = pq_min;
	if(lvt > net_min)
		lvt = net_min;

	all_reduce_cnt++;
	if(MPI_Allreduce(
			&lvt,
			&gvt,
			1,
			MPI_DOUBLE,
			MPI_MIN,
			MPI_COMM_ROSS) != MPI_SUCCESS)
			tw_error(TW_LOC, "MPI_Allreduce for GVT failed");

	gvt = ROSS_MIN(gvt, me->GVT_prev);

	if(gvt != me->GVT_prev)
	{
		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 = %14.14lf, PREV %14.14lf"
				" -- GLOBAL SYNCH -- out of memory!",
				g_tw_gvt_no_change, gvt, me->GVT_prev);
		}
	}

	if (me->GVT > gvt)
	{
		tw_error(TW_LOC, "PE %u GVT decreased %g -> %g",
				me->id, me->GVT, gvt);
	}

	if (gvt / g_tw_ts_end > percent_complete && (g_tw_mynode == g_tw_masternode))
	{
		gvt_print(gvt);
	}

	me->s_nwhite_sent = 0;
	me->s_nwhite_recv = 0;
	me->trans_msg_ts = DBL_MAX;
	me->GVT_prev = DBL_MAX; // me->GVT;
	me->GVT = gvt;
	me->gvt_status = TW_GVT_NORMAL;

	gvt_cnt = 0;

	// update GVT timing stats
	me->stats.s_gvt += tw_clock_read() - start;

	// only FC if OPTIMISTIC or REALTIME, do not do for DEBUG MODE
	if( g_tw_synchronization_protocol == OPTIMISTIC ||
	    g_tw_synchronization_protocol == OPTIMISTIC_REALTIME )
	  {
	    start = tw_clock_read();
	    tw_pe_fossil_collect(me);
	    me->stats.s_fossil_collect += tw_clock_read() - start;
	  }

    // do any necessary instrumentation calls
    if ((g_st_engine_stats == GVT_STATS || g_st_engine_stats == ALL_STATS) && 
            g_tw_gvt_done % g_st_num_gvt == 0 && gvt <= g_tw_ts_end)
    {
#ifdef USE_DAMARIS
        if (g_st_damaris_enabled)
        {
            st_damaris_expose_data(me, gvt, GVT_COL);
            st_damaris_end_iteration();
        }
        else
            st_collect_engine_data(me, GVT_COL);
#else
		st_collect_engine_data(me, GVT_COL);
#endif
    }
#ifdef USE_DAMARIS
    // need to make sure damaris_end_iteration is called if GVT instrumentation not turned on
    //if (!g_st_stats_enabled && g_st_real_time_samp) //need to make sure if one PE enters this, all do; otherwise deadlock
    if (g_st_damaris_enabled && (g_st_engine_stats == RT_STATS || g_st_engine_stats == VT_STATS))
    {
        st_damaris_end_iteration();
    }
#endif

    if ((g_st_model_stats == GVT_STATS || g_st_model_stats == ALL_STATS) && g_tw_gvt_done % g_st_num_gvt == 0)
        st_collect_model_data(me, (tw_stime)tw_clock_read() / g_tw_clock_rate, GVT_STATS);
    
    st_inst_dump();
    // done with instrumentation related stuff

	g_tw_gvt_done++;

	// reset for the next gvt round -- for use in realtime GVT mode only!!
	g_tw_gvt_interval_start_cycles = tw_clock_read();
 }