1 /* -*- Mode: C; c-basic-offset:4 ; -*- */
2 /*
3  *
4  *  (C) 2001 by Argonne National Laboratory.
5  *      See COPYRIGHT in top-level directory.
6  */
7 
8 #include "mpiimpl.h"
9 #include "topo.h"
10 
11 /* -- Begin Profiling Symbol Block for routine MPI_Graph_neighbors_count */
12 #if defined(HAVE_PRAGMA_WEAK)
13 #pragma weak MPI_Graph_neighbors_count = PMPI_Graph_neighbors_count
14 #elif defined(HAVE_PRAGMA_HP_SEC_DEF)
15 #pragma _HP_SECONDARY_DEF PMPI_Graph_neighbors_count  MPI_Graph_neighbors_count
16 #elif defined(HAVE_PRAGMA_CRI_DUP)
17 #pragma _CRI duplicate MPI_Graph_neighbors_count as PMPI_Graph_neighbors_count
18 #endif
19 /* -- End Profiling Symbol Block */
20 
21 /* Define MPICH_MPI_FROM_PMPI if weak symbols are not supported to build
22    the MPI routines */
23 #ifndef MPICH_MPI_FROM_PMPI
24 #undef MPI_Graph_neighbors_count
25 #define MPI_Graph_neighbors_count PMPI_Graph_neighbors_count
26 
27 #undef FUNCNAME
28 #define FUNCNAME MPIR_Graph_neighbors_count_impl
29 #undef FCNAME
30 #define FCNAME MPIU_QUOTE(FUNCNAME)
MPIR_Graph_neighbors_count_impl(MPID_Comm * comm_ptr,int rank,int * nneighbors)31 int MPIR_Graph_neighbors_count_impl(MPID_Comm *comm_ptr, int rank, int *nneighbors)
32 {
33     int mpi_errno = MPI_SUCCESS;
34     MPIR_Topology *graph_ptr;
35 
36     graph_ptr = MPIR_Topology_get( comm_ptr );
37 
38     MPIU_ERR_CHKANDJUMP((!graph_ptr || graph_ptr->kind != MPI_GRAPH), mpi_errno, MPI_ERR_TOPOLOGY, "**notgraphtopo");
39     MPIU_ERR_CHKANDJUMP2((rank < 0 || rank >= graph_ptr->topo.graph.nnodes), mpi_errno, MPI_ERR_RANK, "**rank",
40                          "**rank %d %d", rank, graph_ptr->topo.graph.nnodes );
41 
42     if ( rank == 0 )
43         *nneighbors = graph_ptr->topo.graph.index[rank];
44     else
45         *nneighbors = graph_ptr->topo.graph.index[rank] -
46             graph_ptr->topo.graph.index[rank-1];
47 
48 fn_exit:
49     return mpi_errno;
50 fn_fail:
51     goto fn_exit;
52 }
53 
54 #endif
55 
56 #undef FUNCNAME
57 #define FUNCNAME MPI_Graph_neighbors_count
58 #undef FCNAME
59 #define FCNAME MPIU_QUOTE(FUNCNAME)
60 
61 /*@
62 MPI_Graph_neighbors_count - Returns the number of neighbors of a node
63                             associated with a graph topology
64 
65 Input Parameters:
66 + comm - communicator with graph topology (handle)
67 - rank - rank of process in group of 'comm' (integer)
68 
69 Output Parameter:
70 . nneighbors - number of neighbors of specified process (integer)
71 
72 .N SignalSafe
73 
74 .N Fortran
75 
76 .N Errors
77 .N MPI_SUCCESS
78 .N MPI_ERR_TOPOLOGY
79 .N MPI_ERR_COMM
80 .N MPI_ERR_ARG
81 .N MPI_ERR_RANK
82 @*/
MPI_Graph_neighbors_count(MPI_Comm comm,int rank,int * nneighbors)83 int MPI_Graph_neighbors_count(MPI_Comm comm, int rank, int *nneighbors)
84 {
85     int mpi_errno = MPI_SUCCESS;
86     MPID_Comm *comm_ptr = NULL;
87     MPID_MPI_STATE_DECL(MPID_STATE_MPI_GRAPH_NEIGHBORS_COUNT);
88 
89     MPIR_ERRTEST_INITIALIZED_ORDIE();
90     /* Note that this routine does not require a CS_ENTER/EXIT */
91     MPID_MPI_FUNC_ENTER(MPID_STATE_MPI_GRAPH_NEIGHBORS_COUNT);
92 
93     /* Validate parameters, especially handles needing to be converted */
94 #   ifdef HAVE_ERROR_CHECKING
95     {
96         MPID_BEGIN_ERROR_CHECKS;
97         {
98 	    MPIR_ERRTEST_COMM(comm, mpi_errno);
99         }
100         MPID_END_ERROR_CHECKS;
101     }
102 #   endif
103 
104     /* Convert MPI object handles to object pointers */
105     MPID_Comm_get_ptr( comm, comm_ptr );
106 
107     /* Validate parameters and objects (post conversion) */
108 #   ifdef HAVE_ERROR_CHECKING
109     {
110         MPID_BEGIN_ERROR_CHECKS;
111         {
112             /* Validate comm_ptr */
113             MPID_Comm_valid_ptr( comm_ptr, mpi_errno );
114             if (mpi_errno) goto fn_fail;
115 	    MPIR_ERRTEST_ARGNULL(nneighbors, "nneighbors", mpi_errno);
116 	    /* If comm_ptr is not value, it will be reset to null */
117         }
118         MPID_END_ERROR_CHECKS;
119     }
120 #   endif /* HAVE_ERROR_CHECKING */
121 
122     /* ... body of routine ...  */
123 
124     mpi_errno = MPIR_Graph_neighbors_count_impl(comm_ptr, rank, nneighbors);
125     if (mpi_errno) MPIU_ERR_POP(mpi_errno);
126 
127     /* ... end of body of routine ... */
128 
129   fn_exit:
130     MPID_MPI_FUNC_EXIT(MPID_STATE_MPI_GRAPH_NEIGHBORS_COUNT);
131     return mpi_errno;
132 
133   fn_fail:
134     /* --BEGIN ERROR HANDLING-- */
135 #   ifdef HAVE_ERROR_CHECKING
136     {
137 	mpi_errno = MPIR_Err_create_code(
138 	    mpi_errno, MPIR_ERR_RECOVERABLE, FCNAME, __LINE__, MPI_ERR_OTHER, "**mpi_graph_neighbors_count",
139 	    "**mpi_graph_neighbors_count %C %d %p", comm, rank, nneighbors);
140     }
141 #   endif
142     mpi_errno = MPIR_Err_return_comm( comm_ptr, FCNAME, mpi_errno );
143     goto fn_exit;
144     /* --END ERROR HANDLING-- */
145 }
146