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 }