-/* Copyright (c) 2009, 2010, 2011, 2012. The SimGrid Team.
+/* Copyright (c) 2009 - 2013. The SimGrid Team.
* All rights reserved. */
/* This program is free software; you can redistribute it and/or modify it
}
typedef struct {
- xbt_dynar_t isends; /* of MPI_Request */
xbt_dynar_t irecvs; /* of MPI_Request */
} s_smpi_replay_globals_t, *smpi_replay_globals_t;
static MPI_Datatype decode_datatype(const char *const action)
{
// Declared datatypes,
-
+
switch(atoi(action))
{
case 0:
break;
default:
MPI_CURRENT_TYPE=MPI_DEFAULT_TYPE;
-
+
}
return MPI_CURRENT_TYPE;
}
int i;
XBT_DEBUG("Initialize the counters");
smpi_replay_globals_t globals = xbt_new(s_smpi_replay_globals_t, 1);
- globals->isends = xbt_dynar_new(sizeof(MPI_Request),NULL);
globals->irecvs = xbt_dynar_new(sizeof(MPI_Request),NULL);
if(action[2]) MPI_DEFAULT_TYPE= MPI_DOUBLE; // default MPE dataype
else MPI_DEFAULT_TYPE= MPI_BYTE; // default TAU datatype
-
+
smpi_process_set_user_data((void*) globals);
/* start a simulated timer */
if (!reqq) {
reqq=xbt_new0(xbt_dynar_t,active_processes);
-
+
for(i=0;i<active_processes;i++){
reqq[i]=xbt_dynar_new(sizeof(MPI_Request),NULL);
}
smpi_replay_globals_t globals =
(smpi_replay_globals_t) smpi_process_get_user_data();
if (globals){
- XBT_DEBUG("There are %lu isends and %lu irecvs in the dynars",
- xbt_dynar_length(globals->isends),xbt_dynar_length(globals->irecvs));
- xbt_dynar_free_container(&(globals->isends));
+ XBT_DEBUG("There are %lu irecvs in the dynar",
+ xbt_dynar_length(globals->irecvs));
xbt_dynar_free_container(&(globals->irecvs));
}
free(globals);
} else {
MPI_CURRENT_TYPE= MPI_DEFAULT_TYPE;
}
-
+
#ifdef HAVE_TRACING
int rank = smpi_comm_rank(MPI_COMM_WORLD);
TRACE_smpi_computing_out(rank);
if(action[4]) MPI_CURRENT_TYPE=decode_datatype(action[4]);
else MPI_CURRENT_TYPE= MPI_DEFAULT_TYPE;
- smpi_replay_globals_t globals =
- (smpi_replay_globals_t) smpi_process_get_user_data();
#ifdef HAVE_TRACING
int rank = smpi_comm_rank(MPI_COMM_WORLD);
TRACE_smpi_computing_out(rank);
#endif
request = smpi_mpi_isend(NULL, size, MPI_CURRENT_TYPE, to, 0,MPI_COMM_WORLD);
-
+
#ifdef HAVE_TRACING
TRACE_smpi_ptp_out(rank, rank, dst_traced, __FUNCTION__);
request->send = 1;
TRACE_smpi_computing_in(rank);
#endif
- xbt_dynar_push(globals->isends,&request);
xbt_dynar_push(reqq[smpi_comm_rank(MPI_COMM_WORLD)],&request);
log_timed_action (action, clock);
if(action[4]) MPI_CURRENT_TYPE=decode_datatype(action[4]);
else MPI_CURRENT_TYPE= MPI_DEFAULT_TYPE;
-
+
#ifdef HAVE_TRACING
int rank = smpi_comm_rank(MPI_COMM_WORLD);
int src_traced = smpi_group_rank(smpi_comm_group(MPI_COMM_WORLD), from);
smpi_replay_globals_t globals =
(smpi_replay_globals_t) smpi_process_get_user_data();
-
+
if(action[4]) MPI_CURRENT_TYPE=decode_datatype(action[4]);
else MPI_CURRENT_TYPE= MPI_DEFAULT_TYPE;
#endif
request = smpi_mpi_irecv(NULL, size, MPI_CURRENT_TYPE, from, 0, MPI_COMM_WORLD);
-
+
#ifdef HAVE_TRACING
TRACE_smpi_ptp_out(rank, src_traced, rank, __FUNCTION__);
request->recv = 1;
if (count_requests>0) {
MPI_Request requests[count_requests];
MPI_Status status[count_requests];
-
+
/* The reqq is an array of dynars. Its index corresponds to the rank.
Thus each rank saves its own requests to the array request. */
xbt_dynar_foreach(reqq[smpi_comm_rank(MPI_COMM_WORLD)],i,requests[i]);
-
+
#ifdef HAVE_TRACING
//save information from requests
-
+
xbt_dynar_t srcs = xbt_dynar_new(sizeof(int), NULL);
xbt_dynar_t dsts = xbt_dynar_new(sizeof(int), NULL);
xbt_dynar_t recvs = xbt_dynar_new(sizeof(int), NULL);
xbt_dynar_free(&recvs);
TRACE_smpi_computing_in(rank_traced);
#endif
-
+
xbt_dynar_reset(reqq[smpi_comm_rank(MPI_COMM_WORLD)]);
}
log_timed_action (action, clock);
MPI_CURRENT_TYPE=decode_datatype(action[4]);
}
}
-
+
#ifdef HAVE_TRACING
int rank = smpi_comm_rank(MPI_COMM_WORLD);
TRACE_smpi_computing_out(rank);
double clock = smpi_process_simulated_elapsed();
int root=0;
MPI_CURRENT_TYPE= MPI_DEFAULT_TYPE;
-
+
if(action[4]) {
- root= atoi(action[4]);
- if(action[5]) {
- MPI_CURRENT_TYPE=decode_datatype(action[5]);
- }
+ root= atoi(action[4]);
+ if(action[5]) {
+ MPI_CURRENT_TYPE=decode_datatype(action[5]);
+ }
}
#ifdef HAVE_TRACING
static void action_allReduce(const char *const *action) {
double comm_size = parse_double(action[2]);
double comp_size = parse_double(action[3]);
-
+
if(action[4]) MPI_CURRENT_TYPE=decode_datatype(action[4]);
else MPI_CURRENT_TYPE= MPI_DEFAULT_TYPE;
-
+
double clock = smpi_process_simulated_elapsed();
#ifdef HAVE_TRACING
int rank = smpi_comm_rank(MPI_COMM_WORLD);
TRACE_smpi_computing_out(rank);
TRACE_smpi_collective_in(rank, -1, __FUNCTION__);
#endif
- mpi_coll_reduce_fun(NULL, NULL, comm_size, MPI_CURRENT_TYPE, MPI_OP_NULL, 0, MPI_COMM_WORLD);
+ mpi_coll_reduce_fun(NULL, NULL, comm_size, MPI_CURRENT_TYPE, MPI_OP_NULL, 0, MPI_COMM_WORLD);
smpi_execute_flops(comp_size);
- mpi_coll_bcast_fun(NULL, comm_size, MPI_CURRENT_TYPE, 0, MPI_COMM_WORLD);
+ mpi_coll_bcast_fun(NULL, comm_size, MPI_CURRENT_TYPE, 0, MPI_COMM_WORLD);
#ifdef HAVE_TRACING
TRACE_smpi_collective_out(rank, -1, __FUNCTION__);
TRACE_smpi_computing_in(rank);
int send_size = parse_double(action[2]);
int recv_size = parse_double(action[3]);
MPI_Datatype MPI_CURRENT_TYPE2;
-
+
if(action[4]) {
MPI_CURRENT_TYPE=decode_datatype(action[4]);
MPI_CURRENT_TYPE2=decode_datatype(action[5]);
TRACE_smpi_computing_out(rank);
TRACE_smpi_collective_in(rank, -1, __FUNCTION__);
#endif
-
+
mpi_coll_alltoall_fun(send, send_size, MPI_CURRENT_TYPE, recv, recv_size, MPI_CURRENT_TYPE2, MPI_COMM_WORLD);
#ifdef HAVE_TRACING
static void action_gather(const char *const *action) {
-
-
/*
The structure of the gather action for the rank 0 (total 4 processes)
is the following:
3) 0 is the root node
4) 0 is the send datatype id, see decode_datatype()
5) 0 is the recv datatype id, see decode_datatype()
-
*/
double clock = smpi_process_simulated_elapsed();
int comm_size = smpi_comm_size(MPI_COMM_WORLD);
MPI_CURRENT_TYPE=MPI_DEFAULT_TYPE;
MPI_CURRENT_TYPE2=MPI_DEFAULT_TYPE;
}
- void *send = calloc(send_size, smpi_datatype_size(MPI_CURRENT_TYPE));
- void *recv = calloc(recv_size, smpi_datatype_size(MPI_CURRENT_TYPE2));
+ void *send = calloc(send_size, smpi_datatype_size(MPI_CURRENT_TYPE));
+ void *recv = calloc(recv_size, smpi_datatype_size(MPI_CURRENT_TYPE2));
int root=atoi(action[4]);
int rank = smpi_process_index();
static void action_reducescatter(const char *const *action) {
-
+
/*
The structure of the reducescatter action for the rank 0 (total 4 processes)
is the following:
1) The first four values after the name of the action declare the recvcounts array
2) The value 11346849 is the amount of instructions
3) The last value corresponds to the datatype, see decode_datatype().
-
+
We analyze a MPI_Reduce_scatter call to one MPI_Reduce and one MPI_Scatterv.
-
+
*/
double clock = smpi_process_simulated_elapsed();
smpi_mpi_scatterv(NULL, recvcounts, disps, MPI_CURRENT_TYPE, NULL,
recvcounts[rank], MPI_CURRENT_TYPE, 0, MPI_COMM_WORLD);
smpi_execute_flops(comp_size);
-
-
+
+
#ifdef HAVE_TRACING
TRACE_smpi_collective_out(rank, -1, __FUNCTION__);
TRACE_smpi_computing_in(rank);
static void action_allgatherv(const char *const *action) {
-
+
/*
The structure of the allgatherv action for the rank 0 (total 4 processes)
is the following:
*/
double clock = smpi_process_simulated_elapsed();
-
+
int comm_size = smpi_comm_size(MPI_COMM_WORLD);
int i=0;
int sendcount=atoi(action[2]);
TRACE_smpi_computing_out(rank);
TRACE_smpi_collective_in(rank, -1, __FUNCTION__);
#endif
-
+
mpi_coll_allgatherv_fun(sendbuf, sendcount, MPI_CURRENT_TYPE, recvbuf, recvcounts, disps, MPI_CURRENT_TYPE2, MPI_COMM_WORLD);
#ifdef HAVE_TRACING
TRACE_smpi_collective_out(rank, -1, __FUNCTION__);
TRACE_smpi_computing_in(rank);
#endif
-
+
log_timed_action (action, clock);
xbt_free(sendbuf);
xbt_free(recvbuf);
4) 100*sizeof(int) is the size of the receiver buffer
5) 1 70 10 5 is the recvcounts array
6) 1 5 77 90 is the rdispls array
-
+
*/
-
-
+
+
double clock = smpi_process_simulated_elapsed();
-
+
int comm_size = smpi_comm_size(MPI_COMM_WORLD);
int send_buf_size=0,recv_buf_size=0,i=0;
int *sendcounts = xbt_new0(int, comm_size);
int *recvdisps = xbt_new0(int, comm_size);
MPI_Datatype MPI_CURRENT_TYPE2;
-
+
send_buf_size=parse_double(action[2]);
recv_buf_size=parse_double(action[3+2*comm_size]);
if(action[4+4*comm_size]) {
MPI_CURRENT_TYPE=MPI_DEFAULT_TYPE;
MPI_CURRENT_TYPE2=MPI_DEFAULT_TYPE;
}
-
+
void *sendbuf = calloc(send_buf_size, smpi_datatype_size(MPI_CURRENT_TYPE));
void *recvbuf = calloc(recv_buf_size, smpi_datatype_size(MPI_CURRENT_TYPE2));
recvcounts[i] = atoi(action[i+4+2*comm_size]);
recvdisps[i] = atoi(action[i+4+3*comm_size]);
}
-
+
#ifdef HAVE_TRACING
int rank = MPI_COMM_WORLD != MPI_COMM_NULL ? smpi_process_index() : -1;
TRACE_smpi_collective_out(rank, -1, __FUNCTION__);
TRACE_smpi_computing_in(rank);
#endif
-
+
log_timed_action (action, clock);
xbt_free(sendbuf);
xbt_free(recvbuf);
xbt_free(recvcounts);
xbt_free(senddisps);
xbt_free(recvdisps);
-
-
}
void smpi_replay_init(int *argc, char***argv){