Skip to content

Commit 7834537

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 74fc0ac commit 7834537

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):
@@ -1172,8 +1176,6 @@ def type_text(self, enable_count=False):
11721176

11731177
@Type.add_type('COMM_COPY_ATTR_FUNCTION', abi_type=['standard'])
11741178
class TypeCommCopyAttrFunctionStandard(Type):
1175-
# TODO: This may require a special function to wrap the callback
1176-
# pass
11771179

11781180
def type_text(self, enable_count=False):
11791181
type_name = self.mangle_name('MPI_Comm_copy_attr_function')
@@ -1183,16 +1185,40 @@ def type_text(self, enable_count=False):
11831185
def argument(self):
11841186
return f'(MPI_Comm_copy_attr_function *) {self.name}'
11851187

1186-
# @property
1187-
# def init_code(self):
1188-
# code = []
1189-
# code = ['ompi_abi_wrapper_helper_t *helper = NULL;']
1190-
# code.append('helper = ( ompi_abi_wrapper_helper_t *)malloc(sizeof(ompi_abi_wrapper_helper_t));')
1191-
# code.append('if (NULL == helper) return MPI_ERR_NO_MEM;')
1192-
# code.append('helper->user_extra_state = extra_state;')
1193-
# code.append('helper->user_copy_fn = comm_copy_attr_fn;')
1194-
# code.append('helper->user_delete_fn = comm_delete_attr_fn;')
1195-
# return code
1188+
@property
1189+
def init_code(self):
1190+
code = []
1191+
code = ['ompi_abi_wrapper_helper_t *helper = NULL;']
1192+
code.append('helper = ( ompi_abi_wrapper_helper_t *)malloc(sizeof(ompi_abi_wrapper_helper_t));')
1193+
code.append('if (NULL == helper) return MPI_ERR_NO_MEM;')
1194+
code.append('helper->user_extra_state = extra_state;')
1195+
code.append('helper->user_copy_fn = comm_copy_attr_fn;')
1196+
code.append('helper->user_delete_fn = comm_delete_attr_fn;')
1197+
return code
1198+
1199+
# TODO: This should be generalized to be reused with type and win
1200+
@property
1201+
def callback_wrapper_code(self):
1202+
code = []
1203+
code = ['typedef struct {']
1204+
code.append(' MPI_Comm_copy_attr_function_ABI_INTERNAL *user_copy_fn;')
1205+
code.append(' MPI_Comm_delete_attr_function_ABI_INTERNAL *user_delete_fn;')
1206+
code.append(' void *user_extra_state;')
1207+
code.append('} ompi_abi_wrapper_helper_t;')
1208+
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)')
1209+
code.append('{')
1210+
code.append(' ompi_abi_wrapper_helper_t *helper = (ompi_abi_wrapper_helper_t *)extra_state;')
1211+
code.append(' MPI_Comm_ABI_INTERNAL comm_tmp = ompi_convert_comm_ompi_to_standard(oldcomm);')
1212+
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);')
1213+
code.append('}')
1214+
code.append('static int ompi_abi_delete_attr_fn(MPI_Comm oldcomm, int comm_keyval, void *attribute_val, void *extra_state)')
1215+
code.append('{')
1216+
code.append(' ompi_abi_wrapper_helper_t *helper = (ompi_abi_wrapper_helper_t *)extra_state;')
1217+
code.append(' MPI_Comm_ABI_INTERNAL comm_tmp = ompi_convert_comm_ompi_to_standard(oldcomm);')
1218+
code.append(' return helper->user_delete_fn((MPI_Comm_ABI_INTERNAL)comm_tmp, comm_keyval, attribute_val, helper->user_extra_state);')
1219+
code.append(' free(helper);')
1220+
code.append('}')
1221+
return code
11961222

11971223
@Type.add_type('COMM_DELETE_ATTR_FUNCTION', abi_type=['ompi'])
11981224
class TypeCommDeleteAttrFunction(Type):
@@ -1203,8 +1229,6 @@ def type_text(self, enable_count=False):
12031229

