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 60a18b62187..4ed9ce07c1f 100644 --- a/maint/gen_binding_c.py +++ b/maint/gen_binding_c.py @@ -145,46 +145,39 @@ def dump_c_binding_abi(): G.check_write_path(abi_file_path) dump_c_file(abi_file_path, G.out) - def dump_io_funcs(do_abi=False): + def dump_io_funcs(): + G.io_impl_declares = [] G.out = [] G.out.append("#include \"mpiimpl.h\"") - if do_abi: - G.out.append("#include \"mpi_abi_util.h\"") + G.out.append("#include \"mpir_io_impl.h\"") G.out.append("") - # Add a couple direct impl prototypes - G.out.append("void MPIR_Ext_cs_enter(void);") - G.out.append("void MPIR_Ext_cs_exit(void);") - G.out.append("#ifndef HAVE_ROMIO") - G.out.append("#define MPIO_Err_return_file(fh, errorcode) MPIR_Err_return_comm(0, __func__, errorcode)") - G.out.append("#else") - G.out.append("MPI_Fint MPIR_File_c2f_impl(MPI_File fh);") - G.out.append("MPI_File MPIR_File_f2c_impl(MPI_Fint fh);") - G.out.append("int MPIO_Err_return_file(MPI_File fh, int errorcode);") - G.out.append("#endif") - - G.doc3_src_txt = [] - G.poly_aliases = [] # large-count mansrc aliases for func in io_func_list: G.err_codes = {} manpage_out = [] - if not do_abi: - dump_func(func, manpage_out) - else: - dump_func_abi(func) - - if not do_abi: - dump_out(c_dir + "/io.c") - else: - abi_file_path = abi_dir + "/io_abi.c" - G.check_write_path(abi_file_path) - dump_c_file(abi_file_path, G.out) + dump_func(func, manpage_out) + + 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("") + + 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(True) + dump_io_funcs_abi() if 'output-mansrc' in G.opts: f = c_dir + '/mansrc/' + 'poly_aliases.lst' @@ -198,6 +191,7 @@ def dump_io_funcs(do_abi=False): G.check_write_path("src/include/mpi_proto.h") dump_Makefile_mk("%s/Makefile.mk" % c_dir) dump_mpir_impl_h("src/include/mpir_impl.h") + dump_mpir_io_impl_h("src/include/mpir_io_impl.h") dump_errnames_txt("%s/errnames.txt" % c_dir) dump_qmpi_register_h("src/mpi_t/qmpi_register.h") dump_mpi_proto_h("src/include/mpi_proto.h") diff --git a/maint/local_python/binding_c.py b/maint/local_python/binding_c.py index 1e74702be54..7abbb671834 100644 --- a/maint/local_python/binding_c.py +++ b/maint/local_python/binding_c.py @@ -81,14 +81,15 @@ def dump_romio_reference(name): dump_profiling(func) - if 'polymorph' in func: + if func['dir'] == 'io': + dump_function_io(func) + 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 @@ -208,6 +209,32 @@ def dump_mpix_symbols(): print("", file=Out) print("#endif /* MPIR_IMPL_H_INCLUDED */", file=Out) +def dump_mpir_io_impl_h(f): + print(" --> [%s]" %f) + with open(f, "w") as Out: + for l in G.copyright_c: + print(l, file=Out) + print("#ifndef MPIR_IO_IMPL_H_INCLUDED", file=Out) + print("#define MPIR_IO_IMPL_H_INCLUDED", file=Out) + + print("", file=Out) + print("void MPIR_Ext_cs_enter(void);", file=Out) + print("void MPIR_Ext_cs_exit(void);", file=Out) + print("#ifndef HAVE_ROMIO", file=Out) + print("int MPIR_Err_return_comm(void *, const char[], int);", file=Out) + print("#define MPIO_Err_return_file(fh, errorcode) MPIR_Err_return_comm((void *)0, __func__, errorcode)", file=Out) + print("#else", file=Out) + print("MPI_Fint MPIR_File_c2f_impl(MPI_File fh);", file=Out) + print("MPI_File MPIR_File_f2c_impl(MPI_Fint fh);", file=Out) + print("int MPIO_Err_return_file(MPI_File fh, int errorcode);", file=Out) + print("#endif", file=Out) + + print("", file=Out) + for l in G.io_impl_declares: + print(l, file=Out) + print("", file=Out) + print("#endif /* MPIR_IO_IMPL_H_INCLUDED */", file=Out) + def filter_out_abi(): funcname = None for l in G.out: @@ -816,6 +843,62 @@ 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) + func_name = get_function_name(func, is_large) + # declare impl functions, but only do it once + if '_is_abi' not in func and 'return' not in func: + if func['_is_large'] and func['_poly_impl'] != "separate": + pass + else: + impl_name = re.sub(r'^MPIX?_', 'MPIR_', func['name']) + "_impl" + if func['_is_large'] and func['_poly_impl'] == "separate": + impl_name = re.sub(r'_impl$', '_large_impl', impl_name) + if func['_impl_param_list']: + params = ', '.join(func['_impl_param_list']) + else: + params="void" + G.io_impl_declares.append("int %s(%s);" % (impl_name, params)) + + 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']: