Epetra Package Browser (Single Doxygen Collection) Development
Epetra_LongLongVector.cpp
Go to the documentation of this file.
00001 
00002 //@HEADER
00003 // ************************************************************************
00004 //
00005 //               Epetra: Linear Algebra Services Package
00006 //                 Copyright 2011 Sandia Corporation
00007 //
00008 // Under the terms of Contract DE-AC04-94AL85000 with Sandia Corporation,
00009 // the U.S. Government retains certain rights in this software.
00010 //
00011 // Redistribution and use in source and binary forms, with or without
00012 // modification, are permitted provided that the following conditions are
00013 // met:
00014 //
00015 // 1. Redistributions of source code must retain the above copyright
00016 // notice, this list of conditions and the following disclaimer.
00017 //
00018 // 2. Redistributions in binary form must reproduce the above copyright
00019 // notice, this list of conditions and the following disclaimer in the
00020 // documentation and/or other materials provided with the distribution.
00021 //
00022 // 3. Neither the name of the Corporation nor the names of the
00023 // contributors may be used to endorse or promote products derived from
00024 // this software without specific prior written permission.
00025 //
00026 // THIS SOFTWARE IS PROVIDED BY SANDIA CORPORATION "AS IS" AND ANY
00027 // EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
00028 // IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
00029 // PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL SANDIA CORPORATION OR THE
00030 // CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
00031 // EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
00032 // PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
00033 // PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
00034 // LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
00035 // NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
00036 // SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
00037 //
00038 // Questions? Contact Michael A. Heroux (maherou@sandia.gov)
00039 //
00040 // ************************************************************************
00041 //@HEADER
00042 
00043 #include "Epetra_ConfigDefs.h"
00044 #include "Epetra_LongLongVector.h"
00045 #include "Epetra_Map.h"
00046 #include "Epetra_Comm.h"
00047 #include <limits>
00048 
00049 #ifndef EPETRA_NO_64BIT_GLOBAL_INDICES
00050 
00051 //=============================================================================
00052 Epetra_LongLongVector::Epetra_LongLongVector(const Epetra_BlockMap& map, bool zeroOut)
00053   : Epetra_DistObject(map, "Epetra::LongLongVector"),
00054     Values_(0),
00055     UserAllocated_(false),
00056     Allocated_(false)
00057 {
00058   if(!map.GlobalIndicesLongLong())
00059      throw ReportError("Epetra_IntVector::Epetra_IntVector: cannot be called with non long long map index type", -1);
00060 
00061   AllocateForCopy();
00062   if(zeroOut) PutValue(0); // Zero out values
00063 }
00064 //=============================================================================
00065 Epetra_LongLongVector::Epetra_LongLongVector(const Epetra_LongLongVector& Source)
00066   : Epetra_DistObject(Source),
00067     Values_(0),
00068     UserAllocated_(false),
00069     Allocated_(false)
00070 {
00071   if(!Source.Map().GlobalIndicesLongLong())
00072      throw ReportError("Epetra_IntVector::Epetra_IntVector: cannot be called with non long long map index type", -1);
00073 
00074   AllocateForCopy();
00075   DoCopy(Source.Values_);
00076 }
00077 //=============================================================================
00078 Epetra_LongLongVector::Epetra_LongLongVector(Epetra_DataAccess CV, const Epetra_BlockMap& map, long long *V)
00079   : Epetra_DistObject(map, "Epetra::LongLongVector"),
00080     Values_(0),
00081     UserAllocated_(false),
00082     Allocated_(false)
00083 {
00084   if(!map.GlobalIndicesLongLong())
00085      throw ReportError("Epetra_IntVector::Epetra_IntVector: cannot be called with non long long map index type", -1);
00086 
00087   if (CV==Copy) {
00088     AllocateForCopy();
00089     DoCopy(V);
00090   }
00091   else {
00092     AllocateForView();
00093     DoView(V);
00094   }
00095 }
00096 //=========================================================================
00097 Epetra_LongLongVector::~Epetra_LongLongVector(){
00098 
00099 
00100  if (Allocated_ && (!UserAllocated_) && Values_!=0) delete [] Values_;
00101 }
00102 
00103 //=========================================================================
00104 int Epetra_LongLongVector::AllocateForCopy()
00105 {
00106 
00107   if (Allocated_) return(0);
00108 
00109   int myLength = MyLength();
00110   if (myLength>0)
00111     Values_ = new long long[myLength];
00112   else
00113     Values_ = 0;
00114 
00115   Allocated_ = true;
00116   UserAllocated_ = false;
00117   return(0);
00118 }
00119 
00120 //=========================================================================
00121 int Epetra_LongLongVector::DoCopy(long long * V)
00122 {
00123   int iend = MyLength();
00124   for (int i=0; i<iend; i++) Values_[i] = V[i];
00125 
00126   return(0);
00127 }
00128 //=========================================================================
00129 int Epetra_LongLongVector::AllocateForView()
00130 {
00131 
00132   Allocated_ = true;
00133   UserAllocated_ = true;
00134 
00135   return(0);
00136 }
00137 
00138 //=========================================================================
00139 int Epetra_LongLongVector::DoView(long long * V)
00140 {
00141 
00142   Values_ = V;
00143 
00144   return(0);
00145 }
00146 //=============================================================================
00147 int Epetra_LongLongVector::ExtractCopy(long long *V) const {
00148 
00149   int iend = MyLength();
00150   for (int i=0; i<iend; i++) V[i] = Values_[i];
00151   return(0);
00152 }
00153 
00154 //=============================================================================
00155 int Epetra_LongLongVector::ExtractView(long long **V) const
00156 {
00157   *V = Values_;
00158   return(0);
00159 }
00160 
00161 //=============================================================================
00162 int Epetra_LongLongVector::PutValue(long long Value) {
00163   int iend = MyLength();
00164   for (int i=0; i<iend; i++) Values_[i] = Value;
00165   return(0);
00166 }
00167 //=============================================================================
00168 long long Epetra_LongLongVector::MaxValue() {
00169   long long result = std::numeric_limits<long long>::min(); // smallest 64 bit int
00170   int iend = MyLength();
00171   if (iend>0) result = Values_[0];
00172   for (int i=0; i<iend; i++) result = EPETRA_MAX(result, Values_[i]);
00173   long long globalResult;
00174   this->Comm().MaxAll(&result, &globalResult, 1);
00175   return(globalResult);
00176 }
00177 //=============================================================================
00178 long long Epetra_LongLongVector::MinValue() {
00179   long long result = std::numeric_limits<long long>::max(); // largest 64 bit int
00180   int iend = MyLength();
00181   if (iend>0) result = Values_[0];
00182   for (int i=0; i<iend; i++) result = EPETRA_MIN(result, Values_[i]);
00183   long long globalResult;
00184   this->Comm().MinAll(&result, &globalResult, 1);
00185   return(globalResult);
00186 }
00187 //========================================================================
00188 Epetra_LongLongVector& Epetra_LongLongVector::operator = (const Epetra_LongLongVector& V) {
00189 
00190 
00191   if (MyLength() != V.MyLength())
00192     throw ReportError("Length of LongLongVectors incompatible in Assign.  The this LongLongVector has MyLength = " + toString(MyLength())
00193           + ".  The V LongLongVector has MyLength = " + toString(V.MyLength()), -1);
00194 
00195   int iend = MyLength();
00196   for (int i=0; i<iend; i++) Values_[i] =V[i];
00197   return(*this);
00198 }
00199 
00200 void Epetra_LongLongVector::Print(std::ostream& os) const {
00201   int MyPID = Map().Comm().MyPID();
00202   int NumProc = Map().Comm().NumProc();
00203 
00204   for (int iproc=0; iproc < NumProc; iproc++) {
00205     if (MyPID==iproc) {
00206       int NumMyElements1 =Map(). NumMyElements();
00207       int MaxElementSize1 = Map().MaxElementSize();
00208     long long * MyGlobalElements1 = Map().MyGlobalElements64();
00209       int * FirstPointInElementList1=0;
00210       if (MaxElementSize1!=1) FirstPointInElementList1 = Map().FirstPointInElementList();
00211 
00212       if (MyPID==0) {
00213   os.width(8);
00214   os <<  "     MyPID"; os << "    ";
00215   os.width(12);
00216   if (MaxElementSize1==1)
00217     os <<  "GID  ";
00218   else
00219     os <<  "     GID/Point";
00220   os.width(20);
00221   os <<  "Value  ";
00222   os << std::endl;
00223       }
00224       for (int i=0; i < NumMyElements1; i++) {
00225   for (int ii=0; ii< Map().ElementSize(i); ii++) {
00226     int iii;
00227     os.width(10);
00228     os <<  MyPID; os << "    ";
00229     os.width(10);
00230     if (MaxElementSize1==1) {
00231       os << MyGlobalElements1[i] << "    ";
00232       iii = i;
00233     }
00234     else {
00235       os <<  MyGlobalElements1[i]<< "/" << ii << "    ";
00236       iii = FirstPointInElementList1[i]+ii;
00237     }
00238         os.width(20);
00239         os <<  Values_[iii];
00240     os << std::endl;
00241   }
00242       }
00243       os << std::flush;
00244     }
00245 
00246     // Do a few global ops to give I/O a chance to complete
00247     Map().Comm().Barrier();
00248     Map().Comm().Barrier();
00249     Map().Comm().Barrier();
00250   }
00251   return;
00252 }
00253 //=========================================================================
00254 int Epetra_LongLongVector::CheckSizes(const Epetra_SrcDistObject& Source)
00255 {
00256   (void)Source;
00257   return(0);
00258 }
00259 
00260 //=========================================================================
00261 int Epetra_LongLongVector::CopyAndPermute(const Epetra_SrcDistObject& Source,
00262                                      int NumSameIDs,
00263                                      int NumPermuteIDs,
00264                                      int * PermuteToLIDs,
00265                                      int *PermuteFromLIDs,
00266                                      const Epetra_OffsetIndex * Indexor)
00267 {
00268   (void)Indexor;
00269   const Epetra_LongLongVector & A = dynamic_cast<const Epetra_LongLongVector &>(Source);
00270 
00271   long long * From;
00272   A.ExtractView(&From);
00273   long long *To = Values_;
00274 
00275   int * ToFirstPointInElementList = 0;
00276   int * FromFirstPointInElementList = 0;
00277   int * FromElementSizeList = 0;
00278   int MaxElementSize = Map().MaxElementSize();
00279   bool ConstantElementSize = Map().ConstantElementSize();
00280 
00281   if (!ConstantElementSize) {
00282     ToFirstPointInElementList =   Map().FirstPointInElementList();
00283     FromFirstPointInElementList = A.Map().FirstPointInElementList();
00284     FromElementSizeList = A.Map().ElementSizeList();
00285   }
00286   int j, jj, jjj, k;
00287 
00288   int NumSameEntries;
00289 
00290   bool Case1 = false;
00291   bool Case2 = false;
00292   // bool Case3 = false;
00293 
00294   if (MaxElementSize==1) {
00295     Case1 = true;
00296     NumSameEntries = NumSameIDs;
00297   }
00298   else if (ConstantElementSize) {
00299     Case2 = true;
00300     NumSameEntries = NumSameIDs * MaxElementSize;
00301   }
00302   else {
00303     // Case3 = true;
00304     NumSameEntries = FromFirstPointInElementList[NumSameIDs];
00305   }
00306 
00307   // Short circuit for the case where the source and target vector is the same.
00308   if (To==From) NumSameEntries = 0;
00309 
00310   // Do copy first
00311   if (NumSameIDs>0)
00312     if (To!=From) {
00313   for (j=0; j<NumSameEntries; j++)
00314     To[j] = From[j];
00315     }
00316   // Do local permutation next
00317   if (NumPermuteIDs>0) {
00318 
00319     // Point entry case
00320     if (Case1) {
00321 
00322       for (j=0; j<NumPermuteIDs; j++)
00323   To[PermuteToLIDs[j]] = From[PermuteFromLIDs[j]];
00324     }
00325     // constant element size case
00326     else if (Case2) {
00327 
00328       for (j=0; j<NumPermuteIDs; j++) {
00329   jj = MaxElementSize*PermuteToLIDs[j];
00330   jjj = MaxElementSize*PermuteFromLIDs[j];
00331     for (k=0; k<MaxElementSize; k++)
00332       To[jj+k] = From[jjj+k];
00333       }
00334     }
00335 
00336     // variable element size case
00337     else {
00338 
00339       for (j=0; j<NumPermuteIDs; j++) {
00340   jj = ToFirstPointInElementList[PermuteToLIDs[j]];
00341   jjj = FromFirstPointInElementList[PermuteFromLIDs[j]];
00342   int ElementSize = FromElementSizeList[PermuteFromLIDs[j]];
00343     for (k=0; k<ElementSize; k++)
00344       To[jj+k] = From[jjj+k];
00345       }
00346     }
00347   }
00348   return(0);
00349 }
00350 
00351 //=========================================================================
00352 int Epetra_LongLongVector::PackAndPrepare(const Epetra_SrcDistObject & Source,
00353                                      int NumExportIDs,
00354                                      int * ExportLIDs,
00355                                      int & LenExports,
00356                                      char * & Exports,
00357                                      int & SizeOfPacket,
00358                                      int * Sizes,
00359                                      bool & VarSizes,
00360                                      Epetra_Distributor & Distor)
00361 {
00362   (void)Sizes;
00363   (void)VarSizes;
00364   (void)Distor;
00365   const Epetra_LongLongVector & A = dynamic_cast<const Epetra_LongLongVector &>(Source);
00366 
00367   int j, jj, k;
00368 
00369   long long  * From;
00370   A.ExtractView(&From);
00371   int MaxElementSize = Map().MaxElementSize();
00372   bool ConstantElementSize = Map().ConstantElementSize();
00373 
00374   int * FromFirstPointInElementList = 0;
00375   int * FromElementSizeList = 0;
00376 
00377   if (!ConstantElementSize) {
00378     FromFirstPointInElementList = A.Map().FirstPointInElementList();
00379     FromElementSizeList = A.Map().ElementSizeList();
00380   }
00381 
00382   SizeOfPacket = MaxElementSize * (int)sizeof(long long);
00383 
00384   if(NumExportIDs*SizeOfPacket>LenExports) {
00385     if (LenExports>0) delete [] Exports;
00386     LenExports = NumExportIDs*SizeOfPacket;
00387     Exports = new char[LenExports];
00388   }
00389 
00390   long long * ptr;
00391 
00392   if (NumExportIDs>0) {
00393     ptr = (long long *) Exports;
00394 
00395     // Point entry case
00396     if (MaxElementSize==1) for (j=0; j<NumExportIDs; j++) *ptr++ = From[ExportLIDs[j]];
00397 
00398     // constant element size case
00399     else if (ConstantElementSize) {
00400 
00401       for (j=0; j<NumExportIDs; j++) {
00402   jj = MaxElementSize*ExportLIDs[j];
00403     for (k=0; k<MaxElementSize; k++)
00404       *ptr++ = From[jj+k];
00405       }
00406     }
00407 
00408     // variable element size case
00409     else {
00410 
00411       int thisSizeOfPacket = MaxElementSize;
00412       for (j=0; j<NumExportIDs; j++) {
00413   ptr = (long long *) Exports + j*thisSizeOfPacket;
00414   jj = FromFirstPointInElementList[ExportLIDs[j]];
00415   int ElementSize = FromElementSizeList[ExportLIDs[j]];
00416     for (k=0; k<ElementSize; k++)
00417       *ptr++ = From[jj+k];
00418       }
00419     }
00420   }
00421 
00422   return(0);
00423 }
00424 
00425 //=========================================================================
00426 int Epetra_LongLongVector::UnpackAndCombine(const Epetra_SrcDistObject & Source,
00427                                        int NumImportIDs,
00428                                        int * ImportLIDs,
00429                                        int LenImports,
00430                                        char * Imports,
00431                                        int & SizeOfPacket,
00432                                        Epetra_Distributor & Distor,
00433                                        Epetra_CombineMode CombineMode,
00434                                        const Epetra_OffsetIndex * Indexor)
00435 {
00436   (void)Source;
00437   (void)LenImports;
00438   (void)SizeOfPacket;
00439   (void)Distor;
00440   (void)Indexor;
00441   int j, jj, k;
00442 
00443   if(    CombineMode != Add
00444       && CombineMode != Zero
00445       && CombineMode != Insert
00446       && CombineMode != Average
00447       && CombineMode != AbsMax )
00448     EPETRA_CHK_ERR(-1); //Unsupported CombinedMode, will default to Zero
00449 
00450   if (NumImportIDs<=0) return(0);
00451 
00452   long long * To = Values_;
00453   int MaxElementSize = Map().MaxElementSize();
00454   bool ConstantElementSize = Map().ConstantElementSize();
00455 
00456   int * ToFirstPointInElementList = 0;
00457   int * ToElementSizeList = 0;
00458 
00459   if (!ConstantElementSize) {
00460     ToFirstPointInElementList = Map().FirstPointInElementList();
00461     ToElementSizeList = Map().ElementSizeList();
00462   }
00463 
00464   long long * ptr;
00465   // Unpack it...
00466 
00467   ptr = (long long *) Imports;
00468 
00469   // Point entry case
00470   if (MaxElementSize==1) {
00471 
00472       if (CombineMode==Add)
00473   for (j=0; j<NumImportIDs; j++) To[ImportLIDs[j]] += *ptr++; // Add to existing value
00474       else if(CombineMode==Insert)
00475   for (j=0; j<NumImportIDs; j++) To[ImportLIDs[j]] = *ptr++;
00476       else if(CombineMode==AbsMax)
00477         for (j=0; j<NumImportIDs; j++) {
00478     To[ImportLIDs[j]] = EPETRA_MAX( To[ImportLIDs[j]],(*ptr > 0 ? *ptr : -*ptr)); // CJ: No std::abs(long long) in VS2005
00479     ptr++;
00480   }
00481       // Note:  The following form of averaging is not a true average if more that one value is combined.
00482       //        This might be an issue in the future, but we leave this way for now.
00483       else if(CombineMode==Average)
00484   for (j=0; j<NumImportIDs; j++) {To[ImportLIDs[j]] += *ptr++; To[ImportLIDs[j]] /= 2;}
00485   }
00486 
00487   // constant element size case
00488 
00489   else if (ConstantElementSize) {
00490 
00491     if (CombineMode==Add) {
00492       for (j=0; j<NumImportIDs; j++) {
00493   jj = MaxElementSize*ImportLIDs[j];
00494     for (k=0; k<MaxElementSize; k++)
00495       To[jj+k] += *ptr++; // Add to existing value
00496       }
00497     }
00498     else if(CombineMode==Insert) {
00499       for (j=0; j<NumImportIDs; j++) {
00500   jj = MaxElementSize*ImportLIDs[j];
00501     for (k=0; k<MaxElementSize; k++)
00502       To[jj+k] = *ptr++;
00503       }
00504     }
00505     else if(CombineMode==AbsMax) {
00506       for (j=0; j<NumImportIDs; j++) {
00507   jj = MaxElementSize*ImportLIDs[j];
00508   for (k=0; k<MaxElementSize; k++) {
00509       To[jj+k] = EPETRA_MAX( To[jj+k], (*ptr > 0 ? *ptr : -*ptr)); // CJ: No std::abs(long long) in VS2005
00510       ptr++;
00511   }
00512       }
00513     }
00514     // Note:  The following form of averaging is not a true average if more that one value is combined.
00515     //        This might be an issue in the future, but we leave this way for now.
00516     else if(CombineMode==Average) {
00517       for (j=0; j<NumImportIDs; j++) {
00518   jj = MaxElementSize*ImportLIDs[j];
00519     for (k=0; k<MaxElementSize; k++)
00520       { To[jj+k] += *ptr++; To[jj+k] /= 2;}
00521       }
00522     }
00523   }
00524 
00525   // variable element size case
00526 
00527   else {
00528 
00529     int thisSizeOfPacket = MaxElementSize;
00530 
00531     if (CombineMode==Add) {
00532       for (j=0; j<NumImportIDs; j++) {
00533   ptr = (long long *) Imports + j*thisSizeOfPacket;
00534   jj = ToFirstPointInElementList[ImportLIDs[j]];
00535   int ElementSize = ToElementSizeList[ImportLIDs[j]];
00536     for (k=0; k<ElementSize; k++)
00537       To[jj+k] += *ptr++; // Add to existing value
00538       }
00539     }
00540     else  if(CombineMode==Insert){
00541       for (j=0; j<NumImportIDs; j++) {
00542   ptr = (long long *) Imports + j*thisSizeOfPacket;
00543   jj = ToFirstPointInElementList[ImportLIDs[j]];
00544   int ElementSize = ToElementSizeList[ImportLIDs[j]];
00545     for (k=0; k<ElementSize; k++)
00546       To[jj+k] = *ptr++;
00547       }
00548     }
00549     else  if(CombineMode==AbsMax){
00550       for (j=0; j<NumImportIDs; j++) {
00551   ptr = (long long *) Imports + j*thisSizeOfPacket;
00552   jj = ToFirstPointInElementList[ImportLIDs[j]];
00553   int ElementSize = ToElementSizeList[ImportLIDs[j]];
00554   for (k=0; k<ElementSize; k++) {
00555       To[jj+k] = EPETRA_MAX( To[jj+k], (*ptr > 0 ? *ptr : -*ptr)); // CJ: No std::abs(long long) in VS2005
00556       ptr++;
00557   }
00558       }
00559     }
00560     // Note:  The following form of averaging is not a true average if more that one value is combined.
00561     //        This might be an issue in the future, but we leave this way for now.
00562     else if(CombineMode==Average) {
00563       for (j=0; j<NumImportIDs; j++) {
00564   ptr = (long long *) Imports + j*thisSizeOfPacket;
00565   jj = ToFirstPointInElementList[ImportLIDs[j]];
00566   int ElementSize = ToElementSizeList[ImportLIDs[j]];
00567     for (k=0; k<ElementSize; k++)
00568       { To[jj+k] += *ptr++; To[jj+k] /= 2;}
00569       }
00570     }
00571   }
00572 
00573   return(0);
00574 }
00575 
00576 #endif // EPETRA_NO_64BIT_GLOBAL_INDICES
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines