Skip to content

Commit 4661c68

Browse files
committed
attributes: add wrapper infrastructure
This approach works for attributes but other approaches will be needed for error handlers and datatype conversion related functions. Signed-off-by: Howard Pritchard <howardp@lanl.gov>
1 parent 340e7ad commit 4661c68

File tree

6 files changed

+131
-1315
lines changed

6 files changed

+131
-1315
lines changed

ompi/mpi/bindings/ompi_bindings/c.py

Lines changed: 8 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -442,9 +442,14 @@ def standard_abi(base_name, template, out):
442442

443443
# If any parameters are pointers to user callback functions, generate code
444444
# for callback wrappers
445-
# if util.prototype_needs_callback_wrappers(template.prototype):
446-
# for param in prototype.params:
447-
# if param.callback_wrapper_code:
445+
if util.prototype_needs_callback_wrappers(template.prototype):
446+
params = [param.construct(abi_type='standard') for param in template.prototype.params]
447+
for param in params:
448+
if param.callback_wrapper_code:
449+
lines = []
450+
lines.extend(param.callback_wrapper_code)
451+
for line in lines:
452+
out.dump(line)
448453

449454
# Static internal function (add a random component to avoid conflicts)
450455
internal_name = f'ompi_abi_{template.prototype.name}'

ompi/mpi/bindings/ompi_bindings/c_type.py

Lines changed: 108 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -84,6 +84,10 @@ def tmp_type_text(self, enable_count=False):
8484
def parameter(self, enable_count=False, **kwargs):
8585
return f'{self.type_text(enable_count=enable_count)} {self.name}'
8686

87+
@property
88+
def callback_wrapper_code(self):
89+
"""Return True if this parameter has callback wrapper code to generate."""
90+
return False
8791

8892
@Type.add_type('ERROR_CLASS')
8993
class TypeErrorClass(Type):
@@ -1148,8 +1152,6 @@ def type_text(self, enable_count=False):
11481152

11491153
@Type.add_type('COMM_COPY_ATTR_FUNCTION', abi_type=['standard'])
11501154
class TypeCommCopyAttrFunctionStandard(Type):
1151-
# TODO: This may require a special function to wrap the callback
1152-
# pass
11531155

11541156
def type_text(self, enable_count=False):
11551157
type_name = self.mangle_name('MPI_Comm_copy_attr_function')
@@ -1159,16 +1161,40 @@ def type_text(self, enable_count=False):
11591161
def argument(self):
11601162
return f'(MPI_Comm_copy_attr_function *) {self.name}'
11611163

1162-
# @property
1163-
# def init_code(self):
1164-
# code = []
1165-
# code = ['ompi_abi_wrapper_helper_t *helper = NULL;']
1166-
# code.append('helper = ( ompi_abi_wrapper_helper_t *)malloc(sizeof(ompi_abi_wrapper_helper_t));')
1167-
# code.append('if (NULL == helper) return MPI_ERR_NO_MEM;')
1168-
# code.append('helper->user_extra_state = extra_state;')
1169-
# code.append('helper->user_copy_fn = comm_copy_attr_fn;')
1170-
# code.append('helper->user_delete_fn = comm_delete_attr_fn;')
1171-
# return code
1164+
@property
1165+
def init_code(self):
1166+
code = []
1167+
code = ['ompi_abi_wrapper_helper_t *helper = NULL;']
1168+
code.append('helper = ( ompi_abi_wrapper_helper_t *)malloc(sizeof(ompi_abi_wrapper_helper_t));')
1169+
code.append('if (NULL == helper) return MPI_ERR_NO_MEM;')
1170+
code.append('helper->user_extra_state = extra_state;')
1171+
code.append('helper->user_copy_fn = comm_copy_attr_fn;')
1172+
code.append('helper->user_delete_fn = comm_delete_attr_fn;')
1173+
return code
1174+
1175+
# TODO: This should be generalized to be reused with type and win
1176+
@property
1177+
def callback_wrapper_code(self):
1178+
code = []
1179+
code = ['typedef struct {']
1180+
code.append(' MPI_Comm_copy_attr_function_ABI_INTERNAL *user_copy_fn;')
1181+
code.append(' MPI_Comm_delete_attr_function_ABI_INTERNAL *user_delete_fn;')
1182+
code.append(' void *user_extra_state;')
1183+
code.append('} ompi_abi_wrapper_helper_t;')
1184+
code.append('static int ompi_abi_copy_attr_fn(MPI_Comm oldcomm, int comm_keyval, void *extra_state, void *attribute_val_in, void *attribute_val_out, int *flag)')
1185+
code.append('{')
1186+
code.append(' ompi_abi_wrapper_helper_t *helper = (ompi_abi_wrapper_helper_t *)extra_state;')
1187+
code.append(' MPI_Comm_ABI_INTERNAL comm_tmp = ompi_convert_comm_ompi_to_standard(oldcomm);')
1188+
code.append(' return helper->user_copy_fn((MPI_Comm_ABI_INTERNAL)comm_tmp, comm_keyval, helper->user_extra_state, attribute_val_in, attribute_val_out, flag);')
1189+
code.append('}')
1190+
code.append('static int ompi_abi_delete_attr_fn(MPI_Comm oldcomm, int comm_keyval, void *attribute_val, void *extra_state)')
1191+
code.append('{')
1192+
code.append(' ompi_abi_wrapper_helper_t *helper = (ompi_abi_wrapper_helper_t *)extra_state;')
1193+
code.append(' MPI_Comm_ABI_INTERNAL comm_tmp = ompi_convert_comm_ompi_to_standard(oldcomm);')
1194+
code.append(' return helper->user_delete_fn((MPI_Comm_ABI_INTERNAL)comm_tmp, comm_keyval, attribute_val, helper->user_extra_state);')
1195+
code.append(' free(helper);')
1196+
code.append('}')
1197+
return code
11721198

11731199
@Type.add_type('COMM_DELETE_ATTR_FUNCTION', abi_type=['ompi'])
11741200
class TypeCommDeleteAttrFunction(Type):
@@ -1179,8 +1205,6 @@ def type_text(self, enable_count=False):
11791205

11801206
@Type.add_type('COMM_DELETE_ATTR_FUNCTION', abi_type=['standard'])
11811207
class TypeCommDeleteAttrFunctionStandard(Type):
1182-
# TODO: This may require a special function to wrap the callback
1183-
# pass
11841208

11851209
def type_text(self, enable_count=False):
11861210
type_name = self.mangle_name('MPI_Comm_delete_attr_function')
@@ -1293,11 +1317,8 @@ class TypeTypeCopyAttrFunction(Type):
12931317
def type_text(self, enable_count=False):
12941318
return 'MPI_Type_copy_attr_function *'
12951319

1296-
12971320
@Type.add_type('TYPE_COPY_ATTR_FUNCTION', abi_type=['standard'])
12981321
class TypeTypeCopyAttrFunctionStandard(Type):
1299-
# TODO: This may require a special function to wrap the callback
1300-
# pass
13011322

13021323
def type_text(self, enable_count=False):
13031324
type_name = self.mangle_name('MPI_Type_copy_attr_function')
@@ -1307,6 +1328,41 @@ def type_text(self, enable_count=False):
13071328
def argument(self):
13081329
return f'(MPI_Type_copy_attr_function *) {self.name}'
13091330

1331+
@property
1332+
def init_code(self):
1333+
code = []
1334+
code = ['ompi_abi_wrapper_helper_t *helper = NULL;']
1335+
code.append('helper = ( ompi_abi_wrapper_helper_t *)malloc(sizeof(ompi_abi_wrapper_helper_t));')
1336+
code.append('if (NULL == helper) return MPI_ERR_NO_MEM;')
1337+
code.append('helper->user_extra_state = extra_state;')
1338+
code.append('helper->user_copy_fn = type_copy_attr_fn;')
1339+
code.append('helper->user_delete_fn = type_delete_attr_fn;')
1340+
return code
1341+
1342+
# TODO: This should be generalized to be reused with type and win
1343+
@property
1344+
def callback_wrapper_code(self):
1345+
code = []
1346+
code = ['typedef struct {']
1347+
code.append(' MPI_Type_copy_attr_function_ABI_INTERNAL *user_copy_fn;')
1348+
code.append(' MPI_Type_delete_attr_function_ABI_INTERNAL *user_delete_fn;')
1349+
code.append(' void *user_extra_state;')
1350+
code.append('} ompi_abi_wrapper_helper_t;')
1351+
code.append('static int ompi_abi_copy_attr_fn(MPI_Datatype oldtype, int type_keyval, void *extra_state, void *attribute_val_in, void *attribute_val_out, int *flag)')
1352+
code.append('{')
1353+
code.append(' ompi_abi_wrapper_helper_t *helper = (ompi_abi_wrapper_helper_t *)extra_state;')
1354+
code.append(' MPI_Datatype_ABI_INTERNAL type_tmp = ompi_convert_datatype_ompi_to_standard(oldtype);')
1355+
code.append(' return helper->user_copy_fn((MPI_Datatype_ABI_INTERNAL)type_tmp, type_keyval, helper->user_extra_state, attribute_val_in, attribute_val_out, flag);')
1356+
code.append('}')
1357+
code.append('static int ompi_abi_delete_attr_fn(MPI_Datatype oldtype, int type_keyval, void *attribute_val, void *extra_state)')
1358+
code.append('{')
1359+
code.append(' ompi_abi_wrapper_helper_t *helper = (ompi_abi_wrapper_helper_t *)extra_state;')
1360+
code.append(' MPI_Datatype_ABI_INTERNAL type_tmp = ompi_convert_datatype_ompi_to_standard(oldtype);')
1361+
code.append(' return helper->user_delete_fn((MPI_Datatype_ABI_INTERNAL)type_tmp, type_keyval, attribute_val, helper->user_extra_state);')
1362+
code.append(' free(helper);')
1363+
code.append('}')
1364+
return code
1365+
13101366
@Type.add_type('TYPE_DELETE_ATTR_FUNCTION', abi_type=['ompi'])
13111367
class TypeTypeDeleteAttrFunction(Type):
13121368

@@ -1316,8 +1372,6 @@ def type_text(self, enable_count=False):
13161372

13171373
@Type.add_type('TYPE_DELETE_ATTR_FUNCTION', abi_type=['standard'])
13181374
class TypeTypeDeleteAttrFunctionStandard(Type):
1319-
# TODO: This may require a special function to wrap the callback
1320-
# pass
13211375

13221376
def type_text(self, enable_count=False):
13231377
type_name = self.mangle_name('MPI_Type_delete_attr_function')
@@ -1352,8 +1406,6 @@ def type_text(self, enable_count=False):
13521406

13531407
@Type.add_type('WIN_COPY_ATTR_FUNCTION', abi_type=['standard'])
13541408
class TypeWinCopyAttrFunctionStandard(Type):
1355-
# TODO: This may require a special function to wrap the callback
1356-
# pass
13571409

13581410
def type_text(self, enable_count=False):
13591411
type_name = self.mangle_name('MPI_Win_copy_attr_function')
@@ -1363,6 +1415,41 @@ def type_text(self, enable_count=False):
13631415
def argument(self):
13641416
return f'(MPI_Win_copy_attr_function *) {self.name}'
13651417

1418+
@property
1419+
def init_code(self):
1420+
code = []
1421+
code = ['ompi_abi_wrapper_helper_t *helper = NULL;']
1422+
code.append('helper = ( ompi_abi_wrapper_helper_t *)malloc(sizeof(ompi_abi_wrapper_helper_t));')
1423+
code.append('if (NULL == helper) return MPI_ERR_NO_MEM;')
1424+
code.append('helper->user_extra_state = extra_state;')
1425+
code.append('helper->user_copy_fn = win_copy_attr_fn;')
1426+
code.append('helper->user_delete_fn = win_delete_attr_fn;')
1427+
return code
1428+
1429+
@property
1430+
def callback_wrapper_code(self):
1431+
code = []
1432+
code = ['typedef struct {']
1433+
code.append(' MPI_Win_copy_attr_function_ABI_INTERNAL *user_copy_fn;')
1434+
code.append(' MPI_Win_delete_attr_function_ABI_INTERNAL *user_delete_fn;')
1435+
code.append(' void *user_extra_state;')
1436+
code.append('} ompi_abi_wrapper_helper_t;')
1437+
code.append('static int ompi_abi_copy_attr_fn(MPI_Win oldwin, int win_keyval, void *extra_state, void *attribute_val_in, void *attribute_val_out, int *flag)')
1438+
code.append('{')
1439+
code.append(' ompi_abi_wrapper_helper_t *helper = (ompi_abi_wrapper_helper_t *)extra_state;')
1440+
code.append(' MPI_Win_ABI_INTERNAL win_tmp = ompi_convert_win_ompi_to_standard(oldwin);')
1441+
code.append(' return helper->user_copy_fn((MPI_Win_ABI_INTERNAL)win_tmp, win_keyval, helper->user_extra_state, attribute_val_in, attribute_val_out, flag);')
1442+
code.append('}')
1443+
code.append('static int ompi_abi_delete_attr_fn(MPI_Win oldwin, int win_keyval, void *attribute_val, void *extra_state)')
1444+
code.append('{')
1445+
code.append(' ompi_abi_wrapper_helper_t *helper = (ompi_abi_wrapper_helper_t *)extra_state;')
1446+
code.append(' MPI_Win_ABI_INTERNAL win_tmp = ompi_convert_win_ompi_to_standard(oldwin);')
1447+
code.append(' return helper->user_delete_fn((MPI_Win_ABI_INTERNAL)win_tmp, win_keyval, attribute_val, helper->user_extra_state);')
1448+
code.append(' free(helper);')
1449+
code.append('}')
1450+
return code
1451+
1452+
13661453
@Type.add_type('WIN_DELETE_ATTR_FUNCTION', abi_type=['ompi'])
13671454
class TypeWinDeleteAttrFunction(Type):
13681455

@@ -1372,8 +1459,6 @@ def type_text(self, enable_count=False):
13721459

13731460
@Type.add_type('WIN_DELETE_ATTR_FUNCTION', abi_type=['standard'])
13741461
class TypeWinDeleteAttrFunctionStandard(Type):
1375-
# TODO: This may require a special function to wrap the callback
1376-
# pass
13771462

13781463
def type_text(self, enable_count=False):
13791464
type_name = self.mangle_name('MPI_Win_delete_attr_function')

0 commit comments

Comments
 (0)