/*Processes the packet after it arrives from the neighboring torus node */ void packet_arrive( nodes_state * s, tw_bf * bf, nodes_message * msg, tw_lp * lp ) { bf->c2 = 0; int i; tw_event *e; tw_stime ts; nodes_message *m; /* send an ack back to the sender node */ credit_send( s, bf, lp, msg); msg->my_N_hop++; ts = 0.1 + tw_rand_exponential(lp->rng, MEAN_INTERVAL/200); /* if the flit has arrived on the final destination */ if( lp->gid == msg->dest_lp ) { /* check if this is the last flit of the packet */ if( msg->chunk_id == num_chunks - 1 ) { bf->c2 = 1; int index = floor(N_COLLECT_POINTS*(tw_now(lp)/g_tw_ts_end)); for(i = 0; i < 2 * N_dims; i++) N_queue_depth[index]+=s->buffer[i][0]; e = tw_event_new(lp->gid + N_nodes, ts, lp); m = tw_event_data(e); m->type = MPI_RECV; m->travel_start_time = msg->travel_start_time; m->my_N_hop = msg->my_N_hop; m->packet_ID = msg->packet_ID; tw_event_send(e); } } else { /* forward the flit to another node */ e = tw_event_new(lp->gid, ts , lp); m = tw_event_data( e ); m->type = SEND; // Carry on the message info for( i = 0; i < N_dims; i++ ) m->dest[i] = msg->dest[i]; m->dest_lp = msg->dest_lp; m->source_dim = msg->source_dim; m->source_direction = msg->source_direction; m->packet_ID = msg->packet_ID; m->travel_start_time = msg->travel_start_time; m->my_N_hop = msg->my_N_hop; m->sender_lp = msg->sender_lp; m->chunk_id = msg->chunk_id; m->next_stop = -1; tw_event_send(e); } }
/*Processes the packet after it arrives from the neighboring torus node * routes it to the next compute node if this is not the destination * OR if this is the destination then a remote event at the server is issued. */ static void packet_arrive( nodes_state * s, tw_bf * bf, nodes_message * msg, tw_lp * lp ) { bf->c2 = 0; tw_event *e; tw_stime ts; nodes_message *m; mn_stats* stat; credit_send( s, bf, lp, msg); msg->my_N_hop++; ts = 0.1 + tw_rand_exponential(lp->rng, MEAN_INTERVAL/200); if(msg->packet_ID == TRACE) printf("\n packet arrived at lp %d final dest %d ", (int)lp->gid, (int)msg->dest_lp); if( lp->gid == msg->dest_lp ) { uint64_t num_chunks = msg->packet_size/s->params->chunk_size; if(msg->packet_size % s->params->chunk_size) num_chunks++; if( msg->chunk_id == num_chunks - 1 ) { bf->c2 = 1; stat = model_net_find_stats(msg->category, s->torus_stats_array); stat->recv_count++; stat->recv_bytes += msg->packet_size; stat->recv_time += tw_now( lp ) - msg->travel_start_time; /*count the number of packets completed overall*/ N_finished_packets++; total_time += tw_now( lp ) - msg->travel_start_time; total_hops += msg->my_N_hop; if (max_latency < tw_now( lp ) - msg->travel_start_time) { bf->c3 = 1; msg->saved_available_time = max_latency; max_latency=tw_now( lp ) - msg->travel_start_time; } // Trigger an event on receiving server if(msg->remote_event_size_bytes) { void *tmp_ptr = model_net_method_get_edata(TORUS, msg); if (msg->is_pull) { int net_id = model_net_get_id(LP_METHOD_NM); model_net_event(net_id, msg->category, msg->sender_svr, msg->pull_size, 0.0, msg->remote_event_size_bytes, tmp_ptr, 0, NULL, lp); } else { e = tw_event_new(msg->final_dest_gid, ts, lp); m = tw_event_data(e); memcpy(m, tmp_ptr, msg->remote_event_size_bytes); tw_event_send(e); } } } } else { //e = tw_event_new(lp->gid, ts , lp); //m = tw_event_data( e ); //memcpy(m, msg, torus_get_msg_sz() + msg->remote_event_size_bytes); void *m_data; e = model_net_method_event_new(lp->gid, ts, lp, TORUS, (void**)&m, &m_data); memcpy(m, msg, sizeof(nodes_message)); if (msg->remote_event_size_bytes) { memcpy(m_data, model_net_method_get_edata(TORUS, msg), msg->remote_event_size_bytes); } m->type = SEND; m->next_stop = -1; tw_event_send(e); } }