12041230
@Type.add_type('COMM_DELETE_ATTR_FUNCTION', abi_type=['standard'])
12051231
class TypeCommDeleteAttrFunctionStandard(Type):
1206-
# TODO: This may require a special function to wrap the callback
1207-
# pass
12081232

12091233
def type_text(self, enable_count=False):
12101234
type_name = self.mangle_name('MPI_Comm_delete_attr_function')
@@ -1317,11 +1341,8 @@ class TypeTypeCopyAttrFunction(Type):
13171341
def type_text(self, enable_count=False):
13181342
return 'MPI_Type_copy_attr_function *'
13191343

1320-
13211344
@Type.add_type('TYPE_COPY_ATTR_FUNCTION', abi_type=['standard'])
13221345
class TypeTypeCopyAttrFunctionStandard(Type):
1323-
# TODO: This may require a special function to wrap the callback
1324-
# pass
13251346

13261347
def type_text(self, enable_count=False):
13271348
type_name = self.mangle_name('MPI_Type_copy_attr_function')
@@ -1331,6 +1352,41 @@ def type_text(self, enable_count=False):
13311352
def argument(self):
13321353
return f'(MPI_Type_copy_attr_function *) {self.name}'
13331354

1355+
@property
1356+
def init_code(self):
1357+
code = []
1358+
code = ['ompi_abi_wrapper_helper_t *helper = NULL;']
1359+
code.append('helper = ( ompi_abi_wrapper_helper_t *)malloc(sizeof(ompi_abi_wrapper_helper_t));')
1360+
code.append('if (NULL == helper) return MPI_ERR_NO_MEM;')
1361+
code.append('helper->user_extra_state = extra_state;')
1362+
code.append('helper->user_copy_fn = type_copy_attr_fn;')
1363+
code.append('helper->user_delete_fn = type_delete_attr_fn;')
1364+
return code
1365+
1366+
# TODO: This should be generalized to be reused with type and win
1367+
@property
1368+
def callback_wrapper_code(self):
1369+
code = []
1370+
code = ['typedef struct {']
1371+
code.append(' MPI_Type_copy_attr_function_ABI_INTERNAL *user_copy_fn;')
1372+
code.append(' MPI_Type_delete_attr_function_ABI_INTERNAL *user_delete_fn;')
1373+
code.append(' void *user_extra_state;')
1374+
code.append('} ompi_abi_wrapper_helper_t;')
1375+
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)')
1376+
code.append('{')
1377+
code.append(' ompi_abi_wrapper_helper_t *helper = (ompi_abi_wrapper_helper_t *)extra_state;')
1378+
code.append(' MPI_Datatype_ABI_INTERNAL type_tmp = ompi_convert_datatype_ompi_to_standard(oldtype);')
1379+
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);')
1380+
code.append('}')
1381+
code.append('static int ompi_abi_delete_attr_fn(MPI_Datatype oldtype, int type_keyval, void *attribute_val, void *extra_state)')
1382+
code.append('{')
1383+
code.append(' ompi_abi_wrapper_helper_t *helper = (ompi_abi_wrapper_helper_t *)extra_state;')
1384+
code.append(' MPI_Datatype_ABI_INTERNAL type_tmp = ompi_convert_datatype_ompi_to_standard(oldtype);')
1385+
code.append(' return helper->user_delete_fn((MPI_Datatype_ABI_INTERNAL)type_tmp, type_keyval, attribute_val, helper->user_extra_state);')
1386+
code.append(' free(helper);')
1387+
code.append('}')
1388+
return code
1389+
13341390
@Type.add_type('TYPE_DELETE_ATTR_FUNCTION', abi_type=['ompi'])
13351391
class TypeTypeDeleteAttrFunction(Type):
13361392

@@ -1340,8 +1396,6 @@ def type_text(self, enable_count=False):
13401396

