⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 buildiface

📁 刚才是说明 现在是安装程序在 LINUX环境下进行编程的MPICH安装文件
💻
📖 第 1 页 / 共 3 页
字号:
		    $lctype = $mytopclass{$lctype};		}		print $OUTFD "&(v$count->the_real_$lctype)";	    }	    else {		print $OUTFD "&v$count";	    }	}	elsif ($count == $class_pos) {	    # Skip this arg in the definition 	    if ($parm =~ /\*/) {		print $OUTFD "($parm) &the_real_$lctopclass";	    }	    else {		print $OUTFD "($parm) the_real_$lctopclass";	    }	}	elsif (defined($special_args{"${routine_name}-$count"})) {	    # We must handle this argument specially	    &print_special_call_arg( $routine_name, $count );	}	else {	    # Convert to/from object type as required.  	    if (defined($argsneedcast{$parm})) {		$argval = "v$count";		$callparm = $argsneedcast{$parm};		$callparm =~ s/ARG/$argval/;				print $OUTFD &HandleObjectParm( $parm, $argval );	    }	    else {		print $OUTFD &HandleObjectParm( $parm, "v$count" );	    }	}	$count++;    }    print $OUTFD " )";}# Print the option function attribute; this supports GCC, particularly # the __atribute__ weak option.sub print_attr {    if ($do_weak) {	print $OUTFD "FUNC_ATTRIBUTES\n";    }}## Special processing# This routine handles the special arguments in the *call*sub print_special_call_arg {    my $routine_name = $_[0];    my $count = $_[1];    $rule = $special_args{"${routine_name}-$count"};    ($direction,$method,$Array_size) = split(/:/,$rule);    $processing_routine = "${method}_${direction}_arg";    &$processing_routine( $count );}# This routine prints any declarations that are needed sub print_special_decls {    my $routine_name = $_[0];    if (defined($special_args{$routine_name})) {	# First do the declarations	foreach $count (split(/:/,$special_args{$routine_name})) {	    $rule = $special_args{"${routine_name}-$count"};	    ($direction,$method,$Array_size) = split(/:/,$rule);	    $processing_routine = "${method}_${direction}_decl";	    &$processing_routine( $count );	}	# Then do the precall steps	foreach $count (split(/:/,$special_args{$routine_name})) {	    $rule = $special_args{"${routine_name}-$count"};	    ($direction,$method,$Array_size) = split(/:/,$rule);	    if ($direction eq "in") {		$processing_routine = "${method}_ftoc";		&$processing_routine( $count );	    }	}    }}## Look through $args for parameter names (foo\s\s*name)# and remove themsub clean_args {    my $newargs = "";    my $comma = "";    for $parm (split(',',$args)) {	# Remove any leading or trailing spaces	$parm =~ s/^\s*//;	$parm =~ s/\s*$//;	# Handle parameters with parameter names	# First if handles "int foo", second handles "int *foo"	if ( ($parm =~ /^([A-Za-z0-9_]+)\s+[A-Za-z0-9_]+$/) ) {	    $parm = $1;	}	elsif ( ($parm =~ /^([A-Za-z0-9_]+\s*\*)\s*[A-Za-z0-9_]+$/) ) {	    $parm = $1;	}	$newargs .= "$comma$parm";	$comma = ",";    }    print STDERR "$newargs\n" if $debug;    $args = $newargs;}## Build the special routinessub build_specials {    # The init routine contains some configure-time values.    open( $OUTFD, ">initcxx.cpp" ) || die "Cannot open initcxx.cpp\n";    @files[$#files+1] = "initcxx.cpp";    &print_header;    print $OUTFD "#include \"mpi.h\"\n";    print $OUTFD "#include \"mpicxx.h\"\n";    # Start the namespace    print $OUTFD "namespace MPI {\n";    # Initialize the datatypes    foreach $dtype (@dtypes) {	print $OUTFD "Datatype MPI::$dtype(MPI_$dtype);\n";    }    # special case    print $OUTFD "Datatype MPI::TWOINT(MPI_2INT);\n";    # Initialize the operations    foreach $op (@ops) {	print $OUTFD "const Op MPI::$op(MPI_$op);\n";    }    # Predefined communicators and groups    print $OUTFD "Intracomm MPI::COMM_WORLD(MPI_COMM_WORLD);\n";    print $OUTFD "Intracomm MPI::COMM_SELF(MPI_COMM_SELF);\n";    print $OUTFD "const Comm MPI::COMM_NULL;\n";    print $OUTFD "const Group MPI::GROUP_EMPTY(MPI_GROUP_EMPTY);\n";    print $OUTFD "void Init";    $args = "";    &print_args( $OUTFD, $args );    &print_attr;    print $OUTFD "{\n";    print $OUTFD "    MPI_Init( 0, 0 );\n";    print $OUTFD "}\n";    print $OUTFD "void Finalize";     $args = "";    &print_args( $OUTFD, $args );    &print_attr;    print $OUTFD "{\n";    print $OUTFD "    MPI_Finalize( );\n";    print $OUTFD "}\n";    print $OUTFD "} // namespace MPI\n";    close ($OUTFD);}# Given an integer location of an argument, return the corresponding# type, from the arg listsub Convert_pos_to_type {    my @parm = split( ',', $_[0] );    my $loc = $_[1];    return $parm[$loc-1];}sub Convert_type_to_pos {    my @parm = split( ',', $_[0] );    my $type = $_[1];    my $loc = 1;        for $parm (@parm) {	if ($parm =~ /$type/) { return $loc; }	$loc ++;    }    return 0;}# Print the class header # PrintClassHead( $OUTFD, class, mpitype, friends )# E.g., PrintClassHead( $OUTFD, "Datatype", "MPI_Datatype", "Comm,Status" )sub PrintClassHead {    my $OUTFD = $_[0];    my $class = $_[1];    my $mpi_type = $_[2];    my $friends  = $_[3];    my $mpi_null_type = uc("${mpi_type}_NULL" );    my $lcclass = lc($class);    my $lctopclass = $lcclass;    # For derived classes, we sometimes need to know the name of the    # top-most class, particularly for the "the_real_xxx" name.    if (defined($mytopclass{$lcclass})) {	$lctopclass = $mytopclass{$lcclass};    }    my $parent = "";    if (defined($derived_class{$shortclass})) {	$parent = ": public $derived_class{$shortclass}";    }        print $OUTFD "class $class $parent {\n";    if ($friends ne "") {	foreach $name (split(/,/,$friends)) {	    print $OUTFD "    friend class $name;\n";	}    }    if ($lcclass eq $lctopclass) {	print $OUTFD "\		  protected:    $mpi_type the_real_$lcclass;\n"    }  print $OUTFD "\  public:    // new/delete    inline $class($mpi_type obj) { the_real_$lctopclass = obj; }\n";    if (defined($class_has_no_default{$class})) {	print $OUTFD "    inline $class(void) {}\n";    }    else {	print $OUTFD "    inline $class(void) {the_real_$lctopclass = $mpi_null_type;}\n";    }    print $OUTFD "\    virtual ~$class() {}    // copy/assignment    $class :: $class(const $class &obj) {      the_real_$lctopclass = obj.the_real_$lctopclass; }    $class& ${class}::operator=(const $class &obj) {      the_real_$lctopclass = obj.the_real_$lctopclass; return *this; }";    if (!defined($class_has_no_compare{$class})) {	# Some classes (e.g., Status) do not have compare operations	print $OUTFD "    // logical    bool operator== (const $class &obj) {      return (the_real_$lctopclass == obj.the_real_$lctopclass); }    bool operator!= (const $class &obj) {      return (the_real_$lctopclass != obj.the_real_$lctopclass); }";    }    print $OUTFD "    // C/C++ cast and assignment    inline operator $mpi_type*() { return &the_real_$lctopclass; }    inline operator $mpi_type() { return the_real_$lctopclass; }    $class& ${class}::operator=(const $mpi_type& obj) {      the_real_$lctopclass = obj; return *this; }";}sub PrintClassTail {     my $OUTFD = $_[0];    print $OUTFD "};\n";}# -----------------------------------------------------------------------------# Here will go routines for handling return values.  These need to move them# from pointer arguments in the parameter list into a local declaration # (possibly using new)## We process a binding *first* and set the global variables#    return_type (type of return value)#    return_parm_pos (number of location of arg in parm list; 0 if none)# return_info is either a number or a type.  If a type, it does NOT include# the * (e.g., int instead of int *), but the * must be in the parameter# FindReturnInfo( return_info, args )sub FindReturnInfo {    my @parms = split(/,/,$_[1] );    my $return_info = $_[0];    if ($return_info eq "0") {	$return_type = "void";	$return_parm_pos = 0;    }    elsif ($return_info =~ /^[0-9]/) {	# We have the position but we need to find the type	my $count = 1;	for $parm (@parms) {	    if ($count == $return_info) { 		$return_type     = $parm;		$return_type     =~ s/\s*\*$//;   # Remove *		$return_parm_pos = $count;	    }	    $count ++;	}    }    else {	# Return info is a type. Find the matching location	my $count = 1;	for $parm (@parms) {	    if ($parm =~ /$return_info\s*\*/) {		$return_parm_pos = $count;		$return_type     = $return_info;		last;	    }	    $count ++;	}    }}# -----------------------------------------------------------------------------# Convert other arguments from C to C++ versions.  E.g., change the# MPI_Datatype arg in Comm::Send from MPI_Datatype to Datatype.  Use# (MPI_Datatype)datatype.the_real_datatype (always).## HandleObjectParms( parmtype, parm )# e.g., HandleObjectParms( MPI_Datatype, v7 )# returns appropriate string.  If parmtype unknown, just return parm sub HandleObjectParm {    my $parmtype = $_[0];    my $parm     = $_[1];    my $need_address = 0;    my $newparm;    if ($parmtype =~ /MPI_/) {	$ctype = $parmtype;	if ($ctype =~ /\*/) {	    $need_address = 1;	    $ctype =~ s/\*//;	}	$ctype =~ s/MPI_//;	$lctype = lc( $ctype );	# For derived classes, we sometimes need to know the name of the	# top-most class, particularly for the "the_real_xxx" name.	if (defined($mytopclass{$lctype})) {	    $lctype = $mytopclass{$lctype};	}	if ($need_address) {	    $newparm = "($parmtype)&($parm.the_real_$lctype)";	}	else {	    $newparm = "($parmtype)($parm.the_real_$lctype)";	}	return $newparm;    }    return $parm;}# ----------------------------------------------------------------------------## MUST DO BEFORE USABLE# The initialization of the objects:#   const Datatype MPI::<name>(MPI_<name>);#   Intracomm MPI::COMM_WORLD(MPI_COMM_WORLD), SELF#   const COMM MPI::COMM_NULL;#   const Group MPI::GROUP_EMPTY(MPI_GROUP_EMPTY);#   const Op MPI::<op>(MPI_<op>)#   const int MPI::IDENT,CONGRUENT,SIMILAR,UNEQUAL## static functions that are in no class  (init already done)# Get_error_class, Wtime, Wtick, Finalize, Is_initialized## Namespace wrapper## Insert use of const.  Can we do this automatically, with some# exceptions?  E.g., all Datatype, void *, Comm, Group etc.# Only recv of void *, output of collective aren't const (?)## Returned objects that are not simple types must be created with new, not# just declared and returned.  In addition, make sure that the correct# value is passed into the C version.  E.g.,#   Request *v7 = new Request;#   .... MPI_Isend( ..., &(v7->the_real_request) )#   return *v7;## ----------------------------------------------------------------------------## ReadInterface( filename )sub ReadInterface {    my $filename =$_[0];    open( FD, "<$filename" ) || die "Cannot open $filename\n";    # Skip to prototypes    while (<FD>) {	if ( /\/\*\s*Begin Prototypes/ ) { last; }    }    # Read each one    # Save as    #$mpi_routine{name} = args;    while (<FD>) {	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;	    # Special substitutions	    $args =~ s/MPIO_Request/MPI_Request/g;	    $lcname = lc($routine_name);	    if (defined($special_routines{$routine_name})) {		print "Skipping $routine_name\n" if $debug;	    }	    else {		# Clear variables		$clean_up = "";		&clean_args;		$mpi_routine{$routine_name} = $args;		print "Saving $routine_name ( $args )\n" if $debug;	    }				}    }    close( FD );}## ISSUES NOT YET HANDLED# ----------------------------------------------------------------------------# This tool becomes particularly interesting if it allows custom generation# of a mpicxx.h header file that contains references to only the# requested routines (and even classes; e.g., no Groups if no-one is using# them).## Pack_size, Pack, and Unpack cannot be defined within the Datatype# class definition because they also need Comm, and Comm needs datatype.# We need to replace this with#   Just provide the Pack_size, Pack, Unpack prototypes in the Datatype#   class definition#   Add these to the end## Routines with arrays of aggregate types (e.g., arrays of Datatypes) # really require special processing.  We need to either do something like# is done for the Fortran routines (for any routine with special needs, # enumerate which args require special handling and name the routine) # or simply provide hand-written code for the internals of those operations.

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -