This source file includes following definitions.
- portals4_init_interface
- create_maptable
- create_endpoint
- ompi_mtl_portals4_get_proc_group
- add_endpoints
- ompi_mtl_portals4_add_procs
- ompi_mtl_portals4_del_procs
- ompi_mtl_portals4_finalize
- ompi_mtl_portals4_add_comm
- ompi_mtl_portals4_del_comm
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21 #include "ompi_config.h"
22
23 #include <portals4.h>
24
25 #include "ompi/communicator/communicator.h"
26 #include "ompi/proc/proc.h"
27 #include "ompi/mca/mtl/mtl.h"
28 #include "opal/class/opal_list.h"
29 #include "opal/mca/pmix/pmix.h"
30
31 #include "mtl_portals4.h"
32 #include "mtl_portals4_recv_short.h"
33
34 extern mca_mtl_base_component_2_0_0_t mca_mtl_portals4_component;
35
36 mca_mtl_portals4_module_t ompi_mtl_portals4 = {
37 {
38 8191,
39 (1UL << 30),
40 0,
41 0,
42
43 ompi_mtl_portals4_add_procs,
44 ompi_mtl_portals4_del_procs,
45 ompi_mtl_portals4_finalize,
46
47 ompi_mtl_portals4_send,
48 ompi_mtl_portals4_isend,
49 ompi_mtl_portals4_irecv,
50 ompi_mtl_portals4_iprobe,
51 ompi_mtl_portals4_imrecv,
52 ompi_mtl_portals4_improbe,
53
54 ompi_mtl_portals4_cancel,
55 ompi_mtl_portals4_add_comm,
56 ompi_mtl_portals4_del_comm
57 }
58 };
59
60 static int
61 portals4_init_interface(void)
62 {
63 unsigned int ret;
64 ptl_md_t md;
65 ptl_me_t me;
66
67
68 ret = PtlEQAlloc(ompi_mtl_portals4.ni_h,
69 ompi_mtl_portals4.send_queue_size,
70 &ompi_mtl_portals4.send_eq_h);
71 if (PTL_OK != ret) {
72 opal_output_verbose(1, ompi_mtl_base_framework.framework_output,
73 "%s:%d: PtlEQAlloc failed: %d\n",
74 __FILE__, __LINE__, ret);
75 goto error;
76 }
77 ret = PtlEQAlloc(ompi_mtl_portals4.ni_h,
78 ompi_mtl_portals4.recv_queue_size,
79 &ompi_mtl_portals4.recv_eq_h);
80 if (PTL_OK != ret) {
81 opal_output_verbose(1, ompi_mtl_base_framework.framework_output,
82 "%s:%d: PtlEQAlloc failed: %d\n",
83 __FILE__, __LINE__, ret);
84 goto error;
85 }
86
87
88 ret = PtlPTAlloc(ompi_mtl_portals4.ni_h,
89 #if OMPI_MTL_PORTALS4_FLOW_CONTROL
90 PTL_PT_FLOWCTRL |
91 #endif
92 PTL_PT_ONLY_USE_ONCE |
93 PTL_PT_ONLY_TRUNCATE,
94 ompi_mtl_portals4.recv_eq_h,
95 REQ_RECV_TABLE_ID,
96 &ompi_mtl_portals4.recv_idx);
97 if (PTL_OK != ret) {
98 opal_output_verbose(1, ompi_mtl_base_framework.framework_output,
99 "%s:%d: PtlPTAlloc failed: %d\n",
100 __FILE__, __LINE__, ret);
101 goto error;
102 }
103 if (ompi_mtl_portals4.recv_idx != REQ_RECV_TABLE_ID) {
104 opal_output_verbose(1, ompi_mtl_base_framework.framework_output,
105 "%s:%d: PtlPTAlloc did not allocate the requested PT: %d\n",
106 __FILE__, __LINE__, ompi_mtl_portals4.recv_idx);
107 goto error;
108 }
109
110 ret = PtlPTAlloc(ompi_mtl_portals4.ni_h,
111 PTL_PT_ONLY_USE_ONCE |
112 PTL_PT_ONLY_TRUNCATE,
113 ompi_mtl_portals4.send_eq_h,
114 REQ_READ_TABLE_ID,
115 &ompi_mtl_portals4.read_idx);
116 if (PTL_OK != ret) {
117 opal_output_verbose(1, ompi_mtl_base_framework.framework_output,
118 "%s:%d: PtlPTAlloc failed: %d\n",
119 __FILE__, __LINE__, ret);
120 goto error;
121 }
122 if (ompi_mtl_portals4.read_idx != REQ_READ_TABLE_ID) {
123 opal_output_verbose(1, ompi_mtl_base_framework.framework_output,
124 "%s:%d: PtlPTAlloc did not allocate the requested PT: %d\n",
125 __FILE__, __LINE__, ompi_mtl_portals4.read_idx);
126 goto error;
127 }
128
129
130 md.start = NULL;
131 md.length = 0;
132 md.options = 0;
133 md.eq_handle = PTL_EQ_NONE;
134 md.ct_handle = PTL_CT_NONE;
135
136 ret = PtlMDBind(ompi_mtl_portals4.ni_h,
137 &md,
138 &ompi_mtl_portals4.zero_md_h);
139 if (PTL_OK != ret) {
140 opal_output_verbose(1, ompi_mtl_base_framework.framework_output,
141 "%s:%d: PtlMDBind failed: %d\n",
142 __FILE__, __LINE__, ret);
143 goto error;
144 }
145
146
147 md.start = 0;
148 md.length = PTL_SIZE_MAX;
149 md.options = 0;
150 md.eq_handle = ompi_mtl_portals4.send_eq_h;
151 md.ct_handle = PTL_CT_NONE;
152
153 ret = PtlMDBind(ompi_mtl_portals4.ni_h,
154 &md,
155 &ompi_mtl_portals4.send_md_h);
156 if (PTL_OK != ret) {
157 opal_output_verbose(1, ompi_mtl_base_framework.framework_output,
158 "%s:%d: PtlMDBind failed: %d\n",
159 __FILE__, __LINE__, ret);
160 goto error;
161 }
162
163
164 me.start = NULL;
165 me.length = 0;
166 me.ct_handle = PTL_CT_NONE;
167 me.min_free = 0;
168 me.uid = ompi_mtl_portals4.uid;
169 me.options = PTL_ME_OP_PUT |
170 PTL_ME_EVENT_LINK_DISABLE |
171 PTL_ME_EVENT_COMM_DISABLE |
172 PTL_ME_EVENT_UNLINK_DISABLE;
173 if (ompi_mtl_portals4.use_logical) {
174 me.match_id.rank = PTL_RANK_ANY;
175 } else {
176 me.match_id.phys.nid = PTL_NID_ANY;
177 me.match_id.phys.pid = PTL_PID_ANY;
178 }
179 me.match_bits = MTL_PORTALS4_LONG_MSG;
180 me.ignore_bits = MTL_PORTALS4_CONTEXT_MASK |
181 MTL_PORTALS4_SOURCE_MASK |
182 MTL_PORTALS4_TAG_MASK;
183 ret = PtlMEAppend(ompi_mtl_portals4.ni_h,
184 ompi_mtl_portals4.recv_idx,
185 &me,
186 PTL_OVERFLOW_LIST,
187 NULL,
188 &ompi_mtl_portals4.long_overflow_me_h);
189 if (PTL_OK != ret) {
190 opal_output_verbose(1, ompi_mtl_base_framework.framework_output,
191 "%s:%d: PtlMEAppend failed: %d\n",
192 __FILE__, __LINE__, ret);
193 goto error;
194 }
195
196
197 ret = ompi_mtl_portals4_recv_short_init();
198 if (OMPI_SUCCESS != ret) {
199 opal_output_verbose(1, ompi_mtl_base_framework.framework_output,
200 "%s:%d: short receive block initialization failed: %d\n",
201 __FILE__, __LINE__, ret);
202 goto error;
203 }
204
205 ompi_mtl_portals4.opcount = 0;
206 #if OPAL_ENABLE_DEBUG
207 ompi_mtl_portals4.recv_opcount = 0;
208 #endif
209
210 #if OMPI_MTL_PORTALS4_FLOW_CONTROL
211 ret = ompi_mtl_portals4_flowctl_init();
212 if (OMPI_SUCCESS != ret) {
213 opal_output_verbose(1, ompi_mtl_base_framework.framework_output,
214 "%s:%d: ompi_mtl_portals4_flowctl_init failed: %d\n",
215 __FILE__, __LINE__, ret);
216 goto error;
217 }
218 #endif
219
220 return OMPI_SUCCESS;
221
222 error:
223 if (!PtlHandleIsEqual(ompi_mtl_portals4.long_overflow_me_h, PTL_INVALID_HANDLE)) {
224 PtlMEUnlink(ompi_mtl_portals4.long_overflow_me_h);
225 }
226 if (!PtlHandleIsEqual(ompi_mtl_portals4.zero_md_h, PTL_INVALID_HANDLE)) {
227 PtlMDRelease(ompi_mtl_portals4.zero_md_h);
228 }
229 if (!PtlHandleIsEqual(ompi_mtl_portals4.send_md_h, PTL_INVALID_HANDLE)) {
230 PtlMDRelease(ompi_mtl_portals4.send_md_h);
231 }
232 if (ompi_mtl_portals4.read_idx != (ptl_pt_index_t) ~0UL) {
233 PtlPTFree(ompi_mtl_portals4.ni_h, ompi_mtl_portals4.read_idx);
234 }
235 if (ompi_mtl_portals4.recv_idx != (ptl_pt_index_t) ~0UL) {
236 PtlPTFree(ompi_mtl_portals4.ni_h, ompi_mtl_portals4.recv_idx);
237 }
238 if (!PtlHandleIsEqual(ompi_mtl_portals4.send_eq_h, PTL_INVALID_HANDLE)) {
239 PtlEQFree(ompi_mtl_portals4.send_eq_h);
240 }
241 if (!PtlHandleIsEqual(ompi_mtl_portals4.recv_eq_h, PTL_INVALID_HANDLE)) {
242 PtlEQFree(ompi_mtl_portals4.recv_eq_h);
243 }
244 return OMPI_ERROR;
245 }
246
247 static int
248 create_maptable(size_t nprocs,
249 ompi_proc_t **procs)
250 {
251 int ret;
252 size_t i;
253 ptl_process_t *maptable;
254
255 maptable = malloc(sizeof(ptl_process_t) * nprocs);
256 if (NULL == maptable) {
257 opal_output_verbose(1, ompi_mtl_base_framework.framework_output,
258 "%s:%d: malloc failed\n",
259 __FILE__, __LINE__);
260 return OMPI_ERR_OUT_OF_RESOURCE;
261 }
262
263 for (i=0;i<nprocs;i++) {
264 ptl_process_t *modex_id;
265 size_t size;
266
267 OPAL_MODEX_RECV(ret, &mca_mtl_portals4_component.mtl_version,
268 &procs[i]->super.proc_name, (uint8_t**)&modex_id, &size);
269 if (OMPI_SUCCESS != ret) {
270 opal_output_verbose(1, ompi_mtl_base_framework.framework_output,
271 "%s:%d: ompi_modex_recv failed: %d\n",
272 __FILE__, __LINE__, ret);
273 return ret;
274 } else if (sizeof(ptl_process_t) != size) {
275 opal_output_verbose(1, ompi_mtl_base_framework.framework_output,
276 "%s:%d: ompi_modex_recv failed: %d\n",
277 __FILE__, __LINE__, ret);
278 return OMPI_ERR_BAD_PARAM;
279 }
280
281 maptable[i].phys.pid = modex_id->phys.pid;
282 maptable[i].phys.nid = modex_id->phys.nid;
283 opal_output_verbose(50, ompi_mtl_base_framework.framework_output,
284 "logical: global rank=%d pid=%x nid=%x\n",
285 (int)i, maptable[i].phys.pid, maptable[i].phys.nid);
286 }
287
288 ret = PtlSetMap(ompi_mtl_portals4.ni_h, nprocs, maptable);
289 if (OMPI_SUCCESS != ret) {
290 opal_output_verbose(1, ompi_mtl_base_framework.framework_output,
291 "%s:%d: logical mapping failed: %d\n",
292 __FILE__, __LINE__, ret);
293 return ret;
294 }
295 opal_output_verbose(1, ompi_mtl_base_framework.framework_output,
296 "logical mapping OK\n");
297
298 free(maptable);
299
300 return OMPI_SUCCESS;
301 }
302
303 static int
304 create_endpoint(ompi_proc_t *proc)
305 {
306 ptl_process_t *endpoint;
307
308 endpoint = malloc(sizeof(ptl_process_t));
309 if (NULL == endpoint) {
310 opal_output_verbose(1, ompi_mtl_base_framework.framework_output,
311 "%s:%d: malloc failed: %s\n",
312 __FILE__, __LINE__, strerror(errno));
313 return OMPI_ERR_OUT_OF_RESOURCE;
314 } else {
315 if (ompi_mtl_portals4.use_logical) {
316 endpoint->phys.nid = 0;
317 endpoint->phys.pid = 0;
318 endpoint->rank = proc->super.proc_name.vpid;
319 } else {
320 int ret;
321 ptl_process_t *modex_id;
322 size_t size;
323
324 OPAL_MODEX_RECV(ret, &mca_mtl_portals4_component.mtl_version,
325 &proc->super.proc_name, (uint8_t**)&modex_id, &size);
326 if (OMPI_SUCCESS != ret) {
327 opal_output_verbose(1, ompi_mtl_base_framework.framework_output,
328 "%s:%d: ompi_modex_recv failed: %d\n",
329 __FILE__, __LINE__, ret);
330 return ret;
331 } else if (sizeof(ptl_process_t) != size) {
332 opal_output_verbose(1, ompi_mtl_base_framework.framework_output,
333 "%s:%d: ompi_modex_recv failed (size mismatch): %d\n",
334 __FILE__, __LINE__, ret);
335 return OMPI_ERR_BAD_PARAM;
336 }
337
338 *endpoint = *modex_id;
339 }
340 }
341
342 proc->proc_endpoints[OMPI_PROC_ENDPOINT_TAG_PORTALS4] = endpoint;
343
344 return OMPI_SUCCESS;
345 }
346
347 ompi_proc_t *
348 ompi_mtl_portals4_get_proc_group(struct ompi_group_t *group, int rank)
349 {
350 int ret;
351
352 ompi_proc_t *proc = ompi_group_peer_lookup (group, rank);
353 if (NULL == proc->proc_endpoints[OMPI_PROC_ENDPOINT_TAG_PORTALS4]) {
354 ret = create_endpoint(proc);
355 if (OMPI_SUCCESS != ret) {
356 return NULL;
357 }
358 #if 0
359 } else {
360
361
362
363 int ret;
364 ptl_process_t *modex_id;
365 size_t size;
366
367 OPAL_MODEX_RECV(ret, &mca_mtl_portals4_component.mtl_version,
368 &proc->super.proc_name, (uint8_t**)&modex_id, &size);
369
370 ptl_process_t *peer = (ptl_process_t*) proc->proc_endpoints[OMPI_PROC_ENDPOINT_TAG_PORTALS4];
371 if (ompi_mtl_portals4.use_logical) {
372 if ((size_t)peer->rank != proc->super.proc_name.vpid) {
373 opal_output_verbose(1, ompi_mtl_base_framework.framework_output,
374 "%s:%d: existing peer and rank don't match\n",
375 __FILE__, __LINE__);
376 return OMPI_ERROR;
377 }
378 }
379 else if (peer->phys.nid != modex_id->phys.nid ||
380 peer->phys.pid != modex_id->phys.pid) {
381 opal_output_verbose(1, ompi_mtl_base_framework.framework_output,
382 "%s:%d: existing peer and modex peer don't match\n",
383 __FILE__, __LINE__);
384 return OMPI_ERROR;
385 }
386 #endif
387 }
388
389 return proc;
390 }
391
392 static int
393 add_endpoints(size_t nprocs,
394 ompi_proc_t **procs)
395 {
396 int ret;
397 size_t i;
398
399
400 for (i = 0 ; i < nprocs ; ++i) {
401 if (procs[i]->super.proc_arch != ompi_proc_local()->super.proc_arch) {
402 opal_output_verbose(1, ompi_mtl_base_framework.framework_output,
403 "Portals 4 MTL does not support heterogeneous operations.");
404 opal_output_verbose(1, ompi_mtl_base_framework.framework_output,
405 "Proc %s architecture %x, mine %x.",
406 OMPI_NAME_PRINT(&procs[i]->super.proc_name),
407 procs[i]->super.proc_arch, ompi_proc_local()->super.proc_arch);
408 return OMPI_ERR_NOT_SUPPORTED;
409 }
410
411 if (NULL == procs[i]->proc_endpoints[OMPI_PROC_ENDPOINT_TAG_PORTALS4]) {
412 ret = create_endpoint(procs[i]);
413 if (OMPI_SUCCESS != ret) {
414 return ret;
415 }
416 #if 0
417 } else {
418
419
420
421 int ret;
422 ptl_process_t *modex_id;
423 size_t size;
424
425 OPAL_MODEX_RECV(ret, &mca_mtl_portals4_component.mtl_version,
426 &procs[i]->super.proc_name, (uint8_t**)&modex_id, &size);
427
428 ptl_process_t *proc = (ptl_process_t*) procs[i]->proc_endpoints[OMPI_PROC_ENDPOINT_TAG_PORTALS4];
429 if (ompi_mtl_portals4.use_logical) {
430 if ((size_t)proc->rank != procs[i]->super.proc_name.vpid) {
431 opal_output_verbose(1, ompi_mtl_base_framework.framework_output,
432 "%s:%d: existing peer and rank don't match\n",
433 __FILE__, __LINE__);
434 return OMPI_ERROR;
435 }
436 }
437 else if (proc->phys.nid != modex_id->phys.nid ||
438 proc->phys.pid != modex_id->phys.pid) {
439 opal_output_verbose(1, ompi_mtl_base_framework.framework_output,
440 "%s:%d: existing peer and modex peer don't match\n",
441 __FILE__, __LINE__);
442 return OMPI_ERROR;
443 }
444 #endif
445 }
446 }
447
448 return OMPI_SUCCESS;
449 }
450
451 #define NEED_ALL_PROCS (ompi_mtl_portals4.use_logical || ompi_mtl_portals4.use_flowctl)
452
453 int
454 ompi_mtl_portals4_add_procs(struct mca_mtl_base_module_t *mtl,
455 size_t nprocs,
456 struct ompi_proc_t** procs)
457 {
458 int ret;
459
460
461
462
463
464 ret = add_endpoints(nprocs,
465 procs);
466 if (OMPI_SUCCESS != ret) {
467 opal_output_verbose(1, ompi_mtl_base_framework.framework_output,
468 "%s:%d: add_endpoints failed: %d\n",
469 __FILE__, __LINE__, ret);
470 return ret;
471 }
472
473 if (1 == ompi_mtl_portals4.need_init) {
474 if (1 == ompi_mtl_portals4.use_logical) {
475 ret = create_maptable(nprocs, procs);
476 if (OMPI_SUCCESS != ret) {
477 opal_output_verbose(1, ompi_mtl_base_framework.framework_output,
478 "%s:%d: ompi_mtl_portals4_add_procs::create_maptable() failed: %d\n",
479 __FILE__, __LINE__, ret);
480 return ret;
481 }
482 }
483
484
485
486
487
488 portals4_init_interface();
489
490
491 ret = opal_progress_register(ompi_mtl_portals4_progress);
492 if (OMPI_SUCCESS != ret) {
493 opal_output_verbose(1, ompi_mtl_base_framework.framework_output,
494 "%s:%d: opal_progress_register failed: %d\n",
495 __FILE__, __LINE__, ret);
496 return ret;
497 }
498
499 #if OMPI_MTL_PORTALS4_FLOW_CONTROL
500 opal_output_verbose(50, ompi_mtl_base_framework.framework_output,
501 "add_procs() - me=%d\n", ompi_proc_local_proc->super.proc_name.vpid);
502
503 opal_output_verbose(50, ompi_mtl_base_framework.framework_output,
504 "add_procs() - adding flowctl procs\n");
505
506 ret = ompi_mtl_portals4_flowctl_add_procs(ompi_proc_local_proc->super.proc_name.vpid,
507 nprocs,
508 procs);
509 if (OMPI_SUCCESS != ret) {
510 opal_output_verbose(1, ompi_mtl_base_framework.framework_output,
511 "%s:%d: flowctl_add_procs failed: %d\n",
512 __FILE__, __LINE__, ret);
513 return ret;
514 }
515 #endif
516
517 ompi_mtl_portals4.need_init = 0;
518 }
519
520 return OMPI_SUCCESS;
521 }
522
523
524 int
525 ompi_mtl_portals4_del_procs(struct mca_mtl_base_module_t *mtl,
526 size_t nprocs,
527 struct ompi_proc_t** procs)
528 {
529 size_t i;
530
531 opal_output_verbose(50, ompi_mtl_base_framework.framework_output,
532 "del_procs() - enter\n");
533
534 for (i = 0 ; i < nprocs ; ++i) {
535 if (NULL != procs[i]->proc_endpoints[OMPI_PROC_ENDPOINT_TAG_PORTALS4]) {
536 free(procs[i]->proc_endpoints[OMPI_PROC_ENDPOINT_TAG_PORTALS4]);
537 procs[i]->proc_endpoints[OMPI_PROC_ENDPOINT_TAG_PORTALS4] = NULL;
538 }
539 }
540
541 opal_output_verbose(50, ompi_mtl_base_framework.framework_output,
542 "del_procs() - exit\n");
543
544 return OMPI_SUCCESS;
545 }
546
547
548 int
549 ompi_mtl_portals4_finalize(struct mca_mtl_base_module_t *mtl)
550 {
551 if (0 == ompi_mtl_portals4.need_init) {
552 opal_progress_unregister(ompi_mtl_portals4_progress);
553 while (0 != ompi_mtl_portals4_progress()) { }
554 }
555
556 #if OMPI_MTL_PORTALS4_FLOW_CONTROL
557 ompi_mtl_portals4_flowctl_fini();
558 #endif
559 ompi_mtl_portals4_recv_short_fini();
560
561 if (!PtlHandleIsEqual(ompi_mtl_portals4.long_overflow_me_h, PTL_INVALID_HANDLE)) {
562 PtlMEUnlink(ompi_mtl_portals4.long_overflow_me_h);
563 }
564 if (!PtlHandleIsEqual(ompi_mtl_portals4.zero_md_h, PTL_INVALID_HANDLE)) {
565 PtlMDRelease(ompi_mtl_portals4.zero_md_h);
566 }
567 if (!PtlHandleIsEqual(ompi_mtl_portals4.send_md_h, PTL_INVALID_HANDLE)) {
568 PtlMDRelease(ompi_mtl_portals4.send_md_h);
569 }
570 if (ompi_mtl_portals4.read_idx != (ptl_pt_index_t) ~0UL) {
571 PtlPTFree(ompi_mtl_portals4.ni_h, ompi_mtl_portals4.read_idx);
572 }
573 if (ompi_mtl_portals4.recv_idx != (ptl_pt_index_t) ~0UL) {
574 PtlPTFree(ompi_mtl_portals4.ni_h, ompi_mtl_portals4.recv_idx);
575 }
576 if (!PtlHandleIsEqual(ompi_mtl_portals4.send_eq_h, PTL_INVALID_HANDLE)) {
577 PtlEQFree(ompi_mtl_portals4.send_eq_h);
578 }
579 if (!PtlHandleIsEqual(ompi_mtl_portals4.recv_eq_h, PTL_INVALID_HANDLE)) {
580 PtlEQFree(ompi_mtl_portals4.recv_eq_h);
581 }
582 if (!PtlHandleIsEqual(ompi_mtl_portals4.ni_h, PTL_INVALID_HANDLE)) {
583 PtlNIFini(ompi_mtl_portals4.ni_h);
584 }
585
586 PtlFini();
587
588 return OMPI_SUCCESS;
589 }
590
591
592 int
593 ompi_mtl_portals4_add_comm(struct mca_mtl_base_module_t *mtl,
594 struct ompi_communicator_t *comm)
595 {
596 return OMPI_SUCCESS;
597 }
598
599 int
600 ompi_mtl_portals4_del_comm(struct mca_mtl_base_module_t *mtl,
601 struct ompi_communicator_t *comm)
602 {
603 return OMPI_SUCCESS;
604 }