OpenMPI 0.1.1

- Main Page
- Related Pages
- Modules
- Data Structures
- Files

- File List
- Globals

common_ugni.h
1 /* -*- Mode: C; c-basic-offset:4 ; indent-tabs-mode:nil -*- */
2 /*
3 * Copyright (c) 2011-2012 Los Alamos National Security, LLC. All rights
4 * reserved.
5 * Copyright (c) 2011 UT-Battelle, LLC. All rights reserved.
6 * $COPYRIGHT$
7 *
8 * Additional copyrights may follow
9 *
10 * $HEADER$
11 */
12
13 #include "ompi_config.h"
14
15 #include "opal/util/output.h"
16 #include "opal/class/opal_list.h"
17 #include "opal/include/opal/prefetch.h"
18 #include "opal_stdint.h"
19
20 #include "ompi/include/ompi/constants.h"
21 #include "ompi/runtime/ompi_module_exchange.h"
22 #include "ompi/proc/proc.h"
23
24 #include <errno.h>
25 #include <stdint.h>
26 #include <sys/types.h>
27 #include <assert.h>
28 #include <sys/time.h>
29 #include <gni_pub.h>
30
31 #include "common_ugni_ep.h"
32
33 #if !defined(MPI_COMMON_UGNI_H)
34 #define MPI_COMMON_UGNI_H
35
36 struct ompi_common_ugni_modex_t {
37 uint32_t addr;
38 int id;
39 };
40 typedef struct ompi_common_ugni_modex_t ompi_common_ugni_modex_t;
41
42 struct ompi_common_ugni_device_t {
43 opal_object_t super;
44
45 gni_nic_handle_t dev_handle;
46
47 /* Minor number of the Gemini NIC */
48 int32_t dev_id;
49 uint32_t dev_pe_addr;
50 uint32_t dev_addr;
51 uint32_t dev_cpu_id;
52
53 gni_cq_handle_t dev_local_cq;
54
55 size_t dev_ep_count;
56 ompi_common_ugni_endpoint_t **dev_eps;
57 void *btl_ctx;
58 };
59 typedef struct ompi_common_ugni_device_t ompi_common_ugni_device_t;
60
61 struct ompi_common_ugni_module_t {
62 /* protection tag */
63 uint8_t ptag;
64
65 /* unique id for this process assigned by the system */
66 uint32_t cookie;
67
68 /* communication domain handle */
69 gni_cdm_handle_t cd_handle;
70
71 /* device count. to be used if we have more than 1 common per ugni device */
72 int device_count;
73 ompi_common_ugni_device_t *devices;
74
75 int local_cq_size;
76
77 int rdma_max_retries;
78 };
79 typedef struct ompi_common_ugni_module_t ompi_common_ugni_module_t;
80
81 struct ompi_common_ugni_post_desc_t {
82 gni_post_descriptor_t base;
83
84 ompi_common_ugni_endpoint_t *endpoint;
85 int tries;
86
87 /* NTH: callback function for this post. this may change in the future */
88 void (*cbfunc) (struct ompi_common_ugni_post_desc_t *, int);
89 };
90 typedef struct ompi_common_ugni_post_desc_t ompi_common_ugni_post_desc_t;
91
92 extern ompi_common_ugni_module_t ompi_common_ugni_module;
93 extern mca_base_component_t ompi_common_ugni_component;
94
95 static inline int
96 ompi_common_rc_ugni_to_ompi (gni_return_t rc)
97 {
98 int codes[] = {OMPI_SUCCESS,
99 OMPI_ERR_RESOURCE_BUSY,
100 OMPI_ERR_BAD_PARAM,
101 OMPI_ERR_OUT_OF_RESOURCE,
102 OMPI_ERR_TIMEOUT,
103 OMPI_ERR_PERM,
104 OMPI_ERROR,
105 OMPI_ERR_BAD_PARAM,
106 OMPI_ERR_BAD_PARAM,
107 OMPI_ERR_NOT_FOUND,
108 OMPI_ERR_VALUE_OUT_OF_BOUNDS,
109 OMPI_ERROR,
110 OMPI_ERR_NOT_SUPPORTED,
111 OMPI_ERR_OUT_OF_RESOURCE};
112 return codes[rc];
113 }
114
115 /*
116 * Initialize uGNI communication domain and device(s).
117 */
118 int ompi_common_ugni_init (void);
119
120 /*
121 * Finalize uGNI communication domain and device(s).
122 */
123 int ompi_common_ugni_fini (void);
124
125 extern void mca_btl_ugni_local_smsg_complete (void *, uint32_t, int);
126
127 static inline int
128 ompi_common_ugni_process_completed_post (ompi_common_ugni_device_t *dev,
129 gni_cq_handle_t cq_handle) {
130 ompi_common_ugni_post_desc_t *desc;
131 gni_return_t rc = GNI_RC_NOT_DONE;
132 gni_cq_entry_t event_data = 0;
133 uint32_t recoverable = 1;
134
135 rc = GNI_CqGetEvent (cq_handle, &event_data);
136 if (GNI_RC_NOT_DONE == rc) {
137 return 0;
138 }
139
140 if (OPAL_UNLIKELY((GNI_RC_SUCCESS != rc && !event_data) || GNI_CQ_OVERRUN(event_data))) {
141 /* TODO -- need to handle overrun -- how do we do this without an event?
142 will the event eventually come back? Ask Cray */
143 OPAL_OUTPUT((-1, "post error! cq overrun = %d", (int)GNI_CQ_OVERRUN(event_data)));
144 assert (0);
145 return ompi_common_rc_ugni_to_ompi (rc);
146 }
147
148 /* local SMS completion */
149 if (GNI_CQ_GET_TYPE(event_data) == GNI_CQ_EVENT_TYPE_SMSG) {
150 uint32_t msg_id = GNI_CQ_GET_MSG_ID(event_data);
151
152 assert (GNI_CQ_STATUS_OK(event_data));
153
154 if ((uint32_t)-1 == msg_id) {
155 /* nothing to do */
156 return 1;
157 }
158
159 /* inform the btl of local smsg completion */
160 mca_btl_ugni_local_smsg_complete (dev->btl_ctx, msg_id,
161 GNI_CQ_STATUS_OK(event_data) ? OMPI_SUCCESS : OMPI_ERROR);
162
163 return 1;
164 }
165
166 rc = GNI_GetCompleted (cq_handle, event_data, (gni_post_descriptor_t **) &desc);
167 if (OPAL_UNLIKELY(GNI_RC_SUCCESS != rc)) {
168 OPAL_OUTPUT((-1, "Error in GNI_GetComplete %s", gni_err_str[rc]));
169 return ompi_common_rc_ugni_to_ompi (rc);
170 }
171
172 if (OPAL_UNLIKELY(!GNI_CQ_STATUS_OK(event_data))) {
173 (void) GNI_CqErrorRecoverable (event_data, &recoverable);
174
175 if (OPAL_UNLIKELY(!recoverable ||
176 ++desc->tries >= ompi_common_ugni_module.rdma_max_retries)) {
177 OPAL_OUTPUT((-1, "giving up on descriptor %p", (void *) desc));
178 /* give up */
179 desc->cbfunc (desc, OMPI_ERROR);
180
181 return OMPI_ERROR;
182 }
183
184 /* repost transaction */
185 if (GNI_POST_RDMA_PUT == desc->base.type ||
186 GNI_POST_RDMA_GET == desc->base.type) {
187 rc = GNI_PostRdma (desc->endpoint->ep_handle, &desc->base);
188 } else {
189 rc = GNI_PostFma (desc->endpoint->ep_handle, &desc->base);
190 }
191
192 return ompi_common_rc_ugni_to_ompi (rc);
193 }
194
195 desc->cbfunc (desc, OMPI_SUCCESS);
196
197 return 1;
198 }
199
200 static inline int ompi_common_ugni_progress (void) {
201 ompi_common_ugni_device_t *dev;
202 int count, i;
203
204 for (i = 0, count = 0 ; i < ompi_common_ugni_module.device_count ; ++i) {
205 dev = ompi_common_ugni_module.devices + i;
206 /* progress fma/local smsg completions */
207 count += ompi_common_ugni_process_completed_post (dev, dev->dev_local_cq);
208 }
209
210 return count;
211 }
212
213 #endif /* MPI_COMMON_UGNI_H */
OPAL_OUTPUT
#define OPAL_OUTPUT(a)
Main macro for use in sending debugging output to output streams; will be "compiled out" when OPAL is...
Definition: output.h:534
mca_base_component_2_0_0_t
Common type for all MCA components.
Definition: mca.h:250
output.h
OPAL output stream facility.
opal_list.h
The opal_list_t interface is used to provide a generic doubly-linked list container for Open MPI...
proc.h
Process identification structure interface.
ompi_common_ugni_module_t
Definition: common_ugni.h:61
ompi_common_ugni_modex_t
Definition: common_ugni.h:36
ompi_common_ugni_device_t
Definition: common_ugni.h:42
ompi_common_ugni_endpoint_t::ep_handle
gni_ep_handle_t ep_handle
uGNI handle for this endpoint
Definition: common_ugni_ep.h:28
opal_object_t
Base object.
Definition: opal_object.h:182
ompi_module_exchange.h
Open MPI module-related data transfer mechanism.
prefetch.h
Compiler-specific prefetch functions.
ompi_common_ugni_endpoint_t
Definition: common_ugni_ep.h:26
ompi_common_ugni_post_desc_t
Definition: common_ugni.h:81