X-Git-Url: http://info.iut-bm.univ-fcomte.fr/pub/gitweb/simgrid.git/blobdiff_plain/861682bbd33ba13c51148538775838f0d9f181a5..4386010688d60bea7f54c2383aa9c923f2980948:/src/smpi/smpi_topo.cpp diff --git a/src/smpi/smpi_topo.cpp b/src/smpi/smpi_topo.cpp index 6ed191adb2..432174ed2b 100644 --- a/src/smpi/smpi_topo.cpp +++ b/src/smpi/smpi_topo.cpp @@ -1,5 +1,4 @@ -/* Copyright (c) 2014, 2017. The SimGrid Team. - * All rights reserved. */ +/* Copyright (c) 2014-2017. The 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. */ @@ -9,173 +8,102 @@ #include "private.h" #include #include +#include "src/smpi/smpi_comm.hpp" +#include "src/smpi/smpi_topo.hpp" -typedef struct s_smpi_mpi_cart_topology { - int nnodes; - int ndims; - int *dims; - int *periodic; - int *position; -} s_smpi_mpi_cart_topology_t; - -typedef struct s_smpi_mpi_graph_topology { - int nnodes; - int nedges; - int *index; - int *edges; -} s_smpi_mpi_graph_topology_t; - -typedef struct s_smpi_dist_graph_topology { - int indegree; - int *in; - int *in_weights; - int outdegree; - int *out; - int *out_weights; - int is_weighted; -} s_smpi_mpi_dist_graph_topology_t; - -typedef struct s_smpi_mpi_topology { - MPIR_Topo_type kind; - union topo { - MPIR_Graph_Topology graph; - MPIR_Cart_Topology cart; - MPIR_Dist_Graph_Topology dist_graph; - } topo; -} s_smpi_mpi_topology_t; - -void smpi_topo_destroy(MPI_Topology topo) { - if(topo == nullptr) { - return; - } - switch (topo->kind) { - case MPI_CART: - smpi_cart_topo_destroy(topo->topo.cart); - break; - case MPI_GRAPH: - // This topology is not supported by SMPI yet - smpi_graph_topo_destroy(topo->topo.graph); - break; - case MPI_DIST_GRAPH: - // This topology is not supported by SMPI yet - smpi_dist_graph_topo_destroy(topo->topo.dist_graph); - break; - default: - return; - } - xbt_free(topo); -} +/* static functions */ +static int assignnodes(int ndim, int nfactor, int *pfacts,int **pdims); +static int getfactors(int num, int *nfators, int **factors); -MPI_Topology smpi_topo_create(MPIR_Topo_type kind) { - MPI_Topology newTopo = static_cast(xbt_malloc(sizeof(*newTopo))); - newTopo->kind = kind; - // Allocate and initialize the right topo should be done by the caller - return newTopo; -} -void smpi_graph_topo_destroy(MPIR_Graph_Topology graph) { - if (graph) { - delete[] graph->index; - delete[] graph->edges; - xbt_free(graph); - } +namespace simgrid{ +namespace smpi{ + +Topo_Graph::~Topo_Graph() +{ + delete[] index_; + delete[] edges_; } -void smpi_dist_graph_topo_destroy(MPIR_Dist_Graph_Topology dist_graph) { - if (dist_graph) { - delete[] dist_graph->in; - delete[] dist_graph->in_weights; - delete[] dist_graph->out; - delete[] dist_graph->out_weights; - xbt_free(dist_graph); - } +Topo_Dist_Graph::~Topo_Dist_Graph() +{ + delete[] in_; + delete[] in_weights_; + delete[] out_; + delete[] out_weights_; } /******************************************************************************* * Cartesian topologies ******************************************************************************/ -void smpi_cart_topo_destroy(MPIR_Cart_Topology cart) { - if (cart) { - delete[] cart->dims; - delete[] cart->periodic; - delete[] cart->position; - xbt_free(cart); - } +Topo_Cart::~Topo_Cart() +{ + delete[] dims_; + delete[] periodic_; + delete[] position_; } -MPI_Topology smpi_cart_topo_create(int ndims) { - MPI_Topology newTopo = smpi_topo_create(MPI_CART); - MPIR_Cart_Topology newCart = static_cast(xbt_malloc(sizeof(*newCart))); - newCart->nnodes = 0; - newCart->ndims = ndims; - newCart->dims = new int[ndims]; - newCart->periodic = new int[ndims]; - newCart->position = new int[ndims]; - newTopo->topo.cart = newCart; - return newTopo; +Topo_Cart::Topo_Cart(int ndims) : ndims_(ndims) +{ + dims_ = new int[ndims]; + periodic_ = new int[ndims]; + position_ = new int[ndims]; } /* reorder is ignored, don't know what would be the consequences of a dumb reordering but neither do I see the point of * reordering*/ -int smpi_mpi_cart_create(MPI_Comm comm_old, int ndims, int dims[], int periods[], int reorder, MPI_Comm *comm_cart) { - int retval = MPI_SUCCESS; - MPI_Topology newCart; +Topo_Cart::Topo_Cart(MPI_Comm comm_old, int ndims, int dims[], int periods[], int reorder, MPI_Comm *comm_cart) : Topo_Cart(ndims) { MPI_Group newGroup; MPI_Group oldGroup; - int nranks; - int rank = smpi_comm_rank(comm_old); + int rank = comm_old->rank(); - int newSize = 1; if(ndims != 0) { + int newSize = 1; for (int i = 0 ; i < ndims ; i++) { newSize *= dims[i]; } if(rank >= newSize) { *comm_cart = MPI_COMM_NULL; - return retval; + return; } - newCart = smpi_cart_topo_create(ndims); - oldGroup = smpi_comm_group(comm_old); - newGroup = smpi_group_new(newSize); + oldGroup = comm_old->group(); + newGroup = new Group(newSize); for (int i = 0 ; i < newSize ; i++) { - smpi_group_set_mapping(newGroup, smpi_group_index(oldGroup, i), i); + newGroup->set_mapping(oldGroup->index(i), i); } - newCart->topo.cart->nnodes = newSize; + nnodes_ = newSize; - // FIXME : code duplication... See smpi_mpi_cart_coords - nranks = newSize; + // FIXME : code duplication... See coords + int nranks = newSize; for (int i=0; itopo.cart->dims[i] = dims[i]; - newCart->topo.cart->periodic[i] = periods[i]; + dims_[i] = dims[i]; + periodic_[i] = periods[i]; nranks = nranks / dims[i]; /* FIXME: nranks could be zero (?) */ - newCart->topo.cart->position[i] = rank / nranks; + position_[i] = rank / nranks; rank = rank % nranks; } - *comm_cart = smpi_comm_new(newGroup, newCart); + *comm_cart = new Comm(newGroup, this); } else { if (rank == 0) { - newCart = smpi_cart_topo_create(ndims); - *comm_cart = smpi_comm_new(smpi_group_copy(smpi_comm_group(MPI_COMM_SELF)), newCart); + *comm_cart = new Comm(new Group(MPI_COMM_SELF->group()), this); } else { *comm_cart = MPI_COMM_NULL; } } - return retval; + comm_=*comm_cart; } -int smpi_mpi_cart_sub(MPI_Comm comm, const int remain_dims[], MPI_Comm *newcomm) { - MPI_Topology oldTopo = smpi_comm_topo(comm); - int oldNDims = oldTopo->topo.cart->ndims; - int j = 0; +Topo_Cart* Topo_Cart::sub(const int remain_dims[], MPI_Comm *newcomm) { + int oldNDims = ndims_; int *newDims = nullptr; int *newPeriodic = nullptr; if (remain_dims == nullptr && oldNDims != 0) { - return MPI_ERR_ARG; + return nullptr; } int newNDims = 0; for (int i = 0 ; i < oldNDims ; i++) { @@ -188,65 +116,62 @@ int smpi_mpi_cart_sub(MPI_Comm comm, const int remain_dims[], MPI_Comm *newcomm) newPeriodic = xbt_new(int, newNDims); // that should not segfault + int j = 0; for (int i = 0 ; j < newNDims ; i++) { if(remain_dims[i]) { - newDims[j] = oldTopo->topo.cart->dims[i]; - newPeriodic[j] = oldTopo->topo.cart->periodic[i]; + newDims[j] =dims_[i]; + newPeriodic[j] =periodic_[i]; j++; } } } - return smpi_mpi_cart_create(comm, newNDims, newDims, newPeriodic, 0, newcomm); + return new Topo_Cart(comm_, newNDims, newDims, newPeriodic, 0, newcomm); } -int smpi_mpi_cart_coords(MPI_Comm comm, int rank, int maxdims, int coords[]) { - MPI_Topology topo = smpi_comm_topo(comm); - int nnodes = topo->topo.cart->nnodes; - for (int i = 0; i< topo->topo.cart->ndims; i++ ) { - nnodes = nnodes / topo->topo.cart->dims[i]; +int Topo_Cart::coords(int rank, int maxdims, int coords[]) { + int nnodes = nnodes_; + for (int i = 0; i< ndims_; i++ ) { + nnodes = nnodes /dims_[i]; coords[i] = rank / nnodes; rank = rank % nnodes; } return MPI_SUCCESS; } -int smpi_mpi_cart_get(MPI_Comm comm, int maxdims, int* dims, int* periods, int* coords) { - MPI_Topology topo = smpi_comm_topo(comm); - int ndims=topo->topo.cart->ndims < maxdims ? topo->topo.cart->ndims : maxdims; +int Topo_Cart::get(int maxdims, int* dims, int* periods, int* coords) { + int ndims=ndims_ < maxdims ?ndims_ : maxdims; for(int i = 0 ; i < ndims ; i++) { - dims[i] = topo->topo.cart->dims[i]; - periods[i] = topo->topo.cart->periodic[i]; - coords[i] = topo->topo.cart->position[i]; + dims[i] =dims_[i]; + periods[i] =periodic_[i]; + coords[i] =position_[i]; } return MPI_SUCCESS; } -int smpi_mpi_cart_rank(MPI_Comm comm, int* coords, int* rank) { - MPI_Topology topo = smpi_comm_topo(comm); - int ndims = topo->topo.cart->ndims; - int coord; +int Topo_Cart::rank(int* coords, int* rank) { + int ndims =ndims_; *rank = 0; int multiplier = 1; for (int i=ndims-1; i >=0; i-- ) { - coord = coords[i]; + int coord = coords[i]; /* The user can give us whatever coordinates he wants. If one of them is out of range, either this dimension is * periodic, and we consider the equivalent coordinate inside the bounds, or it's not and then it's an error */ - if (coord >= topo->topo.cart->dims[i]) { - if ( topo->topo.cart->periodic[i] ) { - coord = coord % topo->topo.cart->dims[i]; + if (coord >=dims_[i]) { + if (periodic_[i] ) { + coord = coord %dims_[i]; } else { // Should I do that ? *rank = -1; return MPI_ERR_ARG; } } else if (coord < 0) { - if(topo->topo.cart->periodic[i]) { - coord = coord % topo->topo.cart->dims[i]; + if(periodic_[i]) { + coord = coord %dims_[i]; if (coord) - coord = topo->topo.cart->dims[i] + coord; + coord =dims_[i] + coord; } else { *rank = -1; return MPI_ERR_ARG; @@ -254,56 +179,54 @@ int smpi_mpi_cart_rank(MPI_Comm comm, int* coords, int* rank) { } *rank += multiplier * coord; - multiplier *= topo->topo.cart->dims[i]; + multiplier *=dims_[i]; } return MPI_SUCCESS; } -int smpi_mpi_cart_shift(MPI_Comm comm, int direction, int disp, int *rank_source, int *rank_dest) { - MPI_Topology topo = smpi_comm_topo(comm); - int position[topo->topo.cart->ndims]; +int Topo_Cart::shift(int direction, int disp, int *rank_source, int *rank_dest) { + + int position[ndims_]; - if(topo->topo.cart->ndims == 0) { + if(ndims_ == 0) { return MPI_ERR_ARG; } - if (topo->topo.cart->ndims < direction) { + if (ndims_ < direction) { return MPI_ERR_DIMS; } - smpi_mpi_cart_coords(comm, smpi_comm_rank(comm), topo->topo.cart->ndims, position); + this->coords(comm_->rank(),ndims_, position); position[direction] += disp; if(position[direction] < 0 || - position[direction] >= topo->topo.cart->dims[direction]) { - if(topo->topo.cart->periodic[direction]) { - position[direction] %= topo->topo.cart->dims[direction]; - smpi_mpi_cart_rank(comm, position, rank_dest); + position[direction] >=dims_[direction]) { + if(periodic_[direction]) { + position[direction] %=dims_[direction]; + this->rank(position, rank_dest); } else { *rank_dest = MPI_PROC_NULL; } } else { - smpi_mpi_cart_rank(comm, position, rank_dest); + this->rank(position, rank_dest); } - position[direction] = topo->topo.cart->position[direction] - disp; - if(position[direction] < 0 || position[direction] >= topo->topo.cart->dims[direction]) { - if(topo->topo.cart->periodic[direction]) { - position[direction] %= topo->topo.cart->dims[direction]; - smpi_mpi_cart_rank(comm, position, rank_source); + position[direction] = position_[direction] - disp; + if(position[direction] < 0 || position[direction] >=dims_[direction]) { + if(periodic_[direction]) { + position[direction] %=dims_[direction]; + this->rank(position, rank_source); } else { *rank_source = MPI_PROC_NULL; } } else { - smpi_mpi_cart_rank(comm, position, rank_source); + this->rank(position, rank_source); } return MPI_SUCCESS; } -int smpi_mpi_cartdim_get(MPI_Comm comm, int *ndims) { - MPI_Topology topo = smpi_comm_topo(comm); - - *ndims = topo->topo.cart->ndims; +int Topo_Cart::dim_get(int *ndims) { + *ndims =ndims_; return MPI_SUCCESS; } @@ -316,12 +239,12 @@ int smpi_mpi_cartdim_get(MPI_Comm comm, int *ndims) { * Copyright (c) 2004-2005 The University of Tennessee and The University * of Tennessee Research Foundation. All rights * reserved. - * Copyright (c) 2004-2014 High Performance Computing Center Stuttgart, + * Copyright (c) 2004-2014 High Performance Computing Center Stuttgart, * University of Stuttgart. All rights reserved. * Copyright (c) 2004-2005 The Regents of the University of California. * All rights reserved. * Copyright (c) 2012 Los Alamos National Security, LLC. All rights - * reserved. + * reserved. * Copyright (c) 2014 Intel, Inc. All rights reserved * $COPYRIGHT$ * @@ -330,14 +253,10 @@ int smpi_mpi_cartdim_get(MPI_Comm comm, int *ndims) { * $HEADER$ */ -/* static functions */ -static int assignnodes(int ndim, int nfactor, int *pfacts,int **pdims); -static int getfactors(int num, int *nfators, int **factors); - /* * This is a utility function, no need to have anything in the lower layer for this at all */ -int smpi_mpi_dims_create(int nnodes, int ndims, int dims[]) +int Topo_Cart::Dims_create(int nnodes, int ndims, int dims[]) { /* Get # of free-to-be-assigned processes and # of free dimensions */ int freeprocs = nnodes; @@ -401,6 +320,9 @@ int smpi_mpi_dims_create(int nnodes, int ndims, int dims[]) return MPI_SUCCESS; } +} +} + /* * assignnodes * @@ -425,9 +347,7 @@ static int assignnodes(int ndim, int nfactor, int *pfacts, int **pdims) /* Allocate and initialize the bins */ int *bins = new int[ndim]; - if (nullptr == bins) { - return MPI_ERR_NO_MEM; - } + *pdims = bins; int *p = bins; @@ -508,3 +428,4 @@ static int getfactors(int num, int *nfactors, int **factors) { (*nfactors) = i; return MPI_SUCCESS; } +