Commit b186dfb4 authored by Misbah Mubarak's avatar Misbah Mubarak

Merge branch 'analysis-lp' into 'master'

Analysis LP/Virtual Time Sampling

See merge request !50
parents 296e38d1 6f4c0603
## README for using ROSS instrumentation with CODES
For details about the ROSS instrumentation, see the [ROSS Instrumentation blog post](http://carothersc.github.io/ROSS/feature/instrumentation.html)
For details about the ROSS instrumentation, see the [ROSS Instrumentation blog post](http://carothersc.github.io/ROSS/instrumentation/instrumentation.html)
on the ROSS webpage.
There are currently 3 types of instrumentation: GVT-based, real time, and event tracing. See the ROSS documentation for more info on
the specific options or use `--help` with your model. To collect data about the simulation engine, no changes are needed to model code
for any of the instrumentation modes. Some additions to the model code is needed in order to turn on any model-level data collection.
See the "Model-level data sampling" section on [ROSS Instrumentation blog post](http://carothersc.github.io/ROSS/feature/instrumentation.html).
There are currently 4 types of instrumentation: GVT-based, real time sampling, virtual time sampling, and event tracing.
See the ROSS documentation for more info on the specific options or use `--help` with your model.
To collect data about the simulation engine, no changes are needed to model code for any of the instrumentation modes.
Some additions to the model code is needed in order to turn on any model-level data collection.
See the "Model-level data sampling" section on [ROSS Instrumentation blog post](http://carothersc.github.io/ROSS/instrumentation/instrumentation.html).
Here we describe CODES specific details.
### Register Instrumentation Callback Functions
......@@ -17,15 +18,11 @@ The examples here are based on the dragonfly router and terminal LPs (`src/netwo
As described in the ROSS Vis documentation, we need to create a `st_model_types` struct with the pointer and size information.
```C
st_model_types dragonfly_model_types[] = {
{(rbev_trace_f) dragonfly_event_collect,
sizeof(int),
(ev_trace_f) dragonfly_event_collect,
{(ev_trace_f) dragonfly_event_collect,
sizeof(int),
(model_stat_f) dragonfly_model_stat_collect,
sizeof(tw_lpid) + sizeof(long) * 2 + sizeof(double) + sizeof(tw_stime) * 2},
{(rbev_trace_f) dragonfly_event_collect,
sizeof(int),
(ev_trace_f) dragonfly_event_collect,
{(ev_trace_f) dragonfly_event_collect,
sizeof(int),
(model_stat_f) dfly_router_model_stat_collect,
0}, // updated in router_setup()
......@@ -33,20 +30,17 @@ st_model_types dragonfly_model_types[] = {
}
```
`dragonfly_model_types[0]` is the function pointers for the terminal LP and `dragonfly_model_types[1]` is for the router LP.
For the first two function pointers for each LP, we use the same `dragonfly_event_collec()` because right now we just collect the event type, so
it's the same for both of these LPs. You can change these if you want to use different functions for different LP types or if you want a different
function for the full event tracing than that used for the rollback event trace (`rbev_trace_f` is for the event tracing of rollback triggering events only,
while `ev_trace_f` is for the full event tracing).
The number following each function pointer is the size of the data that will be saved when the function is called.
The third pointer is for the data to be sampled at the GVT or real time sampling points.
For the first function pointer for each LP type, we use the same `dragonfly_event_collect()` because right now we just collect the event type, so it's the same for both of these LP types.
You can change these if you want to use different functions for different LP types.
The number following that function pointer is the size of the data that will be saved when the function is called.
The second pointer is for the data to be sampled at the GVT or real time sampling points.
In this case the LPs have different function pointers since we want to collect different types of data for the two LP types.
For the terminal, I set the appropriate size of the data to be collected, but for the router, the size of the data is dependent on the radix for the
dragonfly configuration being used, which isn't known until runtime.
For the terminal, I set the appropriate size of the data to be collected, but for the router, the size of the data is dependent on the radix for the dragonfly configuration being used, which isn't known until runtime.
*Note*: You can only reuse the function for event tracing for LPs that use the same type of message struct.
For example, the dragonfly terminal and router LPs both use the `terminal_message` struct, so they can
use the same functions for event tracing. However the model net base LP uses the `model_net_wrap_msg` struct, so it gets its own event collection function and
`st_trace_type` struct, in order to read the event type correctly from the model.
use the same functions for event tracing.
However the model net base LP uses the `model_net_wrap_msg` struct, so it gets its own event collection function and `st_trace_type` struct, in order to read the event type correctly from the model.
In the ROSS instrumentation documentation, there are two methods provided for letting ROSS know about these `st_model_types` structs.
In CODES, this step is a little different, as `codes_mapping_setup()` calls `tw_lp_settype()`.
......@@ -106,9 +100,7 @@ Using the synthetic workload LP for dragonfly as an example (`src/network-worklo
In the main function, you call the register function *before* calling `codes_mapping_setup()`.
```C
st_model_types svr_model_types[] = {
{(rbev_trace_f) svr_event_collect,
sizeof(int),
(ev_trace_f) svr_event_collect,
{(ev_trace_f) svr_event_collect,
sizeof(int),
(model_stat_f) svr_model_stat_collect,
0}, // at the moment, we're not actually collecting any data about this LP
......@@ -143,10 +135,13 @@ modes are collecting model-level data as well.
### CODES LPs that currently have event type collection implemented:
If you're using any of the following CODES models, you don't have to add anything, unless you want to change the data that's being collected.
- nw-lp (model-net-mpi-replay.c)
- original dragonfly router and terminal LPs (dragonfly.c)
- dfly server LP (model-net-synthetic.c)
- model-net-base-lp (model-net-lp.c)
- custom dfly server LP (model-net-synthetic-custom-dfly.c)
- fat tree server LP (model-net-synthetic-fattree.c)
- slimfly server LP (model-net-synthetic-slimfly.c)
- original dragonfly router and terminal LPs (dragonfly.c)
- dragonfly custom router and terminal LPs (dragonfly-custom.C)
- slimfly router and terminal LPs (slimfly.c)
- fat tree switch and terminal LPs (fat-tree.c)
- model-net-base-lp (model-net-lp.c)
The fat-tree terminal and switch LPs (fattree.c) are only partially implemented at the moment. It needs two `model_net_method` structs to fully implement,
but currently both terminal and switch LPs use the same `fattree_method` struct.
......@@ -85,6 +85,8 @@ struct terminal_custom_message
tw_stime saved_total_time;
tw_stime saved_sample_time;
tw_stime msg_start_time;
tw_stime saved_busy_time_ross;
tw_stime saved_fin_chunks_ross;
};
#ifdef __cplusplus
......
......@@ -2554,8 +2554,6 @@ static void nw_add_lp_type()
}
/* setup for the ROSS event tracing
* can have a different function for rbev_trace_f and ev_trace_f
* but right now it is set to the same function for both
*/
void nw_lp_event_collect(nw_message *m, tw_lp *lp, char *buffer, int *collect_flag)
{
......@@ -2580,13 +2578,14 @@ void nw_lp_model_stat_collect(nw_state *s, tw_lp *lp, char *buffer)
}
st_model_types nw_lp_model_types[] = {
{(rbev_trace_f) nw_lp_event_collect,
sizeof(int),
(ev_trace_f) nw_lp_event_collect,
{(ev_trace_f) nw_lp_event_collect,
sizeof(int),
(model_stat_f) nw_lp_model_stat_collect,
0,
NULL,
NULL,
0},
{NULL, 0, NULL, 0, NULL, 0}
{NULL, 0, NULL, 0, NULL, NULL, 0}
};
static const st_model_types *nw_lp_get_model_stat_types(void)
......@@ -2705,7 +2704,7 @@ int modelnet_mpi_replay(MPI_Comm comm, int* argc, char*** argv )
nw_add_lp_type();
model_net_register();
if (g_st_ev_trace || g_st_model_stats)
if (g_st_ev_trace || g_st_model_stats || g_st_use_analysis_lps)
nw_lp_register_model();
net_ids = model_net_configure(&num_nets);
......
......@@ -107,6 +107,49 @@ tw_lptype svr_lp = {
sizeof(svr_state),
};
/* setup for the ROSS event tracing
*/
void custom_svr_event_collect(svr_msg *m, tw_lp *lp, char *buffer, int *collect_flag)
{
(void)lp;
(void)collect_flag;
int type = (int) m->svr_event_type;
memcpy(buffer, &type, sizeof(type));
}
/* can add in any model level data to be collected along with simulation engine data
* in the ROSS instrumentation. Will need to update the last field in
* svr_model_types[0] for the size of the data to save in each function call
*/
void custom_svr_model_stat_collect(svr_state *s, tw_lp *lp, char *buffer)
{
(void)s;
(void)lp;
(void)buffer;
return;
}
st_model_types custom_svr_model_types[] = {
{(ev_trace_f) custom_svr_event_collect,
sizeof(int),
(model_stat_f) custom_svr_model_stat_collect,
0,
NULL,
NULL,
0},
{NULL, 0, NULL, 0, NULL, NULL, 0}
};
static const st_model_types *custom_svr_get_model_stat_types(void)
{
return(&custom_svr_model_types[0]);
}
void custom_svr_register_model_types()
{
st_model_type_register("nw-lp", custom_svr_get_model_stat_types());
}
const tw_optdef app_opt [] =
{
TWOPT_GROUP("Model net synthetic traffic " ),
......@@ -380,6 +423,9 @@ int main(
model_net_register();
svr_add_lp_type();
if (g_st_ev_trace || g_st_model_stats || g_st_use_analysis_lps)
custom_svr_register_model_types();
codes_mapping_setup();
net_ids = model_net_configure(&num_nets);
......
......@@ -123,8 +123,6 @@ tw_lptype svr_lp = {
};
/* setup for the ROSS event tracing
* can have a different function for rbev_trace_f and ev_trace_f
* but right now it is set to the same function for both
*/
void ft_svr_event_collect(svr_msg *m, tw_lp *lp, char *buffer, int *collect_flag)
{
......@@ -150,13 +148,14 @@ void ft_svr_model_stat_collect(svr_state *s, tw_lp *lp, char *buffer)
}
st_model_types ft_svr_model_types[] = {
{(rbev_trace_f) ft_svr_event_collect,
sizeof(int),
(ev_trace_f) ft_svr_event_collect,
{(ev_trace_f) ft_svr_event_collect,
sizeof(int),
(model_stat_f) ft_svr_model_stat_collect,
0,
NULL,
NULL,
0},
{NULL, 0, NULL, 0, NULL, 0}
{NULL, 0, NULL, 0, NULL, NULL, 0}
};
static const st_model_types *ft_svr_get_model_stat_types(void)
......@@ -456,7 +455,7 @@ int main(
svr_add_lp_type();
if (g_st_ev_trace)
if (g_st_ev_trace || g_st_model_stats || g_st_use_analysis_lps)
ft_svr_register_model_stats();
codes_mapping_setup();
......
......@@ -120,6 +120,49 @@ tw_lptype svr_lp = {
sizeof(svr_state),
};
/* setup for the ROSS event tracing
*/
void svr_event_collect(svr_msg *m, tw_lp *lp, char *buffer, int *collect_flag)
{
(void)lp;
(void)collect_flag;
int type = (int) m->svr_event_type;
memcpy(buffer, &type, sizeof(type));
}
/* can add in any model level data to be collected along with simulation engine data
* in the ROSS instrumentation. Will need to update the last field in
* svr_model_types[0] for the size of the data to save in each function call
*/
void svr_model_stat_collect(svr_state *s, tw_lp *lp, char *buffer)
{
(void)s;
(void)lp;
(void)buffer;
return;
}
st_model_types svr_model_types[] = {
{(ev_trace_f) svr_event_collect,
sizeof(int),
(model_stat_f) svr_model_stat_collect,
0,
NULL,
NULL,
0},
{NULL, 0, NULL, 0, NULL, NULL, 0}
};
static const st_model_types *svr_get_model_stat_types(void)
{
return(&svr_model_types[0]);
}
void svr_register_model_types()
{
st_model_type_register("server", svr_get_model_stat_types());
}
const tw_optdef app_opt [] =
{
TWOPT_GROUP("Model net synthetic traffic " ),
......@@ -465,6 +508,10 @@ int main(
configuration_load(argv[2], MPI_COMM_WORLD, &config);
model_net_register();
svr_add_lp_type();
if (g_st_ev_trace || g_st_model_stats || g_st_use_analysis_lps)
svr_register_model_types();
codes_mapping_setup();
net_ids = model_net_configure(&num_nets);
// assert(num_nets==1);
......
......@@ -108,8 +108,6 @@ tw_lptype svr_lp = {
};
/* setup for the ROSS event tracing
* can have a different function for rbev_trace_f and ev_trace_f
* but right now it is set to the same function for both
*/
void svr_event_collect(svr_msg *m, tw_lp *lp, char *buffer, int *collect_flag)
{
......@@ -132,13 +130,14 @@ void svr_model_stat_collect(svr_state *s, tw_lp *lp, char *buffer)
}
st_model_types svr_model_types[] = {
{(rbev_trace_f) svr_event_collect,
sizeof(int),
(ev_trace_f) svr_event_collect,
{(ev_trace_f) svr_event_collect,
sizeof(int),
(model_stat_f) svr_model_stat_collect,
0,
NULL,
NULL,
0},
{NULL, 0, NULL, 0, NULL, 0}
{NULL, 0, NULL, 0, NULL, NULL, 0}
};
static const st_model_types *svr_get_model_stat_types(void)
......@@ -424,7 +423,7 @@ int main(
model_net_register();
svr_add_lp_type();
if (g_st_ev_trace || g_st_model_stats)
if (g_st_ev_trace || g_st_model_stats || g_st_use_analysis_lps)
svr_register_model_types();
codes_mapping_setup();
......
This diff is collapsed.
This diff is collapsed.
......@@ -296,6 +296,47 @@ struct switch_state
int *lft;
};
/* ROSS Instrumentation Support */
struct fattree_cn_sample
{
tw_lpid terminal_id;
tw_stime end_time;
int vc_occupancy;
};
struct fattree_switch_sample
{
tw_lpid switch_id;
int *vc_occupancy;
tw_stime end_time;
};
void fattree_event_collect(fattree_message *m, tw_lp *lp, char *buffer, int *collect_flag);
void fattree_model_stat_collect(ft_terminal_state *s, tw_lp *lp, char *buffer);
static void ross_fattree_sample_fn(ft_terminal_state * s, tw_bf * bf, tw_lp * lp, struct fattree_cn_sample *sample);
static void ross_fattree_sample_rc_fn(ft_terminal_state * s, tw_bf * bf, tw_lp * lp, struct fattree_cn_sample *sample);
static void ross_fattree_ssample_fn(switch_state * s, tw_bf * bf, tw_lp * lp, struct fattree_switch_sample *sample);
static void ross_fattree_ssample_rc_fn(switch_state * s, tw_bf * bf, tw_lp * lp, struct fattree_switch_sample *sample);
st_model_types fattree_model_types[] = {
{(ev_trace_f) fattree_event_collect,
sizeof(int),
(model_stat_f) fattree_model_stat_collect,
0, // update when changing fattree_model_stat_collect
(sample_event_f) ross_fattree_sample_fn,
(sample_revent_f) ross_fattree_sample_rc_fn,
sizeof(struct fattree_cn_sample) } ,
{(ev_trace_f) fattree_event_collect,
sizeof(int),
(model_stat_f) fattree_model_stat_collect,
0, // update when changing fattree_model_stat_collect
(sample_event_f) ross_fattree_ssample_fn,
(sample_revent_f) ross_fattree_ssample_rc_fn,
0 } , // updated in switch_init()
{NULL, 0, NULL, 0, NULL, NULL, 0}
};
/* End of ROSS model stats collection */
static tw_stime fattree_total_time = 0;
static tw_stime fattree_max_latency = 0;
//static tw_stime max_collective = 0;
......@@ -1130,6 +1171,10 @@ void switch_init(switch_state * r, tw_lp * lp)
r->busy_time = (tw_stime*)malloc(r->radix * sizeof(tw_stime));
r->busy_time_sample = (tw_stime*)malloc(r->radix * sizeof(tw_stime));
// ROSS Instrumentation
if (g_st_use_analysis_lps && g_st_model_stats)
lp->model_types->sample_struct_sz = sizeof(struct fattree_switch_sample) + sizeof(int) * r->radix;
rc_stack_create(&r->st);
for(int i = 0; i < r->radix; i++)
......@@ -2967,7 +3012,23 @@ tw_lptype fattree_lps[] =
{NULL, NULL, NULL, NULL, NULL, NULL, NULL, 0},
};
/* For ROSS event tracing */
/* returns the fattree lp type for lp registration */
static const tw_lptype* fattree_get_cn_lp_type(void)
{
return(&fattree_lps[0]);
}
/*static const tw_lptype* fattree_get_switch_lp_type(void)
{
return(&fattree_lps[1]);
} */
static void fattree_register(tw_lptype *base_type) {
lp_type_register(LP_CONFIG_NM, base_type);
lp_type_register("fattree_switch", &fattree_lps[1]);
}
/* For ROSS Instrumentation */
void fattree_event_collect(fattree_message *m, tw_lp *lp, char *buffer, int *collect_flag)
{
(void)lp;
......@@ -2977,46 +3038,73 @@ void fattree_event_collect(fattree_message *m, tw_lp *lp, char *buffer, int *col
memcpy(buffer, &type, sizeof(type));
}
// TODO will need to separate fattree_method into one for terminal and one for switch
// in order to use the ROSS model stats collection
st_model_types fattree_model_types[] = {
{(rbev_trace_f) fattree_event_collect,
sizeof(int),
(ev_trace_f) fattree_event_collect,
sizeof(int),
NULL,
0},
{NULL, 0, NULL, 0, NULL, 0}
};
void fattree_model_stat_collect(ft_terminal_state *s, tw_lp *lp, char *buffer)
{
(void)lp;
(void)s;
(void)buffer;
return;
}
static const st_model_types *fattree_get_model_stat_types(void)
static void ross_fattree_sample_fn(ft_terminal_state * s, tw_bf * bf, tw_lp * lp, struct fattree_cn_sample *sample)
{
return(&fattree_model_types[0]);
(void)bf;
sample->terminal_id = s->terminal_id;
sample->end_time = tw_now(lp);
sample->vc_occupancy = s->vc_occupancy[0];
return;
}
static void fattree_register_model_stats(st_model_types *base_type)
static void ross_fattree_sample_rc_fn(ft_terminal_state * s, tw_bf * bf, tw_lp * lp, struct fattree_cn_sample *sample)
{
st_model_type_register(LP_CONFIG_NM, base_type);
st_model_type_register("fattree_switch", &fattree_model_types[0]);
//trace_type_register("fattree_switch", base_type);
(void)lp;
(void)bf;
(void)s;
(void)sample;
return;
}
/*** END of ROSS event tracing additions */
/* returns the fattree lp type for lp registration */
static const tw_lptype* fattree_get_cn_lp_type(void)
static void ross_fattree_ssample_fn(switch_state * s, tw_bf * bf, tw_lp * lp, struct fattree_switch_sample *sample)
{
return(&fattree_lps[0]);
(void)bf;
int i;
sample->switch_id = s->switch_id;
sample->end_time = tw_now(lp);
sample->vc_occupancy = (int*)((&sample->end_time) + 1);
for (i = 0; i < s->radix; i++)
sample->vc_occupancy[i] = s->vc_occupancy[i];
return;
}
/*static const tw_lptype* fattree_get_switch_lp_type(void)
static void ross_fattree_ssample_rc_fn(switch_state * s, tw_bf * bf, tw_lp * lp, struct fattree_switch_sample *sample)
{
return(&fattree_lps[1]);
} */
(void)lp;
(void)bf;
(void)s;
(void)sample;
static void fattree_register(tw_lptype *base_type) {
lp_type_register(LP_CONFIG_NM, base_type);
lp_type_register("fattree_switch", &fattree_lps[1]);
return;
}
static const st_model_types *fattree_get_cn_model_stat_types(void)
{
return(&fattree_model_types[0]);
}
static void fattree_register_model_stats(st_model_types *base_type)
{
st_model_type_register(LP_CONFIG_NM, base_type);
st_model_type_register("fattree_switch", &fattree_model_types[1]);
}
/*** END of ROSS event tracing additions */
struct model_net_method fattree_method =
{
.mn_configure = fattree_configure,
......@@ -3032,7 +3120,7 @@ struct model_net_method fattree_method =
.mn_collective_call = NULL,
.mn_collective_call_rc = NULL,
.mn_model_stat_register = fattree_register_model_stats,
.mn_get_model_stat_types = fattree_get_model_stat_types
.mn_get_model_stat_types = fattree_get_cn_model_stat_types
};
#ifdef ENABLE_CORTEX
......
......@@ -122,8 +122,6 @@ tw_lptype model_net_base_lp = {
};
/* setup for the ROSS event tracing
* can have a different function for rbev_trace_f and ev_trace_f
* but right now it is set to the same function for both
*/
void mn_event_collect(model_net_wrap_msg *m, tw_lp *lp, char *buffer, int *collect_flag)
{
......@@ -146,10 +144,11 @@ void mn_event_collect(model_net_wrap_msg *m, tw_lp *lp, char *buffer, int *colle
break;
case MN_BASE_PASS:
sub_msg = ((char*)m)+msg_offsets[((model_net_base_state*)lp->cur_state)->net_id];
if (g_st_ev_trace == RB_TRACE || g_st_ev_trace == COMMIT_TRACE)
(((model_net_base_state*)lp->cur_state)->sub_model_type->rbev_trace)(sub_msg, lp, buffer, collect_flag);
else if (g_st_ev_trace == FULL_TRACE)
(((model_net_base_state*)lp->cur_state)->sub_model_type->ev_trace)(sub_msg, lp, buffer, collect_flag);
if (((model_net_base_state*)lp->cur_state)->sub_model_type)
{
if (g_st_ev_trace)
(((model_net_base_state*)lp->cur_state)->sub_model_type->ev_trace)(sub_msg, lp, buffer, collect_flag);
}
break;
default: // this shouldn't happen, but can help detect an issue
type = 9004;
......@@ -160,18 +159,32 @@ void mn_event_collect(model_net_wrap_msg *m, tw_lp *lp, char *buffer, int *colle
void mn_model_stat_collect(model_net_base_state *s, tw_lp *lp, char *buffer)
{
// need to call the model level stats collection fn
(*s->sub_model_type->model_stat_fn)(s->sub_state, lp, buffer);
if (s->sub_model_type)
(*s->sub_model_type->model_stat_fn)(s->sub_state, lp, buffer);
return;
}
void mn_sample_event(model_net_base_state *s, tw_bf * bf, tw_lp * lp, void *sample)
{
if (s->sub_model_type)
(*s->sub_model_type->sample_event_fn)(s->sub_state, bf, lp, sample);
}
void mn_sample_rc_event(model_net_base_state *s, tw_bf * bf, tw_lp * lp, void *sample)
{
if (s->sub_model_type)
(*s->sub_model_type->sample_revent_fn)(s->sub_state, bf, lp, sample);
}
st_model_types mn_model_types[MAX_NETS];
st_model_types mn_model_base_type = {
(rbev_trace_f) mn_event_collect,
sizeof(int),
(ev_trace_f) mn_event_collect,
sizeof(int),
(model_stat_f) mn_model_stat_collect,
0,
(sample_event_f) mn_sample_event,
(sample_revent_f) mn_sample_rc_event,
0
};
......@@ -213,14 +226,15 @@ void model_net_base_register(int *do_config_nets){
&model_net_base_lp);
else
method_array[i]->mn_register(&model_net_base_lp);
if (g_st_ev_trace || g_st_model_stats) // for ROSS event tracing
if (g_st_ev_trace || g_st_model_stats || g_st_use_analysis_lps) // for ROSS event tracing
{
memcpy(&mn_model_types[i], &mn_model_base_type, sizeof(st_model_types));
if (method_array[i]->mn_model_stat_register == NULL)
st_model_type_register(model_net_lp_config_names[i], &mn_model_types[i]);
else
if (method_array[i]->mn_model_stat_register != NULL)
// st_model_type_register(model_net_lp_config_names[i], &mn_model_types[i]);
//else
{
memcpy(&mn_model_types[i], &mn_model_base_type, sizeof(st_model_types));
method_array[i]->mn_model_stat_register(&mn_model_types[i]);
}
}
}
}
......@@ -465,10 +479,14 @@ void model_net_base_lp_init(
ns->sub_type = model_net_get_lp_type(ns->net_id);
/* some ROSS instrumentation setup */
if (g_st_ev_trace || g_st_model_stats)
if (g_st_ev_trace || g_st_model_stats || g_st_use_analysis_lps)
{
ns->sub_model_type = model_net_get_model_stat_type(ns->net_id);
mn_model_types[ns->net_id].mstat_sz = ns->sub_model_type->mstat_sz;
if (ns->sub_model_type)
{
mn_model_types[ns->net_id].mstat_sz = ns->sub_model_type->mstat_sz;
mn_model_types[ns->net_id].sample_struct_sz = ns->sub_model_type->sample_struct_sz;
}
}
// NOTE: some models actually expect LP state to be 0 initialized...
......
......@@ -5,7 +5,7 @@ n is the number of input bgp-log files */
#include <sys/stat.h>
#include <mpi.h>
#include <assert.h>
#define RADIX 16
#define RADIX 8
struct dfly_samples
{
......
......@@ -284,6 +284,47 @@ struct router_state
int* cur_hist_num; //Aren't used
};
/* ROSS Instrumentation Support */
struct slimfly_cn_sample
{
tw_lpid terminal_id;
tw_stime end_time;
int vc_occupancy; // will sum occupancy for all vc
};
struct slimfly_router_sample
{
tw_lpid router_id;
int* vc_occupancy; // sum for all vc for each port
tw_stime end_time;
};
void slimfly_event_collect(slim_terminal_message *m, tw_lp *lp, char *buffer, int *collect_flag);
void slimfly_model_stat_collect(terminal_state *s, tw_lp *lp, char *buffer);
static void ross_slimfly_sample_fn(terminal_state * s, tw_bf * bf, tw_lp * lp, struct slimfly_cn_sample *sample);
static void ross_slimfly_sample_rc_fn(terminal_state * s, tw_bf * bf, tw_lp * lp, struct slimfly_cn_sample *sample);
static void ross_slimfly_rsample_fn(router_state * s, tw_bf * bf, tw_lp * lp, struct slimfly_router_sample *sample);
static void ross_slimfly_rsample_rc_fn(router_state * s, tw_bf * bf, tw_lp * lp, struct slimfly_router_sample *sample);
st_model_types slimfly_model_types[] = {
{(ev_trace_f) slimfly_event_collect,
sizeof(int),
(model_stat_f) slimfly_model_stat_collect,
0, // update this when changing slimfly_model_stat_collect
(sample_event_f) ross_slimfly_sample_fn,
(sample_revent_f) ross_slimfly_sample_rc_fn,
sizeof(struct slimfly_cn_sample) } ,
{(ev_trace_f) slimfly_event_collect,
sizeof(int),
(model_stat_f) slimfly_model_stat_collect,
0, // update this when changing slimfly_model_stat_collect
(sample_event_f) ross_slimfly_rsample_fn,
(sample_revent_f) ross_slimfly_rsample_rc_fn,
0 } , //updated in slim_router_setup() since it's based on the radix
{NULL, 0, NULL, 0, NULL, NULL, 0}
};
/* End of ROSS model stats collection */
static short routing = MINIMAL;
static tw_stime slimfly_total_time = 0;
......@@ -860,6 +901,10 @@ void slim_router_setup(router_state * r, tw_lp * lp)
r->last_buf_full = (tw_stime**)malloc(p->radix * sizeof(tw_stime*));
r->busy_time = (tw_stime*)malloc(p->radix * sizeof(tw_stime));
// ROSS Instrumentation
if (g_st_use_analysis_lps && g_st_model_stats)
lp->model_types->sample_struct_sz = sizeof(struct slimfly_router_sample) + sizeof(int) * p->radix;
rc_stack_create(&r->st);
for(int i=0; i < p->radix; i++)
......@@ -3373,6 +3418,96 @@ static void slimfly_register(tw_lptype *base_type) {
lp_type_register("slimfly_router", &slimfly_lps[1]);
}
/* For ROSS Instrumentation */
void slimfly_event_collect(slim_terminal_message *m, tw_lp *lp, char *buffer, int *collect_flag)
{
(void)lp;
(void)collect_flag;
int type = (int) m->type;
memcpy(buffer, &type, sizeof(type));
}
void slimfly_model_stat_collect(terminal_state *s, tw_lp *lp, char *buffer)
{
(void)lp;
(void)s;
(void)buffer;
return;