File: ompi_rte.h

package info (click to toggle)
openmpi 5.0.7-1
  • links: PTS, VCS
  • area: main
  • in suites: forky, sid, trixie
  • size: 202,312 kB
  • sloc: ansic: 612,441; makefile: 42,495; sh: 11,230; javascript: 9,244; f90: 7,052; java: 6,404; perl: 5,154; python: 1,856; lex: 740; fortran: 61; cpp: 20; tcl: 12
file content (286 lines) | stat: -rw-r--r-- 13,546 bytes parent folder | download | duplicates (2)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
/* -*- Mode: C; c-basic-offset:4 ; indent-tabs-mode:nil -*- */
/*
 * Copyright (c) 2012-2015 Los Alamos National Security, LLC.  All rights reserved.
 * Copyright (c) 2013      Mellanox Technologies, Inc.
 *                         All rights reserved.
 * Copyright (c) 2014-2020 Intel, Inc.  All rights reserved.
 * Copyright (c) 2019      Research Organization for Information Science
 *                         and Technology (RIST).  All rights reserved.
 * Copyright (c) 2020-2022  Triad National Security, LLC. All rights
 *                         reserved.
 * Copyright (c) 2020      Amazon.com, Inc. or its affiliates.  All Rights
 *                         reserved.
 *
 * Copyright (c) 2021      Nanook Consulting.  All rights reserved.
 * $COPYRIGHT$
 *
 * Additional copyrights may follow
 */

