src/SubField/SubFieldAssign.cpp

Go to the documentation of this file.
00001 // -*- C++ -*-
00002 /***************************************************************************
00003  *
00004  * The IPPL Framework
00005  * 
00006  * This program was prepared by PSI. 
00007  * All rights in the program are reserved by PSI.
00008  * Neither PSI nor the author(s)
00009  * makes any warranty, express or implied, or assumes any liability or
00010  * responsibility for the use of this software
00011  *
00012  * Visit http://www.acl.lanl.gov/POOMS for more details
00013  *
00014  ***************************************************************************/
00015 
00016 // -*- C++ -*-
00017 /***************************************************************************
00018  *
00019  * The IPPL Framework
00020  * 
00021  *
00022  * Visit http://people.web.psi.ch/adelmann/ for more details
00023  *
00024  ***************************************************************************/
00025 
00026 // include files
00027 #include "SubField/SubFieldAssign.h"
00028 #include "SubField/SubFieldAssignDefs.h"
00029 #include "SubField/SubBareField.h"
00030 #include "SubField/SubFieldTraits.h"
00031 #include "SubField/SubFieldIter.h"
00032 #include "Field/BareField.h"
00033 #include "Field/BrickExpression.h"
00034 #include "Field/LField.h"
00035 #include "Field/Assign.h"
00036 #include "Field/AssignDefs.h"
00037 #include "Profile/Profiler.h"
00038 #include "Utility/IpplInfo.h"
00039 
00040 
00042 // assign an arbitrary expression to a SubBareField, with aligned Fields
00043 template<class T1, unsigned Dim, class S, class RHS, class OP>
00044 void assign(SubBareField<T1,Dim,S> a, RHS b, OP op, ExprTag<true>) {
00045   TAU_TYPE_STRING(taustr, "void (" + CT(a) + ", " + CT(b) + ", " + CT(op) 
00046                   + ", ExprTag<true> )" );
00047   TAU_PROFILE("assign()", taustr, TAU_SUBFIELD | TAU_ASSIGN);
00048 
00049   // Get the object wrapped in the PETE expression object
00050   typename RHS::Wrapped& bb = b.PETE_unwrap();
00051 
00052   // Inform msg("SubField::assign");
00053 
00054   // Check to see if any of the terms on the rhs
00055   // are the field on the lhs.  If so we'll have to make temporaries.
00056   int lhs_id = a.getBareField().get_Id();
00057   bool both_sides = for_each(bb,SameFieldID(lhs_id),PETE_OrCombiner());
00058 
00059   // Check to see if the same type of indexing object is used by all
00060   // the Field's involved in the expression.  If any are different, we
00061   // must flag an error.  This also checks to make sure that all
00062   // indexed fields have the proper number of brackets.
00063   PInsist(for_each(bb,SameSubsetType(a.getSubsetType()),PETE_AndCombiner()),
00064           "Sparse-Indexed expressions must use consistent indexing.");
00065 
00066   // Find the 'bounding box' of the LHS domain
00067   NDIndex<Dim> boundBox;
00068   a.makeNDIndex(boundBox);
00069 
00070   // Fill guard cells, if necessary ... this is done if the RHS domains
00071   // represent a stencil, and the guard cells for the corresponding fields
00072   // actually need to be swapped.
00073   //tjw3/3/99  for_each(bb, FillGCIfNecessary(boundBox), PETE_NullCombiner());
00074 
00075   // This weird tag is needed, because using a no-argument FillGCIFNEcessary()
00076   // function didn't work for some reason, at least with some compilers like
00077   // the pre-7.3 SGI compiler and CodeWarrior Pro4. Once the global function
00078   // invocation syntax FillGCIfNecessary<T,D>() is supported by all our
00079   // compilers (it's not there yet in the non-beta SGI compiler), should be
00080   // able to eliminate this FGCINTag business. --tjw 3/3/1999
00081   for_each(bb, FillGCIfNecessary(FGCINTag<Dim,T1>()), PETE_NullCombiner());
00082 
00083   // Iterators for the LHS components and LField's
00084   typename SubBareField<T1,Dim,S>::iterator sba    = a.begin();
00085   typename BareField<T1,Dim>::iterator_if   la     = sba.getLFieldIter();
00086   typename BareField<T1,Dim>::iterator_if   aend   = a.end().getLFieldIter();
00087 
00088   // Do any initial work on the expression it needs before starting.
00089   // E.g., for single-value subsets, this will distribute the values to nodes
00090   sba.initialize();
00091   for_each(bb, SubsetInit(), PETE_NullCombiner());
00092 
00093   // Loop over all the local fields of the left hand side.
00094   while (la != aend) {
00095     // Some typedefs to make the lines shorter...
00096     // types for the left hand side, right hand side and
00097     // the whole expression.
00098     typedef typename SubBareField<T1,Dim,S>::iterator LHS;
00099     typedef BrickExpression<LHS::ExprDim_u,LHS,typename RHS::Wrapped,OP> ExprT;
00100 
00101     // The pointer to the current lhs local field.
00102     // If it is on the rhs somewhere, make a copy of it, and tell the
00103     // subfield iterator about it.
00104     LField<T1,Dim> *lf = (*la).second.get();
00105     if ( both_sides )
00106       lf = new LField<T1,Dim>( *lf );
00107 
00108     //msg << "  Now doing LField pointer = " << &(*lf);
00109     //msg << ", id = " << lf->getVnode();
00110     //msg << ", data pointer = " << &(*(lf->getP()));
00111     //msg << endl;
00112 
00113     // Find the local domain, if any.  To do so, intersect
00114     // with the indexes used to see how much we will actually use.  If
00115     // findIntersect returns false, then we know there is nothing to do.
00116     // The domain over which we'll be working (and which will be used
00117     // in BrickExpression) is returned in local_domain.
00118     NDIndex<Dim> local_domain;
00119     if (sba.findIntersection(lf->getOwned(), local_domain)) {
00120       // First look and see if the arrays are sufficiently aligned
00121       // to do this in one shot.
00122       // We do this by trying to do a plugBase and seeing if it worked.
00123       if (for_each(bb,PlugBase<Dim>(local_domain), PETE_AndCombiner())) {
00124 
00125         // Check and see if the lhs can be compressed.
00126         if (sba.DomainCompressed() &&
00127             for_each(bb, DomainCompressed(), PETE_AndCombiner()) &&
00128             a.getBareField().compressible() &&
00129             TryCompressLHS(*lf,bb,op,local_domain)) {
00130 
00131           // Compressed assign.
00132           PETE_apply(op, *(lf->begin()), for_each(bb,EvalFunctor_0()));
00133 
00134         } else {
00135 
00136           // Loop assign.
00137           lf->Uncompress();
00138           sba.setLFieldData(lf, local_domain);
00139           ExprT(sba,bb).apply();
00140 
00141           // Try to compress this LField since we did an uncompressed
00142           // assignment, if the user has requested this kind of
00143           // check right after computation on the LField.
00144           if (IpplInfo::extraCompressChecks)
00145             lf->TryCompress();
00146         }
00147       } else {
00148         ERRORMSG("All Fields in an expression must be aligned.  ");
00149         ERRORMSG("(Do you have enough guard cells?)" << endl);
00150         ERRORMSG("This error occurred while evaluating an SIndex-expression ");
00151         ERRORMSG("for an LField with domain " << lf->getOwned() << endl);
00152         Ippl::abort();
00153       }
00154     }
00155 
00156     // If we had to make a copy of the current LField,
00157     // swap the pointers and delete the old memory.
00158     if (both_sides) {
00159       (*la).second->swapData( *lf );
00160       delete lf;
00161     }
00162 
00163     // move iterators on to the next LField
00164     la = sba.nextLField();
00165     for_each(bb, SubsetNextLField(), PETE_NullCombiner());
00166   }
00167 
00168   // Fill the guard cells on the left hand side.
00169   a.getBareField().setDirtyFlag();
00170   a.getBareField().fillGuardCellsIfNotDirty();
00171 
00172   // Compress the LHS, if necessary.
00173   if (!IpplInfo::extraCompressChecks)
00174     a.getBareField().Compress();
00175 
00176   INCIPPLSTAT(incExpressions);
00177   INCIPPLSTAT(incSubEqualsExpression);
00178 }
00179 
00180 
00181 /***************************************************************************
00182  * $RCSfile: SubFieldAssign.cpp,v $   $Author: adelmann $
00183  * $Revision: 1.1.1.1 $   $Date: 2003/01/23 07:40:33 $
00184  * IPPL_VERSION_ID: $Id: SubFieldAssign.cpp,v 1.1.1.1 2003/01/23 07:40:33 adelmann Exp $ 
00185  ***************************************************************************/
00186 

Generated on Mon Jan 16 13:23:56 2006 for IPPL by  doxygen 1.4.6