X-Git-Url: http://info.iut-bm.univ-fcomte.fr/pub/gitweb/simgrid.git/blobdiff_plain/a96fee701e6134a05471e7f796d0b156bbfee8a3..4740be30808ce9367af87084c8bf989883b1f2a0:/src/surf/sg_platf.cpp diff --git a/src/surf/sg_platf.cpp b/src/surf/sg_platf.cpp index 0c7df96202..2c4dd116ae 100644 --- a/src/surf/sg_platf.cpp +++ b/src/surf/sg_platf.cpp @@ -11,17 +11,26 @@ #include "xbt/RngStream.h" #include #include "simgrid/platf_interface.h" -#include "surf/surf_routing.h" #include "surf/surf.h" #include "src/simix/smx_private.h" #include "src/surf/platform.hpp" -#include "cpu_interface.hpp" -#include "host_interface.hpp" +#include "surf/surfxml_parse.h"// FIXME: brain dead public header + +#include "src/surf/platform.hpp" +#include "src/surf/cpu_interface.hpp" +#include "src/surf/host_interface.hpp" +#include "src/surf/network_interface.hpp" +#include "surf/surf_routing.h" // FIXME: brain dead public header +#include "src/surf/surf_routing_cluster.hpp" +#include "src/surf/surf_routing_cluster_torus.hpp" +#include "src/surf/surf_routing_cluster_fat_tree.hpp" XBT_LOG_EXTERNAL_DEFAULT_CATEGORY(surf_parse); +XBT_PRIVATE xbt_dynar_t mount_list = NULL; + namespace simgrid { namespace surf { @@ -34,9 +43,6 @@ simgrid::xbt::signal on_postparse; static int surf_parse_models_setup_already_called = 0; -/* one RngStream for the platform, to respect some statistic rules */ -static RngStream sg_platf_rng_stream = NULL; - /** Module management function: creates all internal data structures */ void sg_platf_init(void) { } @@ -49,6 +55,7 @@ void sg_platf_exit(void) { /* make sure that we will reinit the models while loading the platf once reinited */ surf_parse_models_setup_already_called = 0; + surf_parse_lex_destroy(); } /** @brief Add an "host" to the current AS */ @@ -58,13 +65,13 @@ void sg_platf_new_host(sg_platf_host_cbarg_t host) "Refusing to create a second host named '%s'.", host->id); simgrid::surf::As* current_routing = routing_get_current(); - if (current_routing->p_hierarchy == SURF_ROUTING_NULL) - current_routing->p_hierarchy = SURF_ROUTING_BASE; + if (current_routing->hierarchy_ == SURF_ROUTING_NULL) + current_routing->hierarchy_ = SURF_ROUTING_BASE; simgrid::surf::NetCard *netcard = - new simgrid::surf::NetCardImpl(xbt_strdup(host->id), -1, SURF_NETWORK_ELEMENT_HOST, current_routing); + new simgrid::surf::NetCardImpl(host->id, SURF_NETWORK_ELEMENT_HOST, current_routing); - netcard->setId(current_routing->parsePU(netcard)); + netcard->setId(current_routing->addComponent(netcard)); sg_host_t h = simgrid::s4u::Host::by_name_or_create(host->id); h->pimpl_netcard = netcard; simgrid::surf::netcardCreatedCallbacks(netcard); @@ -114,18 +121,16 @@ void sg_platf_new_router(sg_platf_router_cbarg_t router) { simgrid::surf::As* current_routing = routing_get_current(); - if (current_routing->p_hierarchy == SURF_ROUTING_NULL) - current_routing->p_hierarchy = SURF_ROUTING_BASE; - xbt_assert(!xbt_lib_get_or_null(as_router_lib, router->id, ROUTING_ASR_LEVEL), - "Reading a router, processing unit \"%s\" already exists", - router->id); + if (current_routing->hierarchy_ == SURF_ROUTING_NULL) + current_routing->hierarchy_ = SURF_ROUTING_BASE; + xbt_assert(nullptr == xbt_lib_get_or_null(as_router_lib, router->id, ROUTING_ASR_LEVEL), + "Refusing to create a router named '%s': this name already describes a node.", router->id); - simgrid::surf::NetCard *info = new simgrid::surf::NetCardImpl( - xbt_strdup(router->id), -1, SURF_NETWORK_ELEMENT_ROUTER, current_routing); - info->setId(current_routing->parsePU(info)); - xbt_lib_set(as_router_lib, router->id, ROUTING_ASR_LEVEL, (void *) info); - XBT_DEBUG("Having set name '%s' id '%d'", router->id, info->getId()); - simgrid::surf::netcardCreatedCallbacks(info); + simgrid::surf::NetCard *netcard = new simgrid::surf::NetCardImpl(router->id, SURF_NETWORK_ELEMENT_ROUTER, current_routing); + netcard->setId(current_routing->addComponent(netcard)); + xbt_lib_set(as_router_lib, router->id, ROUTING_ASR_LEVEL, (void *) netcard); + XBT_DEBUG("Having set name '%s' id '%d'", router->id, netcard->id()); + simgrid::surf::netcardCreatedCallbacks(netcard); if (router->coord && strcmp(router->coord, "")) { unsigned int cursor; @@ -156,7 +161,251 @@ void sg_platf_new_link(sg_platf_link_cbarg_t link){ void sg_platf_new_cluster(sg_platf_cluster_cbarg_t cluster) { - routing_new_cluster(cluster); + using simgrid::surf::AsCluster; + using simgrid::surf::AsClusterTorus; + using simgrid::surf::AsClusterFatTree; + + char *host_id, *groups, *link_id = NULL; + xbt_dict_t patterns = NULL; + int rankId=0; + + s_sg_platf_host_cbarg_t host = SG_PLATF_HOST_INITIALIZER; + s_sg_platf_link_cbarg_t link = SG_PLATF_LINK_INITIALIZER; + + unsigned int iter; + + if ((cluster->availability_trace && strcmp(cluster->availability_trace, "")) + || (cluster->state_trace && strcmp(cluster->state_trace, ""))) { + patterns = xbt_dict_new_homogeneous(xbt_free_f); + xbt_dict_set(patterns, "id", xbt_strdup(cluster->id), NULL); + xbt_dict_set(patterns, "prefix", xbt_strdup(cluster->prefix), NULL); + xbt_dict_set(patterns, "suffix", xbt_strdup(cluster->suffix), NULL); + } + + /* Parse the topology attributes. + * Nothing to do in a vanilla cluster, but that's another story for torus and flat_trees */ + s_sg_platf_AS_cbarg_t AS = SG_PLATF_AS_INITIALIZER; + AS.id = cluster->id; + + switch (cluster->topology) { + case SURF_CLUSTER_TORUS: + AS.routing = A_surfxml_AS_routing_ClusterTorus; + break; + case SURF_CLUSTER_FAT_TREE: + AS.routing = A_surfxml_AS_routing_ClusterFatTree; + break; + default: + AS.routing = A_surfxml_AS_routing_Cluster; + break; + } + + // What an inventive way of initializing the AS that I have as ancestor :-( + sg_platf_new_AS_begin(&AS); + simgrid::surf::As *current_routing = routing_get_current(); + static_cast(current_routing)->parse_specific_arguments(cluster); + + if(cluster->loopback_bw!=0 || cluster->loopback_lat!=0){ + ((AsCluster*)current_routing)->nb_links_per_node_++; + ((AsCluster*)current_routing)->has_loopback_=1; + } + + if(cluster->limiter_link!=0){ + ((AsCluster*)current_routing)->nb_links_per_node_++; + ((AsCluster*)current_routing)->has_limiter_=1; + } + + + //Make all hosts + xbt_dynar_t radical_elements = xbt_str_split(cluster->radical, ","); + xbt_dynar_foreach(radical_elements, iter, groups) { + + xbt_dynar_t radical_ends = xbt_str_split(groups, "-"); + int start = surf_parse_get_int(xbt_dynar_get_as(radical_ends, 0, char *)); + int end; + + switch (xbt_dynar_length(radical_ends)) { + case 1: + end = start; + break; + case 2: + end = surf_parse_get_int(xbt_dynar_get_as(radical_ends, 1, char *)); + break; + default: + surf_parse_error("Malformed radical"); + break; + } + for (int i = start; i <= end; i++) { + host_id = bprintf("%s%d%s", cluster->prefix, i, cluster->suffix); + link_id = bprintf("%s_link_%d", cluster->id, i); + + XBT_DEBUG("", host_id, cluster->speed); + + memset(&host, 0, sizeof(host)); + host.id = host_id; + if ((cluster->properties != NULL) && (!xbt_dict_is_empty(cluster->properties))) { + xbt_dict_cursor_t cursor=NULL; + char *key,*data; + host.properties = xbt_dict_new(); + + xbt_dict_foreach(cluster->properties,cursor,key,data) { + xbt_dict_set(host.properties, key, xbt_strdup(data),free); + } + } + if (cluster->availability_trace && strcmp(cluster->availability_trace, "")) { + xbt_dict_set(patterns, "radical", bprintf("%d", i), NULL); + char *avail_file = xbt_str_varsubst(cluster->availability_trace, patterns); + XBT_DEBUG("\tavailability_file=\"%s\"", avail_file); + host.speed_trace = tmgr_trace_new_from_file(avail_file); + xbt_free(avail_file); + } else { + XBT_DEBUG("\tavailability_file=\"\""); + } + + if (cluster->state_trace && strcmp(cluster->state_trace, "")) { + char *avail_file = xbt_str_varsubst(cluster->state_trace, patterns); + XBT_DEBUG("\tstate_file=\"%s\"", avail_file); + host.state_trace = tmgr_trace_new_from_file(avail_file); + xbt_free(avail_file); + } else { + XBT_DEBUG("\tstate_file=\"\""); + } + + host.speed_peak = xbt_dynar_new(sizeof(double), NULL); + xbt_dynar_push(host.speed_peak,&cluster->speed); + host.pstate = 0; + + //host.power_peak = cluster->power; + host.speed_scale = 1.0; + host.core_amount = cluster->core_amount; + host.initiallyOn = 1; + host.coord = ""; + sg_platf_new_host(&host); + xbt_dynar_free(&host.speed_peak); + XBT_DEBUG(""); + + XBT_DEBUG("", link_id, + cluster->bw, cluster->lat); + + + s_surf_parsing_link_up_down_t info_lim, info_loop; + // All links are saved in a matrix; + // every row describes a single node; every node + // may have multiple links. + // the first column may store a link from x to x if p_has_loopback is set + // the second column may store a limiter link if p_has_limiter is set + // other columns are to store one or more link for the node + + //add a loopback link + if(cluster->loopback_bw!=0 || cluster->loopback_lat!=0){ + char *tmp_link = bprintf("%s_loopback", link_id); + XBT_DEBUG("", tmp_link, + cluster->limiter_link); + + + memset(&link, 0, sizeof(link)); + link.id = tmp_link; + link.bandwidth = cluster->loopback_bw; + link.latency = cluster->loopback_lat; + link.initiallyOn = 1; + link.policy = SURF_LINK_FATPIPE; + sg_platf_new_link(&link); + info_loop.link_up = Link::byName(tmp_link); + info_loop.link_down = info_loop.link_up; + free(tmp_link); + xbt_dynar_set(current_routing->upDownLinks, + rankId*(static_cast(current_routing))->nb_links_per_node_, &info_loop); + } + + //add a limiter link (shared link to account for maximal bandwidth of the node) + if(cluster->limiter_link!=0){ + char *tmp_link = bprintf("%s_limiter", link_id); + XBT_DEBUG("", tmp_link, + cluster->limiter_link); + + + memset(&link, 0, sizeof(link)); + link.id = tmp_link; + link.bandwidth = cluster->limiter_link; + link.latency = 0; + link.initiallyOn = 1; + link.policy = SURF_LINK_SHARED; + sg_platf_new_link(&link); + info_lim.link_up = Link::byName(tmp_link); + info_lim.link_down = info_lim.link_up; + free(tmp_link); + auto as_cluster = static_cast(current_routing); + xbt_dynar_set(current_routing->upDownLinks, + rankId*(as_cluster)->nb_links_per_node_ + as_cluster->has_loopback_ , + &info_lim); + + } + + + //call the cluster function that adds the others links + if (cluster->topology == SURF_CLUSTER_FAT_TREE) { + ((AsClusterFatTree*) current_routing)->addProcessingNode(i); + } + else { + static_cast(current_routing)->create_links_for_node(cluster, i, rankId, rankId* + static_cast(current_routing)->nb_links_per_node_ + + static_cast(current_routing)->has_loopback_ + + static_cast(current_routing)->has_limiter_ ); + } + xbt_free(link_id); + xbt_free(host_id); + rankId++; + } + + xbt_dynar_free(&radical_ends); + } + xbt_dynar_free(&radical_elements); + + // For fat trees, the links must be created once all nodes have been added + if(cluster->topology == SURF_CLUSTER_FAT_TREE) { + static_cast(current_routing)->create_links(); + } + // Add a router. It is magically used thanks to the way in which surf_routing_cluster is written, + // and it's very useful to connect clusters together + XBT_DEBUG(" "); + XBT_DEBUG("", cluster->router_id); + char *newid = NULL; + s_sg_platf_router_cbarg_t router = SG_PLATF_ROUTER_INITIALIZER; + memset(&router, 0, sizeof(router)); + router.id = cluster->router_id; + router.coord = ""; + if (!router.id || !strcmp(router.id, "")) + router.id = newid = + bprintf("%s%s_router%s", cluster->prefix, cluster->id, + cluster->suffix); + sg_platf_new_router(&router); + ((AsCluster*)current_routing)->router_ = (simgrid::surf::NetCard*) xbt_lib_get_or_null(as_router_lib, router.id, ROUTING_ASR_LEVEL); + free(newid); + + //Make the backbone + if ((cluster->bb_bw != 0) || (cluster->bb_lat != 0)) { + char *link_backbone = bprintf("%s_backbone", cluster->id); + XBT_DEBUG("", link_backbone, + cluster->bb_bw, cluster->bb_lat); + + memset(&link, 0, sizeof(link)); + link.id = link_backbone; + link.bandwidth = cluster->bb_bw; + link.latency = cluster->bb_lat; + link.initiallyOn = 1; + link.policy = cluster->bb_sharing_policy; + + sg_platf_new_link(&link); + + routing_cluster_add_backbone(Link::byName(link_backbone)); + + free(link_backbone); + } + + XBT_DEBUG(""); + sg_platf_new_AS_end(); + XBT_DEBUG(" "); + xbt_dict_free(&patterns); // no op if it were never set + simgrid::surf::on_cluster(cluster); } @@ -233,19 +482,6 @@ void sg_platf_new_storage_type(sg_platf_storage_type_cbarg_t storage_type){ void sg_platf_new_mstorage(sg_platf_mstorage_cbarg_t mstorage) { THROW_UNIMPLEMENTED; -// mount_t mnt = xbt_new0(s_mount_t, 1); -// mnt->id = xbt_strdup(mstorage->type_id); -// mnt->name = xbt_strdup(mstorage->name); -// -// if(!mount_list){ -// XBT_DEBUG("Creata a Mount list for %s",A_surfxml_host_id); -// mount_list = xbt_dynar_new(sizeof(char *), NULL); -// } -// xbt_dynar_push(mount_list,(void *) mnt); -// free(mnt->id); -// free(mnt->name); -// xbt_free(mnt); -// XBT_DEBUG("ROUTING Mount a storage name '%s' with type_id '%s'",mstorage->name, mstorage->id); } static void mount_free(void *p) @@ -256,10 +492,8 @@ static void mount_free(void *p) void sg_platf_new_mount(sg_platf_mount_cbarg_t mount){ // Verification of an existing storage -#ifndef NDEBUG - void* storage = xbt_lib_get_or_null(storage_lib, mount->storageId, ROUTING_STORAGE_LEVEL); -#endif - xbt_assert(storage,"Disk id \"%s\" does not exists", mount->storageId); + xbt_assert(xbt_lib_get_or_null(storage_lib, mount->storageId, ROUTING_STORAGE_LEVEL), + "Cannot mount non-existent disk \"%s\"", mount->storageId); XBT_DEBUG("ROUTING Mount '%s' on '%s'",mount->storageId, mount->name); @@ -276,28 +510,17 @@ void sg_platf_new_mount(sg_platf_mount_cbarg_t mount){ void sg_platf_new_route(sg_platf_route_cbarg_t route) { - routing_get_current()->parseRoute(route); -} - -void sg_platf_new_ASroute(sg_platf_route_cbarg_t ASroute) -{ - routing_get_current()->parseASroute(ASroute); + routing_get_current()->addRoute(route); } void sg_platf_new_bypassRoute(sg_platf_route_cbarg_t bypassRoute) { - routing_get_current()->parseBypassroute(bypassRoute); -} - -void sg_platf_new_bypassASroute(sg_platf_route_cbarg_t bypassASroute) -{ - routing_get_current()->parseBypassroute(bypassASroute); + routing_get_current()->addBypassRoute(bypassRoute); } void sg_platf_new_process(sg_platf_process_cbarg_t process) { - if (!simix_global) - xbt_die("Cannot create process without SIMIX."); + xbt_assert(simix_global,"Cannot create process without SIMIX."); sg_host_t host = sg_host_by_name(process->host); if (!host) { @@ -390,29 +613,6 @@ void sg_platf_new_process(sg_platf_process_cbarg_t process) current_property_set = NULL; } -void sg_platf_route_begin (sg_platf_route_cbarg_t route){ - route->link_list = xbt_dynar_new(sizeof(char *), &xbt_free_ref); -} -void sg_platf_ASroute_begin (sg_platf_route_cbarg_t ASroute){ - ASroute->link_list = xbt_dynar_new(sizeof(char *), &xbt_free_ref); -} - -void sg_platf_route_end (sg_platf_route_cbarg_t route){ - sg_platf_new_route(route); -} -void sg_platf_ASroute_end (sg_platf_route_cbarg_t ASroute){ - sg_platf_new_ASroute(ASroute); -} - -void sg_platf_route_add_link (const char* link_id, sg_platf_route_cbarg_t route){ - char *link_name = xbt_strdup(link_id); - xbt_dynar_push(route->link_list, &link_name); -} -void sg_platf_ASroute_add_link (const char* link_id, sg_platf_route_cbarg_t ASroute){ - char *link_name = xbt_strdup(link_id); - xbt_dynar_push(ASroute->link_list, &link_name); -} - void sg_platf_begin() { /* Do nothing: just for symmetry of user code */ } void sg_platf_end() { @@ -454,20 +654,3 @@ void sg_platf_new_AS_end() if (TRACE_is_enabled()) sg_instr_AS_end(); } -/* ***************************************** */ - -void sg_platf_rng_stream_init(unsigned long seed[6]) { - RngStream_SetPackageSeed(seed); - sg_platf_rng_stream = RngStream_CreateStream(NULL); -} - -RngStream sg_platf_rng_stream_get(const char* id) { - RngStream stream = NULL; - unsigned int id_hash; - - stream = RngStream_CopyStream(sg_platf_rng_stream); - id_hash = xbt_str_hash(id); - RngStream_AdvanceState(stream, 0, (long)id_hash); - - return stream; -}