00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
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
00035
00036 #ifndef IPPL_CACHE_LINE_SIZE
00037 #define IPPL_CACHE_LINE_SIZE 32
00038 #endif
00039
00040
00041
00042
00043
00044
00045 #ifndef IPPL_OFFSET_BLOCKS
00046 #define IPPL_OFFSET_BLOCKS 16
00047 #endif
00048
00049
00050 #ifdef DEBUG_LFIELD
00051 #define LFIELDMSG(x) x
00052 #else
00053 #define LFIELDMSG(x)
00054 #endif
00055
00056
00058
00059
00060
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
00092
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
00116 LFieldInitializer<T>::apply(*Begin);
00117
00118
00119
00120 if (IpplInfo::noFieldCompression)
00121 this->ReallyUncompress(true);
00122
00123
00124 }
00125
00126
00128
00129
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
00152 Begin = iterator(Owned,CompressedData);
00153
00154
00155 CompressedData = lf.CompressedData;
00156 }
00157 else
00158 {
00159
00160 PAssert(lf.Allocated.size()!=0);
00161
00162
00163 int n = lf.Allocated.size();
00164 allocateStorage(n);
00165
00166
00167 copy(lf.P, lf.P + n, P);
00168
00169
00170 Begin = iterator(P,Owned,Allocated,CompressedData);
00171 }
00172
00173
00174 }
00175
00176
00178
00179
00180
00182
00183 template<class T, unsigned Dim>
00184 LField<T,Dim>::~LField()
00185 {
00186 deallocateStorage();
00187 }
00188
00189
00191
00192
00193
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
00235
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
00247 LFIELDMSG(Inform dbgmsg("CanCompress"));
00248
00249
00250 if (IpplInfo::noFieldCompression)
00251 return false;
00252
00253
00254 if (IsCompressed())
00255
00256 return true;
00257
00258
00259
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
00273
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
00290
00291 return false;
00292 }
00293 }
00294
00295
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
00303
00304
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
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
00356
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
00369
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
00380
00381 LFIELDMSG(Inform dbgmsg("LField::CanCompressBasedOnPhysicalCells",
00382 INFORM_ALL_NODES));
00383
00384
00385 if (IpplInfo::noFieldCompression)
00386 return false;
00387
00388
00389 if (IsCompressed())
00390 return true;
00391
00392
00393
00394
00395 iterator p = const_cast<LField<T,Dim>*>(this)->begin(getOwned());
00396
00397
00398
00399
00400 T val = *p;
00401 int sz = getOwned().size();
00402 if (IpplInfo::extraCompressChecks && ownedCompressIndex > 0)
00403 {
00404
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
00415
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
00423
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
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
00453
00454
00455
00456
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
00473
00474
00475
00476 if (IpplInfo::noFieldCompression)
00477 {
00478 for (iterator lit = begin(); lit != end(); ++lit)
00479 *lit = val;
00480
00481 return;
00482 }
00483
00484
00485
00486
00487
00488
00489 CompressedData = val;
00490 if (!IsCompressed())
00491 {
00492 Begin.Compress(CompressedData);
00493 deallocateStorage();
00494 }
00495
00496
00497 }
00498
00499
00501
00502
00503
00504
00505
00506
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
00518
00519 if (IpplInfo::noFieldCompression)
00520 return;
00521
00522
00523
00524
00525 CompressedData = *(begin(getOwned()));
00526 if (!IsCompressed())
00527 {
00528 Begin.Compress(CompressedData);
00529 deallocateStorage();
00530 }
00531
00532
00533 }
00534
00535
00537
00538
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
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
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
00571 T val = T();
00572 for (int i=0; i<n; i++)
00573 P[i] = val;
00574 }
00575 #endif
00576
00577
00578
00579 Begin = iterator(P,Owned,Allocated,CompressedData);
00580
00581
00582
00583
00584 }
00585
00586
00588
00589
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
00598
00599
00600 return iterator(P,domain,Allocated,CompressedData);
00601 }
00602
00603
00605
00606
00607
00608
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
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
00640 {
00641 T *temp=P;
00642 P=a.P;
00643 a.P=temp;
00644 }
00645
00646
00647 {
00648 T temp = CompressedData;
00649 CompressedData = a.CompressedData;
00650 a.CompressedData = temp;
00651 }
00652
00653
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
00664 {
00665 int temp = offsetBlocks;
00666 offsetBlocks = a.offsetBlocks;
00667 a.offsetBlocks = temp;
00668 }
00669
00670
00671 Begin = iterator(P,Owned,Allocated,CompressedData);
00672 a.Begin = iterator(a.P,a.Owned,a.Allocated,a.CompressedData);
00673
00674
00675 PAssert(Owned == a.Owned);
00676 PAssert(Allocated == a.Allocated);
00677
00678
00679 }
00680
00681
00683
00684
00685
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
00698
00699 int extra = 0;
00700 if (IpplInfo::offsetStorage)
00701 extra = offsetBlocks*IPPL_CACHE_LINE_SIZE / sizeof(T);
00702
00703
00704
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
00720
00722
00723 template<class T, unsigned Dim>
00724 void
00725 LField<T,Dim>::deallocateStorage()
00726 {
00727 if (P != 0)
00728 {
00729
00730
00731
00732 if (IpplInfo::offsetStorage)
00733 P -= (offsetBlocks*IPPL_CACHE_LINE_SIZE / sizeof(T));
00734
00735
00736
00737 #ifdef IPPL_DIRECTIO
00738 free(P);
00739 #else
00740 delete [] P;
00741 #endif
00742
00743
00744 P = 0;
00745 }
00746 }
00747
00748
00750
00751
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
00767
00768
00769