Commit da9e5e5a authored by William Gropp's avatar William Gropp Committed by Pavan Balaji
Browse files

Change buildiface for C++ to control output order



Add a way to output the order of function output in mpicxx.h.in file
and a way to read in a file specifying the order.  This is used to
meet ABI needs.  Also fixed some old MPI_xxx vs MPI::xxx cases, and
the almost duplicated Create_struct call.  All in a single commit
because the test was against the proposed ABI mpicxx.h.in file
Signed-off-by: Pavan Balaji's avatarPavan Balaji <balaji@mcs.anl.gov>
parent 88580cc2
......@@ -55,6 +55,13 @@
# will have the correct type and some C++ compilers don't recognize NULL
# unless you include header files that needed it and are otherwise unneeded
# by the C++ interface)
#
# To fix the order of virtual methods, the arrays
# @routinesMpi1base
# @routinesMpi2base
# @routines<classname>
# may be defined. If these are not defined, then the order will be determined
# by the perl implementation of the "keys" function.
#
# TODO:
# The derived classes (such as Intracomm) must *not* have their own
......@@ -82,6 +89,8 @@ $gDebugRoutine = "NONE";
$do_subdecls = 1;
$doCoverage = 0;
$doFuncspec = 1;
$outputRoutineLists = 0;
# Process environment variables
# CXX_COVERAGE - yes : turn on coverage code
if (defined($ENV{"CXX_COVERAGE"}) && $ENV{"CXX_COVERAGE"} eq "yes") {
......@@ -99,7 +108,12 @@ if (defined($ENV{"CXX_COVERAGE"}) && $ENV{"CXX_COVERAGE"} eq "yes") {
# -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.
# -routinelist - output files containing the routines to output in the
# classes (mostly as virtual functions) and the order in which they are output
# This can be used to change the output order if it is desired to specify
# a particular order.
$routine_list = "";
$initFile = "";
foreach $_ (@ARGV) {
if (/--?feature=(.*)/) {
foreach $feature (split(/:/,$1)) {
......@@ -125,7 +139,9 @@ foreach $_ (@ARGV) {
elsif (/--?routines=(.*)/) {
$routine_list = $1;
}
elsif (/--?coverage/) { &setCoverage( 1 ); }
elsif (/--?routinelist/) { $outputRoutineLists = 1; }
elsif (/--?initfile=(.*)/) { $initFile = $1; }
elsif (/--?coverage/) { &setCoverage( 1 ); }
elsif (/--?nocoverage/) { &setCoverage( 0 ); }
else {
print STDERR "Unrecognized argument $_\n";
......@@ -133,6 +149,10 @@ foreach $_ (@ARGV) {
}
if (! -d "../../mpi/romio") { $build_io = 0; }
if ($initFile ne "" && -f $initFile) {
do $initFile;
}
# ----------------------------------------------------------------------------
#
# The following hashes define each of the methods that belongs to each class.
......@@ -292,11 +312,14 @@ $specialReturnType{"cart-Dup"} = "Cartcomm";
$specialReturnType{"cart-Sub"} = "Cartcomm";
$specialReturnType{"cart-Split"} = "Cartcomm";
# Create_struct, Pack, and Unpack are handled through definitions elsewhere
# Pack, and Unpack are handled through definitions elsewhere
# Create_struct is also handled through definitions elsewhere, but for
# compatibility with some previous versions, a slightly different
# declaration is generated for this class.
%class_mpi1dtype = ( 'Create_contiguous' => 'MPI_Datatype',
'Create_vector' => 'MPI_Datatype',
'Create_indexed' => 'MPI_Datatype',
# 'Create_struct' => 'static:5:4',
'Create_struct' => 'static:5:4',
'Get_size' => 2,
'Commit' => 0,
'Free' => 0,
......@@ -1126,12 +1149,25 @@ class File;
# and we'll want to use a few of them in the implementations of the
# other functions.
print $OUTFD "// base (classless) routines\n";
foreach $routine (keys(%class_mpi1base)) {
@routines = keys(%class_mpi1base);
if (defined(@routinesMpi1base)) {
@routines = @routinesMpi1base;
}
if ($outputRoutineLists) {
open (FD, ">order.mpi1base.txt" );
print FD "\@routinesMpi1base = (\n";
}
foreach $routine (@routines) {
print FD "\t\"$routine\",\n" if ($outputRoutineLists);
# These aren't really a class, so they don't use Begin/EndClass
$arginfo = $class_mpi1base{$routine};
print $OUTFD "extern ";
&PrintRoutineDef( $OUTFD, "base", $routine, $arginfo, 1 );
}
if ($outputRoutineLists) {
print FD ");\n";
close (FD);
}
# Forward references for externals, used in error handling
print $OUTFD "extern Intracomm COMM_WORLD;\n";
......@@ -1178,13 +1214,23 @@ typedef int MPI_File;\
foreach $mpilevel (@mpilevels) {
$mpiclass = "$mpilevel$class";
$class_hash = "class_$mpiclass";
foreach $routine (keys(%$class_hash)) {
print "processing $routine\n" if $gDebug;
@routines = keys(%$class_hash);
$arrname = "routines$mpiclass";
if (defined(@$arrname)) {
@routines = @$arrname;
}
if ($#routines < 0) { next; }
if ($outputRoutineLists) {
open (FD, ">order.$arrname.txt" );
print FD "\@$arrname = (\n";
}
foreach $routine (@routines) {
print "processing $routine in $mpiclass\n" if $gDebug;
print FD "\t\"$routine\",\n" if ($outputRoutineLists);
# info describes the return parameter and any special
# processing for this routine.
$arginfo = $$class_hash{$routine};
print "Arginfo is $arginfo\n" if $gDebug;
&PrintRoutineDef( $OUTFD, $class, $routine, $arginfo, 0 );
# Check for Status as an arg (handle MPI_STATUS_IGNORE
......@@ -1194,6 +1240,10 @@ typedef int MPI_File;\
$routine, $arginfo, 0 );
}
}
if ($outputRoutineLists) {
print FD ");\n";
close (FD);
}
}
if (defined($class_extra_fnc{$class})) {
$extrafnc = $class_extra_fnc{$class};
......@@ -1216,13 +1266,26 @@ typedef int MPI_File;\
}
# Add a few more external functions (some require the above definitions)
foreach $routine (keys(%class_mpi2base)) {
# These aren't really a class, so they don't use Begin/EndClass
@routines = keys(%class_mpi2base);
if (defined(@routinesMpi2base)) {
@routines = @routinesMpi2base;
}
if ($outputRoutineLists) {
open (FD, ">order.$arrname.txt" );
print FD "\@routinesMpi2base = (\n";
}
foreach $routine (@routines) {
print FD "\t\"$routine\",\n" if ($outputRoutineLists);
# These aren't really a class, so they don't use Begin/EndClass
$arginfo = $class_mpi2base{$routine};
print $OUTFD "extern ";
#print "$routine - $arginfo\n";
&PrintRoutineDef( $OUTFD, "base", $routine, $arginfo, 1 );
}
if ($outputRoutineLists) {
print FD ");\n";
close (FD);
}
# Special case: the typedefs for the datarep function
# Only define these typedefs when MPI-IO is available (this is the same
# test as used for the rest of the I/O routines );
......@@ -1531,10 +1594,13 @@ sub print_args {
print STDERR "Internal error. Could not find basetype\n";
print STDERR "This may be a bug in perl in the handling of certain expressions\n";
}
# Convert C to C++ types
$cxxtype = $basetype;
$cxxtype =~ s/MPI_//;
if ($extrabracks =~ /(\[[\d\s]*\])/) {
$otherdims = $1;
}
print $OUTFD "$qualifier$basetype v$count\[\]$otherdims";
print $OUTFD "$qualifier$cxxtype v$count\[\]$otherdims";
}
elsif ($parm =~ /\.\.\./) {
# Special case for varargs. Only ints!
......@@ -3757,7 +3823,18 @@ sub PrintRoutineDef {
($cArgs, $Croutine) = &GetCArgs( $class, $routine );
&PrintMethodDef( $OUTFD, $class, $routine, $arginfo, $cArgs );
# Hideous hack. To preserve ABI compatibility, for one particular
# case for Create struct, remove the const values
if ($routine eq "Create_struct" && $arginfo eq "static:5:4") {
print "$cArgs\n";
$cDefArgs = $cArgs;
$cDefArgs =~ s/const\s+//g;
}
else {
$cDefArgs = $cArgs;
}
&PrintMethodDef( $OUTFD, $class, $routine, $arginfo, $cDefArgs );
# This inserts a modifier, such as const or =0 (for pure virtual)
if (defined($funcAttributes{$fnchash})) {
......
@routinesMpi1base = (
"Detach_buffer",
"Is_initialized",
"Get_processor_name",
"Get_error_string",
"Compute_dims",
"Get_version",
"Finalize",
"Pcontrol",
"Attach_buffer",
"Get_error_class",
);
@routinesmpi1cart = (
"Get_coords",
"Get_cart_rank",
"Get_dim",
"Dup",
"Get_topo",
"Map",
"Sub",
"Shift",
);
@routinesmpi1comm = (
"Get_group",
"Get_rank",
"Bsend_init",
"Ssend_init",
"Is_inter",
"Rsend_init",
"Ibsend",
"Abort",
"Free",
"Send_init",
"Recv",
"Sendrecv",
"Sendrecv_replace",
"Get_topology",
"Isend",
"Probe",
"Compare",
"Get_size",
"Issend",
"Set_errhandler",
"Send",
"Irsend",
"Ssend",
"Recv_init",
"Iprobe",
"Bsend",
"Irecv",
"Get_errhandler",
"Rsend",
);
@routinesmpi1distgraph = (
"Get_dist_neighbors_count",
"Dup",
);
@routinesmpi1dtype = (
"Commit",
"Free",
"Create_indexed",
"Create_contiguous",
"Create_vector",
"Create_struct",
"Pack_size",
"Pack",
"Get_size",
);
@routinesmpi1errh = (
"Free",
);
@routinesmpi1graph = (
"Get_dims",
"Get_topo",
"Map",
"Get_neighbors",
"Get_neighbors_count",
"Dup",
);
@routinesmpi1group = (
"Excl",
"Get_rank",
"Free",
"Union",
"Intersect",
"Range_excl",
"Range_incl",
"Difference",
"Translate_ranks",
"Incl",
"Get_size",
"Compare",
);
@routinesmpi1inter = (
"Merge",
"Get_remote_group",
"Get_remote_size",
"Dup",
);
@routinesmpi1intra = (
"Create_intercomm",
"Split",
"Create_graph",
"Create_cart",
"Create",
"Dup",
"Scan",
);
@routinesmpi1op = (
"Free",
);
@routinesmpi1preq = (
"Start",
"Startall",
);
@routinesmpi1req = (
"Testany",
"Waitsome",
"Free",
"Testall",
"Wait",
"Testsome",
"Waitall",
"Waitany",
"Test",
"Cancel",
);
@routinesmpi1st = (
"Is_cancelled",
"Get_elements",
"Get_count",
);
@routinesMpi2base = (
"Add_error_class",
"Alloc_mem",
"Lookup_name",
"Publish_name",
"Unpublish_name",
"Get_address",
"Add_error_string",
"Query_thread",
"Close_port",
"Add_error_code",
"Free_mem",
"Open_port",
"Is_finalized",
"Is_thread_main",
);
@routinesmpi2comm = (
"Reduce_scatter_block",
"Gatherv",
"Disconnect",
"Allreduce",
"Alltoallw",
"Join",
"Alltoall",
"Get_attr",
"Barrier",
"Bcast",
"Set_attr",
"Set_name",
"Get_parent",
"Alltoallv",
"Reduce_scatter",
"Scatter",
"Call_errhandler",
"Gather",
"Free_keyval",
"Reduce",
"Allgather",
"Delete_attr",
"Scatterv",
"Get_name",
"Allgatherv",
);
@routinesmpi2distgraph = (
"Get_dist_neighbors",
);
@routinesmpi2dtype = (
"Get_envelope",
"Create_hvector",
"Match_size",
"Create_resized",
"Create_indexed_block",
"Pack_external_size",
"Dup",
"Create_hindexed",
"Get_attr",
"Get_true_extent",
"Create_darray",
"Create_f90_real",
"Get_contents",
"Set_attr",
"Set_name",
"Create_f90_complex",
"Create_subarray",
"Unpack_external",
"Free_keyval",
"Create_struct",
"Create_f90_integer",
"Pack_external",
"Get_extent",
"Delete_attr",
"Get_name",
);
@routinesmpi2file = (
"Get_type_extent",
"Read_ordered_end",
"Seek_shared",
"Read_ordered",
"Iread_shared",
"Get_info",
"Write_ordered_begin",
"Set_info",
"Write_ordered",
"Sync",
"Read",
"Write_all",
"Get_size",
"Write_all_end",
"Delete",
"Read_ordered_begin",
"Iread_at",
"Write_at_all_end",
"Get_position_shared",
"Write_shared",
"Iwrite_at",
"Get_view",
"Call_errhandler",
"Write_all_begin",
"Read_all_end",
"Get_byte_offset",
"Iread",
"Read_at_all_end",
"Write_at",
"Write_at_all_begin",
"Get_errhandler",
"Get_amode",
"Set_atomicity",
"Get_group",
"Get_position",
"Open",
"Seek",
"Read_all_begin",
"Read_at_all_begin",
"Read_all",
"Preallocate",
"Read_at_all",
"Read_shared",
"Iwrite",
"Iwrite_shared",
"Set_errhandler",
"Write_at_all",
"Set_size",
"Set_view",
"Read_at",
"Close",
"Write_ordered_end",
"Write",
"Get_atomicity",
);
@routinesmpi2greq = (
"Complete",
);
@routinesmpi2info = (
"Delete",
"Get_nthkey",
"Free",
"Create",
"Set",
"Dup",
"Get_valuelen",
"Get",
"Get_nkeys",
);
@routinesmpi2inter = (
"Split",
);
@routinesmpi2intra = (
"Exscan",
"Accept",
"Connect",
);
@routinesmpi2op = (
"Is_commutative",
"Reduce_local",
);
@routinesmpi2req = (
"Get_status",
);
@routinesmpi2st = (
"Set_cancelled",
"Set_elements",
);
@routinesmpi2win = (
"Get_group",
"Fence",
"Start",
"Free",
"Put",
"Wait",
"Test",
"Get",
"Get_attr",
"Set_attr",
"Complete",
"Set_errhandler",
"Set_name",
"Accumulate",
"Create",
"Call_errhandler",
"Free_keyval",
"Post",
"Unlock",
"Delete_attr",
"Lock",
"Get_errhandler",
"Get_name",
);
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment