RTOp_apply_op_mpi.c

00001 /*
00002 // @HEADER
00003 // ***********************************************************************
00004 // 
00005 // Moocho: Multi-functional Object-Oriented arCHitecture for Optimization
00006 //                  Copyright (2003) Sandia Corporation
00007 // 
00008 // Under terms of Contract DE-AC04-94AL85000, there is a non-exclusive
00009 // license for use of this work by or on behalf of the U.S. Government.
00010 // 
00011 // This library is free software; you can redistribute it and/or modify
00012 // it under the terms of the GNU Lesser General Public License as
00013 // published by the Free Software Foundation; either version 2.1 of the
00014 // License, or (at your option) any later version.
00015 //  
00016 // This library is distributed in the hope that it will be useful, but
00017 // WITHOUT ANY WARRANTY; without even the implied warranty of
00018 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
00019 // Lesser General Public License for more details.
00020 //  
00021 // You should have received a copy of the GNU Lesser General Public
00022 // License along with this library; if not, write to the Free Software
00023 // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
00024 // USA
00025 // Questions? Contact Roscoe A. Bartlett (rabartl@sandia.gov) 
00026 // 
00027 // ***********************************************************************
00028 // @HEADER
00029 */
00030 
00031 #include "RTOp_apply_op_mpi.h"
00032 #include "RTOp_parallel_helpers.h"
00033 #include "RTOpToMPI.h"
00034 
00035 int RTOp_apply_op_mpi(
00036   MPI_Comm comm
00037   ,RTOp_index_type global_dim_in, RTOp_index_type local_sub_dim_in, RTOp_index_type local_offset_in
00038   ,const int num_cols
00039   ,const int      num_vecs,  const RTOp_value_type*      l_vec_ptrs[],  const ptrdiff_t      l_vec_strides[], const ptrdiff_t      l_vec_leading_dim[]
00040   ,const int num_targ_vecs,  RTOp_value_type*       l_targ_vec_ptrs[],  const ptrdiff_t l_targ_vec_strides[], const ptrdiff_t l_targ_vec_leading_dim[]
00041   ,const RTOp_index_type first_ele_in, const RTOp_index_type sub_dim_in, const RTOp_index_type global_offset_in
00042   ,const struct RTOp_RTOp* op
00043   ,RTOp_ReductTarget reduct_objs[]
00044   )
00045 {
00046   int                          err                      = 0;
00047   struct RTOp_SubVector        *local_vecs              = NULL;
00048   struct RTOp_MutableSubVector *local_targ_vecs         = NULL;
00049   RTOp_index_type              overlap_first_local_ele  = 0;
00050   RTOp_index_type              overalap_local_sub_dim   = 0;
00051   RTOp_index_type              overlap_global_offset    = 0;
00052   int                          k;
00053   int                          kc;
00054   /* Validate the input */
00055 #ifdef RTOp_DEBUG
00056   assert( num_vecs || num_targ_vecs );
00057   if(num_vecs)
00058     assert( l_vec_ptrs != NULL );
00059   if(num_targ_vecs)
00060     assert( l_targ_vec_ptrs != NULL );
00061   assert( 0 <= sub_dim_in && sub_dim_in <= global_dim_in );
00062 #endif
00063   /* Pre-initialize the local sub-vectors */
00064   if(num_vecs) {
00065     local_vecs = malloc( sizeof(struct RTOp_SubVector) * num_vecs * num_cols );
00066     for( kc = 0; kc < num_cols; ++kc ) {
00067       for( k = 0; k < num_vecs; ++k )
00068         RTOp_sub_vector_null(&local_vecs[kc*num_cols+k]);
00069     }
00070   }
00071   if(num_targ_vecs) {
00072     local_targ_vecs = malloc( sizeof(struct RTOp_MutableSubVector) * num_targ_vecs );
00073     for( kc = 0; kc < num_cols; ++kc ) {
00074       for( k = 0; k < num_targ_vecs; ++k )
00075         RTOp_mutable_sub_vector_null(&local_targ_vecs[kc*num_cols+k]);
00076     }
00077   }
00078   /* Get the overlap in the current process with the input logical sub-vector */
00079   /* from (first_ele_in,sub_dim_in,global_offset_in) */
00080   RTOp_parallel_calc_overlap(
00081     global_dim_in, local_sub_dim_in, local_offset_in, first_ele_in, sub_dim_in, global_offset_in
00082     ,&overlap_first_local_ele, &overalap_local_sub_dim, &overlap_global_offset
00083     );
00084   if( overlap_first_local_ele != 0 ) {
00085     /* Sub-vector structs for the local elements that are to participate in the */
00086     /* reduction/transforamtion operation. */
00087     for( kc = 0; kc < num_cols; ++kc ) {
00088       for(k = 0; k < num_vecs; ++k) {
00089         RTOp_sub_vector(
00090           overlap_global_offset                                                  /* global_offset */
00091           ,overalap_local_sub_dim                                                /* sub_dim */
00092           ,l_vec_ptrs[k]+(overlap_first_local_ele-1)*l_vec_strides[k]
00093           + ( num_cols > 1 ? kc*l_vec_leading_dim[k] : 0 )                       /* values */
00094           ,l_vec_strides[k]                                                      /* values_stride */
00095           ,&local_vecs[kc*num_cols+k]
00096           );
00097       }
00098       for(k = 0; k < num_targ_vecs; ++k) {
00099         RTOp_mutable_sub_vector(
00100           overlap_global_offset                                                  /* global_offset */
00101           ,overalap_local_sub_dim                                                /* sub_dim */
00102           ,l_targ_vec_ptrs[k]+(overlap_first_local_ele-1)*l_targ_vec_strides[k]
00103           + ( num_cols > 1 ? kc*l_targ_vec_leading_dim[k] : 0 )                  /* values */
00104           ,l_targ_vec_strides[k]                                                 /* values_stride */
00105           ,&local_targ_vecs[kc*num_cols+k]
00106           );
00107       }
00108     }
00109   }
00110   /* */
00111   /* Apply the reduction operation over the sub-vectors in */
00112   /* this process then collect the reductions over */
00113   /* all the processes and return the result */
00114   /* to all the processes (including this one of course). */
00115   /* If all of the sub-svectors are empty then this will */
00116   /* just call the reduction operation with NULL sub-vectors */
00117   /* */
00118   err = RTOp_MPI_apply_op(
00119     comm, op, -1 /* MPI_Allreduce(...) */
00120     ,num_cols
00121     ,num_vecs,      num_vecs && overlap_first_local_ele      ? &local_vecs[0]      : NULL
00122     ,num_targ_vecs, num_targ_vecs && overlap_first_local_ele ? &local_targ_vecs[0] : NULL
00123     ,reduct_objs
00124     );
00125 
00126   if(local_vecs)      free(local_vecs);
00127   if(local_targ_vecs) free(local_targ_vecs);
00128 
00129   /* Deallocate memory */
00130 
00131   return err;
00132 }

Generated on Thu Sep 18 12:33:38 2008 for RTOpPack: Extra C/C++ Code for Vector Reduction/Transformation Operators by doxygen 1.3.9.1