From: mquinson Date: Thu, 8 Oct 2009 14:47:45 +0000 (+0000) Subject: Start working on a trace replayer in GRAS (to replay it on real platforms) X-Git-Tag: SVN~965 X-Git-Url: http://info.iut-bm.univ-fcomte.fr/pub/gitweb/simgrid.git/commitdiff_plain/9f77378267bd5d7abb5dcdd498d4a461616d9689 Start working on a trace replayer in GRAS (to replay it on real platforms) git-svn-id: svn+ssh://scm.gforge.inria.fr/svn/simgrid/simgrid/trunk@6749 48e7efb5-ca39-0410-a469-dd3cf9ba447f --- diff --git a/configure.ac b/configure.ac index bf3e689e6c..2337ece7a2 100644 --- a/configure.ac +++ b/configure.ac @@ -528,6 +528,7 @@ AC_CONFIG_FILES([ examples/gras/mmrpc/Makefile examples/gras/pmm/Makefile examples/gras/all2all/Makefile + examples/gras/replay/Makefile examples/amok/Makefile examples/smpi/Makefile ]) diff --git a/examples/gras/Makefile.am b/examples/gras/Makefile.am index b686017e69..55941bc6fe 100644 --- a/examples/gras/Makefile.am +++ b/examples/gras/Makefile.am @@ -5,7 +5,8 @@ # GNU LGPL (v2.1) licence. -SUBDIRS= ping rpc spawn timer chrono mutual_exclusion/simple_token mmrpc all2all pmm synchro properties +SUBDIRS= ping rpc spawn timer chrono mutual_exclusion/simple_token \ + mmrpc all2all pmm synchro properties replay # p2p include $(top_srcdir)/acmacro/dist-files.mk diff --git a/examples/gras/replay/Makefile.am b/examples/gras/replay/Makefile.am new file mode 100644 index 0000000000..1a8b2d8468 --- /dev/null +++ b/examples/gras/replay/Makefile.am @@ -0,0 +1,30 @@ +# Copyright (c) 2004-2007. The SimGrid team. All right reserved. + +# This file is part of the SimGrid project. This is free software: +# You can redistribute and/or modify it under the terms of the +# GNU LGPL (v2.1) licence. + + +INCLUDES= -I$(top_srcdir)/include +EXTRA_DIST= +include $(top_srcdir)/examples/gras/tests.mk + +# AUTOMAKE variable definition +noinst_PROGRAMS=replay_worker replay_master replay_simulator + +replay_simulator_SOURCES=_replay_simulator.c replay.c xbt_workload.c +replay_simulator_LDADD= $(top_builddir)/src/libsimgrid.la + +replay_master_SOURCES= _replay_master.c replay.c xbt_workload.c +replay_master_LDADD= $(top_builddir)/src/libgras.la + +replay_worker_SOURCES= _replay_worker.c replay.c xbt_workload.c +replay_worker_LDADD= $(top_builddir)/src/libgras.la + +# Take care of generatated sources +NAME=replay +PROCESSES= master worker +include $(top_srcdir)/examples/temps-gras-stub.mk + +# Cruft +include $(top_srcdir)/acmacro/dist-files.mk diff --git a/examples/gras/replay/replay.c b/examples/gras/replay/replay.c new file mode 100644 index 0000000000..327c8187bb --- /dev/null +++ b/examples/gras/replay/replay.c @@ -0,0 +1,67 @@ +/* Copyright (c) 2009 Da SimGrid Team. All rights reserved. */ + +/* This program is free software; you can redistribute it and/or modify it + * under the terms of the license (GNU LGPL) which comes with this package. */ + +/* This example replays a trace as produced by examples/simdag/dax, or other means + * This is mainly interesting when run on real platforms, to validate the results + * given in the simulator when running SimDag. + */ + +#include "xbt/ex.h" +#include "xbt/log.h" +#include "xbt/str.h" +#include "xbt/dynar.h" +#include "workload.h" +#include "gras.h" +#include "amok/peermanagement.h" +#include + +int master(int argc,char *argv[]); +int worker(int argc,char *argv[]); + +XBT_LOG_NEW_DEFAULT_CATEGORY(replay, "Messages specific to this example"); + +static void declare_msg() { + gras_datadesc_type_t command_assignment_type; + + +} + +int master(int argc,char *argv[]) { + gras_init(&argc,argv); + amok_pm_init(); + + xbt_assert0(argc==3,"usage: replay_master tracefile port"); + gras_socket_server(atoi(argv[2])); /* open my master socket, even if I don't use it */ + xbt_dynar_t peers = amok_pm_group_new("replay"); /* group of slaves */ + xbt_dynar_t cmds = xbt_workload_parse_file(argv[1]); + xbt_workload_sort_who_date(cmds); + unsigned int cursor; + xbt_workload_elm_t cmd; + + xbt_dynar_foreach(cmds,cursor,cmd) { + char *str = xbt_workload_elm_to_string(cmd); + INFO1("%s",str); + free(str); + } + + /* friends, we're ready. Come and play */ + INFO0("Wait for peers for 5 sec"); + gras_msg_handleall(5); + INFO1("Got %ld pals", xbt_dynar_length(peers)); + + + /* Done, exiting */ + xbt_dynar_free(&cmds); + gras_exit(); + return 0; +} + +int worker(int argc,char *argv[]) { + gras_init(&argc,argv); + amok_pm_init(); + + gras_exit(); + return 0; +} diff --git a/examples/gras/replay/replay.xml b/examples/gras/replay/replay.xml new file mode 100644 index 0000000000..27a3d7585c --- /dev/null +++ b/examples/gras/replay/replay.xml @@ -0,0 +1,12 @@ + + + + + + + + + + + + diff --git a/examples/gras/replay/workload.h b/examples/gras/replay/workload.h new file mode 100644 index 0000000000..e4e3543fa1 --- /dev/null +++ b/examples/gras/replay/workload.h @@ -0,0 +1,40 @@ +/* Copyright (c) 2009 Da SimGrid Team. All rights reserved. */ + +/* This program is free software; you can redistribute it and/or modify it + * under the terms of the license (GNU LGPL) which comes with this package. */ + +/* This datatype stores a a trace as produced by examples/simdag/dax, or other means + * It can be replayed in simulation with examples/msg/actions or on a real platform with + * examples/gras/replay. + */ + +#ifndef XBT_WORKLOAD_H_ +#define XBT_WORKLOAD_H_ + +#include "xbt/misc.h" +#include "xbt/dynar.h" + +/* kind of elements */ +#define XBT_WORKLOAD_COMPUTE 0 +#define XBT_WORKLOAD_SEND 1 +#define XBT_WORKLOAD_RECV 2 + +/* one command to do */ +typedef struct { + char *who; /* the slave who should do it */ + char *comment; /* a comment placed at the end of the line, if any */ + int action; /* 0: compute(darg flops); 1: send darg bytes to strarg; 2: recv darg bytes from strarg */ + double date; /* when it occured when the trace was captured */ + double d_arg; /* double argument, if any */ + char * str_arg; /* string argument, if any */ +} s_xbt_workload_elm_t, *xbt_workload_elm_t; + +XBT_PUBLIC(xbt_workload_elm_t) xbt_workload_elm_parse(char *line); +XBT_PUBLIC(void) xbt_workload_elm_free(xbt_workload_elm_t cmd); +XBT_PUBLIC(void) xbt_workload_elm_free_voidp(void*cmd); +XBT_PUBLIC(char *)xbt_workload_elm_to_string(xbt_workload_elm_t cmd); +XBT_PUBLIC(int) xbt_workload_elm_cmp_who_date(const void* _c1, const void* _c2); +XBT_PUBLIC(void) xbt_workload_sort_who_date(xbt_dynar_t c); +XBT_PUBLIC(xbt_dynar_t) xbt_workload_parse_file(char *filename); + +#endif /* XBT_WORKLOAD_H_ */ diff --git a/examples/gras/replay/xbt_workload.c b/examples/gras/replay/xbt_workload.c new file mode 100644 index 0000000000..ab22b50b07 --- /dev/null +++ b/examples/gras/replay/xbt_workload.c @@ -0,0 +1,156 @@ +/* Copyright (c) 2009 Da SimGrid Team. All rights reserved. */ + +/* This program is free software; you can redistribute it and/or modify it + * under the terms of the license (GNU LGPL) which comes with this package. */ + +/* This datatype stores a a trace as produced by examples/simdag/dax, or other means + * It can be replayed in simulation with examples/msg/actions or on a real platform with + * examples/gras/replay. + */ + +#include "xbt/log.h" +#include "xbt/sysdep.h" +#include "xbt/str.h" +#include "workload.h" + +XBT_LOG_NEW_DEFAULT_SUBCATEGORY(xbt_workload,xbt, "Workload characterisation mecanisms"); + + +xbt_workload_elm_t xbt_workload_elm_parse(char *line) { + xbt_workload_elm_t res = xbt_new(s_xbt_workload_elm_t,1); + res->date=-1; + res->comment=NULL; /* it's not enough to memset for valgrind, apparently */ + res->who=NULL; + res->str_arg=NULL; + + xbt_dynar_t w = xbt_str_split(line," "); + + if (xbt_dynar_length(w) == 0) { + free(res); + xbt_dynar_free(&w); + return NULL; + } + + char **words = xbt_dynar_get_ptr(w,0); + int i=0; + if (words[i][0] == '[') { + sscanf(words[i]+1,"%lg",&(res->date)); + i++; + } + res->who = xbt_strdup(words[i++]); + if (!strcmp(words[i],"recv")) { + res->action = XBT_WORKLOAD_RECV; + res->str_arg = xbt_strdup(words[++i]); + sscanf(words[++i],"%lg",&(res->d_arg)); + + } else if (!strcmp(words[i],"send")) { + res->action = XBT_WORKLOAD_SEND; + res->str_arg = xbt_strdup(words[++i]); + sscanf(words[++i],"%lg",&(res->d_arg)); + + } else if (!strcmp(words[i],"compute")) { + res->action = XBT_WORKLOAD_COMPUTE; + sscanf(words[++i],"%lg",&(res->d_arg)); + } else { + xbt_die(bprintf("Unparsable command: %s (in %s)",words[i],line)); + } + i++; + if (words[i] && words[i][0] == '#') { + res->comment = xbt_strdup(strchr(line,'#')+1); + } + + xbt_dynar_free(&w); + return res; +} +void xbt_workload_elm_free(xbt_workload_elm_t cmd) { + if (!cmd) + return; + if (cmd->who) + free(cmd->who); + if (cmd->comment) + free(cmd->comment); + if (cmd->str_arg) + free(cmd->str_arg); + free(cmd); +} +void xbt_workload_elm_free_voidp(void*cmd) { + xbt_workload_elm_free(*(xbt_workload_elm_t*)cmd); +} + +char *xbt_workload_elm_to_string(xbt_workload_elm_t cmd) { + char res[2048]; + char *addon; + res[0]='\0'; + if (cmd==NULL) + return xbt_strdup("(null command)"); + if (cmd->date != -1) { + addon=bprintf("[%f] ",cmd->date); + strcat(res,addon); + free(addon); + } + addon= bprintf("'%s' ",cmd->who); + strcat(res,addon);free(addon); + + switch (cmd->action) { + case XBT_WORKLOAD_COMPUTE: + addon=bprintf("computed %f flops",cmd->d_arg); + strcat(res,addon);free(addon); + break; + case XBT_WORKLOAD_SEND: + addon=bprintf("sent %f bytes to '%s'",cmd->d_arg,cmd->str_arg); + strcat(res,addon);free(addon); + break; + case XBT_WORKLOAD_RECV: + addon=bprintf("received %f bytes from '%s'",cmd->d_arg,cmd->str_arg); + strcat(res,addon);free(addon); + break; + default: + xbt_die(bprintf("Unknown command %d in '%s...'",cmd->action,res)); + } + if (cmd->comment) { + addon=bprintf(" (comment: %s)",cmd->comment); + strcat(res,addon);free(addon); + } + return xbt_strdup(res); +} + +int xbt_workload_elm_cmp_who_date(const void* _c1, const void* _c2) { + xbt_workload_elm_t c1=*(xbt_workload_elm_t*)_c1; + xbt_workload_elm_t c2=*(xbt_workload_elm_t*)_c2; + if (!c1 || !c1->who) + return -1; + if (!c2 || !c2->who) + return 1; + int r = strcmp(c1->who,c2->who); + if (r) + return r; + if (c1->date == c2->date) + return 0; + if (c1->date < c2->date) + return -1; + return 1; +} +void xbt_workload_sort_who_date(xbt_dynar_t c) { + qsort(xbt_dynar_get_ptr(c,0),xbt_dynar_length(c),sizeof(xbt_workload_elm_t),xbt_workload_elm_cmp_who_date); +} +xbt_dynar_t xbt_workload_parse_file(char *filename) { + FILE *file_in; + file_in = fopen(filename,"r"); + xbt_assert1(file_in, "cannot open tracefile '%s'",filename); + char *str_in = xbt_str_from_file(file_in); + fclose(file_in); + xbt_dynar_t in = xbt_str_split(str_in,"\n"); + free(str_in); + xbt_dynar_t cmds=xbt_dynar_new(sizeof(xbt_workload_elm_t),xbt_workload_elm_free_voidp); + + unsigned int cursor; + char *line; + xbt_dynar_foreach(in,cursor,line) { + xbt_workload_elm_t cmd = xbt_workload_elm_parse(line); + if (cmd) + xbt_dynar_push(cmds,&cmd); + } + xbt_dynar_shrink(cmds,0); + xbt_dynar_free(&in); + return cmds; +}