📄 buildiface
字号:
#! /usr/bin/perl## 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$buildfiles = 1;$build_prototypes = 1;$print_line_len = 0;$write_mpif = 1;$debug = 0;@arg_addresses = ();#feature variables$do_logical = 1;$do_fint = 1;$do_weak = 1;$do_subdecls = 1;$do_bufptr = 1;$prototype_file = "../../include/mpi.h.in";# 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 (/-debug/) { $debug = 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; } } else { print STDERR "Unrecognized argument $_\n"; }}%tof77 = ( 'MPI_Datatype' => 'MPI_Fint *', 'MPI_Comm' => 'MPI_Fint *', '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 'int' => 'MPI_Fint *', 'int [][3]' => 'MPI_Fint *', 'MPI_Datatype *' => 'MPI_Fint *', '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 *', 'MPI_Op *' => 'MPI_Fint *', 'MPI_Status *' => 'MPI_Fint *', 'MPI_Info *' => 'MPI_Fint *', 'MPI_Errhandler *' => 'MPI_Fint *', );%argsneedcast = ( 'MPI_Request *' => '(MPI_Request *)(ARG)', 'MPI_Status *' => '(MPI_Status *)(ARG)', 'int [][3]' => '(int (*)[3])(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_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' => 'typeextent', '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)%special_routines = ( 'Init' => 1, 'Init_thread' => 1, 'Pcontrol' => '1', 'Address' => 1, 'Get_address' => 1, 'Keyval_create' => 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. Use a copy of the string# for the call to the C routine.# 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.# bufaddr: Argument is *output* as a buffer address. Discarded before# passing to Fortran.%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',# 'Scan' => '1:2', 'Scan-1' => 'in:bufptr', 'Scan-2' => 'in:bufptr', 'Add_error_string' => '2', 'Add_error_string-2' => 'in:addnull', 'Attr_put' => '3', 'Attr_put-3' => 'in:addrint', 'Attr_get' => '3:4', 'Attr_get-4' => 'out:logical', 'Attr_get-3' => 'out:attrint:4', 'Buffer_detach' => '1', 'Buffer_detach-1' => 'out:bufaddr', 'Cart_create' => '4:5', 'Cart_create-4' => 'in:logical_array:*v2', 'Cart_create-5' => 'in:logical', 'Cart_get' => '4', 'Cart_get-4' => 'out:logical_array:*v2', 'Comm_accept' => '1', 'Comm_accept-1' => 'in:addnull', 'Comm_connect' => '1', 'Comm_connect-1' => 'in:addnull', 'Comm_get_name' => '2', 'Comm_get_name-2' => 'out:blankpad', 'Comm_set_name' => '2', 'Comm_set_name-2' => 'in:addnull', 'Comm_spawn' => '1', 'Comm_spawn-1' => 'in:addnull', # really needs 2 args 'Comm_test_inter' => '2', 'Comm_test_inter-2' => 'out:logical', 'Get_processor_name' => '1', 'Get_processor_name-1' => 'out:blankpad', 'Error_string' => '2', 'Error_string-2' => 'out:blankpad', 'Intercomm_merge' => '2', 'Intercomm_merge-2' => 'in:logical', 'Info_get' => '2:4:5', 'Info_get-2' => 'in:addnull', 'Info_get-4' => 'out:blankpad', 'Info_get-5' => 'out:logical', 'Info_set' => '2:3', 'Info_set-2' => 'in:addnull', 'Info_set-3' => 'in:addnull', 'Info_get_nthkey' => '3', 'Info_get_nthkey-3' => 'in:addnull', 'Info_get_valuelen' => '2:4', 'Info_get_valuelen-2' => 'in:addnull', 'Info_get_valuelen-4' => 'out:logical', 'Lookup_name' => '1:3', 'Lookup_name-1' => 'in:addnull', 'Lookup_name-3' => 'out:blankpad', 'Open_port' => '2', 'Open_port-2' => 'in:addnull', 'Pack_external' => '1', 'Pack_external-1' => 'in:addnull', 'Pack_external_size' => '1', 'Pack_external_size-1' => 'in:addnull', 'Publish_name' => '1:3', 'Publish_name-1' => 'in:addnull', 'Publish_name-3' => 'in:addnull',# 'Comm_spawn_multiple => '2:3' are arrays and arrays of arrays 'Initialized' => '1', 'Initialized-1' => 'out:logical', 'Iprobe' => '4:5', 'Iprobe-4' => 'out:logical', 'Iprobe-5' => 'in:status', 'Probe' => '4', 'Probe-4' => 'in:status', 'Recv' => '7', 'Recv-7' => 'in:status', 'Sendrecv' => '12', 'Sendrecv-12' => 'in:status', 'Sendrecv_replace' => '9', 'Sendrecv_replace-9' => 'in:status',# 'Send' => '1', 'Send-1' => 'in:bufptr',# 'Ssend' => '1', 'Ssend-1' => 'in:bufptr',# 'Rsend' => '1', 'Rsend-1' => 'in:bufptr',# 'Bsend' => '1', 'Bsend-1' => 'in:bufptr',# 'Isend' => '1', 'Isend-1' => 'in:bufptr',# 'Issend' => '1', 'Issend-1' => 'in:bufptr',# 'Irsend' => '1', 'Irsend-1' => 'in:bufptr',# 'Ibsend' => '1', 'Ibsend-1' => 'in:bufptr',# 'Irecv' => '1', 'Irecv-1' => 'in:bufptr',# 'Recv' => '1', 'Recv-1' => 'in:bufptr', # 'Send_init' => '1', 'Send_init-1' => 'in:bufptr',# 'Bsend_init' => '1', 'Bsend_init-1' => 'in:bufptr',# 'Ssend_init' => '1', 'Ssend_init-1' => 'in:bufptr',# 'Rsend_init' => '1', 'Rsend_init-1' => 'in:bufptr',# 'Recv_init' => '1', 'Recv_init-1' => 'in:bufptr',# 'Sendrecv' => '1:6', 'Sendrecv-1' => 'in:bufptr', 'Sendrecv-6' => 'in:bufptr',# 'Sendrecv_replace' => '1', 'Sendrecv_replace-1' => 'in:bufptr', 'Test_cancelled' => '2', 'Test_cancelled-2' => 'out:logical', 'Test' => '2:3', 'Test-2' => 'out:logical', 'Test-3' => 'in:status', 'Testall' => '3:4', 'Testall-3' => 'out:logical', 'Testall-4' => 'in:status_array', 'Testany' => '3:4:5', 'Testany-4' => 'out:logical', 'Testany-3' => 'out:index', 'Testany-5' => 'in:status', 'Testsome' => '4:5', 'Testsome-4' => 'out:index_array:*v3', 'Testsome-5' => 'in:status_array', 'Type_get_name' => '2', 'Type_get_name-2' => 'out:blankpad', 'Type_set_name' => '2', 'Type_set_name-2' => 'in:addnull', 'Unpack_external' => '1', 'Unpack_external-1' => 'in:addnull', 'Unpublish_name' => '1:3', 'Unpublish_name-1' => 'in:addnull', 'Unpublish_name-3' => 'in:addnull', 'Win_get_name' => '2', 'Win_get_name-2' => 'out:blankpad', 'Win_set_name' => '2', 'Win_set_name-2' => 'in:addnull', 'Wait' => '2', 'Wait-2' => 'in:status', 'Waitall' => '3', 'Waitall-3' => 'in:status_array', 'Waitany' => '3:4', 'Waitany-3' => 'out:index', 'Waitany-4' => 'in:status', 'Waitsome' => '4:5', 'Waitsome-4' => 'out:index_array:*v3', 'Waitsome-5' => 'in:status_array', );$arg_string = join( ' ', @ARGV );if ($build_prototypes) { open( PROTOFD, ">fproto.h" ) || die "Cannot open fproto.h\n"; print PROTOFD "/* -*- Mode: C; c-basic-offset:4 ; -*- */\/* \ * (C) 2001 by Argonne National Laboratory.\ * See COPYRIGHT in top-level directory.\ *\ * This file is automatically generated by buildiface $arg_string\ * DO NOT EDIT\ */\/* Prototypes for Fortran Interface Functions */\n";}open( FD, "<$prototype_file" ) || die "Cannot open $prototype_file\n";# Skip to prototypeswhile (<FD>) { if ( /\/\*\s*Begin Prototypes/ ) { last; }}# Read each onewhile (<FD>) { # Remove any comments s/\/\*.*\*\///g; if (/\/\*\s*End Prototypes/ ) { last; } if (/^int\s*MPI_([A-Z][a-z0-9_]*)\s*\((.*)/) { $routine_name = $1; $args = $2; while (! ($args =~ /;/)) { $args .= <FD>; } $args =~ s/\)\s*;//g; $args =~ s/[\r\n]*//g; $lcname = lc($routine_name); # Eventually, we'll create a new file here. # For C++, we may create similar files by looking up # the corresponding routines. if (defined($special_routines{$routine_name})) { print "Skiping $routine_name\n" if $debug; } else { # Check for duplicates in the list of routines if (defined($mpi_routines{$routine_name})) { print STDERR "Duplicate prototypes for $routine_name\n"; } # Clear variables $clean_up = ""; &clean_args; $mpi_routines{$routine_name} = $args; if ($buildfiles) { if (defined($name_map{$lcname})) { $filename = $name_map{$lcname} . "f.c"; } else { $filename = $lcname . "f.c"; } $OUTFD = OUTPUTFILED; # Needed for pre 5.6 versions of perl open ($OUTFD, ">$filename" ) || die "Cannot open $filename\n"; # Add the name to the list of files" $files[$#files+1] = $filename; } else { $OUTFD = STDOUT; } &print_header( $routine_name, $lcname ); if ($do_subdecls) { print $OUTFD "FORTRAN_API void FORT_CALL "; } else { print $OUTFD "void "; } print $OUTFD "mpi_${lcname}_ "; # Print args not only prints the arguments but fills the # array @arg_addresses to indicate the number of dereference # operations are needed to recover the original value (since # all Fortran parameters are passed either by value-result or # by reference, many value parameters in the C calls are # replaced by reference parameters in the Fortran interface. print "Printing arguments for mpi_${lcname}_\n" if $debug; &print_args( $OUTFD, $args ); &print_attr; print $OUTFD "{\n"; &print_special_decls( $routine_name );
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -