src/Field/LField.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 "Field/LField.h"
00028 #include "Profile/Profiler.h"
00029 #include "Utility/PAssert.h"
00030 #include "Utility/IpplStats.h"
00031 #include "Utility/Unique.h"
00032 #include <stdlib.h>
00033 
00034 // the number of bytes in a single cache line, this is generally set
00035 // by configuration options, but gets a default value if none is given
00036 #ifndef IPPL_CACHE_LINE_SIZE
00037 #define IPPL_CACHE_LINE_SIZE 32
00038 #endif
00039 
00040 // the number of "offset blocks" to use.  We will add a small offset
00041 // to the beginning of where in each malloced storage block the LField
00042 // data is stored, to try to avoid having several blocks all map to
00043 // the same cache line.  This is the maximum number of blocks that we
00044 // will add as an offset, where each block is the size of a cache line.
00045 #ifndef IPPL_OFFSET_BLOCKS
00046 #define IPPL_OFFSET_BLOCKS 16
00047 #endif
00048 
00049 // a debugging output message macro
00050 #ifdef DEBUG_LFIELD
00051 #define LFIELDMSG(x) x
00052 #else
00053 #define LFIELDMSG(x)
00054 #endif
00055 
00056 
00058 //
00059 // Initialize numeric types to zero.
00060 // Everything else uses the default ctor.
00061 //
00063 
00064 template<class T>
00065 struct LFieldInitializer
00066 {
00067   static void apply(T&) {}
00068 };
00069 
00070 #define MAKE_INITIALIZER(T)        \
00071 template <>                        \
00072 struct LFieldInitializer<T>        \
00073 {                                  \
00074   static void apply(T& x) { x=0; } \
00075 };
00076 
00077 MAKE_INITIALIZER(bool)
00078 MAKE_INITIALIZER(char)
00079 MAKE_INITIALIZER(short)
00080 MAKE_INITIALIZER(int)
00081 MAKE_INITIALIZER(long)
00082 MAKE_INITIALIZER(float)
00083 MAKE_INITIALIZER(double)
00084 #ifdef IPPL_LONGLONG
00085 MAKE_INITIALIZER(long long)
00086 #endif
00087 
00088 
00090 //
00091 // Construct given the sizes.
00092 // This builds it compressed.
00093 //
00095 
00096 template<class T, unsigned Dim>
00097 LField<T,Dim>::LField(const NDIndex<Dim>& owned, 
00098                       const NDIndex<Dim>& allocated, 
00099                       int vnode)
00100   : P(0),
00101     Owned(owned),
00102     Allocated(allocated),
00103     Begin(owned, CompressedData),
00104     End(CompressedData),
00105     vnode_m(vnode),
00106     overlapCacheInited(false),
00107     allocCompressIndex(0),
00108     ownedCompressIndex(-1),
00109     offsetBlocks(Unique::get() % IPPL_OFFSET_BLOCKS)
00110 {
00111   TAU_TYPE_STRING(taustr, CT(*this) + " void (" + CT(owned) + ", " 
00112     + CT(allocated) + " )" );
00113   TAU_PROFILE("LField::LField()", taustr, TAU_FIELD);
00114 
00115   // Give the LField some initial (compressed) value
00116   LFieldInitializer<T>::apply(*Begin);
00117 
00118   // If we are not actually doing compression, expand the storage out,
00119   // and copy the initial value to all the elements
00120   if (IpplInfo::noFieldCompression)
00121     this->ReallyUncompress(true);
00122 
00123   //INCIPPLSTAT(incLFields);
00124 }
00125 
00126 
00128 //
00129 // Deep copy constructor.
00130 //
00132 
00133 template<class T, unsigned Dim>
00134 LField<T,Dim>::LField(const LField<T,Dim>& lf)
00135   : P(0),
00136     Owned(lf.Owned),
00137     Allocated(lf.Allocated),
00138     Begin(CompressedData),
00139     End(CompressedData),
00140     vnode_m(lf.vnode_m),
00141     overlapCacheInited(false),
00142     allocCompressIndex(lf.allocCompressIndex),
00143     ownedCompressIndex(lf.ownedCompressIndex),
00144     offsetBlocks(Unique::get() % IPPL_OFFSET_BLOCKS)
00145 {
00146   TAU_TYPE_STRING(taustr, "void (" + CT(lf) + " )" );
00147   TAU_PROFILE("LField::LField()", taustr, TAU_FIELD);
00148 
00149   if ( lf.IsCompressed() )
00150     {
00151       // Build a compressed iterator.
00152       Begin = iterator(Owned,CompressedData);
00153 
00154       // get the constant value in lf.
00155       CompressedData = lf.CompressedData;
00156     }
00157   else
00158     {
00159       // Make sure we have something in this LField
00160       PAssert(lf.Allocated.size()!=0);
00161 
00162       // If it is not compressed, allocate storage
00163       int n = lf.Allocated.size();
00164       allocateStorage(n);
00165 
00166       // Copy the data over.
00167       copy(lf.P, lf.P + n, P);
00168 
00169       // Build an iterator that counts over the real data.
00170       Begin = iterator(P,Owned,Allocated,CompressedData);
00171     }
00172 
00173   //INCIPPLSTAT(incLFields);
00174 }
00175 
00176 
00178 //
00179 // Destructor: just free the memory, if it's there.
00180 //
00182 
00183 template<class T, unsigned Dim>
00184 LField<T,Dim>::~LField()
00185 {
00186   deallocateStorage();
00187 }
00188 
00189 
00191 //
00192 // Let the user tell us to try to compress.
00193 // Return quickly if we already are compressed.
00194 //
00196 
00197 template<class T, unsigned Dim>
00198 bool
00199 LField<T,Dim>::TryCompress(bool baseOnPhysicalCells)
00200 {
00201   TAU_TYPE_STRING(taustr, CT(*this) + " bool ()" );
00202   TAU_PROFILE("LField::TryCompress()", taustr, TAU_FIELD);
00203 
00204   if (IsCompressed() || IpplInfo::noFieldCompression)
00205     return false;
00206 
00207   LFIELDMSG(Inform dbgmsg("LField::TryCompress", INFORM_ALL_NODES));
00208   LFIELDMSG(dbgmsg << "Trying to compress LField with domain = "<<getOwned());
00209   LFIELDMSG(dbgmsg << ", baseOnPhysicalCells = " << baseOnPhysicalCells<<endl);
00210 
00211   if (baseOnPhysicalCells)
00212     {
00213       if (CanCompressBasedOnPhysicalCells())
00214         {
00215           CompressBasedOnPhysicalCells();
00216           return true;
00217         }
00218     }
00219   else
00220     {
00221       if (CanCompress() )
00222         {
00223           Compress();
00224           return true;
00225         }
00226     }
00227 
00228   return false;
00229 }
00230 
00231 
00233 //
00234 // Look through the data and figure out if it can be compressed
00235 // to the given value.
00236 //
00238 
00239 template<class T, unsigned Dim>
00240 bool
00241 LField<T,Dim>::CanCompress(T val) const
00242 {
00243   TAU_TYPE_STRING(taustr, CT(*this) + " bool (" + CT(val) + " )" );
00244   TAU_PROFILE("LField::CanCompress()", taustr, TAU_FIELD);
00245 
00246   // Debugging macro
00247   LFIELDMSG(Inform dbgmsg("CanCompress"));
00248 
00249   // We definitely can't do this if compression is disabled.
00250   if (IpplInfo::noFieldCompression)
00251     return false;
00252 
00253   // If it is already compressed, we can compress it to any value.
00254   if (IsCompressed())
00255     //return *Begin == val;
00256     return true;
00257 
00258   // It is not currently compressed ... so go through and check
00259   // to see if all the elements are the same as the given argument.
00260 
00261   int sz = getAllocated().size();
00262   ADDIPPLSTAT(incCompressionCompareMax, sz);
00263   T *ptr1 = P;
00264   T *mid1 = P + allocCompressIndex;
00265   T *end1 = P + sz;
00266   
00267   PAssert(sz > 0);
00268   PAssert(P != 0);
00269   PAssert(allocCompressIndex >= 0);
00270   PAssert(allocCompressIndex < sz);
00271 
00272   // Quick short-cut check: compare to the last value in the
00273   // array that did not match before.
00274 
00275   if (IpplInfo::extraCompressChecks)
00276     {
00277       LFIELDMSG(dbgmsg << "Doing short-cut check, comparing " << *mid1);
00278       LFIELDMSG(dbgmsg << " to " << val << " at last-alloc-domain-failed");
00279       LFIELDMSG(dbgmsg << " index of " << allocCompressIndex << endl);
00280       ADDIPPLSTAT(incCompressionCompares, 1);
00281 
00282       if (!(*mid1 == val))
00283         {
00284           LFIELDMSG(dbgmsg << "Short-cut check determined we cannot ");
00285           LFIELDMSG(dbgmsg << "compress, by comparing " << *mid1<<" to ");
00286           LFIELDMSG(dbgmsg << val << " at last-alloc-domain-failed index");
00287           LFIELDMSG(dbgmsg << " of " << allocCompressIndex << endl);
00288 
00289           // It failed the test, so we can just keep the same index to
00290           // check next time, and return.  
00291           return false;
00292         }
00293     }
00294 
00295   // Check from the beginning to the last-checked-index
00296 
00297   LFIELDMSG(dbgmsg << "Checking for compression for " << sz << " items, ");
00298   LFIELDMSG(dbgmsg << "comparing to value = " << val << endl);
00299 
00300   if (IpplInfo::extraCompressChecks)
00301     {
00302       // First check from last-failed-position to end, since we've
00303       // already looked at *mid1 and should have that section of memory
00304       // in cache
00305       T *checkptr = mid1 + 1;
00306       while (checkptr != end1)
00307         {
00308           if (!(*checkptr++ == val))
00309             {
00310               LFIELDMSG(dbgmsg << "Found that we cannot compress, after ");
00311               LFIELDMSG(dbgmsg << (checkptr - mid1) << " compares (");
00312               LFIELDMSG(dbgmsg << *(checkptr-1) << " != " << val << ")");
00313               LFIELDMSG(dbgmsg << endl);
00314               ADDIPPLSTAT(incCompressionCompares, (checkptr - mid1));
00315               allocCompressIndex = (checkptr - ptr1) - 1;
00316               return false;
00317             }
00318         }
00319 
00320       // Next, check from the first position to the last-failed-position.
00321       checkptr = ptr1;
00322       while (checkptr != mid1)
00323         {
00324           if (!(*checkptr++ == val))
00325             {
00326               LFIELDMSG(dbgmsg << "Found that we cannot compress, after ");
00327               LFIELDMSG(dbgmsg << (checkptr - ptr1) + (end1 - mid1));
00328               LFIELDMSG(dbgmsg << " compares (");
00329               LFIELDMSG(dbgmsg << *(checkptr-1) << " != " << val << ")");
00330               LFIELDMSG(dbgmsg << endl);
00331               ADDIPPLSTAT(incCompressionCompares,
00332                            (checkptr - ptr1) + (end1 - mid1));
00333               allocCompressIndex = (checkptr - ptr1) - 1;
00334               return false;
00335             }
00336         }
00337     }
00338   else
00339     {
00340       while (ptr1 != end1)
00341         {
00342           if (!(*ptr1++ == val))
00343             {
00344               LFIELDMSG(dbgmsg << "Found that we cannot compress, after ");
00345               LFIELDMSG(dbgmsg << (ptr1 - P) << " compares (");
00346               LFIELDMSG(dbgmsg << *(ptr1-1) << " != " << val << ")");
00347               LFIELDMSG(dbgmsg << endl);
00348               ADDIPPLSTAT(incCompressionCompares, (ptr1 - P));
00349               allocCompressIndex = (ptr1 - P) - 1;
00350               return false;
00351             }
00352         }
00353     }
00354 
00355   // If we are at this point, we did not find anything that did not
00356   // match, so we can compress (woo hoo).
00357   
00358   LFIELDMSG(dbgmsg << "Found that we CAN compress, after " << sz);
00359   LFIELDMSG(dbgmsg << " compares." << endl);
00360   ADDIPPLSTAT(incCompressionCompares, sz);
00361   allocCompressIndex = 0;
00362   return true;
00363 }
00364 
00365 
00367 //
00368 // Return true if this LField can be compressed based on physical
00369 // cells only and false if it could not.
00370 //
00372 
00373 template<class T, unsigned Dim>
00374 bool LField<T,Dim>::CanCompressBasedOnPhysicalCells() const
00375 {
00376   TAU_TYPE_STRING(taustr, CT(*this) + " bool ()" );
00377   TAU_PROFILE("LField::CanCompressBasedOnPhysicalCells()", taustr, TAU_FIELD);
00378 
00379   // Debugging macro
00380 
00381   LFIELDMSG(Inform dbgmsg("LField::CanCompressBasedOnPhysicalCells",
00382                           INFORM_ALL_NODES));
00383 
00384   // We definitely can't do this if compression is disabled.
00385   if (IpplInfo::noFieldCompression)
00386     return false;
00387 
00388   // If it is already compressed, we can compress it to any value.
00389   if (IsCompressed())
00390     return true;
00391 
00392   // Make an iterator over my owned domain. The cast is there because
00393   // this version of begin() is not a const member function.
00394 
00395   iterator p = const_cast<LField<T,Dim>*>(this)->begin(getOwned());
00396 
00397   // Get the value to compare against, either the first item or
00398   // an item from the last point where our compression check failed.
00399 
00400   T val = *p;
00401   int sz = getOwned().size();
00402   if (IpplInfo::extraCompressChecks && ownedCompressIndex > 0)
00403     {
00404       // There was a previous value, so get that one to compare against
00405       PAssert(ownedCompressIndex < getAllocated().size());
00406       val = *(P + ownedCompressIndex);
00407       LFIELDMSG(dbgmsg << "Checking owned cells using previous ");
00408       LFIELDMSG(dbgmsg << "comparison value " << val << " from index = ");
00409       LFIELDMSG(dbgmsg << ownedCompressIndex << " against " << sz);
00410       LFIELDMSG(dbgmsg << " elements." << endl);
00411     }
00412   else
00413     {
00414       // We just use the first element, and will compare against
00415       // the rest, so we know we can skip comparing to this first element.
00416       ++p;
00417       --sz;
00418       LFIELDMSG(dbgmsg << "Checking owned cells using first element " << val);
00419       LFIELDMSG(dbgmsg << " for comparison against " << sz << " items."<<endl);
00420     }
00421 
00422   // Loop through the other physical cells until we encounter one that
00423   // doesn't match the 1st cell. If this occurs, we can't compress.
00424 
00425   ADDIPPLSTAT(incCompressionCompareMax, sz - 1);
00426   for (int i=0; i < sz; ++i, ++p)
00427     {
00428       if (!(*p == val))
00429         {
00430           LFIELDMSG(dbgmsg << "Found that we cannot compress, after ");
00431           LFIELDMSG(dbgmsg << i + 1 << " compares." << endl);
00432           ADDIPPLSTAT(incCompressionCompares, i + 1);
00433           ownedCompressIndex = (&(*p)) - P;
00434           LFIELDMSG(dbgmsg << "changed ownedCompressIndex to ");
00435           LFIELDMSG(dbgmsg << ownedCompressIndex << endl);
00436           return false;
00437         }
00438     }
00439 
00440   // Since we made it here, we can compress.
00441 
00442   LFIELDMSG(dbgmsg << "Found that we CAN compress, after ");
00443   LFIELDMSG(dbgmsg << sz << " compares." << endl);
00444   ADDIPPLSTAT(incCompressionCompares, sz);
00445   ownedCompressIndex = (-1);
00446   return true;
00447 }
00448 
00449 
00451 //
00452 // Force a compression to a specified value.  This version compresses
00453 // the entire allocated domain.  If this is called when compression
00454 // is turned off, it instead copies the given value into the whole
00455 // domain's storage, so that it at least makes the whole domain
00456 // equal to the value.
00457 //
00459 
00460 template<class T, unsigned Dim>
00461 void
00462 LField<T,Dim>::Compress(const T& val)
00463 {
00464   TAU_TYPE_STRING(taustr, CT(*this) + " void (" + CT(val) + " )" );
00465   TAU_PROFILE("LField::Compress()", taustr, TAU_FIELD);
00466 
00467   LFIELDMSG(Inform dbgmsg("LField::Compress", INFORM_ALL_NODES));
00468   LFIELDMSG(dbgmsg << "Compressing LField with domain = " << getOwned());
00469   LFIELDMSG(dbgmsg << " to new value = " << val << ", already compressed = ");
00470   LFIELDMSG(dbgmsg << (IsCompressed() ? 1 : 0) << endl);
00471 
00472   // When compression is disabled, interpret this to mean "assign every element
00473   // of the LField to the specified value," which is equivalent to compressing
00474   // the LField to the value then uncompressing it:
00475 
00476   if (IpplInfo::noFieldCompression)
00477     {
00478       for (iterator lit = begin(); lit != end(); ++lit)
00479         *lit = val;
00480 
00481       return;
00482     }
00483 
00484   // Compression is enabled if we're here, so save the compressed value and
00485   // free up memory if necessary.  We copy the value into the compressed
00486   // value storage, and then if we're currently compressed, we free up
00487   // that memory and update our iterators.
00488 
00489   CompressedData = val;
00490   if (!IsCompressed())
00491     {
00492       Begin.Compress(CompressedData);
00493       deallocateStorage();
00494     }
00495 
00496   //INCIPPLSTAT(incCompresses);
00497 }
00498 
00499 
00501 //
00502 // This function does a compressed based on physical cells only.
00503 // It will compress to the value of the first element in the owned
00504 // domain (instead of in the allocated domain).  If compression is
00505 // turned off, this does nothing, it does not even attempt to fill
00506 // in the owned domain with a value.
00507 //
00509 
00510 template<class T, unsigned Dim>
00511 void
00512 LField<T,Dim>::CompressBasedOnPhysicalCells()
00513 {
00514   TAU_TYPE_STRING(taustr, CT(*this) + " void ()" );
00515   TAU_PROFILE("LField::CompressBasedOnPhysicalCells()", taustr, TAU_FIELD);
00516 
00517   // We do nothing in this case if compression is turned off.
00518 
00519   if (IpplInfo::noFieldCompression)
00520     return;
00521 
00522   // Set compression value to first element in owned domain, and free up
00523   // memory if necessary.
00524 
00525   CompressedData = *(begin(getOwned()));
00526   if (!IsCompressed())
00527     {
00528       Begin.Compress(CompressedData);
00529       deallocateStorage();
00530     }
00531 
00532   //INCIPPLSTAT(incCompresses);
00533 }
00534 
00535 
00537 //
00538 // We know this is compressed, so uncompress it.
00539 //
00541 
00542 template<class T, unsigned Dim>
00543 void LField<T,Dim>::ReallyUncompress(bool fill_domain)
00544 {
00545   TAU_TYPE_STRING(taustr, CT(*this) + " void ()" );
00546   TAU_PROFILE("LField::ReallyUncompress()", taustr, TAU_FIELD);
00547 
00548   PAssert(Allocated.size()!=0);
00549 
00550   // Allocate the data.
00551 
00552   int n = Allocated.size();
00553   allocateStorage(n);
00554 
00555   LFIELDMSG(Inform dbgmsg("LField::ReallyUncompress", INFORM_ALL_NODES));
00556   LFIELDMSG(dbgmsg << "Uncompressing LField with domain = " << getOwned());
00557   LFIELDMSG(dbgmsg << ", fill_domain = " << (fill_domain ? 1 : 0) << endl);
00558 
00559   // Copy the constant value into the new space.
00560 
00561   if (fill_domain)
00562     {
00563       T val = *Begin;
00564       for (int i=0; i<n; i++)
00565         P[i] = val;
00566     }
00567 #ifdef IPPL_PURIFY
00568   else
00569     {
00570       // To avoid Purify UMR's, fill with default value anyway
00571       T val = T();
00572       for (int i=0; i<n; i++)
00573         P[i] = val;
00574     }
00575 #endif
00576 
00577   // Make the Begin iterator point to the new data.
00578 
00579   Begin = iterator(P,Owned,Allocated,CompressedData);
00580 
00581   // Indicate we've done one more decompress
00582 
00583   //INCIPPLSTAT(incDecompresses);
00584 }
00585 
00586 
00588 //
00589 // get an iterator over a subrange.
00590 //
00592 
00593 template<class T, unsigned Dim>
00594 typename LField<T,Dim>::iterator 
00595 LField<T,Dim>::begin(const NDIndex<Dim>& domain)
00596 {
00597   // Remove this profiling because this is too lightweight.
00598   // TAU_TYPE_STRING(taustr, CT(*this) + "::iterator (" + CT(domain) + " )" );
00599   // TAU_PROFILE("LField::begin()", taustr, TAU_FIELD);
00600   return iterator(P,domain,Allocated,CompressedData);
00601 }
00602 
00603 
00605 //
00606 // Get an iterator over a subrange, when we might want to try to
00607 // compress the data in the subrange without affecting the rest of
00608 // the LField data.
00609 //
00611 
00612 template<class T, unsigned Dim>
00613 typename LField<T,Dim>::iterator 
00614 LField<T,Dim>::begin(const NDIndex<Dim>& domain, T& compstore)
00615 {
00616   TAU_TYPE_STRING(taustr, CT(*this) + "::iterator (" + CT(domain) + ", " + CT(compstore) 
00617     + " )" );
00618   TAU_PROFILE("LField::begin()", taustr, TAU_FIELD);
00619 
00620   if (IsCompressed())
00621     compstore = CompressedData;
00622   return iterator(P,domain,Allocated,compstore);
00623 }
00624 
00625 
00627 //
00628 // Swap the pointers between two LFields.
00629 //
00631 
00632 template<class T, unsigned Dim>
00633 void 
00634 LField<T,Dim>::swapData( LField<T,Dim>& a )
00635 {
00636   TAU_TYPE_STRING(taustr, "void (" + CT(a) + " )" );
00637   TAU_PROFILE("LField::swapData()", taustr, TAU_FIELD);
00638 
00639   // Swap the pointers to the data.
00640   {
00641     T *temp=P;
00642     P=a.P;
00643     a.P=temp;
00644   }
00645   
00646   // Swap the compressed data.
00647   {
00648     T temp = CompressedData;
00649     CompressedData = a.CompressedData;
00650     a.CompressedData = temp;
00651   }
00652 
00653   // Swap the last-compared-for-compression indices
00654   {
00655     int temp = allocCompressIndex;
00656     allocCompressIndex = a.allocCompressIndex;
00657     a.allocCompressIndex = temp;
00658     temp = ownedCompressIndex;
00659     ownedCompressIndex = a.ownedCompressIndex;
00660     a.ownedCompressIndex = temp;
00661   }
00662 
00663   // Swap the offset block value
00664   {
00665     int temp = offsetBlocks;
00666     offsetBlocks = a.offsetBlocks;
00667     a.offsetBlocks = temp;
00668   }
00669 
00670   // Reinitialize the begin iterators.
00671   Begin = iterator(P,Owned,Allocated,CompressedData);
00672   a.Begin = iterator(a.P,a.Owned,a.Allocated,a.CompressedData);
00673 
00674   // Make sure the domains agree.
00675   PAssert(Owned == a.Owned);
00676   PAssert(Allocated == a.Allocated);
00677 
00678   // Should we swap the overlap caches?
00679 }
00680 
00681 
00683 //
00684 // Actualy allocate storage for the LField data, doing any special
00685 // memory tricks needed for performance.  Sets P pointer to new memory.
00686 //
00688 
00689 template<class T, unsigned Dim>
00690 void 
00691 LField<T,Dim>::allocateStorage(int newsize)
00692 {
00693   PAssert(P == 0);
00694   PAssert(newsize > 0);
00695   PAssert(offsetBlocks >= 0);
00696 
00697   // Determine how many blocks to offset the data, if we are asked to
00698 
00699   int extra = 0;
00700   if (IpplInfo::offsetStorage)
00701     extra = offsetBlocks*IPPL_CACHE_LINE_SIZE / sizeof(T);
00702 
00703   // Allocate the storage, creating some extra to account for offset, and
00704   // then add in the offset.
00705 
00706 #ifdef IPPL_DIRECTIO
00707   P = (T *)valloc(sizeof(T) * (newsize + extra));
00708 #else
00709   P = new T[newsize + extra];
00710 #endif
00711   P += extra;
00712 
00713   ADDIPPLSTAT(incLFieldBytes, (newsize+extra)*sizeof(T));
00714 }
00715 
00716 
00718 //
00719 // Actually free the storage used in the LField, if any.  Resets P to zero.
00720 //
00722 
00723 template<class T, unsigned Dim>
00724 void 
00725 LField<T,Dim>::deallocateStorage()
00726 {
00727   if (P != 0)
00728     {
00729       // Determine how many blocks to offset the data, if we are asked to.
00730       // If so, move the P pointer back.
00731 
00732       if (IpplInfo::offsetStorage)
00733         P -= (offsetBlocks*IPPL_CACHE_LINE_SIZE / sizeof(T));
00734 
00735       // Free the storage
00736 
00737 #ifdef IPPL_DIRECTIO
00738       free(P);
00739 #else
00740       delete [] P;
00741 #endif
00742       // Reset our own pointer to zero
00743 
00744       P = 0;
00745     }
00746 }
00747 
00748 
00750 //
00751 // print an LField out
00752 //
00754 
00755 template<class T, unsigned Dim>
00756 void LField<T,Dim>::write(ostream& out) const
00757 {
00758   TAU_TYPE_STRING(taustr, CT(*this) + " void (ostream)" );
00759   TAU_PROFILE("LField::write()", taustr, TAU_FIELD | TAU_IO);
00760   for (iterator p = begin(); p!=end(); ++p)
00761     out << *p << " ";
00762 }
00763 
00764 
00765 /***************************************************************************
00766  * $RCSfile: LField.cpp,v $   $Author: adelmann $
00767  * $Revision: 1.1.1.1 $   $Date: 2003/01/23 07:40:26 $
00768  * IPPL_VERSION_ID: $Id: LField.cpp,v 1.1.1.1 2003/01/23 07:40:26 adelmann Exp $ 
00769  ***************************************************************************/

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