13411397
@Type.add_type('TYPE_DELETE_ATTR_FUNCTION', abi_type=['standard'])
13421398
class TypeTypeDeleteAttrFunctionStandard(Type):
1343-
# TODO: This may require a special function to wrap the callback
1344-
# pass
13451399

13461400
def type_text(self, enable_count=False):
13471401
type_name = self.mangle_name('MPI_Type_delete_attr_function')
@@ -1376,8 +1430,6 @@ def type_text(self, enable_count=False):
13761430

13771431
@Type.add_type('WIN_COPY_ATTR_FUNCTION', abi_type=['standard'])
13781432
class TypeWinCopyAttrFunctionStandard(Type):
1379-
# TODO: This may require a special function to wrap the callback
1380-
# pass
13811433

13821434
def type_text(self, enable_count=False):
13831435
type_name = self.mangle_name('MPI_Win_copy_attr_function')
@@ -1387,6 +1439,41 @@ def type_text(self, enable_count=False):
13871439
def argument(self):
13881440
return f'(MPI_Win_copy_attr_function *) {self.name}'
13891441

1442+
@property
1443+
def init_code(self):
1444+
code = []
1445+
code = ['ompi_abi_wrapper_helper_t *helper = NULL;']
1446+
code.append('helper = ( ompi_abi_wrapper_helper_t *)malloc(sizeof(ompi_abi_wrapper_helper_t));')
1447+
code.append('if (NULL == helper) return MPI_ERR_NO_MEM;')
1448+
code.append('helper->user_extra_state = extra_state;')
1449+
code.append('helper->user_copy_fn = win_copy_attr_fn;')
1450+
code.append('helper->user_delete_fn = win_delete_attr_fn;')
1451+
return code
1452+
1453+
@property
1454+
def callback_wrapper_code(self):
1455+
code = []
1456+
code = ['typedef struct {']
1457+
code.append(' MPI_Win_copy_attr_function_ABI_INTERNAL *user_copy_fn;')
1458+
code.append(' MPI_Win_delete_attr_function_ABI_INTERNAL *user_delete_fn;')
1459+
code.append(' void *user_extra_state;')
1460+
code.append('} ompi_abi_wrapper_helper_t;')
1461+
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)')
1462+
code.append('{')
1463+
code.append(' ompi_abi_wrapper_helper_t *helper = (ompi_abi_wrapper_helper_t *)extra_state;')
1464+
code.append(' MPI_Win_ABI_INTERNAL win_tmp = ompi_convert_win_ompi_to_standard(oldwin);')
1465+
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);')
1466+
code.append('}')
1467+
code.append('static int ompi_abi_delete_attr_fn(MPI_Win oldwin, int win_keyval, void *attribute_val, void *extra_state)')
1468+
code.append('{')
1469+
code.append(' ompi_abi_wrapper_helper_t *helper = (ompi_abi_wrapper_helper_t *)extra_state;')
1470+
code.append(' MPI_Win_ABI_INTERNAL win_tmp = ompi_convert_win_ompi_to_standard(oldwin);')
1471+
code.append(' return helper->user_delete_fn((MPI_Win_ABI_INTERNAL)win_tmp, win_keyval, attribute_val, helper->user_extra_state);')
1472+
code.append(' free(helper);')
1473+
code.append('}')
1474+
return code
1475+
1476+
13901477
@Type.add_type('WIN_DELETE_ATTR_FUNCTION', abi_type=['ompi'])
13911478
class TypeWinDeleteAttrFunction(Type):
13921479

@@ -1396,8 +1483,6 @@ def type_text(self, enable_count=False):
13961483

13971484
@Type.add_type('WIN_DELETE_ATTR_FUNCTION', abi_type=['standard'])
13981485
class TypeWinDeleteAttrFunctionStandard(Type):
1399-
# TODO: This may require a special function to wrap the callback
1400-
# pass
14011486

14021487
def type_text(self, enable_count=False):
14031488
type_name = self.mangle_name('MPI_Win_delete_attr_function')

0 commit comments

Comments
 (0)