diff --git a/maint/gen_abi.py b/maint/gen_abi.py index d449339aabd..826bc747b94 100644 --- a/maint/gen_abi.py +++ b/maint/gen_abi.py @@ -25,6 +25,7 @@ def search(pat, str, flags=0): def main(): load_mpi_abi_h("src/binding/abi/mpi_abi.h") dump_mpi_abi_internal_h("src/binding/abi/mpi_abi_internal.h") + dump_io_abi_internal_h("src/binding/abi/io_abi_internal.h") dump_romio_abi_internal_h("src/mpi/romio/include/romio_abi_internal.h") dump_mpi_abi_util_c("src/binding/abi/mpi_abi_util.c") @@ -101,7 +102,7 @@ def gen_mpi_abi_internal_h(out): for line in output_lines: print(line, file=Out) print("", file=Out) - + print("#endif /* MPI_ABI_INTERNAL_H_INCLUDED */", file=Out) def dump_romio_abi_internal_h(romio_abi_internal_h): @@ -181,6 +182,52 @@ def add_other(out): print("#define ROMIO_ABI_INTERNAL_H_INCLUDED", file=Out) print("", file=Out) + for line in output_lines: + print(line, file=Out) + print("", file=Out) + + print("#endif /* ROMIO_ABI_INTERNAL_H_INCLUDED */", file=Out) + +# similar to romio_abi_internal.h but for use in the mpich io binding +def dump_io_abi_internal_h(io_abi_internal_h): + def gen_io_abi_internal_h(out): + for line in G.abi_h_lines: + if RE.search(r'MPI_ABI_H_INCLUDED', line): + # skip the include guard, harmless + pass + elif RE.match(r'typedef struct.*\bMPI_File;\s*$', line): + out.append("typedef struct ADIOI_FileD *MPI_File;") + elif RE.match(r'(int|double|MPI_\w+) (P?MPI\w+)\((.*)\);', line): + # prototypes, rename param prefix, add MPICH_API_PUBLIC + (T, name, param) = RE.m.group(1,2,3) + if RE.match(r'P?MPI_(File_\w+|Register_datarep\w*)', name): + out.append("%s %s(%s) MPICH_API_PUBLIC;" % (T, name, param)) + else: + out.append("%s %s(%s);" % (T, name, param)) + else: + # replace param prefix + out.append(line.rstrip()) + + def add_mpich_visibility(out): + out.append("#if defined(HAVE_VISIBILITY)") + out.append("#define MPICH_API_PUBLIC __attribute__((visibility (\"default\")))") + out.append("#else") + out.append("#define MPICH_API_PUBLIC") + out.append("#endif") + out.append("") + + # ---- + output_lines = [] + add_mpich_visibility(output_lines) + gen_io_abi_internal_h(output_lines) + + print(" --> [%s]" % io_abi_internal_h) + with open(io_abi_internal_h, "w") as Out: + dump_copyright(Out) + print("#ifndef ROMIO_ABI_INTERNAL_H_INCLUDED", file=Out) + print("#define ROMIO_ABI_INTERNAL_H_INCLUDED", file=Out) + print("", file=Out) + for line in output_lines: print(line, file=Out) print("", file=Out) diff --git a/maint/gen_binding_c.py b/maint/gen_binding_c.py index bb9700f3dd7..666556a3c75 100644 --- a/maint/gen_binding_c.py +++ b/maint/gen_binding_c.py @@ -161,10 +161,26 @@ def dump_io_funcs(): dump_out(c_dir + "/io.c") + def dump_io_funcs_abi(): + G.out = [] + G.out.append("#include \"mpichconf.h\"") + G.out.append("#include \"io_abi_internal.h\"") + G.out.append("#include \"mpir_io_impl.h\"") + G.out.append("#include ") + G.out.append("") + + for func in io_func_list: + dump_func_abi(func) + + abi_file_path = abi_dir + "/io_abi.c" + G.check_write_path(abi_file_path) + dump_c_file(abi_file_path, G.out) + # ---- dump_c_binding() dump_c_binding_abi() dump_io_funcs() + dump_io_funcs_abi() if 'output-mansrc' in G.opts: f = c_dir + '/mansrc/' + 'poly_aliases.lst' diff --git a/maint/local_python/binding_c.py b/maint/local_python/binding_c.py index e30d203383e..4fb92e4ab71 100644 --- a/maint/local_python/binding_c.py +++ b/maint/local_python/binding_c.py @@ -81,14 +81,18 @@ def dump_romio_reference(name): dump_profiling(func) - if 'polymorph' in func: + skip_wrappers = False + if func['dir'] == 'io' and '_is_abi' in func: + # The mpi-abi version of io bindings does not have access to MPICH internals (i.e. mpiimpl.h) + dump_function_io(func) + skip_wrappers = True + elif 'polymorph' in func: # MPII_ function to support C/Fortran Polymorphism, eg MPI_Comm_get_attr G.out.append("#ifndef MPICH_MPI_FROM_PMPI") dump_function_internal(func, kind="polymorph") G.out.append("#endif /* MPICH_MPI_FROM_PMPI */") G.out.append("") - if 'polymorph' in func: dump_function_internal(func, kind="call-polymorph") elif 'replace' in func and 'body' not in func: pass @@ -96,7 +100,9 @@ def dump_romio_reference(name): dump_function_internal(func, kind="normal") G.out.append("") - if '_is_abi' in func: + if skip_wrappers: + pass + elif '_is_abi' in func: dump_abi_wrappers(func, func['_is_large']) else: # Create the MPI and QMPI wrapper functions that will call the above, "real" version of the @@ -845,6 +851,48 @@ def dump_copy_right(): G.out.append(" */") G.out.append("") +def dump_function_io(func): + is_large = func['_is_large'] + parameters = "" + for p in func['c_parameters']: + parameters = parameters + ", " + p['name'] + + func_decl = get_declare_function(func, is_large) + + dump_line_with_break(func_decl) + G.out.append("{") + G.out.append("INDENT") + if "impl" in func and func['impl'] == "direct": + dump_function_direct(func) + else: + G.out.append("int mpi_errno = MPI_SUCCESS;") + if not '_skip_global_cs' in func: + G.out.append("MPIR_Ext_cs_enter();") + G.out.append("") + G.out.append("#ifndef HAVE_ROMIO") + if not '_is_abi' in func: + G.out.append("mpi_errno = MPIR_Err_create_code(MPI_SUCCESS, MPIR_ERR_RECOVERABLE, __func__, __LINE__, MPI_ERR_OTHER, \"**notimpl\", 0);") + else: + G.out.append("mpi_errno = MPI_ERR_INTERN;") + G.out.append("goto fn_fail;"); + G.out.append("#else") + dump_body_of_routine(func) + G.out.append("#endif") + G.out.append("") + G.out.append("fn_exit:") + if not '_skip_global_cs' in func: + G.out.append("MPIR_Ext_cs_exit();") + G.out.append("return mpi_errno;") + G.out.append("fn_fail:") + if '_has_file' in func: + G.out.append("mpi_errno = MPIO_Err_return_file(%s, mpi_errno);" % func['_has_file']) + else: + G.out.append("mpi_errno = MPIO_Err_return_file(MPI_FILE_NULL, mpi_errno);") + G.out.append("goto fn_exit;") + G.out.append("DEDENT") + G.out.append("}") + G.out.append("") + def dump_qmpi_wrappers(func, is_large): parameters = "" for p in func['c_parameters']: