📄 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) By groups, create a new file with the name {catname}.h containing # Copyright# For each function in the group, the expansion of the method## Each MPI routine is assigned to a group. Within each group,# a particular argument is (usually) eliminated from the C++ call.# E.g., in MPI::Send, the communicator argument is removed from the# call sequence.# Routines that have out parameters (e.g., the request in MPI_Isend)# remove them as well. Other routines return void.## The replacement text will look something like# void Name( args ) const {# MPIX_CALL( MPI_Name( args, with (cast)((class).the_real_(class)) ); }## A capability of this approach is that a stripped-down interface that # implements only the required routines can be created.## Data structures# %<class>_members (e.g., mpi1comm): keys are names of routines.# Values are string indicating processing:# returnvalue-arg (0 if void, type if unique, position if not)# Pass by reference to process routine# # TODO:# The derived classes (such as Intracomm) must *not* have their own# protected the_real_intracomm; instead, the must refer to the # parent class's private storage.## The pack, unpack, packsize, init, and finalize routines must be # placed in initcpp.cpp.## externs for the predefined objects need to be added to the# end of mpicxx.h## The optional no-status versions need to be created for # methods such as Recv, Test, and Sendrecv .## Setup global variables$buildfiles = 1;$build_sep_files = 0; # If false, build one huge mpicxx.h file$build_io = 1; # If false, exclude the MPI-IO routines$indent = " ";$print_line_len = 0;$debug = 0;@mpilevels = ( 'mpi1' , 'mpi2' );#feature variables$do_subdecls = 1;# 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:# subdecls - Declarations for PC-C++ compilers added# -routines=name - provide a list of routines or a file that# lists the routines to use. The names must be in the same form as the # the class_xxx variables. E.g., comm-Send, dtype-Commit.$routine_list = "";foreach $_ (@ARGV) { if (/-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 (/-nosep/) { $build_sep_files = 0; $indent = " "; } elsif (/-sep/) { $build_sep_files = 1; $indent = ""; } elsif (/-noromio/) { $build_io = 0; } elsif (/-debug/) { $debug = 1; } elsif (/-routines=(.*)/) { $routine_list = $1; } else { print STDERR "Unrecognized argument $_\n"; }}if (! -d "../../mpi/romio") { $build_io = 0; }# Value of the hash is the argument of the routine that returns a value%class_mpi1comm = ( Send => 0, Recv => 0, Bsend => 0, Ssend => 0, Rsend => 0, Isend => MPI_Request, Irsend => MPI_Request, Issend => MPI_Request, Ibsend => MPI_Request, Iprobe => 'int', Probe => 0, Send_init => MPI_Request, Bsend_init => MPI_Request, Rsend_init => MPI_Request, Recv_init => MPI_Request, Sendrecv => 0, Sendrecv_repl => 0, Get_size => 'int', Get_rank => 'int', Free => 0, Get_topology => 2, Get_group => MPI_Group, Compare => 'int', Abort => 0);%class_mpi1cart = ( 'Dup' => MPI_Comm, 'Get_dim' => 'int', 'Get_topo' => 'int', 'Get_cart_rank' => 'int', 'Shift' => 'int', 'Sub' => MPI_Comm, 'Map' => 0,);%class_mpi1dtype = ( 'Create_contiguous' => 'MPI_Datatype', 'Create_vector' => 'MPI_Datatype', 'Create_indexed' => 'MPI_Datatype', 'Get_size' => 2, 'Commit' => 0, 'Free' => 0, 'Pack' => 0, 'Unpack' => 0, 'Pack_size' => 4, );%class_mpi1errh = ( 'Free' => 0, # Init missing );%class_mpi1graph = ( 'Get_dims' => 0, 'Get_topo' => 0, 'Get_neighbors_count' => 'int', 'Get_neighbors' => 0, 'Map' => 0, );# Range routines will require special handling%class_mpi1group = ( 'Get_size' => 'int', 'Get_rank' => 'int', 'Translate_ranks' => 0, 'Compare' => 'int', 'Union' => MPI_Group, 'Intersect' => MPI_Group, 'Difference' => MPI_Group, 'Incl', MPI_Group, 'Excl', MPI_Group,# 'Range_incl', MPI_Group,# 'Range_excl', MPI_Group, 'Free' => 0,);%class_mpi1inter = ( 'Dup' => MPI_Comm, 'Get_remote_size' => 'int', 'Get_remote_group' => MPI_Group, 'Merge' => MPI_Comm, );%class_mpi1intra = ( 'Barrier' => 0, 'Bcast' => 0, 'Gather' => 0, 'Gatherv' => 0, 'Scatter' => 0, 'Scatterv' => 0, 'Allgather' => 0, 'Allgatherv' => 0, 'Alltoall' => 0, 'Alltoallv' => 0, 'Reduce' => 0, 'Allreduce' => 0, 'Reduce_scatter' => 0, 'Scan' => 0, 'Dup' => MPI_Comm, 'Create' => MPI_Comm, 'Split' => MPI_Comm, 'Create_intercomm' => MPI_Comm, 'Create_cart' => MPI_Comm, 'Create_graph' => MPI_Comm );%class_mpi1op = ( 'Free' => 0);%class_mpi1ppreq = ( 'Start' => 0, 'Startall' => 0 );%class_mpi1req = ( 'Wait' => 0, 'Test' => 'int', 'Free' => 0, 'Cancel' => 0, # multiple completion still missing);%class_mpi1st = ( 'Get_count' => 'int', 'Is_cancelled' => 'int', 'Get_elements' => 'int', # get/set source, tag, error have no C binding );%class_mpi2comm = ();%class_mpi2cart = ();%class_mpi2dtype = ( 'Set_name' => 0, 'Get_name' => 0);%class_mpi2errh = ();%class_mpi2graph = ();%class_mpi2group = ();%class_mpi2inter = ();# Alltoallw uses an array of datatypes, which requires special handling%class_mpi2intra = ( #'Alltoallw' => 0, 'Exscan' => 0 );%class_mpi2op = ();%class_mpi2ppreq = ();%class_mpi2req = ();%class_mpi2st = ();%class_mpi2file = ();if ($build_io) { %class_mpi2file = ( 'File_open' => 'MPI_File', 'File_close' => 0, 'File_delete' => 0, 'File_set_size' => 0, 'File_preallocate' => 0, 'File_get_size' => 'MPI_Offset', 'File_get_group' => 'MPI_Group', 'File_get_amode' => 'int', 'File_set_info' => 0, 'File_get_info' => 'MPI_Info', 'File_set_view' => 0, 'File_get_view' => 0, 'File_read_at' => 0, 'File_read_at_all' => 0, 'File_write_at' => 0, 'File_write_at_all' => 0, 'File_iread_at' => 'MPI_Request', 'File_iwrite_at' => 'MPI_Request', 'File_read' => 0, 'File_read_all' => 0, 'File_write' => 0, 'File_write_all' => 0, 'File_iread' => 'MPI_Request', 'File_iwrite' => 'MPI_Request', 'File_seek' => 0, 'File_get_position' => 'MPI_Offset', 'File_get_byte_offset' => 'MPI_Offset', 'File_read_shared' => 0, 'File_write_shared' => 0, 'File_iread_shared' => 'MPI_Request', 'File_iwrite_shared' => 'MPI_Request', 'File_read_ordered' => 0, 'File_write_ordered' => 0, 'File_seek_shared' => 0, 'File_get_position_shared' => 'MPI_Offset', 'File_read_at_all_begin' => 0, 'File_read_at_all_end' => 0, 'File_write_at_all_begin' => 0, 'File_write_at_all_end' => 0, 'File_read_all_begin' => 0, 'File_read_all_end' => 0, 'File_write_all_begin' => 0, 'File_write_all_end' => 0, 'File_read_ordered_begin' => 0, 'File_read_ordered_end' => 0, 'File_write_ordered_begin' => 0, 'File_write_ordered_end' => 0, 'File_get_type_extent' => 'MPI_Aint', 'File_set_atomicity' => 0, 'File_get_atomicity' => 'bool', 'File_sync' => 0, 'File_set_errhandler' => 'MPI_Errhandler', 'File_get_errhandler' => 0, ); }%class_mpi2win = ( );%class_mpi2info = ( );# Name of classes, in the order in which they must be declared.@classes = ( 'dtype', 'info', 'st', 'group', 'op', 'errh', 'req', 'preq', 'comm', 'inter', 'intra', 'greq', 'win', 'file', 'graph', 'cart', );# If there is a specific list of routines, replace the list with this# list%newclasses = ();if ($routine_list ne "") { for $routine (split(/\s+/,$routine_list)) { print "$routine\n" if $debug; ($class,$rname) = split(/-/,$routine); # Look up name in the class list $classvar = "class-mpi1$class"; $result_type = 0; if (defined($$classvar{$rname})) { $result_type = $$classvar{$rname}; } else { $classvar = "class-mpi2$class"; if (defined($$classvar{$rname})) { $result_type = $$classvar{$rname}; } } $newclasses{$class} .= " $rname=>$result_type"; } # Now, clear all of the classes foreach $class (@classes) { $class_name = "class_mpi1$class"; %$class_name = (); $class_name = "class_mpi2$class"; %$class_name = (); } # And unpack newclasses foreach $class (keys(%newclasses)) { $class_name = "class_mpi1$class"; foreach $rpair (split(/\s+/,$newclasses{$class})) { if ($rpair eq "") { next; } print "$rpair\n" if $debug; ($routine, $rval) = split(/=>/,$rpair); $$class_name{$routine} = $rval; } } # At this point, we should generate only the routines requested, # plus all of the classes (we may need the empty classes for the # predefined types)}# MPI objects@dtypes = ( 'CHAR', 'UNSIGNED_CHAR', 'BYTE', 'SHORT', 'UNSIGNED_SHORT', 'INT', 'UNSIGNED', 'LONG', 'UNSIGNED_LONG', 'FLOAT', 'DOUBLE', 'LONG_DOUBLE', 'LONG_LONG_INT', 'LONG_LONG', 'PACKED', 'LB', 'UB', 'FLOAT_INT', 'DOUBLE_INT', 'LONG_INT', 'SHORT_INT', 'LONG_DOUBLE_INT' );@ops = ( 'MAX', 'MIN', 'SUM', 'PROD', 'LAND', 'BAND', 'LOR', 'BOR', 'LXOR', 'BXOR', 'MINLOC', 'MAXLOC', 'REPLACE' );## Special routines require special processing in C++%special_routines = ( 'Init' => 1, 'Init_thread' => 1, 'Pcontrol' => '1' );## Most routines can be processed automatically. However, some# require some special processing. (See the Fortran version# of buildiface)$arg_string = join( ' ', @ARGV );# ---------------------------------------------------------------------------# Here begins more executable code. Read the definitions of the # routines&ReadInterface( "../../include/mpi.h.in" );# if doing MPI2, we also need to read the MPI-2 protottypesif ( -s "../../mpi/romio/include/mpio.h.in" ) { &ReadInterface( "../../mpi/romio/include/mpio.h.in" );}%class_type = ( 'comm' => MPI_Comm, 'cart' => MPI_Comm, 'dtype' => MPI_Datatype, 'errh' => MPI_Errhandler, 'graph' => MPI_Comm, 'group' => MPI_Group, 'inter' => MPI_Comm, 'intra' => MPI_Comm, 'op' => MPI_Op, 'preq' => MPI_Request, 'req' => MPI_Request, 'greq' => MPI_Request, 'st' => MPI_Status, 'info' => MPI_Info, 'win' => MPI_Win, 'file' => MPI_File, );%fullclassname = ( 'comm' => 'Comm', 'cart' => 'Cartcomm', 'dtype' => 'Datatype', 'errh' => 'Errhandler', 'graph' => 'Graphcomm', 'group' => 'Group', 'inter' => 'Intercomm', 'intra' => 'Intracomm', 'op' => 'Op', 'preq' => 'Prequest', 'req' => 'Request', 'st' => 'Status', 'greq' => 'Grequest', 'info' => 'Info', 'win' => 'Win', 'file' => 'File',);## Each class may need to access internal elements of another class.# This has gives the list of friends for each class%class_friends = ( 'comm' => 'Cartcomm,Intercomm,Intracomm,Graphcomm,Datatype', 'cart' => '', 'dtype' => 'Comm,Status,Intracomm,Intercomm', 'errh' => '', 'graph' => '', 'group' => 'Comm,Intracomm,Intercomm', 'inter' => 'Intracomm', 'intra' => 'Cartcomm,Graphcomm,Datatype', 'op' => 'Intracomm', 'preq' => '', 'req' => 'Comm', 'st' => 'Comm,File,Request', 'greq' => '', 'info' => '', 'win' => 'Datatype', 'file' => 'Datatype,Info,Group', );## We also need to know the derived classes%derived_class = ( 'graph' => 'Intracomm', 'preq' => 'Request', 'inter' => 'Comm', 'intra' => 'Comm', 'greq' => 'Request', 'cart' => 'Intracomm', );## Maps all of the derived classes to their ultimate parent%mytopclass = ( 'graph' => 'comm', 'intracomm' => 'comm', 'intercomm' => 'comm', 'intra' => 'comm', 'inter' => 'comm', 'cart' => 'comm',
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -