File: ofi_hook.h

package info (click to toggle)
mpich 5.0.0-1
  • links: PTS, VCS
  • area: main
  • in suites: experimental
  • size: 251,828 kB
  • sloc: ansic: 1,323,147; cpp: 82,869; f90: 72,420; javascript: 40,763; perl: 28,296; sh: 19,399; python: 16,191; xml: 14,418; makefile: 9,468; fortran: 8,046; java: 4,635; pascal: 352; asm: 324; ruby: 176; awk: 27; lisp: 19; php: 8; sed: 4
file content (323 lines) | stat: -rw-r--r-- 9,615 bytes parent folder | download | duplicates (4)
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
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
/*
 * Copyright (c) 2018-2019 Intel Corporation. All rights reserved.
 *
 * This software is available to you under a choice of one of two
 * licenses.  You may choose to be licensed under the terms of the GNU
 * General Public License (GPL); Version 2, available from the file
 * COPYING in the main directory of this source tree, or the
 * BSD license below:
 *
 *     Redistribution and use in source and binary forms, with or
 *     without modification, are permitted provided that the following
 *     conditions are met:
 *
 *      - Redistributions of source code must retain the above
 *        copyright notice, this list of conditions and the following
 *        disclaimer.
 *
 *      - Redistributions in binary form must reproduce the above
 *        copyright notice, this list of conditions and the following
 *        disclaimer in the documentation and/or other materials
 *        provided with the distribution.
 *
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
 * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
 * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
 * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
 * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
 * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
 * SOFTWARE.
 */

#ifndef _OFI_HOOK_H_
#define _OFI_HOOK_H_

#include <assert.h>

#include <rdma/fabric.h>
#include <rdma/fi_atomic.h>
#include <rdma/fi_collective.h>
#include <rdma/fi_cm.h>
#include <rdma/fi_domain.h>
#include <rdma/fi_endpoint.h>
#include <rdma/fi_eq.h>
#include <rdma/fi_rma.h>
#include <rdma/fi_tagged.h>

#include <ofi.h>
#include <rdma/providers/fi_prov.h>

/* This field needs to be updated whenever new FI class is added in fabric.h */
#define HOOK_FI_CLASS_MAX (FI_CLASS_NIC + 1)

/*
 * Hooks are installed from top down.
 * Values must start at 0 and increment by one.
 */
// TODO figure out how to remove this now that we have ini/fini calls
enum ofi_hook_class {
	HOOK_NOOP,
	HOOK_PERF,
	HOOK_TRACE,
	HOOK_PROFILE,
	HOOK_DEBUG,
	HOOK_HMEM,
	HOOK_DMABUF_PEER_MEM,
};


/*
 * Default fi_ops members, can be used to construct custom fi_ops
 */
int hook_close(struct fid *fid);
int hook_bind(struct fid *fid, struct fid *bfid, uint64_t flags);
int hook_control(struct fid *fid, int command, void *arg);
int hook_ops_open(struct fid *fid, const char *name,
		  uint64_t flags, void **ops, void *context);

/*
 * Define hook structs so we can cast from fid to parent using simple cast.
 * This lets us have a single close() call.
 */

extern struct fi_ops hook_fid_ops;
struct fid *hook_to_hfid(const struct fid *fid);
struct fid_wait *hook_to_hwait(const struct fid_wait *wait);

/*
 * TODO
 * comment from GitHub PR #5052:
 * "another option would be to store the ini/fini calls in a separate structure
 * that we reference from struct ofi_prov_context. We could even extend the
 * definition of ofi_prov_context with a union that is accessed based on the
 * prov_type. That might work better if we want to support external hooks,
 * without the external hook provider needing to implement everything"
 */
struct hook_prov_ctx {
	struct fi_provider	prov;
	/*
	 * Hooking providers can override ini/fini calls of a specific fid class
	 * to override any initializations that the common code may have done.
	 * For example, this allows overriding any specific op and not having to
	 * hook into every resource creation call until the point where the op
	 * can be overridden. Refer to hook_perf for an example.
	 *
	 * Note: if a hooking provider overrides any of the resource creation calls
	 * (e.g. fi_endpoint) directly, then these ini/fini calls won't be
	 * invoked. */
	int 			(*ini_fid[HOOK_FI_CLASS_MAX])(struct fid *fid);
	int 			(*fini_fid[HOOK_FI_CLASS_MAX])(struct fid *fid);
};

/*
 * TODO
 * comment from GitHub PR #5052:
 * "We could set all ini/fini calls to a no-op as part of hook initialization
 * to avoid this check"
 */
static inline int hook_ini_fid(struct hook_prov_ctx *prov_ctx, struct fid *fid)
{
	return (prov_ctx->ini_fid[fid->fclass] ?
		prov_ctx->ini_fid[fid->fclass](fid) : 0);
}

static inline int hook_fini_fid(struct hook_prov_ctx *prov_ctx, struct fid *fid)
{
	return (prov_ctx->fini_fid[fid->fclass] ?
		prov_ctx->fini_fid[fid->fclass](fid) : 0);
}

struct hook_fabric {
	struct fid_fabric	fabric;
	struct fid_fabric	*hfabric;
	enum ofi_hook_class	hclass;
	struct fi_provider	*hprov;
	struct hook_prov_ctx	*prov_ctx;
};

void hook_fabric_init(struct hook_fabric *fabric, enum ofi_hook_class hclass,
		      struct fid_fabric *hfabric, struct fi_provider *hprov,
		      struct fi_ops *f_ops, struct hook_prov_ctx *prov_ctx);

struct hook_fabric *hook_to_fabric(const struct fid *fid);

static inline struct hook_prov_ctx *hook_to_prov_ctx(const struct fid *fid)
{
	return (hook_to_fabric(fid))->prov_ctx;
}

static inline struct fi_provider *
hook_fabric_to_hprov(const struct hook_fabric *fabric)
{
	return fabric->hprov;
}

static inline struct fi_provider *hook_to_hprov(const struct fid *fid)
{
	return hook_fabric_to_hprov(hook_to_fabric(fid));
}

struct ofi_ops_flow_ctrl;

struct hook_domain {
	struct fid_domain domain;
	struct fid_domain *hdomain;
	struct hook_fabric *fabric;
	struct ofi_ops_flow_ctrl *base_ops_flow_ctrl;
	ssize_t (*base_credit_handler)(struct fid_ep *ep_fid, uint64_t credits);
};

int hook_domain_init(struct fid_fabric *fabric, struct fi_info *info,
		     struct fid_domain **domain, void *context,
		     struct hook_domain *dom);
int hook_domain(struct fid_fabric *fabric, struct fi_info *info,
		struct fid_domain **domain, void *context);


struct hook_av {
	struct fid_av av;
	struct fid_av *hav;
	struct hook_domain *domain;
};

int hook_av_open(struct fid_domain *domain, struct fi_av_attr *attr,
		 struct fid_av **av, void *context);


struct hook_wait {
	struct fid_wait wait;
	struct fid_wait *hwait;
	struct hook_fabric *fabric;
};

int hook_wait_open(struct fid_fabric *fabric, struct fi_wait_attr *attr,
		   struct fid_wait **waitset);
int hook_trywait(struct fid_fabric *fabric, struct fid **fids, int count);


struct hook_poll {
	struct fid_poll poll;
	struct fid_poll *hpoll;
	struct hook_domain *domain;
};

int hook_poll_open(struct fid_domain *domain, struct fi_poll_attr *attr,
		   struct fid_poll **pollset);

/*
 * EQ
 */

extern struct fi_ops_eq hook_eq_ops;

struct hook_eq {
	struct fid_eq eq;
	struct fid_eq *heq;
	struct hook_fabric *fabric;
};

ssize_t hook_eq_read(struct fid_eq *eq, uint32_t *event,
			    void *buf, size_t len, uint64_t flags);
ssize_t hook_eq_sread(struct fid_eq *eq, uint32_t *event,
			     void *buf, size_t len, int timeout, uint64_t flags);
int hook_eq_init(struct fid_fabric *fabric, struct fi_eq_attr *attr,
		 struct fid_eq **eq, void *context, struct hook_eq *myeq);
int hook_eq_open(struct fid_fabric *fabric, struct fi_eq_attr *attr,
		 struct fid_eq **eq, void *context);

/*
 * CQ
 */

struct hook_cq {
	struct fid_cq cq;
	struct fid_cq *hcq;
	struct hook_domain *domain;
	void *context;
	enum fi_cq_format format;
};

int hook_cq_init(struct fid_domain *domain, struct fi_cq_attr *attr,
		 struct fid_cq **cq, void *context, struct hook_cq *mycq);
int hook_cq_open(struct fid_domain *domain, struct fi_cq_attr *attr,
		 struct fid_cq **cq, void *context);
const char *
hook_cq_strerror(struct fid_cq *cq, int prov_errno,
		 const void *err_data, char *buf, size_t len);

struct hook_cntr {
	struct fid_cntr cntr;
	struct fid_cntr *hcntr;
	struct hook_domain *domain;
};

int hook_cntr_open(struct fid_domain *domain, struct fi_cntr_attr *attr,
		   struct fid_cntr **cntr, void *context);


struct hook_ep {
	struct fid_ep ep;
	struct fid_ep *hep;
	struct hook_domain *domain;
	void *context;
};

int hook_endpoint_init(struct fid_domain *domain, struct fi_info *info,
		       struct fid_ep **ep, void *context, struct hook_ep *myep);
int hook_endpoint(struct fid_domain *domain, struct fi_info *info,
		  struct fid_ep **ep, void *context);
int hook_scalable_ep(struct fid_domain *domain, struct fi_info *info,
		     struct fid_ep **sep, void *context);
int hook_srx_ctx(struct fid_domain *domain,
		 struct fi_rx_attr *attr, struct fid_ep **rx_ep,
		 void *context);

int hook_query_atomic(struct fid_domain *domain, enum fi_datatype datatype,
		  enum fi_op op, struct fi_atomic_attr *attr, uint64_t flags);
int hook_query_collective(struct fid_domain *domain, enum fi_collective_op coll,
			  struct fi_collective_attr *attr, uint64_t flags);

extern struct fi_ops hook_fabric_fid_ops;
extern struct fi_ops hook_domain_fid_ops;
extern struct fi_ops_fabric hook_fabric_ops;
extern struct fi_ops_domain hook_domain_ops;
extern struct fi_ops_cq hook_cq_ops;
extern struct fi_ops_cntr hook_cntr_ops;

extern struct fi_ops_cm hook_cm_ops;
extern struct fi_ops_msg hook_msg_ops;
extern struct fi_ops_rma hook_rma_ops;
extern struct fi_ops_tagged hook_tagged_ops;
extern struct fi_ops_atomic hook_atomic_ops;


struct hook_pep {
	struct fid_pep pep;
	struct fid_pep *hpep;
	struct hook_fabric *fabric;
};

int hook_passive_ep(struct fid_fabric *fabric, struct fi_info *info,
		    struct fid_pep **pep, void *context);


struct hook_stx {
	struct fid_stx stx;
	struct fid_stx *hstx;
	struct hook_domain *domain;
};

int hook_stx_ctx(struct fid_domain *domain,
		 struct fi_tx_attr *attr, struct fid_stx **stx,
		 void *context);


struct hook_mr {
	struct fid_mr mr;
	struct fid_mr *hmr;
	struct hook_domain *domain;
};


#endif /* _OFI_HOOK_H_ */