Commit 2a241e71 authored by Misbah Mubarak's avatar Misbah Mubarak Committed by Neil McGlohon

enabling qos for dragonfly-plus (wip)

parent 0af97862
......@@ -83,6 +83,16 @@ struct terminal_plus_message
int is_pull;
uint32_t pull_size;
/* for counting reverse calls */
short num_rngs;
short num_cll;
/* qos related attributes */
int qos_index;
short last_saved_qos;
short qos_reset1;
short qos_reset2;
/* for reverse computation */
int path_type;
tw_stime saved_available_time;
......
......@@ -37,6 +37,7 @@
#define CREDIT_SIZE 8
#define DFLY_HASH_TABLE_SIZE 40000
#define SHOW_ADAPTIVE_STATS 1
#define BW_MONITOR 1
// debugging parameters
#define TRACK -1
......@@ -83,10 +84,20 @@ extern "C" {
}
#endif
static tw_stime max_qos_monitor = 5000000000;
static int debug_slot_count = 0;
static long term_ecount, router_ecount, term_rev_ecount, router_rev_ecount;
static long packet_gen = 0, packet_fin = 0;
/* bw monitoring time in nanosecs */
static int bw_reset_window = 5000000;
#define indexer3d(_ptr, _x, _y, _z, _maxx, _maxy, _maxz) \
((_ptr) + _z * (_maxx * _maxz) + _y * (_maxx) + _x)
#define indexer2d(_ptr, _x, _y, _maxx, _maxy) \
((_ptr) + _y * (_maxx) + _x)
static double maxd(double a, double b)
{
return a < b ? b : a;
......@@ -202,6 +213,10 @@ struct dragonfly_plus_param
int num_cn;
int intra_grp_radix;
// qos params
int num_qos_levels;
int * qos_bandwidths;
// dfp params start
int num_level_chans; // number of channels between levels of the group(?)
int num_router_spine; // number of spine routers (top level)
......@@ -294,10 +309,21 @@ struct terminal_state
terminal_plus_message_list **terminal_msgs_tail;
int in_send_loop;
struct mn_stats dragonfly_stats_array[CATEGORY_MAX];
int * qos_status;
int * qos_data;
int num_term_rc_windows;
int rc_index;
int* last_qos_status;
int* last_qos_data;
int last_qos_lvl;
int is_monitoring_bw;
struct rc_stack *st;
int issueIdle;
int terminal_length;
int * terminal_length;
const char *anno;
const dragonfly_plus_param *params;
......@@ -348,6 +374,8 @@ typedef enum event_t {
R_SEND,
R_ARRIVE,
R_BUFFER,
R_BANDWIDTH,
T_BANDWIDTH,
} event_t;
/* whether the last hop of a packet was global, local or a terminal */
......@@ -358,6 +386,20 @@ enum last_hop
TERMINAL,
};
typedef enum qos_priority
{
Q_HIGH =0,
Q_MEDIUM,
Q_LOW,
Q_UNKNOWN,
} qos_priority;
typedef enum qos_status
{
Q_ACTIVE = 1,
Q_OVERBW,
} qos_status;
// Used to denote whether a connection is one that would allow a packet to continue along a minimal path or not
// Specifically used to clearly pass whether a connection is a minimal one through to the connection scoring function
typedef enum conn_minimality_t
......@@ -451,7 +493,18 @@ struct router_state
int *global_channel;
tw_stime *next_output_available_time;
tw_stime **last_buf_full;
tw_stime *last_buf_full;
/* qos related state variables */
int rc_index;
int num_rtr_rc_windows;
int is_monitoring_bw;
int* last_qos_lvl;
int** qos_status;
int** qos_data;
/* for reverse handler of qos */
int* last_qos_status;
int* last_qos_data;
tw_stime *busy_time;
tw_stime *busy_time_sample;
......@@ -687,6 +740,43 @@ static void dragonfly_read_config(const char *anno, dragonfly_plus_param *params
p->global_vc_size = 2048;
fprintf(stderr, "Buffer size of global channels not specified, setting to %d\n", p->global_vc_size);
}
rc = configuration_get_value_int(&config, "PARAMS", "qos_levels", anno, &p->num_qos_levels);
if(rc) {
p->num_qos_levels = 1;
fprintf(stderr, "Number of QOS levels not specified, setting to %d\n", p->num_qos_levels);
}
char qos_levels_str[MAX_NAME_LENGTH];
rc = configuration_get_value(&config, "PARAMS", "qos_bandwidth", anno, qos_levels_str, MAX_NAME_LENGTH);
p->qos_bandwidths = (int*)calloc(p->num_qos_levels, sizeof(int));
if(p->num_qos_levels > 1)
{
int total_bw = 0;
char * token;
token = strtok(qos_levels_str, ",");
int i = 0;
while(token != NULL)
{
sscanf(token, "%d", &p->qos_bandwidths[i]);
total_bw += p->qos_bandwidths[i];
if(p->qos_bandwidths[i] <= 0)
{
tw_error(TW_LOC, "\n Invalid bandwidth levels");
}
i++;
token = strtok(NULL,",");
}
assert(total_bw <= 100);
}
else
p->qos_bandwidths[0] = 100;
rc = configuration_get_value_double(&config, "PARAMS", "max_qos_monitor", anno, &max_qos_monitor);
if(rc) {
printf("\n Setting adaptive threshold to %lf ", max_qos_monitor);
}
rc = configuration_get_value_int(&config, "PARAMS", "cn_vc_size", anno, &p->cn_vc_size);
if (rc) {
......@@ -1108,6 +1198,47 @@ int dragonfly_plus_get_assigned_router_id(int terminal_id, const dragonfly_plus_
return router_id;
}
void reset_rtr_bw_counters(router_state * s,
tw_bf * bf,
terminal_plus_message * msg,
tw_lp * lp)
{
int num_qos_levels = s->params->num_qos_levels;
if(msg->type == R_BANDWIDTH)
{
for(int k = 0; k < s->num_rtr_rc_windows; k++)
{
for(int i = 0; i < s->params->radix; i++)
{
for(int j = 0; j < num_qos_levels; j++)
{
*(indexer3d(s->last_qos_status, k, i, j, s->num_rtr_rc_windows, s->params->radix, num_qos_levels)) = 0;
*(indexer3d(s->last_qos_data, k, i, j, s->num_rtr_rc_windows, s->params->radix, num_qos_levels)) = 0;
}
}
}
s->rc_index = 0;
}
}
void reset_bw_counters(terminal_state * s,
tw_bf * bf,
terminal_plus_message * msg,
tw_lp * lp)
{
int num_qos_levels = s->params->num_qos_levels;
if(msg->type == T_BANDWIDTH)
{
for(int i = 0; i < s->num_term_rc_windows; i++)
{
for(int j = 0; j < s->params->num_qos_levels; j++)
{
*(indexer2d(s->last_qos_status, i, j, s->num_term_rc_windows, num_qos_levels)) = 0;
*(indexer2d(s->last_qos_data, i, j, s->num_term_rc_windows, num_qos_levels)) = 0;
}
}
s->rc_index = 0;
}
}
/* initialize a dragonfly compute node terminal */
void terminal_plus_init(terminal_state *s, tw_lp *lp)
{
......@@ -1132,7 +1263,9 @@ void terminal_plus_init(terminal_state *s, tw_lp *lp)
s->params = &all_params[id];
}
int num_qos_levels = s->params->num_qos_levels;
int num_lps = codes_mapping_get_lp_count(lp_group_name, 1, LP_CONFIG_NM_TERM, s->anno, 0);
s->terminal_id = codes_mapping_get_lp_relative_id(lp->gid, 0, 0);
s->router_id = dragonfly_plus_get_assigned_router_id(s->terminal_id, s->params);
......@@ -1157,8 +1290,29 @@ void terminal_plus_init(terminal_state *s, tw_lp *lp)
s->rev_events = 0;
rc_stack_create(&s->st);
s->num_vcs = 1;
s->vc_occupancy = (int *) calloc(s->num_vcs, sizeof(int));
if(num_qos_levels > 1)
s->num_vcs *= num_qos_levels;
/* Whether the virtual channel group is active or over-bw*/
s->qos_status = (int*)calloc(num_qos_levels, sizeof(int));
/* How much data has been transmitted on the virtual channel group within
* the window */
s->qos_data = (int*)calloc(num_qos_levels, sizeof(int));
/* for reverse handlers */
s->last_qos_status = (int*)calloc(s->num_term_rc_windows * num_qos_levels, sizeof(int));
s->last_qos_data = (int*)calloc(s->num_term_rc_windows * num_qos_levels, sizeof(int));
for(i = 0; i < num_qos_levels; i++)
{
s->qos_data[i] = 0;
s->qos_status[i] = Q_ACTIVE;
}
s->last_qos_lvl = 0;
s->last_buf_full = (tw_stime *) calloc(s->num_vcs, sizeof(tw_stime));
for (i = 0; i < s->num_vcs; i++) {
......@@ -1166,15 +1320,12 @@ void terminal_plus_init(terminal_state *s, tw_lp *lp)
s->vc_occupancy[i] = 0;
}
s->rank_tbl = NULL;
s->terminal_msgs =
(terminal_plus_message_list **) calloc(s->num_vcs, sizeof(terminal_plus_message_list *));
s->terminal_msgs_tail =
(terminal_plus_message_list **) calloc(s->num_vcs, sizeof(terminal_plus_message_list *));
s->terminal_msgs[0] = NULL;
s->terminal_msgs_tail[0] = NULL;
s->terminal_length = 0;
s->terminal_length = (int*)calloc(num_qos_levels, sizeof(int));
s->in_send_loop = 0;
s->issueIdle = 0;
......@@ -1218,9 +1369,19 @@ void router_plus_setup(router_state *r, tw_lp *lp)
// printf("\n Local router id %d global id %d ", r->router_id, lp->gid);
r->num_rtr_rc_windows = 100;
r->rc_index = 0;
r->is_monitoring_bw = 0;
r->fwd_events = 0;
r->rev_events = 0;
// QoS related variables
// for reverse computation of QoS
/* history window for bandwidth reverse computation */
int num_qos_levels = p->num_qos_levels;
r->last_qos_status = (int*)calloc(r->num_rtr_rc_windows * r->params->radix * num_qos_levels, sizeof(int));
r->last_qos_data = (int*)calloc(r->num_rtr_rc_windows * r->params->radix * num_qos_levels, sizeof(int));
// Determine if router is a spine or a leaf
int intra_group_id = r->router_id % p->num_routers;
if (intra_group_id >= (p->num_routers / 2)) { //TODO this assumes symmetric spine and leafs
......@@ -1244,6 +1405,9 @@ void router_plus_setup(router_state *r, tw_lp *lp)
r->link_traffic_sample = (int64_t *) calloc(p->radix, sizeof(int64_t));
r->vc_occupancy = (int **) calloc(p->radix, sizeof(int *));
r->qos_data = (int**)calloc(p->radix, sizeof(int*));
r->last_qos_lvl = (int*)calloc(p->radix, sizeof(int));
r->qos_status = (int**)calloc(p->radix, sizeof(int*));
r->in_send_loop = (int *) calloc(p->radix, sizeof(int));
r->pending_msgs =
(terminal_plus_message_list ***) calloc(p->radix, sizeof(terminal_plus_message_list **));
......@@ -1254,7 +1418,7 @@ void router_plus_setup(router_state *r, tw_lp *lp)
r->queued_msgs_tail =
(terminal_plus_message_list ***) calloc(p->radix, sizeof(terminal_plus_message_list **));
r->queued_count = (int *) calloc(p->radix, sizeof(int));
r->last_buf_full = (tw_stime **) calloc(p->radix, sizeof(tw_stime *));
r->last_buf_full = (tw_stime*) calloc(p->radix, sizeof(tw_stime *));
r->busy_time = (tw_stime *) calloc(p->radix, sizeof(tw_stime));
r->busy_time_sample = (tw_stime *) calloc(p->radix, sizeof(tw_stime));
......@@ -1262,9 +1426,11 @@ void router_plus_setup(router_state *r, tw_lp *lp)
for (int i = 0; i < p->radix; i++) {
// Set credit & router occupancy
r->last_buf_full[i] = 0.0;
r->busy_time[i] = 0.0;
r->busy_time_sample[i] = 0.0;
r->next_output_available_time[i] = 0;
r->last_qos_lvl[i] = 0;
r->link_traffic[i] = 0;
r->link_traffic_sample[i] = 0;
r->queued_count[i] = 0;
......@@ -1272,15 +1438,22 @@ void router_plus_setup(router_state *r, tw_lp *lp)
r->vc_occupancy[i] = (int *) calloc(p->num_vcs, sizeof(int));
r->pending_msgs[i] =
(terminal_plus_message_list **) calloc(p->num_vcs, sizeof(terminal_plus_message_list *));
r->last_buf_full[i] = (tw_stime *) calloc(p->num_vcs, sizeof(tw_stime));
r->pending_msgs_tail[i] =
(terminal_plus_message_list **) calloc(p->num_vcs, sizeof(terminal_plus_message_list *));
r->queued_msgs[i] =
(terminal_plus_message_list **) calloc(p->num_vcs, sizeof(terminal_plus_message_list *));
r->queued_msgs_tail[i] =
(terminal_plus_message_list **) calloc(p->num_vcs, sizeof(terminal_plus_message_list *));
r->qos_status[i] = (int*)calloc(num_qos_levels, sizeof(int));
r->qos_data[i] = (int*)calloc(num_qos_levels, sizeof(int));
for(int j = 0; j < num_qos_levels; j++)
{
r->qos_status[i][j] = Q_ACTIVE;
r->qos_data[i][j] = 0;
}
for (int j = 0; j < p->num_vcs; j++) {
r->last_buf_full[i][j] = 0.0;
r->vc_occupancy[i][j] = 0;
r->pending_msgs[i][j] = NULL;
r->pending_msgs_tail[i][j] = NULL;
......@@ -1293,6 +1466,299 @@ void router_plus_setup(router_state *r, tw_lp *lp)
return;
}
int get_vcg_from_category(terminal_plus_message * msg)
{
if(strcmp(msg->category, "high") == 0)
return Q_HIGH;
else if(strcmp(msg->category, "medium") == 0)
return Q_MEDIUM;
else
tw_error(TW_LOC, "\n priority needs to be specified with qos_levels>1 %d", msg->category);
}
static int get_rtr_bandwidth_consumption(router_state * s, int qos_lvl, int output_port)
{
assert(qos_lvl >= Q_HIGH && qos_lvl <= Q_LOW);
assert(output_port < s->params->intra_grp_radix + s->params->num_global_connections + s->params->num_cn);
int bandwidth = s->params->cn_bandwidth;
if(output_port < s->params->intra_grp_radix)
bandwidth = s->params->local_bandwidth;
else if(output_port < s->params->intra_grp_radix + s->params->num_global_connections)
bandwidth = s->params->global_bandwidth;
/* conversion into bytes/sec from GiB/sec */
double max_bw = bandwidth * 1024.0 * 1024.0 * 1024.0;
/* conversion into bytes per one nanosecs */
double max_bw_per_ns = max_bw / (1000.0 * 1000.0 * 1000.0);
/* derive maximum bytes that can be transferred during the window */
double max_bytes_per_win = max_bw_per_ns * bw_reset_window;
int percent_bw = (((double)s->qos_data[output_port][qos_lvl]) / max_bytes_per_win) * 100;
// printf("\n percent bw consumed by qos_lvl %d is %d bytes transferred %d max_bw %lf ", qos_lvl, percent_bw, s->qos_data[output_port][qos_lvl], max_bw_per_ns);
return percent_bw;
}
static int get_term_bandwidth_consumption(terminal_state * s, int qos_lvl)
{
assert(qos_lvl >= Q_HIGH && qos_lvl <= Q_LOW);
/* conversion into bytes/sec from GiB/sec */
double max_bw = s->params->cn_bandwidth * 1024.0 * 1024.0 * 1024.0;
/* conversion into bytes per one nanosecs */
double max_bw_per_ns = max_bw / (1000.0 * 1000.0 * 1000.0);
/* derive maximum bytes that can be transferred during the window */
double max_bytes_per_win = max_bw_per_ns * bw_reset_window;
int percent_bw = (((double)s->qos_data[qos_lvl]) / max_bytes_per_win) * 100;
// printf("\n At terminal %lf max bytes %d percent %d ", max_bytes_per_win, s->qos_data[qos_lvl], percent_bw);
return percent_bw;
}
/* reverse handler for router BW monitor */
void issue_rtr_bw_monitor_event_rc(router_state * s, tw_bf * bf, terminal_plus_message * msg, tw_lp * lp)
{
int num_qos_levels = s->params->num_qos_levels;
int rc_index = msg->qos_index;
for(int i = 0 ; i < msg->num_cll; i++)
codes_local_latency_reverse(lp);
for(int j = 0; j < s->params->radix; j++)
{
for(int k = 0; k < num_qos_levels; k++)
{
s->qos_status[j][k] = *(indexer3d(s->last_qos_status, rc_index, j, k, s->num_rtr_rc_windows, s->params->radix, num_qos_levels));
s->qos_data[j][k] = *(indexer3d(s->last_qos_data, rc_index, j, k, s->num_rtr_rc_windows, s->params->radix, num_qos_levels));
*(indexer3d(s->last_qos_status, rc_index, j, k, s->num_rtr_rc_windows, s->params->radix, num_qos_levels)) = 0;
*(indexer3d(s->last_qos_data, rc_index, j, k, s->num_rtr_rc_windows, s->params->radix, num_qos_levels)) = 0;
}
}
}
void issue_rtr_bw_monitor_event(router_state * s, tw_bf * bf, terminal_plus_message * msg, tw_lp * lp)
{
msg->num_cll = 0;
msg->num_rngs = 0;
int num_qos_levels = s->params->num_qos_levels;
int rc_index = s->rc_index;
int num_rtr_rc_windows = s->num_rtr_rc_windows;
/* dynamically reallocate the array.. */
if(s->rc_index == s->num_rtr_rc_windows)
{
s->num_rtr_rc_windows *= 2;
int * tmp1 = (int*)calloc(s->num_rtr_rc_windows * s->params->radix * num_qos_levels, sizeof(int));
int * tmp2 = (int*)calloc(s->num_rtr_rc_windows * s->params->radix * num_qos_levels, sizeof(int));
/* now copy elements one by one. can't use memcpy with 2d array. */
for(int i = 0; i < num_rtr_rc_windows; i++)
{
for(int j = 0; j < s->params->radix; j++)
{
for(int k = 0; k < num_qos_levels; k++)
{
*(indexer3d(tmp1, i, j, k, s->num_rtr_rc_windows, s->params->radix, num_qos_levels)) = *(indexer3d(s->last_qos_status, i, j, k, num_rtr_rc_windows, s->params->radix, num_qos_levels));
*(indexer3d(tmp2, i, j, k, s->num_rtr_rc_windows, s->params->radix, num_qos_levels)) = *(indexer3d(s->last_qos_data, i, j, k, num_rtr_rc_windows, s->params->radix, num_qos_levels));
}
}
}
free(s->last_qos_status);
free(s->last_qos_data);
s->last_qos_status = tmp1;
s->last_qos_data = tmp2;
}
assert(rc_index < s->num_rtr_rc_windows && rc_index >= 0);
for(int j = 0; j < s->params->radix; j++)
{
for(int k = 0; k < num_qos_levels; k++)
{
*(indexer3d(s->last_qos_status, rc_index, j, k, s->num_rtr_rc_windows, s->params->radix, num_qos_levels)) = s->qos_status[j][k];
*(indexer3d(s->last_qos_data, rc_index, j, k, s->num_rtr_rc_windows, s->params->radix, num_qos_levels)) = s->qos_data[j][k];
}
}
msg->qos_index = s->rc_index;
s->rc_index++;
/*for(int j = 0; j < s->params->radix; j++)
{
for(int k = 0; k < num_qos_levels; k++)
{
int bw_consumed = get_rtr_bandwidth_consumption(s, k, j);
if(s->router_id == 0)
{
//fprintf(dragonfly_rtr_bw_log, "\n %d %f %d %d %d %d %d %f", s->router_id, tw_now(lp), j, k, bw_consumed, s->qos_status[j][k], s->qos_data[j][k], s->busy_time_sample[j]);
}
}
}*/
for(int j = 0; j < s->params->radix; j++)
{
/* Reset the qos status and bandwidth consumption. */
for(int k = 0; k < num_qos_levels; k++)
{
s->qos_status[j][k] = Q_ACTIVE;
s->qos_data[j][k] = 0;
}
//s->busy_time_sample[j] = 0;
}
if(tw_now(lp) > max_qos_monitor)
return;
msg->num_cll++;
tw_stime bw_ts = bw_reset_window + codes_local_latency(lp);
terminal_plus_message *m;
tw_event * e = model_net_method_event_new(lp->gid, bw_ts, lp,
DRAGONFLY_CUSTOM_ROUTER, (void**)&m, NULL);
m->type = R_BANDWIDTH;
m->magic = router_magic_num;
tw_event_send(e);
}
void issue_bw_monitor_event_rc(terminal_state * s, tw_bf * bf, terminal_plus_message * msg, tw_lp * lp)
{
for(int i = 0 ; i < msg->num_cll; i++)
codes_local_latency_reverse(lp);
int num_qos_levels = s->params->num_qos_levels;
int num_term_rc_wins = s->num_term_rc_windows;
int rc_index = msg->qos_index;
for(int k = 0; k < num_qos_levels; k++)
{
s->qos_status[k] = *(indexer2d(s->last_qos_status, rc_index, k, num_term_rc_wins, num_qos_levels));
s->qos_data[k] = *(indexer2d(s->last_qos_data, rc_index, k, num_term_rc_wins, num_qos_levels));
*(indexer2d(s->last_qos_status, rc_index, k, num_term_rc_wins, num_qos_levels)) = 0;
*(indexer2d(s->last_qos_data, rc_index, k, num_term_rc_wins, num_qos_levels)) = 0;
}
}
/* resets the bandwidth numbers recorded so far */
void issue_bw_monitor_event(terminal_state * s, tw_bf * bf, terminal_plus_message * msg, tw_lp * lp)
{
msg->num_cll = 0;
msg->num_rngs = 0;
int num_qos_levels = s->params->num_qos_levels;
int rc_index = s->rc_index;
int num_term_rc_wins = s->num_term_rc_windows;
/* dynamically reallocate array if index has reached max-size */
if(s->rc_index == s->num_term_rc_windows)
{
s->num_term_rc_windows *= 2;
int * tmp1 = (int*)calloc(s->num_term_rc_windows * num_qos_levels, sizeof(int));
int * tmp2 = (int*)calloc(s->num_term_rc_windows * num_qos_levels, sizeof(int));
/* now copy elements one by one. can't use memcpy with 2d array. */
for(int i = 0; i < s->num_term_rc_windows; i++)
{
for(int j = 0; j < num_qos_levels; j++)
{
*(indexer2d(tmp1, i, j, s->num_term_rc_windows, num_qos_levels)) = *(indexer2d(s->last_qos_status, i, j, num_term_rc_wins, num_qos_levels));
*(indexer2d(tmp2, i, j, s->num_term_rc_windows, num_qos_levels)) = *(indexer2d(s->last_qos_data, i, j, num_term_rc_wins, num_qos_levels));
}
}
free(s->last_qos_status);
free(s->last_qos_data);
s->last_qos_status = tmp1;
s->last_qos_data = tmp2;
}
/* Reset the qos status and bandwidth consumption. */
for(int k = 0; k < num_qos_levels; k++)
{
*(indexer2d(s->last_qos_status, rc_index, k, num_term_rc_wins, num_qos_levels)) = s->qos_status[k];
*(indexer2d(s->last_qos_data, rc_index, k, num_term_rc_wins, num_qos_levels)) = s->qos_data[k];
s->qos_status[k] = Q_ACTIVE;
s->qos_data[k] = 0;
}
msg->qos_index = s->rc_index;
s->rc_index++;
assert(s->rc_index < s->num_term_rc_windows);
/* if(s->router_id == 0)
{
fprintf(dragonfly_term_bw_log, "\n %d %lf %lf ", s->terminal_id, tw_now(lp), s->busy_time_sample);
s->busy_time_sample = 0;
}
*/
if(tw_now(lp) > max_qos_monitor)
return;
msg->num_cll++;
terminal_plus_message * m;
tw_stime bw_ts = bw_reset_window + codes_local_latency(lp);
tw_event * e = model_net_method_event_new(lp->gid, bw_ts, lp, DRAGONFLY_CUSTOM,
(void**)&m, NULL);
m->type = T_BANDWIDTH;
m->magic = terminal_magic_num;
tw_event_send(e);
}
static int get_next_vcg(terminal_state * s, tw_bf * bf, terminal_plus_message * msg, tw_lp * lp)
{
int num_qos_levels = s->params->num_qos_levels;
if(num_qos_levels == 1)
{
if(s->terminal_msgs[0] == NULL || s->vc_occupancy[0] + s->params->chunk_size > s->params->cn_vc_size)
return -1;
else
return 0;
}
int bw_consumption[num_qos_levels];
/* First make sure the bandwidth consumptions are up to date. */
for(int k = 0; k < num_qos_levels; k++)
{
if(s->qos_status[k] != Q_OVERBW)
{
bw_consumption[k] = get_term_bandwidth_consumption(s, k);
if(bw_consumption[k] > s->params->qos_bandwidths[k])
{
if(k == 0)
msg->qos_reset1 = 1;
else if(k == 1)
msg->qos_reset2 = 1;
s->qos_status[k] = Q_OVERBW;
}
}
}
if(BW_MONITOR == 1)
{
for(int i = 0; i < num_qos_levels; i++)
{
if(s->qos_status[i] == Q_ACTIVE)
{
if(s->terminal_msgs[i] != NULL && s->vc_occupancy[i] + s->params->chunk_size <= s->params->cn_vc_size)
return i;
}
}
}
int next_rr_vcg = (s->last_qos_lvl + 1) % num_qos_levels;
/* All vcgs are exceeding their bandwidth limits*/
for(int i = 0; i < num_qos_levels; i++)
{
if(s->terminal_msgs[i] != NULL && s->vc_occupancy[i] + s->params->chunk_size <= s->params->cn_vc_size)
{
bf->c2 = 1;
if(msg->last_saved_qos < 0)
msg->last_saved_qos = s->last_qos_lvl;
s->last_qos_lvl = next_rr_vcg;
return i;
}
next_rr_vcg = (next_rr_vcg + 1) % num_qos_levels;
}
return -1;
}
/* MM: These packet events (packet_send, packet_receive etc.) will be used as is, basically, the routing
* functions will be changed only. */
......@@ -1367,7 +1833,7 @@ static void dragonfly_plus_packet_event_rc(tw_lp *sender)
* sending router. */
/*When a packet is sent from the current router and a buffer slot becomes available, a credit is sent back to
* schedule another packet event*/
static void router_credit_send(router_state *s, terminal_plus_message *msg, tw_lp *lp, int sq)
static void router_credit_send(router_state *s, terminal_plus_message *msg, tw_lp *lp, int sq, short* rng_counter)
{
tw_event *buf_e;
tw_stime ts;
......@@ -1390,6 +1856,7 @@ static void router_credit_send(router_state *s, terminal_plus_message *msg, tw_l
else
printf("\n Invalid message type");
(*rng_counter)++;
ts = g_tw_lookahead + p->credit_delay + tw_rand_unif(lp->rng);
if (is_terminal) {
......@@ -1421,27 +1888,37 @@ static void packet_generate_rc(terminal_state *s, tw_bf *bf, terminal_plus_messa
s->packet_gen--;
packet_gen--;
s->packet_counter--;
for(int i = 0; i < msg->num_rngs; i++)
tw_rand_reverse_unif(lp->rng);
tw_rand_reverse_unif(lp->rng);
for(int i = 0; i < msg->num_cll; i++)
codes_local_latency_reverse(lp);
int num_qos_levels = s->params->num_qos_levels;
int num_chunks = msg->packet_size / s->params->chunk_size;
if (msg->packet_size < s->params->chunk_size)
num_chunks++;
int vcg = 0;