00001 /* 00002 00003 Copyright (c) 2005-2015, University of Oxford. 00004 All rights reserved. 00005 00006 University of Oxford means the Chancellor, Masters and Scholars of the 00007 University of Oxford, having an administrative office at Wellington 00008 Square, Oxford OX1 2JD, UK. 00009 00010 This file is part of Chaste. 00011 00012 Redistribution and use in source and binary forms, with or without 00013 modification, are permitted provided that the following conditions are met: 00014 * Redistributions of source code must retain the above copyright notice, 00015 this list of conditions and the following disclaimer. 00016 * Redistributions in binary form must reproduce the above copyright notice, 00017 this list of conditions and the following disclaimer in the documentation 00018 and/or other materials provided with the distribution. 00019 * Neither the name of the University of Oxford nor the names of its 00020 contributors may be used to endorse or promote products derived from this 00021 software without specific prior written permission. 00022 00023 THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 00024 AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 00025 IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 00026 ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE 00027 LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 00028 CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE 00029 GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 00030 HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 00031 LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT 00032 OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 00033 00034 */ 00035 00036 00037 #ifndef DISTRIBUTEDVECTOR_HPP_ 00038 #define DISTRIBUTEDVECTOR_HPP_ 00039 00040 #include <vector> 00041 #include <petscvec.h> 00042 #include <iostream> 00043 #include <cassert> 00044 00045 #include "DistributedVectorException.hpp" 00046 00047 class DistributedVectorFactory; 00048 00055 class DistributedVector 00056 { 00057 private: 00058 friend class TestDistributedVector; 00059 00060 // Data global to all vectors 00061 00063 unsigned mLo; 00064 00066 unsigned mHi; 00067 00069 unsigned mProblemSize; 00070 00071 // Data local to a single vector 00072 00074 unsigned mSizeMultiplier; 00075 00077 Vec mVec; 00078 00080 double* mpVec; 00081 00086 DistributedVectorFactory* mpFactory; 00087 00088 public: 00089 00096 bool IsGlobalIndexLocal(unsigned globalIndex); 00097 00107 DistributedVector(Vec vec, DistributedVectorFactory* pFactory); 00108 00112 unsigned GetHigh() const 00113 { 00114 return mHi; 00115 } 00116 00120 unsigned GetLow() const 00121 { 00122 return mLo; 00123 } 00124 00128 DistributedVectorFactory* GetFactory() 00129 { 00130 return mpFactory; 00131 } 00132 00140 double& operator[](unsigned globalIndex) throw (DistributedVectorException); 00141 00147 void Restore(); 00148 00153 class Iterator 00154 { 00155 public: 00156 unsigned Local; 00157 unsigned Global; 00165 bool operator!=(const Iterator& rOther); 00166 00170 Iterator& operator++(); 00171 }; 00172 00180 class Stripe 00181 { 00182 unsigned mStride; 00183 unsigned mStripe; 00184 double* mpVec; 00185 unsigned mLo; 00186 unsigned mHi; 00187 DistributedVectorFactory* mpFactory; 00189 public: 00196 Stripe(DistributedVector parallelVec, unsigned stripe) 00197 { 00198 mStride = parallelVec.mSizeMultiplier; 00199 mStripe = stripe; 00200 assert(mStripe < mStride); 00201 mpVec = parallelVec.mpVec; 00202 mLo = parallelVec.GetLow(); 00203 mHi = parallelVec.GetHigh(); 00204 mpFactory = parallelVec.GetFactory(); 00205 } 00206 00210 DistributedVectorFactory* GetFactory() 00211 { 00212 return mpFactory; 00213 } 00214 00223 double& operator[](unsigned globalIndex) throw (DistributedVectorException) 00224 { 00225 if (mLo <= globalIndex && globalIndex < mHi) 00226 { 00227 return mpVec[(globalIndex - mLo)*mStride + mStripe]; 00228 } 00229 throw DistributedVectorException(); 00230 } 00231 00236 double& operator[](Iterator index) throw (DistributedVectorException) 00237 { 00238 return mpVec[index.Local*mStride + mStripe]; 00239 } 00240 00241 }; 00242 00250 class Chunk 00251 { 00252 unsigned mOffset; 00253 double* mpVec; 00254 unsigned mLo; 00255 unsigned mHi; 00257 public: 00264 Chunk(DistributedVector parallelVec, unsigned chunk) 00265 { 00266 assert(chunk < parallelVec.mSizeMultiplier); 00267 mLo = parallelVec.GetLow(); 00268 mHi = parallelVec.GetHigh(); 00269 mOffset = chunk * (mHi - mLo); 00270 mpVec = parallelVec.mpVec; 00271 } 00272 00281 double& operator[](unsigned globalIndex) throw (DistributedVectorException) 00282 { 00283 if (mLo <= globalIndex && globalIndex < mHi) 00284 { 00285 //localIndex = globalIndex - mLo 00286 return mpVec[mOffset + globalIndex - mLo]; 00287 } 00288 throw DistributedVectorException(); 00289 } 00290 00295 double& operator[](Iterator index) throw (DistributedVectorException) 00296 { 00297 return mpVec[mOffset + index.Local]; 00298 } 00299 00300 }; 00301 00306 Iterator Begin(); 00307 00312 Iterator End(); 00313 00319 double& operator[](Iterator index) throw (DistributedVectorException); 00320 }; 00321 00322 #endif /*DISTRIBUTEDVECTOR_HPP_*/