Commit 113307ec authored by Misbah Mubarak's avatar Misbah Mubarak
Browse files

Merging cortex with master

parents 9897e59c d5cf9422
......@@ -60,7 +60,6 @@ endif
if USE_DUMPI
AM_CPPFLAGS += ${DUMPI_CFLAGS} -DUSE_DUMPI=1
src_libcodes_la_SOURCES += src/workload/methods/codes-dumpi-trace-nw-wrkld.c
LDADD += ${DUMPI_LIBS}
if USE_CORTEX
if USE_PYTHON
if USE_CORTEX_PYTHON
......@@ -73,5 +72,6 @@ endif
AM_CPPFLAGS += ${CORTEX_CFLAGS} -DENABLE_CORTEX=1
LDADD += ${CORTEX_LIBS}
endif
LDADD += ${DUMPI_LIBS}
endif
/*
* Copyright (C) 2017 University of Chicago.
* See COPYRIGHT notice in top-level directory.
*
*/
#ifndef CODES_MPI_REPLAY_H
#define CODES_MPI_REPLAY_H
#ifdef __cplusplus
extern "C" {
#endif
#include <mpi.h>
int modelnet_mpi_replay(MPI_Comm comm, int* argc, char*** argv );
#ifdef __cplusplus
}
#endif
#endif /* CODES_H */
/*
* Local variables:
* c-indent-level: 4
* c-basic-offset: 4
* End:
*
* vim: ft=c ts=8 sts=4 sw=4 expandtab
*/
......@@ -14,6 +14,9 @@ extern "C" {
#include <ross.h>
#include <assert.h>
#include <mpi.h>
extern MPI_Comm MPI_COMM_CODES;
// for printf conversions: shorthand for cast to long long unsigned format (llu)
#define LLU(x) ((unsigned long long)(x))
......
......@@ -18,6 +18,11 @@ extern "C" {
#include <codes/codes-mapping-context.h>
#include <stdint.h>
#ifdef ENABLE_CORTEX
#include <cortex/cortex.h>
#include <cortex/topology.h>
#endif
#define PULL_MSG_SIZE 128
#define MAX_NAME_LENGTH 256
......@@ -406,6 +411,11 @@ void model_net_print_stats(tw_lpid lpid, mn_stats mn_stats_array[]);
/* find model-net statistics */
mn_stats* model_net_find_stats(char const * category, mn_stats mn_stats_array[]);
#ifdef ENABLE_CORTEX
/* structure that gives access to the topology functions */
extern cortex_topology model_net_topology;
#endif
#ifdef __cplusplus
}
#endif
......
lib_LTLIBRARIES += src/libcodes.la
lib_LTLIBRARIES += src/libcodes.la src/libcodes_mpi_replay.la
BUILT_SOURCES += src/modelconfig/configparser.h \
src/modelconfig/configlex.h
......@@ -95,6 +95,7 @@ nobase_include_HEADERS = \
codes/net/simplenet-upd.h \
codes/net/simplep2p.h \
codes/net/torus.h \
codes/codes-mpi-replay.h \
codes/configfile.h
......@@ -139,6 +140,7 @@ src_libcodes_la_SOURCES = \
src/util/jobmap-impl/jobmap-list.c\
src/util/jobmap-impl/jobmap-identity.c\
src/util/codes-mapping-context.c \
src/util/codes-comm.c \
src/workload/codes-workload.c \
src/workload/methods/codes-iolang-wrkld.c \
src/workload/methods/codes-checkpoint-wrkld.c \
......@@ -160,6 +162,8 @@ src_libcodes_la_SOURCES = \
src/networks/model-net/model-net-sched-impl.h \
src/networks/model-net/model-net-sched-impl.c
src_libcodes_mpi_replay_la_SOURCES = \
src/network-workloads/model-net-mpi-replay.c
#codes/codes-nw-workload.h
#src/network-workload/codes-nw-workload.c
......@@ -175,6 +179,7 @@ src_util_templates_lp_template_dummy_main_SOURCES = \
# get rid of annoying unused function in template
bin_PROGRAMS += src/workload/codes-workload-dump
bin_PROGRAMS += src/networks/model-net/topology-test
bin_PROGRAMS += src/network-workloads/model-net-mpi-replay
bin_PROGRAMS += src/network-workloads/model-net-dumpi-traces-dump
bin_PROGRAMS += src/network-workloads/model-net-synthetic
......@@ -187,10 +192,13 @@ src_workload_codes_workload_dump_SOURCES = \
src_network_workloads_model_net_dumpi_traces_dump_SOURCES = src/network-workloads/model-net-dumpi-traces-dump.c
src_network_workloads_model_net_synthetic_slimfly_SOURCES = src/network-workloads/model-net-synthetic-slimfly.c
src_network_workloads_model_net_mpi_replay_SOURCES = src/network-workloads/model-net-mpi-replay.c
src_network_workloads_model_net_mpi_replay_SOURCES = \
src/network-workloads/model-net-mpi-replay.c \
src/network-workloads/model-net-mpi-replay-main.c
src_network_workloads_model_net_mpi_replay_CFLAGS = $(AM_CFLAGS)
src_network_workloads_model_net_synthetic_SOURCES = src/network-workloads/model-net-synthetic.c
src_network_workloads_model_net_synthetic_custom_dfly_SOURCES = src/network-workloads/model-net-synthetic-custom-dfly.c
src_networks_model_net_topology_test_SOURCES = src/networks/model-net/topology-test.c
#bin_PROGRAMS += src/network-workload/codes-nw-test
......
/*
* Copyright (C) 2014 University of Chicago.
* See COPYRIGHT notice in top-level directory.
*
*/
#include <mpi.h>
#include "codes/codes-mpi-replay.h"
int main(int argc, char** argv) {
MPI_Init(&argc,&argv);
// int rank, size;
// MPI_Comm_rank(MPI_COMM_WORLD,&rank);
// MPI_Comm_size(MPI_COMM_WORLD,&size);
// MPI_Comm comm;
// MPI_Comm_split(MPI_COMM_WORLD, rank < 2, rank, &comm);
// if(rank < 2)
// modelnet_mpi_replay(comm,&argc,&argv);
modelnet_mpi_replay(MPI_COMM_WORLD,&argc,&argv);
int flag;
MPI_Finalized(&flag);
if(!flag) MPI_Finalize();
return 0;
}
/*
* Local variables:
* c-indent-level: 4
* c-basic-offset: 4
* End:
*
* vim: ft=c ts=8 sts=4 sw=4 expandtab
*/
......@@ -2209,17 +2209,21 @@ static int msg_size_hash_compare(
return 0;
}
int main( int argc, char** argv )
int modelnet_mpi_replay(MPI_Comm comm, int* argc, char*** argv )
{
int rank, nprocs;
int num_nets;
int* net_ids;
MPI_COMM_CODES = comm;
tw_comm_set(MPI_COMM_CODES);
g_tw_ts_end = s_to_ns(60*5); /* five minutes, in nsecs */
workload_type[0]='\0';
tw_opt_add(app_opt);
tw_init(&argc, &argv);
tw_init(argc, argv);
if(strcmp(workload_type, "dumpi") != 0)
{
......@@ -2231,6 +2235,7 @@ int main( int argc, char** argv )
#ifdef ENABLE_CORTEX_PYTHON
" --cortex-file=cortex-file-name"
" --cortex-class=cortex-class-name"
" --cortex-gen=cortex-function-name"
#endif
" -- config-file-name\n"
"See model-net/doc/README.dragonfly.txt and model-net/doc/README.torus.txt"
......@@ -2239,6 +2244,8 @@ int main( int argc, char** argv )
return -1;
}
jobmap_ctx = NULL; // make sure it's NULL if it's not used
if(strlen(workloads_conf_file) > 0)
{
FILE *name_file = fopen(workloads_conf_file, "r");
......@@ -2278,11 +2285,16 @@ int main( int argc, char** argv )
strcpy(file_name_of_job[0], workload_file);
num_traces_of_job[0] = num_net_traces;
alloc_spec = 0;
if(strlen(alloc_file) > 0) {
alloc_spec = 1;
jobmap_p.alloc_file = alloc_file;
jobmap_ctx = codes_jobmap_configure(CODES_JOBMAP_LIST, &jobmap_p);
}
}
MPI_Comm_rank(MPI_COMM_WORLD, &rank);
MPI_Comm_size(MPI_COMM_WORLD, &nprocs);
MPI_Comm_rank(MPI_COMM_CODES, &rank);
MPI_Comm_size(MPI_COMM_CODES, &nprocs);
configuration_load(argv[2], MPI_COMM_WORLD, &config);
configuration_load((*argv)[2], MPI_COMM_CODES, &config);
nw_add_lp_type();
model_net_register();
......@@ -2341,7 +2353,7 @@ int main( int argc, char** argv )
do_lp_io = 1;
/* initialize lp io */
int flags = lp_io_use_suffix ? LP_IO_UNIQ_SUFFIX : 0;
int ret = lp_io_prepare(lp_io_dir, flags, &io_handle, MPI_COMM_WORLD);
int ret = lp_io_prepare(lp_io_dir, flags, &io_handle, MPI_COMM_CODES);
assert(ret == 0 || !"lp_io_prepare failure");
}
tw_run();
......@@ -2359,19 +2371,19 @@ int main( int argc, char** argv )
double total_avg_wait_time, total_max_wait_time;
double total_avg_recv_time, total_max_recv_time;
MPI_Reduce(&num_bytes_sent, &total_bytes_sent, 1, MPI_LONG_LONG, MPI_SUM, 0, MPI_COMM_WORLD);
MPI_Reduce(&num_bytes_recvd, &total_bytes_recvd, 1, MPI_LONG_LONG, MPI_SUM, 0, MPI_COMM_WORLD);
MPI_Reduce(&max_comm_time, &max_comm_run_time, 1, MPI_DOUBLE, MPI_MAX, 0, MPI_COMM_WORLD);
MPI_Reduce(&max_time, &max_run_time, 1, MPI_DOUBLE, MPI_MAX, 0, MPI_COMM_WORLD);
MPI_Reduce(&avg_time, &avg_run_time, 1, MPI_DOUBLE, MPI_SUM, 0, MPI_COMM_WORLD);
MPI_Reduce(&num_bytes_sent, &total_bytes_sent, 1, MPI_LONG_LONG, MPI_SUM, 0, MPI_COMM_CODES);
MPI_Reduce(&num_bytes_recvd, &total_bytes_recvd, 1, MPI_LONG_LONG, MPI_SUM, 0, MPI_COMM_CODES);
MPI_Reduce(&max_comm_time, &max_comm_run_time, 1, MPI_DOUBLE, MPI_MAX, 0, MPI_COMM_CODES);
MPI_Reduce(&max_time, &max_run_time, 1, MPI_DOUBLE, MPI_MAX, 0, MPI_COMM_CODES);
MPI_Reduce(&avg_time, &avg_run_time, 1, MPI_DOUBLE, MPI_SUM, 0, MPI_COMM_CODES);
MPI_Reduce(&avg_recv_time, &total_avg_recv_time, 1, MPI_DOUBLE, MPI_SUM, 0, MPI_COMM_WORLD);
MPI_Reduce(&avg_comm_time, &avg_comm_run_time, 1, MPI_DOUBLE, MPI_SUM, 0, MPI_COMM_WORLD);
MPI_Reduce(&max_wait_time, &total_max_wait_time, 1, MPI_DOUBLE, MPI_MAX, 0, MPI_COMM_WORLD);
MPI_Reduce(&max_send_time, &total_max_send_time, 1, MPI_DOUBLE, MPI_MAX, 0, MPI_COMM_WORLD);
MPI_Reduce(&max_recv_time, &total_max_recv_time, 1, MPI_DOUBLE, MPI_MAX, 0, MPI_COMM_WORLD);
MPI_Reduce(&avg_wait_time, &total_avg_wait_time, 1, MPI_DOUBLE, MPI_SUM, 0, MPI_COMM_WORLD);
MPI_Reduce(&avg_send_time, &total_avg_send_time, 1, MPI_DOUBLE, MPI_SUM, 0, MPI_COMM_WORLD);
MPI_Reduce(&avg_recv_time, &total_avg_recv_time, 1, MPI_DOUBLE, MPI_SUM, 0, MPI_COMM_CODES);
MPI_Reduce(&avg_comm_time, &avg_comm_run_time, 1, MPI_DOUBLE, MPI_SUM, 0, MPI_COMM_CODES);
MPI_Reduce(&max_wait_time, &total_max_wait_time, 1, MPI_DOUBLE, MPI_MAX, 0, MPI_COMM_CODES);
MPI_Reduce(&max_send_time, &total_max_send_time, 1, MPI_DOUBLE, MPI_MAX, 0, MPI_COMM_CODES);
MPI_Reduce(&max_recv_time, &total_max_recv_time, 1, MPI_DOUBLE, MPI_MAX, 0, MPI_COMM_CODES);
MPI_Reduce(&avg_wait_time, &total_avg_wait_time, 1, MPI_DOUBLE, MPI_SUM, 0, MPI_COMM_CODES);
MPI_Reduce(&avg_send_time, &total_avg_send_time, 1, MPI_DOUBLE, MPI_SUM, 0, MPI_COMM_CODES);
assert(num_net_traces);
......@@ -2385,7 +2397,7 @@ int main( int argc, char** argv )
total_max_recv_time, total_avg_recv_time/num_net_traces,
total_max_wait_time, total_avg_wait_time/num_net_traces);
if (do_lp_io){
int ret = lp_io_flush(io_handle, MPI_COMM_WORLD);
int ret = lp_io_flush(io_handle, MPI_COMM_CODES);
assert(ret == 0 || !"lp_io_flush failure");
}
model_net_report_stats(net_id);
......
......@@ -358,10 +358,10 @@ int main(
return 0;
}
MPI_Comm_rank(MPI_COMM_WORLD, &rank);
MPI_Comm_size(MPI_COMM_WORLD, &nprocs);
MPI_Comm_rank(MPI_COMM_CODES, &rank);
MPI_Comm_size(MPI_COMM_CODES, &nprocs);
configuration_load(argv[2], MPI_COMM_WORLD, &config);
configuration_load(argv[2], MPI_COMM_CODES, &config);
model_net_register();
svr_add_lp_type();
......@@ -401,12 +401,12 @@ int main(
{
do_lp_io = 1;
int flags = lp_io_use_suffix ? LP_IO_UNIQ_SUFFIX : 0;
int ret = lp_io_prepare(lp_io_dir, flags, &io_handle, MPI_COMM_WORLD);
int ret = lp_io_prepare(lp_io_dir, flags, &io_handle, MPI_COMM_CODES);
assert(ret == 0 || !"lp_io_prepare failure");
}
tw_run();
if (do_lp_io){
int ret = lp_io_flush(io_handle, MPI_COMM_WORLD);
int ret = lp_io_flush(io_handle, MPI_COMM_CODES);
assert(ret == 0 || !"lp_io_flush failure");
}
model_net_report_stats(net_id);
......
......@@ -19,6 +19,12 @@
#include "codes/rc-stack.h"
#include <vector>
#include <map>
#include <set>
#ifdef ENABLE_CORTEX
#include <cortex/cortex.h>
#include <cortex/topology.h>
#endif
#define DUMP_CONNECTIONS 0
#define CREDIT_SIZE 8
......@@ -63,6 +69,13 @@ struct InterGroupLink {
int src, dest;
};
#ifdef ENABLE_CORTEX
/* This structure is defined at the end of the file */
extern "C" {
extern cortex_topology dragonfly_custom_cortex_topology;
}
#endif
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;
......@@ -482,7 +495,7 @@ static void dragonfly_read_config(const char * anno, dragonfly_param *params){
// shorthand
dragonfly_param *p = params;
int myRank;
MPI_Comm_rank(MPI_COMM_WORLD, &myRank);
MPI_Comm_rank(MPI_COMM_CODES, &myRank);
int rc = configuration_get_value_int(&config, "PARAMS", "local_vc_size", anno, &p->local_vc_size);
if(rc) {
......@@ -564,7 +577,7 @@ static void dragonfly_read_config(const char * anno, dragonfly_param *params){
rc = configuration_get_value_int(&config, "PARAMS", "num_groups", anno, &p->num_groups);
if(rc) {
printf("Number of groups not specified. Aborting");
MPI_Abort(MPI_COMM_WORLD, 1);
MPI_Abort(MPI_COMM_CODES, 1);
}
rc = configuration_get_value_int(&config, "PARAMS", "num_col_chans", anno, &p->num_col_chans);
if(rc) {
......@@ -756,6 +769,9 @@ void dragonfly_custom_configure(){
if (anno_map->has_unanno_lp > 0){
dragonfly_read_config(NULL, &all_params[anno_map->num_annos]);
}
#ifdef ENABLE_CORTEX
model_net_topology = dragonfly_custom_cortex_topology;
#endif
}
/* report dragonfly statistics like average and maximum packet latency, average number of hops traversed */
......@@ -767,20 +783,20 @@ void dragonfly_custom_report_stats()
int total_minimal_packets, total_nonmin_packets;
long total_gen, total_fin;
MPI_Reduce( &total_hops, &avg_hops, 1, MPI_LONG_LONG, MPI_SUM, 0, MPI_COMM_WORLD);
MPI_Reduce( &N_finished_packets, &total_finished_packets, 1, MPI_LONG_LONG, MPI_SUM, 0, MPI_COMM_WORLD);
MPI_Reduce( &N_finished_msgs, &total_finished_msgs, 1, MPI_LONG_LONG, MPI_SUM, 0, MPI_COMM_WORLD);
MPI_Reduce( &N_finished_chunks, &total_finished_chunks, 1, MPI_LONG_LONG, MPI_SUM, 0, MPI_COMM_WORLD);
MPI_Reduce( &total_msg_sz, &final_msg_sz, 1, MPI_LONG_LONG, MPI_SUM, 0, MPI_COMM_WORLD);
MPI_Reduce( &dragonfly_total_time, &avg_time, 1,MPI_DOUBLE, MPI_SUM, 0, MPI_COMM_WORLD);
MPI_Reduce( &dragonfly_max_latency, &max_time, 1, MPI_DOUBLE, MPI_MAX, 0, MPI_COMM_WORLD);
MPI_Reduce( &total_hops, &avg_hops, 1, MPI_LONG_LONG, MPI_SUM, 0, MPI_COMM_CODES);
MPI_Reduce( &N_finished_packets, &total_finished_packets, 1, MPI_LONG_LONG, MPI_SUM, 0, MPI_COMM_CODES);
MPI_Reduce( &N_finished_msgs, &total_finished_msgs, 1, MPI_LONG_LONG, MPI_SUM, 0, MPI_COMM_CODES);
MPI_Reduce( &N_finished_chunks, &total_finished_chunks, 1, MPI_LONG_LONG, MPI_SUM, 0, MPI_COMM_CODES);
MPI_Reduce( &total_msg_sz, &final_msg_sz, 1, MPI_LONG_LONG, MPI_SUM, 0, MPI_COMM_CODES);
MPI_Reduce( &dragonfly_total_time, &avg_time, 1,MPI_DOUBLE, MPI_SUM, 0, MPI_COMM_CODES);
MPI_Reduce( &dragonfly_max_latency, &max_time, 1, MPI_DOUBLE, MPI_MAX, 0, MPI_COMM_CODES);
MPI_Reduce( &packet_gen, &total_gen, 1, MPI_LONG, MPI_SUM, 0, MPI_COMM_WORLD);
MPI_Reduce( &packet_fin, &total_fin, 1, MPI_LONG, MPI_SUM, 0, MPI_COMM_WORLD);
MPI_Reduce( &packet_gen, &total_gen, 1, MPI_LONG, MPI_SUM, 0, MPI_COMM_CODES);
MPI_Reduce( &packet_fin, &total_fin, 1, MPI_LONG, MPI_SUM, 0, MPI_COMM_CODES);
if(routing == ADAPTIVE || routing == PROG_ADAPTIVE)
{
MPI_Reduce(&minimal_count, &total_minimal_packets, 1, MPI_INT, MPI_SUM, 0, MPI_COMM_WORLD);
MPI_Reduce(&nonmin_count, &total_nonmin_packets, 1, MPI_INT, MPI_SUM, 0, MPI_COMM_WORLD);
MPI_Reduce(&minimal_count, &total_minimal_packets, 1, MPI_INT, MPI_SUM, 0, MPI_COMM_CODES);
MPI_Reduce(&nonmin_count, &total_nonmin_packets, 1, MPI_INT, MPI_SUM, 0, MPI_COMM_CODES);
}
/* print statistics */
......@@ -3363,4 +3379,305 @@ struct model_net_method dragonfly_custom_router_method =
(init_f)dragonfly_custom_rsample_init,
NULL,//(final_f)dragonfly_custom_rsample_fin
};
#ifdef ENABLE_CORTEX
static int dragonfly_custom_get_number_of_compute_nodes(void* topo) {
const dragonfly_param * params = &all_params[num_params-1];
if(!params)
return -1.0;
return params->total_terminals;
}
static int dragonfly_custom_get_number_of_routers(void* topo) {
// TODO
const dragonfly_param * params = &all_params[num_params-1];
if(!params)
return -1.0;
return params->total_routers;
}
static double dragonfly_custom_get_router_link_bandwidth(void* topo, router_id_t r1, router_id_t r2) {
// TODO: handle this function for multiple cables between the routers.
// Right now it returns the bandwidth of a single cable only.
// Given two router ids r1 and r2, this function should return the bandwidth (double)
// of the link between the two routers, or 0 of such a link does not exist in the topology.
// The function should return -1 if one of the router id is invalid.
const dragonfly_param * params = &all_params[num_params-1];
if(!params)
return -1.0;
if(r1 > params->total_routers || r2 > params->total_routers)
return -1.0;
if(r1 < 0 || r2 < 0)
return -1.0;
int gid_r1 = r1 / params->num_routers;
int gid_r2 = r2 / params->num_routers;
if(gid_r1 == gid_r2)
{
int lid_r1 = r1 % params->num_routers;
int lid_r2 = r2 % params->num_routers;
/* The connection will be there if the router is in the same row or
* same column */
int src_row_r1 = lid_r1 / params->num_router_cols;
int src_row_r2 = lid_r2 / params->num_router_cols;
int src_col_r1 = lid_r1 % params->num_router_cols;
int src_col_r2 = lid_r2 % params->num_router_cols;
if(src_row_r1 == src_row_r2 || src_col_r1 == src_col_r2)
return params->local_bandwidth;
else
return 0.0;
}
else
{
vector<bLink> &curVec = interGroupLinks[r1][gid_r2];
vector<bLink>::iterator it = curVec.begin();
for(; it != curVec.end(); it++)
{
bLink bl = *it;
if(bl.dest == r2)
return params->global_bandwidth;
}
return 0.0;
}
return 0.0;
}
static double dragonfly_custom_get_compute_node_bandwidth(void* topo, cn_id_t node) {
// TODO
// Given the id of a compute node, this function should return the bandwidth of the
// link connecting this compute node to its router.
// The function should return -1 if the compute node id is invalid.
const dragonfly_param * params = &all_params[num_params-1];
if(!params)
return -1.0;
if(node < 0 || node >= params->total_terminals)
return -1.0;
return params->cn_bandwidth;
}
static int dragonfly_custom_get_router_neighbor_count(void* topo, router_id_t r) {
// TODO
// Given the id of a router, this function should return the number of routers
// (not compute nodes) connected to it. It should return -1 if the router id
// is not valid.
const dragonfly_param * params = &all_params[num_params-1];
if(!params)
return -1.0;
if(r < 0 || r >= params->total_routers)
return -1.0;
/* Now count the global channels */
set<router_id_t> g_neighbors;
map< int, vector<bLink> > &curMap = interGroupLinks[r];
map< int, vector<bLink> >::iterator it = curMap.begin();
for(; it != curMap.end(); it++) {
for(int l = 0; l < it->second.size(); l++) {
g_neighbors.insert(it->second[l].dest);
}
}
return (params->num_router_cols - 1) + (params->num_router_rows - 1) + g_neighbors.size();
}
static void dragonfly_custom_get_router_neighbor_list(void* topo, router_id_t r, router_id_t* neighbors) {
// Given a router id r, this function fills the "neighbors" array with the ids of routers
// directly connected to r. It is assumed that enough memory has been allocated to "neighbors"
// (using get_router_neighbor_count to know the required size).
const dragonfly_param * params = &all_params[num_params-1];
int gid = r / params->num_routers;
int src_row = r / params->num_router_cols;
int src_col = r % params->num_router_cols;
/* First the routers in the same row */
int i = 0;
int offset = 0;
while(i < params->num_router_cols)
{
int neighbor = gid * params->num_routers + (src_row * params->num_router_cols) + i;
if(neighbor != r)
{
neighbors[offset] = neighbor;
offset++;
}
i++;
}
/* Now the routers in the same column. */
offset = 0;
i = 0;
while(i < params->num_router_rows)
{
int neighbor = gid * params->num_routers + src_col + (i * params->num_router_cols);
if(neighbor != r)
{
neighbors[offset+params->num_router_cols-1] = neighbor;
offset++;
}
i++;
}
int g_offset = params->num_router_cols + params->num_router_rows - 2;
/* Now fill up global channels */
set<router_id_t> g_neighbors;
map< int, vector<bLink> > &curMap = interGroupLinks[r];
map< int, vector<bLink> >::iterator it = curMap.begin();
for(; it != curMap.end(); it++) {
for(int l = 0; l < it->second.size(); l++) {
g_neighbors.insert(it->second[l].dest);
}
}
/* Now transfer the content of the sets to the array */
set<router_id_t>::iterator it_set;
int count = 0;
for(it_set = g_neighbors.begin(); it_set != g_neighbors.end(); it_set++)
{
neighbors[g_offset+count] = *it_set;
++count;
}
}
static int dragonfly_custom_get_router_location(void* topo, router_id_t r, int32_t* location, int size) {
// TODO
// Given a router id r, this function should fill the "location" array (of maximum size "size")
// with information providing the location of the router in the topology. In a Dragonfly network,
// for instance, this can be the array [ group_id, router_id ] where group_id is the id of the
// group in which the router is, and router_id is the id of the router inside this group (as opposed
// to "r" which is its global id). For a torus network, this would be the dimensions.
// If the "size" is sufficient to hold the information, the function should return the size
// effectively used (e.g. 2 in the above example). If however the function did not manage to use
// the provided buffer, it should return -1.
const dragonfly_param * params = &all_params[num_params-1];
if(!params)
return -1;
if(r < 0 || r >= params->total_terminals)
return -1;
if(size < 2)
return -1;
int rid = r % params->num_routers;