Skip to content
GitLab
Menu
Projects
Groups
Snippets
Loading...
Help
Help
Support
Community forum
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in
Toggle navigation
Menu
Open sidebar
Elsa Gonsiorowski
codes
Commits
01fca9de
Commit
01fca9de
authored
Jun 30, 2014
by
mubarak
Browse files
Adding model-net collective test
parent
e200280e
Changes
1
Hide whitespace changes
Inline
Side-by-side
tests/modelnet-test-collective.c
0 → 100644
View file @
01fca9de
/*
* Copyright (C) 2013 University of Chicago.
* See COPYRIGHT notice in top-level directory.
*
*/
/* SUMMARY:
*
* This is a test harness for the modelnet module. It sets up a number of
* servers, each of which is paired up with a simplenet LP to serve as the
* NIC. Each server exchanges a sequence of requests and acks with one peer
* and measures the throughput in terms of payload bytes (ack size) moved
* per second.
*/
#include <string.h>
#include <assert.h>
#include <ross.h>
#include "codes/model-net.h"
#include "codes/lp-io.h"
#include "codes/codes.h"
#include "codes/codes_mapping.h"
#include "codes/configuration.h"
#include "codes/lp-type-lookup.h"
#define NUM_REQS 5
/* number of requests sent by each server */
#define PAYLOAD_SZ 2048
/* size of simulated data payload, bytes */
static
int
net_id
=
0
;
static
int
num_routers
=
0
;
static
int
num_servers
=
0
;
static
int
offset
=
2
;
/* whether to pull instead of push */
static
int
do_pull
=
0
;
static
int
num_routers_per_rep
=
0
;
static
int
num_servers_per_rep
=
0
;
static
int
lps_per_rep
=
0
;
typedef
struct
svr_msg
svr_msg
;
typedef
struct
svr_state
svr_state
;
/* types of events that will constitute triton requests */
enum
svr_event
{
KICKOFF
,
/* initial event */
REQ
,
/* request event */
ACK
,
/* ack event */
LOCAL
/* local event */
};
struct
svr_state
{
int
msg_sent_count
;
/* requests sent */
int
msg_recvd_count
;
/* requests recvd */
int
local_recvd_count
;
/* number of local messages received */
tw_stime
start_ts
;
/* time that we started sending requests */
tw_stime
end_ts
;
/* time that we ended sending requests */
};
struct
svr_msg
{
enum
svr_event
svr_event_type
;
// enum net_event net_event_type;
tw_lpid
src
;
/* source of this request or ack */
int
incremented_flag
;
/* helper for reverse computation */
};
static
void
svr_init
(
svr_state
*
ns
,
tw_lp
*
lp
);
static
void
svr_event
(
svr_state
*
ns
,
tw_bf
*
b
,
svr_msg
*
m
,
tw_lp
*
lp
);
static
void
svr_rev_event
(
svr_state
*
ns
,
tw_bf
*
b
,
svr_msg
*
m
,
tw_lp
*
lp
);
static
void
svr_finalize
(
svr_state
*
ns
,
tw_lp
*
lp
);
tw_lptype
svr_lp
=
{
(
init_f
)
svr_init
,
(
event_f
)
svr_event
,
(
revent_f
)
svr_rev_event
,
(
final_f
)
svr_finalize
,
(
map_f
)
codes_mapping
,
sizeof
(
svr_state
),
};
extern
const
tw_lptype
*
svr_get_lp_type
();
static
void
svr_add_lp_type
();
static
tw_stime
ns_to_s
(
tw_stime
ns
);
static
tw_stime
s_to_ns
(
tw_stime
ns
);
static
void
handle_kickoff_event
(
svr_state
*
ns
,
tw_bf
*
b
,
svr_msg
*
m
,
tw_lp
*
lp
);
static
void
handle_req_event
(
svr_state
*
ns
,
tw_bf
*
b
,
svr_msg
*
m
,
tw_lp
*
lp
);
static
void
handle_local_event
(
svr_state
*
ns
,
tw_bf
*
b
,
svr_msg
*
m
,
tw_lp
*
lp
);
static
void
handle_local_rev_event
(
svr_state
*
ns
,
tw_bf
*
b
,
svr_msg
*
m
,
tw_lp
*
lp
);
static
void
handle_kickoff_rev_event
(
svr_state
*
ns
,
tw_bf
*
b
,
svr_msg
*
m
,
tw_lp
*
lp
);
static
void
handle_req_rev_event
(
svr_state
*
ns
,
tw_bf
*
b
,
svr_msg
*
m
,
tw_lp
*
lp
);
const
tw_optdef
app_opt
[]
=
{
TWOPT_GROUP
(
"Model net test case"
),
TWOPT_END
()
};
int
main
(
int
argc
,
char
**
argv
)
{
int
nprocs
;
int
rank
;
//printf("\n Config count %d ",(int) config.lpgroups_count);
g_tw_ts_end
=
s_to_ns
(
60
*
60
*
24
*
365
);
/* one year, in nsecs */
lp_io_handle
handle
;
tw_opt_add
(
app_opt
);
tw_init
(
&
argc
,
&
argv
);
if
(
argc
<
2
)
{
printf
(
"
\n
Usage: mpirun <args> --sync=2/3 mapping_file_name.conf (optional --nkp) "
);
MPI_Finalize
();
return
0
;
}
MPI_Comm_rank
(
MPI_COMM_WORLD
,
&
rank
);
MPI_Comm_size
(
MPI_COMM_WORLD
,
&
nprocs
);
configuration_load
(
argv
[
2
],
MPI_COMM_WORLD
,
&
config
);
net_id
=
model_net_set_params
();
svr_add_lp_type
();
codes_mapping_setup
();
num_servers
=
codes_mapping_get_group_reps
(
"MODELNET_GRP"
)
*
codes_mapping_get_lp_count
(
"MODELNET_GRP"
,
"server"
);
if
(
net_id
==
DRAGONFLY
)
{
num_routers
=
codes_mapping_get_group_reps
(
"MODELNET_GRP"
)
*
codes_mapping_get_lp_count
(
"MODELNET_GRP"
,
"dragonfly_router"
);
offset
=
1
;
}
if
(
lp_io_prepare
(
"modelnet-test"
,
LP_IO_UNIQ_SUFFIX
,
&
handle
,
MPI_COMM_WORLD
)
<
0
)
{
return
(
-
1
);
}
tw_run
();
model_net_report_stats
(
net_id
);
if
(
lp_io_flush
(
handle
,
MPI_COMM_WORLD
)
<
0
)
{
return
(
-
1
);
}
tw_end
();
return
0
;
}
const
tw_lptype
*
svr_get_lp_type
()
{
return
(
&
svr_lp
);
}
static
void
svr_add_lp_type
()
{
lp_type_register
(
"server"
,
svr_get_lp_type
());
}
static
void
svr_init
(
svr_state
*
ns
,
tw_lp
*
lp
)
{
tw_event
*
e
;
svr_msg
*
m
;
tw_stime
kickoff_time
;
memset
(
ns
,
0
,
sizeof
(
*
ns
));
/* each server sends a dummy event to itself that will kick off the real
* simulation
*/
//printf("\n Initializing servers %d ", (int)lp->gid);
/* skew each kickoff event slightly to help avoid event ties later on */
kickoff_time
=
g_tw_lookahead
+
tw_rand_unif
(
lp
->
rng
);
e
=
codes_event_new
(
lp
->
gid
,
kickoff_time
,
lp
);
m
=
tw_event_data
(
e
);
m
->
svr_event_type
=
KICKOFF
;
tw_event_send
(
e
);
return
;
}
static
void
svr_event
(
svr_state
*
ns
,
tw_bf
*
b
,
svr_msg
*
m
,
tw_lp
*
lp
)
{
switch
(
m
->
svr_event_type
)
{
case
REQ
:
handle_req_event
(
ns
,
b
,
m
,
lp
);
break
;
case
KICKOFF
:
handle_kickoff_event
(
ns
,
b
,
m
,
lp
);
break
;
case
LOCAL
:
handle_local_event
(
ns
,
b
,
m
,
lp
);
break
;
default:
printf
(
"
\n
Invalid message type %d "
,
m
->
svr_event_type
);
assert
(
0
);
break
;
}
}
static
void
svr_rev_event
(
svr_state
*
ns
,
tw_bf
*
b
,
svr_msg
*
m
,
tw_lp
*
lp
)
{
switch
(
m
->
svr_event_type
)
{
case
REQ
:
handle_req_rev_event
(
ns
,
b
,
m
,
lp
);
break
;
case
KICKOFF
:
handle_kickoff_rev_event
(
ns
,
b
,
m
,
lp
);
break
;
case
LOCAL
:
handle_local_rev_event
(
ns
,
b
,
m
,
lp
);
break
;
default:
assert
(
0
);
break
;
}
return
;
}
static
void
svr_finalize
(
svr_state
*
ns
,
tw_lp
*
lp
)
{
printf
(
"server %llu recvd %d bytes in %f seconds, %f MiB/s sent_count %d recvd_count %d local_count %d
\n
"
,
(
unsigned
long
long
)
lp
->
gid
,
PAYLOAD_SZ
*
ns
->
msg_recvd_count
,
ns_to_s
(
ns
->
end_ts
-
ns
->
start_ts
),
((
double
)(
PAYLOAD_SZ
*
NUM_REQS
)
/
(
double
)(
1024
*
1024
)
/
ns_to_s
(
ns
->
end_ts
-
ns
->
start_ts
)),
ns
->
msg_sent_count
,
ns
->
msg_recvd_count
,
ns
->
local_recvd_count
);
return
;
}
/* convert ns to seconds */
static
tw_stime
ns_to_s
(
tw_stime
ns
)
{
return
(
ns
/
(
1000
.
0
*
1000
.
0
*
1000
.
0
));
}
/* convert seconds to ns */
static
tw_stime
s_to_ns
(
tw_stime
ns
)
{
return
(
ns
*
(
1000
.
0
*
1000
.
0
*
1000
.
0
));
}
/* handle initial event */
static
void
handle_kickoff_event
(
svr_state
*
ns
,
tw_bf
*
b
,
svr_msg
*
m
,
tw_lp
*
lp
)
{
svr_msg
*
m_local
=
malloc
(
sizeof
(
svr_msg
));
svr_msg
*
m_remote
=
malloc
(
sizeof
(
svr_msg
));
// m_local->svr_event_type = REQ;
m_local
->
svr_event_type
=
LOCAL
;
m_local
->
src
=
lp
->
gid
;
memcpy
(
m_remote
,
m_local
,
sizeof
(
svr_msg
));
m_remote
->
svr_event_type
=
(
do_pull
)
?
ACK
:
REQ
;
//printf("handle_kickoff_event(), lp %llu.\n", (unsigned long long)lp->gid);
/* record when transfers started on this server */
ns
->
start_ts
=
tw_now
(
lp
);
num_servers_per_rep
=
codes_mapping_get_lp_count
(
"MODELNET_GRP"
,
"server"
);
num_routers_per_rep
=
codes_mapping_get_lp_count
(
"MODELNET_GRP"
,
"dragonfly_router"
);
lps_per_rep
=
num_servers_per_rep
*
2
+
num_routers_per_rep
;
int
opt_offset
=
0
;
int
total_lps
=
num_servers
*
2
+
num_routers
;
if
(
net_id
==
DRAGONFLY
&&
(
lp
->
gid
%
lps_per_rep
==
num_servers_per_rep
-
1
))
opt_offset
=
num_servers_per_rep
+
num_routers_per_rep
;
/* optional offset due to dragonfly mapping */
/* each server sends a request to the next highest server */
int
dest_id
=
(
lp
->
gid
+
offset
+
opt_offset
)
%
total_lps
;
if
(
do_pull
){
model_net_pull_event
(
net_id
,
"test"
,
dest_id
,
PAYLOAD_SZ
,
0
.
0
,
sizeof
(
svr_msg
),
(
const
void
*
)
m_remote
,
lp
);
}
else
{
model_net_event
(
net_id
,
"test"
,
dest_id
,
PAYLOAD_SZ
,
0
.
0
,
sizeof
(
svr_msg
),
(
const
void
*
)
m_remote
,
sizeof
(
svr_msg
),
(
const
void
*
)
m_local
,
lp
);
}
ns
->
msg_sent_count
++
;
}
static
void
handle_local_event
(
svr_state
*
ns
,
tw_bf
*
b
,
svr_msg
*
m
,
tw_lp
*
lp
)
{
ns
->
local_recvd_count
++
;
}
static
void
handle_local_rev_event
(
svr_state
*
ns
,
tw_bf
*
b
,
svr_msg
*
m
,
tw_lp
*
lp
)
{
ns
->
local_recvd_count
--
;
}
/* reverse handler for req event */
static
void
handle_req_rev_event
(
svr_state
*
ns
,
tw_bf
*
b
,
svr_msg
*
m
,
tw_lp
*
lp
)
{
ns
->
msg_recvd_count
--
;
if
(
m
->
incremented_flag
)
{
ns
->
msg_sent_count
--
;
model_net_event_collective_rc
(
net_id
,
PAYLOAD_SZ
,
lp
);
}
return
;
}
/* reverse handler for kickoff */
static
void
handle_kickoff_rev_event
(
svr_state
*
ns
,
tw_bf
*
b
,
svr_msg
*
m
,
tw_lp
*
lp
)
{
ns
->
msg_sent_count
--
;
if
(
do_pull
){
model_net_pull_event_rc
(
net_id
,
lp
);
}
else
{
model_net_event_rc
(
net_id
,
lp
,
PAYLOAD_SZ
);
}
return
;
}
/* handle receiving request
* (note: this should never be called when doing the "pulling" version of
* the program) */
static
void
handle_req_event
(
svr_state
*
ns
,
tw_bf
*
b
,
svr_msg
*
m
,
tw_lp
*
lp
)
{
assert
(
!
do_pull
);
svr_msg
*
m_local
=
malloc
(
sizeof
(
svr_msg
));
svr_msg
*
m_remote
=
malloc
(
sizeof
(
svr_msg
));
m_local
->
svr_event_type
=
LOCAL
;
m_local
->
src
=
lp
->
gid
;
memcpy
(
m_remote
,
m_local
,
sizeof
(
svr_msg
));
m_remote
->
svr_event_type
=
REQ
;
//printf("handle_req_event(), lp %llu src %llu .\n", (unsigned long long)lp->gid, (unsigned long long) m->src);
/* safety check that this request got to the right server */
// printf("\n m->src %d lp->gid %d ", m->src, lp->gid);
//assert(lp->gid == (m->src + offset + opt_offset)%(num_servers*2 + num_routers));
ns
->
msg_recvd_count
++
;
/* send ack back */
/* simulated payload of 1 MiB */
/* also trigger a local event for completion of payload msg */
/* remote host will get an ack event */
// mm Q: What should be the size of an ack message? may be a few bytes? or larger..?
if
(
ns
->
msg_sent_count
<
NUM_REQS
)
{
ns
->
msg_sent_count
++
;
model_net_event_collective
(
net_id
,
"test"
,
PAYLOAD_SZ
,
sizeof
(
svr_msg
),
(
const
void
*
)
m_remote
,
lp
);
m
->
incremented_flag
=
1
;
}
else
{
ns
->
end_ts
=
tw_now
(
lp
);
m
->
incremented_flag
=
0
;
}
//model_net_event(net_id, "test", m->src, PAYLOAD_SZ, 0.0, sizeof(svr_msg), (const void*)m_remote, sizeof(svr_msg), (const void*)m_local, lp);
// printf("\n Sending ack to LP %d %d ", m->src, m_remote->src);
return
;
}
/*
* Local variables:
* c-indent-level: 4
* c-basic-offset: 4
* End:
*
* vim: ft=c ts=8 sts=4 sw=4 expandtab
*/
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
.
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment