|
9 | 9 | * University of Stuttgart. All rights reserved. |
10 | 10 | * Copyright (c) 2004-2005 The Regents of the University of California. |
11 | 11 | * All rights reserved. |
12 | | - * Copyright (c) 2014-2017 Research Organization for Information Science |
13 | | - * and Technology (RIST). All rights reserved. |
| 12 | + * Copyright (c) 2014-2019 Research Organization for Information Science |
| 13 | + * and Technology (RIST). All rights reserved. |
14 | 14 | * $COPYRIGHT$ |
15 | 15 | * |
16 | 16 | * Additional copyrights may follow |
|
29 | 29 | #include "ompi/mca/pml/pml.h" |
30 | 30 | #include "coll_base_util.h" |
31 | 31 |
|
| 32 | +struct retain_op_data { |
| 33 | + ompi_request_complete_fn_t req_complete_cb; |
| 34 | + void *req_complete_cb_data; |
| 35 | + ompi_op_t *op; |
| 36 | + ompi_datatype_t *datatype; |
| 37 | +}; |
| 38 | + |
| 39 | +struct retain_datatypes_data { |
| 40 | + ompi_request_complete_fn_t req_complete_cb; |
| 41 | + void *req_complete_cb_data; |
| 42 | + ompi_datatype_t *stype; |
| 43 | + ompi_datatype_t *rtype; |
| 44 | +}; |
| 45 | + |
| 46 | +struct retain_datatypes_w_data { |
| 47 | + ompi_request_complete_fn_t req_complete_cb; |
| 48 | + void *req_complete_cb_data; |
| 49 | + int count; |
| 50 | + ompi_datatype_t *types[]; |
| 51 | +}; |
| 52 | + |
32 | 53 | int ompi_coll_base_sendrecv_actual( const void* sendbuf, size_t scount, |
33 | 54 | ompi_datatype_t* sdatatype, |
34 | 55 | int dest, int stag, |
@@ -103,3 +124,142 @@ int ompi_rounddown(int num, int factor) |
103 | 124 | num /= factor; |
104 | 125 | return num * factor; /* floor(num / factor) * factor */ |
105 | 126 | } |
| 127 | + |
| 128 | +static int release_op_callback(struct ompi_request_t *request) { |
| 129 | + struct retain_op_data * p = (struct retain_op_data *)request->req_complete_cb_data; |
| 130 | + int rc = OMPI_SUCCESS; |
| 131 | + assert (NULL != p); |
| 132 | + if (NULL != p->req_complete_cb) { |
| 133 | + request->req_complete_cb = p->req_complete_cb; |
| 134 | + request->req_complete_cb_data = p->req_complete_cb_data; |
| 135 | + rc = request->req_complete_cb(request); |
| 136 | + } |
| 137 | + if (NULL != p->op) { |
| 138 | + OBJ_RELEASE(p->op); |
| 139 | + } |
| 140 | + if (NULL != p->datatype) { |
| 141 | + OBJ_RELEASE(p->datatype); |
| 142 | + } |
| 143 | + free(p); |
| 144 | + return rc; |
| 145 | +} |
| 146 | + |
| 147 | +int ompi_coll_base_retain_op( ompi_request_t *request, ompi_op_t *op, |
| 148 | + ompi_datatype_t *type) { |
| 149 | + bool retain = !ompi_op_is_intrinsic(op); |
| 150 | + retain |= !ompi_datatype_is_predefined(type); |
| 151 | + if (OPAL_UNLIKELY(retain)) { |
| 152 | + struct retain_op_data *p = (struct retain_op_data *)calloc(1, sizeof(struct retain_op_data)); |
| 153 | + if (OPAL_UNLIKELY(NULL == p)) { |
| 154 | + return OMPI_ERR_OUT_OF_RESOURCE; |
| 155 | + } |
| 156 | + if (!ompi_op_is_intrinsic(op)) { |
| 157 | + OBJ_RETAIN(op); |
| 158 | + p->op = op; |
| 159 | + } |
| 160 | + if (!ompi_datatype_is_predefined(type)) { |
| 161 | + OBJ_RETAIN(type); |
| 162 | + p->datatype = type; |
| 163 | + } |
| 164 | + p->req_complete_cb = request->req_complete_cb; |
| 165 | + p->req_complete_cb_data = request->req_complete_cb_data; |
| 166 | + request->req_complete_cb = release_op_callback; |
| 167 | + request->req_complete_cb_data = p; |
| 168 | + } |
| 169 | + return OMPI_SUCCESS; |
| 170 | +} |
| 171 | + |
| 172 | +static int release_datatypes_callback(struct ompi_request_t *request) { |
| 173 | + struct retain_datatypes_data * p = (struct retain_datatypes_data *)request->req_complete_cb_data; |
| 174 | + int rc = OMPI_SUCCESS; |
| 175 | + assert (NULL != p); |
| 176 | + if (NULL != p->req_complete_cb) { |
| 177 | + request->req_complete_cb = p->req_complete_cb; |
| 178 | + request->req_complete_cb_data = p->req_complete_cb_data; |
| 179 | + rc = request->req_complete_cb(request); |
| 180 | + } |
| 181 | + if (NULL != p->stype) { |
| 182 | + OBJ_RELEASE(p->stype); |
| 183 | + } |
| 184 | + if (NULL != p->rtype) { |
| 185 | + OBJ_RELEASE(p->rtype); |
| 186 | + } |
| 187 | + free(p); |
| 188 | + return rc; |
| 189 | +} |
| 190 | + |
| 191 | +int ompi_coll_base_retain_datatypes( ompi_request_t *request, ompi_datatype_t *stype, |
| 192 | + ompi_datatype_t *rtype) { |
| 193 | + bool retain = NULL != stype && !ompi_datatype_is_predefined(stype); |
| 194 | + retain |= NULL != rtype && !ompi_datatype_is_predefined(rtype); |
| 195 | + if (OPAL_UNLIKELY(retain)) { |
| 196 | + struct retain_datatypes_data *p = (struct retain_datatypes_data *)calloc(1, sizeof(struct retain_datatypes_data)); |
| 197 | + if (OPAL_UNLIKELY(NULL == p)) { |
| 198 | + return OMPI_ERR_OUT_OF_RESOURCE; |
| 199 | + } |
| 200 | + if (NULL != stype && !ompi_datatype_is_predefined(stype)) { |
| 201 | + OBJ_RETAIN(stype); |
| 202 | + p->stype = stype; |
| 203 | + } |
| 204 | + if (NULL != rtype && !ompi_datatype_is_predefined(rtype)) { |
| 205 | + OBJ_RETAIN(rtype); |
| 206 | + p->rtype = rtype; |
| 207 | + } |
| 208 | + p->req_complete_cb = request->req_complete_cb; |
| 209 | + p->req_complete_cb_data = request->req_complete_cb_data; |
| 210 | + request->req_complete_cb = release_datatypes_callback; |
| 211 | + request->req_complete_cb_data = p; |
| 212 | + } |
| 213 | + return OMPI_SUCCESS; |
| 214 | +} |
| 215 | + |
| 216 | +static int release_datatypes_w_callback(struct ompi_request_t *request) { |
| 217 | + struct retain_datatypes_w_data * p = (struct retain_datatypes_w_data *)request->req_complete_cb_data; |
| 218 | + int rc = OMPI_SUCCESS; |
| 219 | + assert (NULL != p); |
| 220 | + if (NULL != p->req_complete_cb) { |
| 221 | + request->req_complete_cb = p->req_complete_cb; |
| 222 | + request->req_complete_cb_data = p->req_complete_cb_data; |
| 223 | + rc = request->req_complete_cb(request); |
| 224 | + } |
| 225 | + for (int i=0; i<p->count; i++) { |
| 226 | + OBJ_RELEASE(p->types[i]); |
| 227 | + } |
| 228 | + free(p); |
| 229 | + return rc; |
| 230 | +} |
| 231 | + |
| 232 | +int ompi_coll_base_retain_datatypes_w( ompi_request_t *request, int count, |
| 233 | + ompi_datatype_t *const stypes[], ompi_datatype_t *const rtypes[]) { |
| 234 | + int datatypes = 0; |
| 235 | + for (int i=0; i<count; i++) { |
| 236 | + if (NULL != stypes[i] && !ompi_datatype_is_predefined(stypes[i])) { |
| 237 | + datatypes++; |
| 238 | + } |
| 239 | + if (NULL != rtypes[i] && !ompi_datatype_is_predefined(rtypes[i])) { |
| 240 | + datatypes++; |
| 241 | + } |
| 242 | + } |
| 243 | + if (OPAL_UNLIKELY(0 < datatypes)) { |
| 244 | + struct retain_datatypes_w_data *p = (struct retain_datatypes_w_data *)calloc(1, sizeof(struct retain_datatypes_data)+(datatypes-1)*sizeof(ompi_datatype_t *)); |
| 245 | + if (OPAL_UNLIKELY(NULL == p)) { |
| 246 | + return OMPI_ERR_OUT_OF_RESOURCE; |
| 247 | + } |
| 248 | + datatypes = 0; |
| 249 | + for (int i=0; i<count; i++) { |
| 250 | + if (NULL != stypes[i] && !ompi_datatype_is_predefined(stypes[i])) { |
| 251 | + p->types[datatypes++] = stypes[i]; |
| 252 | + OBJ_RETAIN(stypes[i]); |
| 253 | + } |
| 254 | + if (NULL != rtypes[i] && !ompi_datatype_is_predefined(rtypes[i])) { |
| 255 | + p->types[datatypes++] = rtypes[i]; |
| 256 | + OBJ_RETAIN(rtypes[i]); |
| 257 | + } |
| 258 | + } |
| 259 | + p->req_complete_cb = request->req_complete_cb; |
| 260 | + p->req_complete_cb_data = request->req_complete_cb_data; |
| 261 | + request->req_complete_cb = release_datatypes_w_callback; |
| 262 | + request->req_complete_cb_data = p; |
| 263 | + } |
| 264 | + return OMPI_SUCCESS; |
| 265 | +} |
0 commit comments