From: casanova Date: Wed, 31 Jan 2007 19:38:24 +0000 (+0000) Subject: First draft integration of SURF and GTNetS. The code isn't even close to compile... X-Git-Tag: v3.3~2274 X-Git-Url: http://info.iut-bm.univ-fcomte.fr/pub/gitweb/simgrid.git/commitdiff_plain/809ce498a496be4898e4ed739c54b129b55be4c0 First draft integration of SURF and GTNetS. The code isn't even close to compile here and in fact the API calls are not even in the repository (and some aren't fully implemented). The point is to have something for Arnaud, Kayo, and Henri to look at. This should break the build as the build system shouldn't really know about this code (but not quite sure about that given that I never really looked into the cryptic build system) git-svn-id: svn+ssh://scm.gforge.inria.fr/svn/simgrid/simgrid/trunk@3085 48e7efb5-ca39-0410-a469-dd3cf9ba447f --- diff --git a/src/surf/network_dassf.c b/src/surf/network_dassf.c index 696286a8c5..ec0b99b94c 100644 --- a/src/surf/network_dassf.c +++ b/src/surf/network_dassf.c @@ -229,6 +229,10 @@ static void action_change_state(surf_action_t action, return; } +/* I nothing more happens, return the date at which the first action that will terminate does terminate */ +/* This returns the time for the first NETWORK action to complete */ +/* It would be nice to store this minimum somewhere so that the next function can + figure out whether the min comes from the network or from something else */ static double share_resources(double now) { s_surf_action_network_DASSF_t s_action; @@ -247,6 +251,13 @@ static double share_resources(double now) return min; } +/* delta: by how many time units the simulation must advance */ +/* In this function: change the state of actions that terminate */ +/* The delta may not come from the network, and thus may be different (smaller) + than the one returned by the function above */ +/* If the delta is a network-caused min, then do not emulate any timer in the + network simulation, otherwise fake a timer somehow to advance the simulation of min seconds */ + static void update_actions_state(double now, double delta) { double deltap = 0.0; @@ -287,6 +298,7 @@ static void update_actions_state(double now, double delta) action->generic_action.finish = surf_get_clock(); action_change_state((surf_action_t) action, SURF_ACTION_DONE); } else { /* Need to check that none of the resource has failed */ + /* to ignore for now */ lmm_constraint_t cnst = NULL; int i = 0; network_link_DASSF_t nw_link = NULL; @@ -307,6 +319,7 @@ static void update_actions_state(double now, double delta) return; } +/* Called only when there is a change in trace: Useless in packet-level simulation */ static void update_resource_state(void *id, tmgr_trace_event_t event_type, double value) diff --git a/src/surf/network_gtnets.c b/src/surf/network_gtnets.c new file mode 100644 index 0000000000..e3a6b0d750 --- /dev/null +++ b/src/surf/network_gtnets.c @@ -0,0 +1,530 @@ +/* $Id$ */ + +/* Copyright (c) 2005 Henri Casanova. 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. */ + +#include "network_gtnets_private.h" + +XBT_LOG_EXTERNAL_DEFAULT_CATEGORY(surf_network_gtnets); + +/* surf_network_resource_t surf_network_resource = NULL; */ +static xbt_dict_t network_link_set = NULL; + +/* xbt_dict_t network_card_set = NULL; */ + +#if 0 +static int card_number = 0; +static network_link_GTNETS_t **routing_table = NULL; +static int *routing_table_size = NULL; + +#define ROUTE(i,j) routing_table[(i)+(j)*card_number] +#define ROUTE_SIZE(i,j) routing_table_size[(i)+(j)*card_number] +#endif + +/** QUESTIONS for GTNetS integration + ** 1. What's the deal with name_service and get_resource_name + ** Right now our local dictionaries contain only integers + ** and not structures, but it seems that surf_network_resource->common_public + ** needs something in it, for the above. + ** 2. Right now there is no "kill flow" in our GTNetS implementation. Do we + ** need to do something about this? + ** 3. We didn't reall do anything with the "action" stuff, which we assume + ** is fine. + ** 4. We ignore the fact there is some max_duration on flows (see #2 above) + ** 5. share_resources() returns a duration, not a date, right? + ** 6. How do we tell the user that "rates" are not supported? + ** 7. We don't update "remaining" for ongoing flows. Is it bad? + **/ + +/* Free memory for a network link: REMOVED BY KF */ +static void network_link_free(void *nw_link) +{ + free(((network_link_GTNETS_t)nw_link)->name); + free(nw_link); +} + +/* Instantiate a new network link: UNMODIFIED BY HC */ +/* name: some name for the link, from the XML */ +/* bw_initial: The bandwidth value */ +/* bw_trace: unused here */ +/* lat_initial: The latency value */ +/* lat_trace: not used here */ +/* state_initial: SURF_NETWORK_LINK_ON */ +/* state_trace: not used here */ +static void network_link_new(char *name, + double bw, + double lat) +{ + static int link_count=-1; + network_link_GTNETS_t gtnets_link; + + /* KF: Check that the link wasn't added before */ + if (xbt_dict_get_or_null(network_link_set, name)) { + return; + } + + /* KF: Increment the link counter for GTNetS */ + link_count++; + +/* + nw_link->resource = (surf_resource_t) surf_network_resource; + nw_link->name = name; + nw_link->bw_current = bw_initial; + if (bw_trace) + nw_link->bw_event = + tmgr_history_add_trace(history, bw_trace, 0.0, 0, nw_link); + nw_link->lat_current = lat_initial; + if (lat_trace) + nw_link->lat_event = + tmgr_history_add_trace(history, lat_trace, 0.0, 0, nw_link); + nw_link->state_current = state_initial; + if (state_trace) + nw_link->state_event = + tmgr_history_add_trace(history, state_trace, 0.0, 0, nw_link); +*/ + + /* KF: Add the link to the GTNetS simulation */ + if (GTNetS_add_link(link_count, bw, lat)) { + xbt_assert0(0,"Cannot create GTNetS link"); + } + + /* KF: Insert entry in the dictionary */ + gtnets_link = xbt_new0(s_network_link_GTNETS_t,1); + gtnets_link->name = strcpy(name); + gtnets_link->bw_current = bw; + gtnets_link->lat_current = lat; + gtnets_link->id = link_count; + xbt_dict_set(network_link_set, name, gtnets_link, network_link_free); + + return; +} + +/* free the network card: REMOVED by KF */ +static void network_card_free(void *nw_card) +{ + free(((network_card_GTNETS_t)nw_card)->name); + free(nw_card); +} + +/* Instantiate a new network card: MODIFYED BY KF */ +static int network_card_new(const char *name) +{ + static int card_count=-1; + + /* KF: Check that we haven't seen the network card before */ + if (xbt_dict_get_or_null(network_card_set, name)) + return; + + /* KF: Increment the card counter for GTNetS */ + card_count++; + + /* KF: just use the dictionary to map link names to link indices */ + gtnets_network_card = xbt_new0(s_network_card_GTNETS_t,1); + gtnets_network_card->name = strcpy(name); + gtnets_network_card->id = card_count; + xbt_dict_set(network_card_set, name, gtnets_network_card, network_card_free); + + /* KF: just return the GTNetS ID as the SURF ID */ + return card_count; +} + +/* Instantiate a new route: MODIFY BY KF */ +static void route_new(int src_id, int dst_id, char **links, int nb_link) +{ +#if 0 + network_link_GTNETS_t *link_list = NULL; + int i; + + ROUTE_SIZE(src_id, dst_id) = nb_link; + link_list = (ROUTE(src_id, dst_id) = xbt_new0(network_link_GTNETS_t, nb_link)); + for (i = 0; i < nb_link; i++) { + link_list[i] = xbt_dict_get_or_null(network_link_set, links[i]); + free(links[i]); + } + free(links); +#endif + int i; + int *gtnets_links; + + /* KF: Build the list of gtnets link IDs */ + gtnets_links = (int *)calloc(nb_link, sizeof(int)); + for (i=0; iname; +} + +/* We do not care about this: only used for traces */ +static int resource_used(void *resource_id) +{ + return 0; /* We don't care */ +} + +static int action_free(surf_action_t action) +{ + action->using--; + if(!action->using) { + xbt_swag_remove(action, action->state_set); + /* KF: No explicit freeing needed for GTNeTS here */ + free(action); + } + return 1; +} + +static void action_use(surf_action_t action) +{ + action->using++; +} + +static void action_cancel(surf_action_t action) +{ + return; +} + +static void action_recycle(surf_action_t action) +{ + return; +} + +static void action_change_state(surf_action_t action, + e_surf_action_state_t state) +{ +/* if((state==SURF_ACTION_DONE) || (state==SURF_ACTION_FAILED)) */ +/* if(((surf_action_network_GTNETS_t)action)->variable) { */ +/* lmm_variable_disable(maxmin_system, ((surf_action_network_GTNETS_t)action)->variable); */ +/* ((surf_action_network_GTNETS_t)action)->variable = NULL; */ +/* } */ + + surf_action_change_state(action, state); + return; +} + + +/* share_resources() */ +static double share_resources(double now) +{ +#if 0 + s_surf_action_network_GTNETS_t s_action; + surf_action_network_GTNETS_t action = NULL; + xbt_swag_t running_actions = surf_network_resource->common_public->states.running_action_set; +#endif + + return GTNetS_get_time_to_next_flow_completion(); +} + +/* delta: by how many time units the simulation must advance */ +/* In this function: change the state of actions that terminate */ +/* The delta may not come from the network, and thus may be different (smaller) + than the one returned by the function above */ +/* If the delta is a network-caused min, then do not emulate any timer in the + network simulation, otherwise fake a timer somehow to advance the simulation of min seconds */ + +static void update_actions_state(double now, double delta) +{ + surf_action_network_GTNETS_t action = NULL; + surf_action_network_GTNETS_t next_action = NULL; + xbt_swag_t running_actions = + surf_network_resource->common_public->states.running_action_set; + + double time_to_next_flow_completion = GTNetS_get_time_to_next_flow_completion(); + + if (time_to_next_flow_completion < delta) { + void *metadata; + surf_action_t action; + + if (GTNetS_run_until_next_flow_completion(&metadata)) { + xbt_assert0(0,"Cannot run GTNetS simulation until next flow completion"); + } + + action = (surf_action_t)metadata; + + action->generic_action.remains = 0; + action->generic_action.finish = now + time_to_next_flow_completion; + action->generic_action.finish = SURF_ACTION_DONE; + /* TODO: Anything else here? */ + } else { + if (GTNetS_run(delta)) { + xbt_assert0(0,"Cannot run GTNetS simulation"); + } + } + + return; +} + +/* UNUSED HERE: no traces */ +static void update_resource_state(void *id, + tmgr_trace_event_t event_type, + double value) +{ + return; +} + +/* KF: Rate not supported */ +static surf_action_t communicate(void *src, void *dst, double size, double rate) +{ + surf_action_network_GTNETS_t action = NULL; + network_card_GTNETS_t card_src = src; + network_card_GTNETS_t card_dst = dst; + int route_size = ROUTE_SIZE(card_src->id, card_dst->id); + network_link_GTNETS_t *route = ROUTE(card_src->id, card_dst->id); + int i; + + xbt_assert2(route_size,"You're trying to send data from %s to %s but there is no connexion between these two cards.", card_src->name, card_dst->name); + + action = xbt_new0(s_surf_action_network_GTNETS_t, 1); + + action->generic_action.using = 1; + action->generic_action.cost = size; + action->generic_action.remains = size; + action->generic_action.max_duration = NO_MAX_DURATION; + action->generic_action.start = surf_get_clock(); + action->generic_action.finish = -1.0; + action->generic_action.resource_type = + (surf_resource_t) surf_network_resource; + + action->generic_action.state_set = + surf_network_resource->common_public->states.running_action_set; + + xbt_swag_insert(action, action->generic_action.state_set); + + /* KF: Add a flow to the GTNets Simulation, associated to this action */ + GTNetS_create_flow(src->id, dst->id, size, (void *)action); + + return (surf_action_t) action; +} + +/* Suspend a flow() */ +static void action_suspend(surf_action_t action) +{ + xbt_assert0(0,"action_suspend() not supported for the GTNets network model"); +} + +/* Resume a flow() */ +static void action_resume(surf_action_t action) +{ + xbt_assert0(0,"action_resume() not supported for the GTNets network model"); +} + +/* Test whether a flow is suspended */ +static int action_is_suspended(surf_action_t action) +{ + return 0; +} + +static void finalize(void) +{ + int i,j; + + xbt_dict_free(&network_card_set); + xbt_dict_free(&network_link_set); + xbt_swag_free(surf_network_resource->common_public->states. + ready_action_set); + xbt_swag_free(surf_network_resource->common_public->states. + running_action_set); + xbt_swag_free(surf_network_resource->common_public->states. + failed_action_set); + xbt_swag_free(surf_network_resource->common_public->states. + done_action_set); + free(surf_network_resource->common_public); + free(surf_network_resource->common_private); + free(surf_network_resource->extension_public); + + free(surf_network_resource); + surf_network_resource = NULL; + +#if 0 + for (i = 0; i < card_number; i++) + for (j = 0; j < card_number; j++) + free(ROUTE(i,j)); + free(routing_table); + routing_table = NULL; + free(routing_table_size); + routing_table_size = NULL; + card_number = 0; +#endif + + /* ADDED BY KF */ + GTNetS_finalize(); + /* END ADDITION */ +} + +static void surf_network_resource_init_internal(void) +{ + s_surf_action_t action; + + surf_network_resource = xbt_new0(s_surf_network_resource_t, 1); + + surf_network_resource->common_private = + xbt_new0(s_surf_resource_private_t, 1); + surf_network_resource->common_public = + xbt_new0(s_surf_resource_public_t, 1); + surf_network_resource->extension_public = + xbt_new0(s_surf_network_resource_extension_public_t, 1); + + surf_network_resource->common_public->states.ready_action_set = + xbt_swag_new(xbt_swag_offset(action, state_hookup)); + surf_network_resource->common_public->states.running_action_set = + xbt_swag_new(xbt_swag_offset(action, state_hookup)); + surf_network_resource->common_public->states.failed_action_set = + xbt_swag_new(xbt_swag_offset(action, state_hookup)); + surf_network_resource->common_public->states.done_action_set = + xbt_swag_new(xbt_swag_offset(action, state_hookup)); + + surf_network_resource->common_public->name_service = name_service; + surf_network_resource->common_public->get_resource_name = + get_resource_name; + surf_network_resource->common_public->action_get_state = + surf_action_get_state; + surf_network_resource->common_public->action_use = action_use; + surf_network_resource->common_public->action_free = action_free; + surf_network_resource->common_public->action_cancel = action_cancel; + surf_network_resource->common_public->action_recycle = action_recycle; + surf_network_resource->common_public->action_change_state = + action_change_state; + surf_network_resource->common_public->action_set_data = surf_action_set_data; + surf_network_resource->common_public->name = "network"; + + surf_network_resource->common_private->resource_used = resource_used; + surf_network_resource->common_private->share_resources = share_resources; + surf_network_resource->common_private->update_actions_state = + update_actions_state; + surf_network_resource->common_private->update_resource_state = + update_resource_state; + surf_network_resource->common_private->finalize = finalize; + + surf_network_resource->common_public->suspend = action_suspend; + surf_network_resource->common_public->resume = action_resume; + surf_network_resource->common_public->is_suspended = action_is_suspended; + + surf_network_resource->extension_public->communicate = communicate; + + network_link_set = xbt_dict_new(); + network_card_set = xbt_dict_new(); + + /* HC: I am assuming that this stays in for simulation of compute tasks */ + xbt_assert0(maxmin_system, "surf_init has to be called first!"); + + /* KF: Added the initialization for GTNetS interface */ + if (GTNetS_initialize()) { + xbt_assert0(0, "impossible to initialize GTNetS interface"); + } +} + +/* HC: I put this prototype here for now but it will have to go in + src/include/surf.h when it is functionnal. */ +void surf_network_resource_init_GTNETS(const char *filename); + +void surf_network_resource_init_GTNETS(const char *filename) +{ + if (surf_network_resource) + return; + surf_network_resource_init_internal(); + parse_file(filename); + xbt_dynar_push(resource_list, &surf_network_resource); +} diff --git a/src/surf/network_gtnets_private.h b/src/surf/network_gtnets_private.h new file mode 100644 index 0000000000..bf1ecfd7bf --- /dev/null +++ b/src/surf/network_gtnets_private.h @@ -0,0 +1,46 @@ +/* $Id$ */ + +/* Copyright (c) 2004 Arnaud Legrand. 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. */ + +#ifndef _SURF_NETWORK_GTNETS_PRIVATE_H +#define _SURF_NETWORK_GTNETS_PRIVATE_H + +#include "surf_private.h" +#include "xbt/dict.h" + +typedef struct network_link_GTNETS { + surf_resource_t resource; /* Any such object, added in a trace + should start by this field!!! */ + /* Using this object with the public part of + resource does not make sense */ + char *name; + double bw_current; + double lat_current; + int id; +} s_network_link_GTNETS_t, *network_link_GTNETS_t; + + +typedef struct network_card_GTNETS { + char *name; + int id; +} s_network_card_GTNETS_t, *network_card_GTNETS_t; + +typedef struct surf_action_network_GTNETS { + s_surf_action_t generic_action; + double latency; + double lat_current; + lmm_variable_t variable; + double rate; + int suspended; + network_card_GTNETS_t src; + network_card_GTNETS_t dst; +} s_surf_action_network_GTNETS_t, *surf_action_network_GTNETS_t; + +extern xbt_dict_t network_card_set; + +#endif /* _SURF_NETWORK_PRIVATE_H */ + +