1 /* 2 * Copyright (c) 2004-2005 The Trustees of Indiana University and Indiana 3 * University Research and Technology 4 * Corporation. All rights reserved. 5 * Copyright (c) 2004-2013 The University of Tennessee and The University 6 * of Tennessee Research Foundation. All rights 7 * reserved. 8 * Copyright (c) 2004-2005 High Performance Computing Center Stuttgart, 9 * University of Stuttgart. All rights reserved. 10 * Copyright (c) 2004-2005 The Regents of the University of California. 11 * All rights reserved. 12 * Copyright (c) 2008 Cisco Systems, Inc. All rights reserved. 13 * Copyright (c) 2012-2013 Inria. All rights reserved. 14 * Copyright (c) 2015 Research Organization for Information Science 15 * and Technology (RIST). All rights reserved. 16 * $COPYRIGHT$ 17 * 18 * Additional copyrights may follow 19 * 20 * $HEADER$ 21 */ 22 23 #include "ompi_config.h" 24 #include "ompi/mca/topo/base/base.h" 25 #include "ompi/communicator/communicator.h" 26 27 /* 28 * function - Determines process rank in communicator given Cartesian 29 * location 30 * 31 * @param comm communicator with cartesian structure (handle) 32 * @param coords integer array (of size 'ndims') specifying the cartesian 33 * coordinates of a process 34 * @param rank rank of specified process (integer) 35 * 36 * @retval MPI_SUCCESS 37 * @retval MPI_ERR_COMM 38 * @retval MPI_ERR_TOPOLOGY 39 * @retval MPI_ERR_ARG 40 */ 41 42 int mca_topo_base_cart_rank(ompi_communicator_t* comm, 43 const int *coords, 44 int *rank) 45 { 46 int prank; 47 int dim; 48 int ord; 49 int factor; 50 int i; 51 int *d; 52 53 /* 54 * Loop over coordinates computing the rank. 55 */ 56 factor = 1; 57 prank = 0; 58 59 i = comm->c_topo->mtc.cart->ndims - 1; 60 d = comm->c_topo->mtc.cart->dims + i; 61 62 for (; i >= 0; --i, --d) { 63 dim = *d; 64 ord = coords[i]; 65 /* Per MPI-2.1 7.5.4 (description of MPI_CART_RANK), if the 66 dimension is periodic and the coordinate is outside of 0 <= 67 coord(i) < dim, then normalize it. If the dimension is not 68 periodic, it's an error. */ 69 if ((ord < 0) || (ord >= dim)) { 70 ord %= dim; 71 if (ord < 0) { 72 ord += dim; 73 } 74 } 75 prank += factor * ord; 76 factor *= dim; 77 } 78 *rank = prank; 79 80 return(MPI_SUCCESS); 81 }