📄 buildiface
字号:
#! /usr/bin/perl -w## This file builds candidate interface files from the descriptions in # mpi.h## Here are the steps:# 1) Find the prototypes in mpi.h.in (Look for *Begin Prototypes*)# 2) For each function, match the name and args:# int MPI_xxxx( ... )# 3) Create a new file with the name lc(xxxx)f.c (lowercase of name), # containing # Copyright# Profiling block indicator# Fortran name version of function, with MPI objects replaced by # MPI_Fint etc. as appropriate# ## Setup global variables%CtoFName = ();@ExtraRoutines = ();$buildfiles = 1;$build_prototypes = 1;$buildMakefile = 1;$prototype_header_file = "fproto.h";$build_io = 1;$print_line_len = 0;$write_mpif = 1;$is_MPI = 1;$do_profiling = 1;$routine_prefix = "MPI_";$routine_pattern = "[A-Z][a-z0-9_]*";$out_prefix="mpi_";$malloc = "MPIU_Malloc";$free = "MPIU_Free";$header_file = "mpi_fortimpl.h";$debug = 0;$writeRoutineList = 0; # Set to 1 to get a list of MPI routines@arg_addresses = ();## Error return handling$errparmtype = "MPI_Fint *";$errparm = "MPI_Fint *ierr";$errparmlval = "*ierr";$errparmrval = "*ierr";$returnErrval = 0;$returnType = "void";%altweak = (); # Alternate weak declarations%altweakrtype = ();#feature variables$do_logical = 1;$do_weak = 1;$do_subdecls = 1;$do_bufptr = 1;$prototype_file = "../../include/mpi.h.in";# Global hashes used for definitions and to record the locations of the# defintions.%mpidef = ();%mpidefFile = ();%mpiRoutinesFile = ();# Handle special initializations## Notes on this string. Some symbols need to be initialized at runtime.# These are typically the addresses of the "special" Fortran symbols, # such as MPIR_F_MPI_BOTTOM. Because MPI-2 requires that MPI_Init and # MPI_Init_thread, called in *any* language, initalize MPI for *all*# languages, we can't depend on having the Fortran versions of MPI_Init or# MPI_Init_thread called before these values might be used in a Fortran# wrapper function.# We also cannot have the C version of MPI_Init and MPI_Init_thread call # the initialization routine, because some Fortran compilers will require# special routines from that particular vendors Fortran runtime library for# any executable that uses routines that are compiled with the Fortran # compiler, forcing user programs that are entirely C to link with the # Fortran runtime. Thus, we must check whether the values are initialized# before any use in any routine.$specialInitAdded = 0;$specialInitString = "\ if (MPIR_F_NeedInit){ mpirinitf_(); MPIR_F_NeedInit = 0; }";# Process arguments## Args# -feature={logical,fint,subdecls,weak,bufptr}, separated by :, value given # by =on or =off, eg# -feature=logical=on:fint=off# The feature names mean:# logical - Fortran logicals are converted to/from C# fint - Fortran integers and C ints are different size (not implemented)# subdecls - Declarations for PC-Fortran compilers added# weak - Use weak symbols # bufptr - Check for MPI_BOTTOM as a special address. This is# not needed if a POINTER declaration is available.foreach $_ (@ARGV) { if (/-noprototypes/) { $build_prototypes = 0; } elsif (/-infile=(.*)/) { # Special arg to help with debugging $prototype_file = $1; $write_mpif = 0; $build_prototypes = 0; $do_weak = 0; } elsif (/-noromio/) { $build_io = 0; } elsif (/-debug/) { $debug = 1; } elsif (/-prefix=(.*)/) { $routine_prefix = $1; $is_MPI = 0; } elsif (/-pattern=(.*)/) { $routine_pattern = $1; } elsif (/-feature=(.*)/) { foreach $feature (split(/:/,$1)) { print STDERR "Processing feature $feature\n" if $debug; # Feature values are foo=on,off ($name,$value) = split(/=/,$feature); if ($value eq "on") { $value = 1; } elsif ($value eq "off") { $value = 0; } # Set the variable based on the string $varname = "do_$name"; $$varname = $value; } } elsif (/deffile=(.*)/) { $definition_file = $1; $is_MPI = 0; } else { print STDERR "Unrecognized argument $_\n"; }}# Note that the code that looks up values strips blanks out of the type name# No blanks should be used in the key.%tof77 = ( 'MPI_Datatype' => 'MPI_Fint *', 'MPI_Comm' => 'MPI_Fint *',#MPI_File must be handled specially, since ROMIO still uses pointers 'MPI_File' => 'MPI_Fint *', 'MPI_Win' => 'MPI_Fint *', 'MPI_Request' => 'MPI_Fint *', 'MPI_Group' => 'MPI_Fint *', 'MPI_Op' => 'MPI_Fint *', 'MPI_Info' => 'MPI_Fint *', 'MPI_Errhandler' => 'MPI_Fint *', 'MPI_Aint' => 'MPI_Fint *', # Should be MPIR_FAint 'MPI_Offset' => 'MPI_Offset *', # Should be MPIR_FOint 'int' => 'MPI_Fint *', 'int[]' => 'MPI_Fint', # no * because we'll use array form 'int[][3]' => 'MPI_Fint', # no * because we'll use array form 'MPI_Datatype*' => 'MPI_Fint *', 'MPI_Datatype[]' => 'MPI_Fint', # no * because we'll use array form 'MPI_Comm*' => 'MPI_Fint *', 'MPI_File*' => 'MPI_Fint *', 'MPI_Win*' => 'MPI_Fint *', 'MPI_Group*' => 'MPI_Fint *', 'MPI_Request*' => 'MPI_Fint *', 'MPI_Aint*' => 'MPI_Fint *', # Should be MPIR_FAint 'int *' => 'MPI_Fint *', 'int*' => 'MPI_Fint *', # Catch missing space 'MPI_Op*' => 'MPI_Fint *', 'MPI_Status*' => 'MPI_Fint *', 'MPI_Info*' => 'MPI_Fint *', 'MPI_Errhandler*' => 'MPI_Fint *', );# declarg is special parameters for certain routines%declarg = ( 'type_extent-2' => 'MPI_Fint *', 'type_lb-2' => 'MPI_Fint *', 'type_ub-2' => 'MPI_Fint *', 'type_struct-3' => 'MPI_Fint *', # Really [], but * is easier 'type_hindexed-3' => 'MPI_Fint *', # As above 'type_hvector-3' => 'MPI_Fint *', # The following are MPI-2 routines with address args. # For these, the user must pass in the correct arguments 'file_get_type_extent-3' => 'MPI_FAint *', 'pack_external-6' => 'MPI_Aint *', # Value in C call 'pack_external-7' => 'MPI_Aint *', 'pack_external_size-4' => 'MPI_Aint *', 'type_create_hvector-3' => 'MPI_Aint *', # Value in C call 'type_create_hindexed-3' => 'MPI_Aint *', 'type_create_struct-3' => 'MPI_Aint *', 'type_get_contents-6' => 'MPI_Aint *', 'type_get_extent-2' => 'MPI_Aint *', 'type_get_extent-3' => 'MPI_Aint *', 'type_get_true_extent-2' => 'MPI_Aint *', 'type_get_true_extent-3' => 'MPI_Aint *', 'type_create_resized-2' => 'MPI_Aint *', # Value in C call 'type_create_resized-3' => 'MPI_Aint *', # Value in C call 'unpack_external-3' => 'MPI_Aint *', # Value in C call 'unpack_external-4' => 'MPI_Aint *', 'win_create-2' => 'MPI_Aint *', 'accumulate-5' => 'MPI_Aint *', 'put-5' => 'MPI_Aint *', 'get-5' => 'MPI_Aint *', 'alloc_mem-1' => 'MPI_Aint *', );%argsneedcast = ( 'MPI_Request *' => '(MPI_Request *)(ARG)', 'MPI_Status *' => '(MPI_Status *)(ARG)', 'MPI_File' => 'MPI_File_f2c(ARG)', 'MPI_Comm' => '(MPI_Comm)(ARG)', 'MPI_Comm *' => '(MPI_Comm *)(ARG)', 'MPI_Datatype' => '(MPI_Datatype)(ARG)', 'MPI_Datatype *' => '(MPI_Datatype *)(ARG)', 'MPI_Info *' => '(MPI_Info *)(ARG)', 'MPI_Info' => '(MPI_Info)(ARG)', 'int [][3]' => '(int (*)[3])(ARG)');#### For implementations other than MPICH2, we'll need to consider using## MPI_C2f_<name> and MPI_F2c_<name>, as in ## 'MPI_Info' => 'MPI_F2c_info(ARG)'### name_map maps the filenames. Most filenames are created automatically# from the routine name, but some names have too many characters (15, # including the extension(.o) is a limit for ar in some systems).%name_map = ( 'add_error_class' => 'adderrclass', 'add_error_code' => 'adderrcode', 'add_error_string' => 'adderrstring', 'buffer_attach' => 'bufattach', 'buffer_detach' => 'bufdetach', 'comm_call_errhandler' => 'commcallerr', 'comm_create_errhandler' => 'commcreerr', 'comm_create_keyval' => 'commnewkey', 'comm_delete_attr' => 'commdelattr', 'comm_disconnect' => 'commdisc', 'comm_free_keyval' => 'commfreekey', 'comm_get_errhandler' => 'commgeterr', 'comm_get_name' => 'commgetnam', 'comm_get_parent' => 'commparent', 'comm_remote_group' => 'commrgroup', 'comm_remote_size' => 'commrsize', 'comm_set_errhandler' => 'commseterr', 'comm_spawn_multiple' => 'spawnmult', 'comm_test_inter' => 'commtestic', 'errhandler_create' => 'errhcreate', 'errhandler_free' => 'errhfree', 'errhandler_get' => 'errhget', 'errhandler_set' => 'errhset', 'file_call_errhandler' => 'filecallerr', 'file_create_errhandler' => 'filecreerr', 'file_get_errhandler' => 'filegeterr', 'file_set_errhandler' => 'fileseterr', 'get_processor_name' => 'getpname', 'graph_neighbors_count' => 'grfnbcount', 'graph_neighbors' => 'grfnbrs', 'grequest_complete' => 'greqcomplete', 'grequest_start' => 'greqstart', 'group_difference' => 'groupdiff', 'group_intersection' => 'groupinter', 'group_range_excl' => 'grouprexcl', 'group_range_incl' => 'grouprincl', 'group_translate_ranks' => 'grouptranks', 'info_get_nkeys' => 'infognk', 'info_get_nthkey' => 'infognthk', 'info_get_valuelen' => 'infovallen', 'intercomm_create' => 'iccreate', 'intercomm_merge' => 'icmerge', 'is_thread_main' => 'isthrmain', 'pack_external_size' => 'packesize', 'reduce_scatter' => 'redscat', 'request_get_status' => 'reqgetstat', 'sendrecv_replace' => 'sndrcvrpl', 'status_set_cancelled' => 'statgetcl', 'status_set_elements' => 'statsetel', 'test_cancelled' => 'testcancel', 'type_contiguous' => 'typecontig', 'type_create_darray' => 'typedarray', 'type_create_f90_integer' => 'typef90int', 'type_create_f90_real' => 'typef90real', 'type_create_f90_complex' => 'typef90cmplx', 'type_create_hindexed' => 'typechind', 'type_create_hvector' => 'typechvec', 'type_create_indexed_block' => 'typecindb', 'type_create_keyval' => 'typenewkey', 'type_create_resized' => 'typecresize', 'type_create_struct' => 'typecstruct', 'type_create_subarray' => 'typecsubarr', 'type_delete_attr' => 'typedelattr', 'type_free_keyval' => 'typefreekey', 'type_get_contents' => 'typegetcnts', 'type_get_envelope' => 'typegetenv', 'type_get_extent' => 'typegetextent', # there is already a type_extent 'type_get_name' => 'typegname', 'type_get_true_extent' => 'typegtext', 'type_set_attr' => 'typesetattr', 'type_set_name' => 'typesetname', 'unpack_external' => 'unpackext', 'unpublish_name' => 'unpubname', 'win_call_errhandler' => 'wincallerr', 'win_create_errhandler' => 'wincreerr', 'win_create_keyval' => 'winnewkey', 'win_delete_attr' => 'windelattr', 'win_free_keyval' => 'winfreekey', 'win_get_errhandler' => 'wingeterr', 'win_set_errhandler' => 'winseterr',);## Special routines have very different calling seqences in C and Fortran# or different behavior.# Init and Init thread have different arg lists (no argc, argv)# Pcontrol has no varargs# Address and Get_address require special integer types and# possibly handling for MPI_BOTTOM# Keyval routines require setting the language to Fortran (Attribute# routines are handled with the special argument processing)## The Type_create_f90_xxx routines are only available as part of the# extended Fortran support, and are excluded from the f77 routines.%special_routines = ( 'Init' => 1, 'Init_thread' => 1, 'Pcontrol' => '1', 'Address' => 1, 'Get_address' => 1, 'Keyval_create' => 1, 'Status_f2c' => 1, 'Status_c2f' => 1, 'Type_create_f90_integer' => 1, 'Type_create_f90_real' => 1, 'Type_create_f90_complex' => 1, );# # Note that wtime and wtick aren't found because they don't match the # int MPI_xxx format. They're handled directly by the special routine# code below## Most routines can be processed automatically. However, some# require some special processing. For example, those routines with# LOGICAL arguments need some special handling. To detect this, there# are two entries in a %special_args hash: the routine name, and the routine# name -arg#. E.g., for MPI_Test, the hash has keys# "Test" and "Test-2". The value for "Test-2" is "out:logical"; this # indicates that the variable is an out variable with logical type.# Processing types (the second field after the :) are# logical: convert to/from Fortran and C representations of logical# index: convert to/from Fortran (1-based) and C (0-based) origins# array: handle arrays of items that may have different lengths# in C and Fortran because the integer types have # different sizes. The term has an additional :expression,# the third term give the array size.# addnull: Add a null character to a *copy* of the input string,# after trimming any blanks.# blankpad: Add blanks and remove nulls. Only used for out args;# must use an allocated space to provide room for the null# that the C routines may require# bufptr: Detect MPI_BOTTOM. Note that a better alternative is to# use MPI_Address and MPI_Get_address to make addresses# relative to the Fortran MPI_BOTTOM. The lines that# define this are commented out below.# addrint: Given the address of an int, provide the int. Used# for attr_put/set routines # attrint: Convert an attribute value to an int.# addraint: Given the address of an address-sized int, provide the# value of that item. Used for the MPI-2 versions of the# attribute caching routines# bufaddr: Argument is *output* as a buffer address. Discarded before# passing to Fortran.# For MPI-2 routines that take MPI_Aints even in Fortran, we need a # special mapping when the value is passed to c# aintToVal: Given the address of an Aint, pass the value to the C routine# (This should really be done by not applying the Aint->int mapping# for MPI-2 routines. But for now, this hack will work)%special_args = ( # 'Allreduce' => '1:2', 'Allreduce-1' => 'in:bufptr', # 'Allreduce-2' => 'in:bufptr', # 'Bcast' => '1', 'Bcast-1' => 'in:bufptr', # 'Gather' => '1:4', 'Gather-1' => 'in:bufptr', 'Gather-4' => 'in:bufptr',# 'Gatherv' => '1:4', 'Gatherv-1' => 'in:bufptr', 'Gatherv-4' => 'in:bufptr',# 'Scatter' => '1:4', 'Scatter-1' => 'in:bufptr', 'Scatter-4' => 'in:bufptr',# 'Scatterv' => '1:5', 'Scatterv-1' => 'in:bufptr', 'Scatterv-5' => 'in:bufptr',# 'Allgather' => '1:4', 'Allgather-1' => 'in:bufptr', 'Allgather-4' => 'in:bufptr',# 'Allgatherv' => '1:4', 'Allgatherv-1' => 'in:bufptr', 'Allgatherv-4' => 'in:bufptr',# 'Alltoall' => '1:4', 'Alltoall-1' => 'in:bufptr', 'Alltoall-4' => 'in:bufptr',# 'Alltoallv' => '1:5', 'Alltoallv-1' => 'in:bufptr', 'Alltoallv-5' => 'in:bufptr',# 'Reduce' => '1:2', 'Reduce-1' => 'in:bufptr', 'Reduce-2' => 'in:bufptr',# 'Reduce_scatter' => '1:2', 'Reduce_scatter-1' => 'in:bufptr', # 'Reduce_scatter-2' => 'in:bufptr',
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -