@@ -36,6 +36,20 @@ struct retain_op_data {
3636 ompi_datatype_t * datatype ;
3737};
3838
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+
3953int ompi_coll_base_sendrecv_nonzero_actual ( void * sendbuf , size_t scount ,
4054 ompi_datatype_t * sdatatype ,
4155 int dest , int stag ,
@@ -94,7 +108,7 @@ int ompi_coll_base_sendrecv_nonzero_actual( void* sendbuf, size_t scount,
94108 return (err );
95109}
96110
97- static int release_callback (struct ompi_request_t * request ) {
111+ static int release_op_callback (struct ompi_request_t * request ) {
98112 struct retain_op_data * p = (struct retain_op_data * )request -> req_complete_cb_data ;
99113 int rc = OMPI_SUCCESS ;
100114 assert (NULL != p );
@@ -132,8 +146,104 @@ int ompi_coll_base_retain_op( ompi_request_t *request, ompi_op_t *op,
132146 }
133147 p -> req_complete_cb = request -> req_complete_cb ;
134148 p -> req_complete_cb_data = request -> req_complete_cb_data ;
135- request -> req_complete_cb = release_callback ;
149+ request -> req_complete_cb = release_op_callback ;
136150 request -> req_complete_cb_data = p ;
137151 }
138152 return OMPI_SUCCESS ;
139153}
154+
155+ static int release_datatypes_callback (struct ompi_request_t * request ) {
156+ struct retain_datatypes_data * p = (struct retain_datatypes_data * )request -> req_complete_cb_data ;
157+ int rc = OMPI_SUCCESS ;
158+ assert (NULL != p );
159+ if (NULL != p -> req_complete_cb ) {
160+ request -> req_complete_cb = p -> req_complete_cb ;
161+ request -> req_complete_cb_data = p -> req_complete_cb_data ;
162+ rc = request -> req_complete_cb (request );
163+ }
164+ if (NULL != p -> stype ) {
165+ OBJ_RELEASE (p -> stype );
166+ }
167+ if (NULL != p -> rtype ) {
168+ OBJ_RELEASE (p -> rtype );
169+ }
170+ free (p );
171+ return rc ;
172+ }
173+
174+ int ompi_coll_base_retain_datatypes ( ompi_request_t * request , ompi_datatype_t * stype ,
175+ ompi_datatype_t * rtype ) {
176+ bool retain = NULL != stype && !ompi_datatype_is_predefined (stype );
177+ retain |= NULL != rtype && !ompi_datatype_is_predefined (rtype );
178+ if (OPAL_UNLIKELY (retain )) {
179+ struct retain_datatypes_data * p = (struct retain_datatypes_data * )calloc (1 , sizeof (struct retain_datatypes_data ));
180+ if (OPAL_UNLIKELY (NULL == p )) {
181+ return OMPI_ERR_OUT_OF_RESOURCE ;
182+ }
183+ if (NULL != stype && !ompi_datatype_is_predefined (stype )) {
184+ OBJ_RETAIN (stype );
185+ p -> stype = stype ;
186+ }
187+ if (NULL != rtype && !ompi_datatype_is_predefined (rtype )) {
188+ OBJ_RETAIN (rtype );
189+ p -> rtype = rtype ;
190+ }
191+ p -> req_complete_cb = request -> req_complete_cb ;
192+ p -> req_complete_cb_data = request -> req_complete_cb_data ;
193+ request -> req_complete_cb = release_datatypes_callback ;
194+ request -> req_complete_cb_data = p ;
195+ }
196+ return OMPI_SUCCESS ;
197+ }
198+
199+ static int release_datatypes_w_callback (struct ompi_request_t * request ) {
200+ struct retain_datatypes_w_data * p = (struct retain_datatypes_w_data * )request -> req_complete_cb_data ;
201+ int rc = OMPI_SUCCESS ;
202+ assert (NULL != p );
203+ if (NULL != p -> req_complete_cb ) {
204+ request -> req_complete_cb = p -> req_complete_cb ;
205+ request -> req_complete_cb_data = p -> req_complete_cb_data ;
206+ rc = request -> req_complete_cb (request );
207+ }
208+ for (int i = 0 ; i < p -> count ; i ++ ) {
209+ OBJ_RELEASE (p -> types [i ]);
210+ }
211+ free (p );
212+ return rc ;
213+ }
214+
215+ int ompi_coll_base_retain_datatypes_w ( ompi_request_t * request , int count ,
216+ ompi_datatype_t * const stypes [], ompi_datatype_t * const rtypes []) {
217+ int datatypes = 0 ;
218+ for (int i = 0 ; i < count ; i ++ ) {
219+ if (NULL != stypes [i ] && !ompi_datatype_is_predefined (stypes [i ])) {
220+ datatypes ++ ;
221+ }
222+ if (NULL != rtypes [i ] && !ompi_datatype_is_predefined (rtypes [i ])) {
223+ datatypes ++ ;
224+ }
225+ }
226+ if (OPAL_UNLIKELY (0 < datatypes )) {
227+ struct retain_datatypes_w_data * p = (struct retain_datatypes_w_data * )calloc (1 , sizeof (struct retain_datatypes_data )+ (datatypes - 1 )* sizeof (ompi_datatype_t * ));
228+ if (OPAL_UNLIKELY (NULL == p )) {
229+ return OMPI_ERR_OUT_OF_RESOURCE ;
230+ }
231+ datatypes = 0 ;
232+ for (int i = 0 ; i < count ; i ++ ) {
233+ if (NULL != stypes [i ] && !ompi_datatype_is_predefined (stypes [i ])) {
234+ p -> types [datatypes ++ ] = stypes [i ];
235+ OBJ_RETAIN (stypes [i ]);
236+ }
237+ if (NULL != rtypes [i ] && !ompi_datatype_is_predefined (rtypes [i ])) {
238+ p -> types [datatypes ++ ] = rtypes [i ];
239+ OBJ_RETAIN (rtypes [i ]);
240+ }
241+ }
242+ p -> req_complete_cb = request -> req_complete_cb ;
243+ p -> req_complete_cb_data = request -> req_complete_cb_data ;
244+ request -> req_complete_cb = release_datatypes_w_callback ;
245+ request -> req_complete_cb_data = p ;
246+ }
247+ return OMPI_SUCCESS ;
248+ }
249+
0 commit comments