/* This is the public RTE interface to the OMPI layer. Any RTE can be
 * connected to the OMPI layer by creating a new static component in
 * this framework, assigning it a priority and including a configure.m4
 * to define when it should be built.
 *
 * Each component must provide a number of types and functions that mimic
 * those provided by PRTE. These include (where flexibility exists, the
 * pmix data type is shown, but any compatible type is allowed. For example,
 * the jobid field in ompi_process_name_t could be any type of integer, but
 * cannot be a string):
 *
 * (a) Process name objects and operations
 *     1. Definitions for integral types ompi_jobid_t and ompi_vpid_t.
 *        The jobid must be unique for a given MPI_COMM_WORLD capable of
 *        connecting to another OMPI_COMM_WORLD and the vpid will be the
 *        process's rank in MPI_COMM_WORLD.
 *     2. ompi_process_name_t - a struct that must contain at least two integer-typed fields:
 *           a. ompi_jobid_t jobid
 *           b. ompi_vpid_t vpid
 *        Note that the structure can contain any number of fields beyond these
 *        two, so the process name struct for any particular RTE can be whatever
 *        is desired.
 *     3. OMPI_NAME_PRINT - a macro that prints a process name when given
 *        a pointer to ompi_process_name_t. The output format is to be
 *        a single string representing the name.  This function should
 *        be thread-safe for multiple threads to call simultaneously.
 *     4. OMPI_PROC_MY_NAME - a pointer to a global variable containing
 *        the ompi_process_name_t for this process. Typically, this is
 *        stored as a field in the ompi_process_info_t struct, but that
 *        is not a requirement.
 *     5. OMPI_NAME_WIlDCARD - a wildcard name.
 *     6. ompi_rte_compare_name_fields - a function used to compare fields
 *        in the ompi_process_name_t struct. The function prototype must be
 *        of the form:
 *        int ompi_rte_compare_name_fields(ompi_rte_cmp_bitmask_t mask,
 *                                         ompi_process_name_t *name1,
 *                                         ompi_process_name_t *name2);
 *        The bitmask must be defined to indicate the fields to be used
 *        in the comparison. Fields not included in the mask must be ignored.
 *        Supported bitmask values must include:
 *           b. OMPI_RTE_CMP_JOBID
 *           c. OMPI_RTE_CMP_VPID
 *           d. OMPI_RTE_CMP_ALL
 *      7. uint64_t ompi_rte_hash_name(name) - return a string hash uniquely
 *         representing the ompi_process_name passed in.
 *      8. OMPI_NAME - an Opal DSS constant for a handler already registered
 *         to serialize/deserialize an ompi_process_name_t structure.
 *
 * (b) Collective objects and operations
 *     1. ompi_rte_collective_t - an OPAL object used during RTE collective operations
 *        such as modex and barrier. It must be an opal_list_item_t and contain the
 *        following fields:
 *           a. id (pmix type: int32_t)
 *           b. bool active
 *              flag that user can poll on to know when collective
 *              has completed - set to false just prior to
 *              calling user callback function, if provided
 *     2. ompi_rte_modex - a function that performs an exchange of endpoint information
 *        to wireup the MPI transports. The function prototype must be of the form:
 *        int ompi_rte_modex(ompi_rte_collective_t *coll);
 *        At the completion of the modex operation, the coll->active flag must be set
 *        to false, and the endpoint information must be stored in the modex database.
 *        This function must have barrier semantics across the MPI_COMM_WORLD of the
 *        calling process.
 *     3. ompi_rte_barrier - a function that performs a barrier operation within the
 *        RTE. The function prototype must be of the form:
 *        int ompi_rte_barrier(ompi_rte_collective_t *coll);
 *        At the completion of the barrier operation, the coll->active flag must be set
 *        to false
 *
 * (c) Process info struct
 *     1. ompi_process_info_t - a struct containing info about the current process.
 *        The struct must contain at least the following fields:
 *           a. app_num -
 *           b. pid - this process's pid.  Should be same as getpid().
 *           c. num_procs - Number of processes in this job (ie, MCW)
 *           d. my_node_rank - relative rank on local node to other peers this run-time
 *                    instance knows about.  If doing dynamics, this may be something
 *                    different than my_local_rank, but will be my_local_rank in a
 *                    static job.
 *           d. my_local_rank - relative rank on local node with other peers in this job (ie, MCW)
 *           e. num_local_peers - Number of local peers (peers in MCW on your node)
 *           f. my_hnp_uri -
 *           g. peer_modex - a collective id for the modex operation
 *           h. peer_init_barrier - a collective id for the barrier during MPI_Init
 *           i. peer_fini_barrier - a collective id for the barrier during MPI_Finalize
 *           j. job_session_dir -
 *           k. proc_session_dir -
 *           l. nodename - a string representation for the name of the node this
 *              process is on
 *           m. cpuset -
 *     2. ompi_process_info - a global instance of the ompi_process_t structure.
 *     3. ompi_rte_proc_is_bound - global boolean that will be true if the runtime bound
 *        the process to a particular core or set of cores and is false otherwise.
 *
 * (d) Error handling objects and operations
 *     1. void ompi_rte_abort(int err_code, char *fmt, ...) - Abort the current
 *        process with the specified error code and message.
 *     2. int ompi_rte_abort_peers(ompi_process_name_t *procs, size_t nprocs) -
 *        Abort the specified list of peers
 *     3. OMPI_ERROR_LOG(rc) - print error message regarding the given return code
 *
 * (e) Init and finalize objects and operations
 *     1. ompi_rte_init - a function to initialize the RTE. The function
 *        prototype must be of the form:
 *        int ompi_rte_init(int *argc, char ***argv);
 *     2. ompi_rte_finalize - a function to finalize the RTE. The function
 *        prototype must be of the form:
 *        int ompi_rte_finalize(void);
 *     3. void ompi_rte_wait_for_debugger(void) - Called during MPI_Init, this
 *        function is used to wait for debuggers to do their pre-MPI attach.
 *        If there is no attached debugger, this function will not block.
 *
 * (f) Database operations
 *     1. ompi_rte_db_store - a function to store modex and other data in
 *        a local database. The function is primarily used for storing modex
 *        data, but can be used for general purposes. The prototype must be
 *        of the form:
 *        int ompi_rte_db_store(const ompi_process_name_t *proc,
 *                              const char *key, const void *data,
 *                              opal_data_type_t type);
 *        The implementation of this function must store a COPY of the data
 *        provided - the data is NOT guaranteed to be valid after return
 *        from the call.
 *     3. ompi_rte_db_fetch -
 *        NOTE: Fetch accepts an 'ompi_proc_t'.
 *        int ompi_rte_db_fetch(const struct ompi_proc_t *proc,
 *                              const char *key,
 *                              void **data,
 *                              opal_data_type_t type);
 *     4. ompi_rte_db_fetch_pointer -
 *        NOTE: Fetch accepts an 'ompi_proc_t'.
 *        int ompi_rte_db_fetch_pointer(const struct ompi_proc_t *proc,
 *                                      const char *key,
 *                                      void **data,
 *                                      opal_data_type_t type);
 *     5. Pre-defined db keys (with associated values after rte_init)
 *        a. OMPI_DB_HOSTNAME
 *        b. OMPI_DB_LOCALITY
 *
 * (g) Communication support
 *
 */

#ifndef OMPI_MCA_RTE_H
#define OMPI_MCA_RTE_H

#include "ompi_config.h"
#include "ompi/constants.h"

#include <stdint.h>
#ifdef HAVE_SYS_TYPES_H
#include <sys/types.h>
#endif

struct opal_proc_t;

#include "opal/mca/threads/threads.h"
#include "opal/util/proc.h"
#include "opal/mca/hwloc/hwloc-internal.h"
#include "opal/mca/pmix/pmix-internal.h"

struct ompi_proc_t;
struct ompi_communicator_t;

BEGIN_C_DECLS

/* Process name objects and operations */
typedef opal_process_name_t ompi_process_name_t;
typedef uint32_t ompi_jobid_t;
typedef uint32_t ompi_vpid_t;

/* some local storage */
OMPI_DECLSPEC extern hwloc_cpuset_t ompi_proc_applied_binding;

#define OMPI_PROC_MY_NAME (&opal_process_info.my_name)
#define OMPI_NAME_WILDCARD  (&opal_name_wildcard)
#define OMPI_PROC_MYID (&opal_process_info.myprocid)
#define OMPI_PRINT_ID(a) ompi_pmix_print_id(a)
OMPI_DECLSPEC char* ompi_pmix_print_id(const pmix_proc_t *procid);

typedef uint8_t ompi_rte_cmp_bitmask_t;
#define OMPI_RTE_CMP_NONE   0x00
#define OMPI_RTE_CMP_JOBID  0x02
#define OMPI_RTE_CMP_VPID   0x04
#define OMPI_RTE_CMP_ALL    0x0f
#define OMPI_RTE_CMP_WILD   0x10

OMPI_DECLSPEC char* ompi_pmix_print_name(const ompi_process_name_t *name);

#define OMPI_NAME_PRINT(a) ompi_pmix_print_name(a)
OMPI_DECLSPEC int ompi_rte_compare_name_fields(ompi_rte_cmp_bitmask_t mask,
                                               const opal_process_name_t* name1,
                                               const opal_process_name_t* name2);
OMPI_DECLSPEC int ompi_rte_convert_string_to_process_name(opal_process_name_t *name,
                                                          const char* name_string);
OMPI_DECLSPEC int ompi_rte_convert_process_name_to_string(char** name_string,
                                                          const opal_process_name_t *name);

OMPI_DECLSPEC void ompi_rte_breakpoint(char *name);

#define OMPI_LOCAL_JOBID(n) \
    ( (n) & 0x0000ffff)
#define OMPI_JOB_FAMILY(n)  \
    (((n) >> 16) & 0x0000ffff)
#define OMPI_CONSTRUCT_LOCAL_JOBID(local, job) \
    ( ((local) & 0xffff0000) | ((job) & 0x0000ffff) )
#define OMPI_CONSTRUCT_JOB_FAMILY(n) \
    ( ((n) << 16) & 0xffff0000)

#define OMPI_CONSTRUCT_JOBID(family, local) \
    OMPI_CONSTRUCT_LOCAL_JOBID(OMPI_CONSTRUCT_JOB_FAMILY(family), local)

/* This is the DSS tag to serialize a proc name */
#define OMPI_NAME OPAL_NAME
#define OMPI_PROCESS_NAME_HTON OPAL_PROCESS_NAME_HTON
#define OMPI_PROCESS_NAME_NTOH OPAL_PROCESS_NAME_NTOH

#if OPAL_ENABLE_DEBUG
static inline opal_process_name_t * OMPI_CAST_RTE_NAME(opal_process_name_t * name) {
    return (opal_process_name_t *)name;
}
#else
#define OMPI_CAST_RTE_NAME(a) ((opal_process_name_t*)(a))
#endif

/* Process info struct and values */
#define ompi_process_info opal_process_info
#define ompi_rte_proc_is_bound opal_process_info.proc_is_bound

/* Error handling objects and operations */
OMPI_DECLSPEC void __opal_attribute_noreturn__
  ompi_rte_abort(int error_code, char *fmt, ...);
OMPI_DECLSPEC void ompi_rte_abort_peers(opal_process_name_t *procs,
                                        int32_t num_procs,
                                        int error_code);
#define OMPI_ERROR_LOG OPAL_ERROR_LOG

/* Init and finalize operations */
OMPI_DECLSPEC int ompi_rte_init(int *argc, char ***argv);
OMPI_DECLSPEC int ompi_rte_finalize(void);
OMPI_DECLSPEC void ompi_rte_wait_for_debugger(void);

/* In a few places, we need to barrier until something happens
 * that changes a flag to indicate we can release - e.g., waiting
 * for a specific RTE message to arrive. We don't want to block MPI
 * progress while waiting, so we loop over opal_progress, letting
 * the RTE progress thread move the RTE along
 */
#define OMPI_WAIT_FOR_COMPLETION(flg)                                       \
    do {                                                                    \
        while ((flg)) {                                                     \
            opal_progress();                                                \
        }                                                                   \
    }while(0);

#define OMPI_LAZY_WAIT_FOR_COMPLETION(flg)                                  \
    do {                                                                    \
        while ((flg)) {                                                     \
            opal_progress();                                                \
            usleep(100);                                                    \
        }                                                                   \
    }while(0);

END_C_DECLS

#endif /* OMPI_RTE_H_ */