PlayaSingleChunkVector.hpp
Go to the documentation of this file.
00001 /* @HEADER@ */
00002 // ************************************************************************
00003 // 
00004 //                 Playa: Programmable Linear Algebra
00005 //                 Copyright 2012 Sandia Corporation
00006 // 
00007 // Under the terms of Contract DE-AC04-94AL85000 with Sandia Corporation,
00008 // the U.S. Government retains certain rights in this software.
00009 //
00010 // Redistribution and use in source and binary forms, with or without
00011 // modification, are permitted provided that the following conditions are
00012 // met:
00013 //
00014 // 1. Redistributions of source code must retain the above copyright
00015 // notice, this list of conditions and the following disclaimer.
00016 //
00017 // 2. Redistributions in binary form must reproduce the above copyright
00018 // notice, this list of conditions and the following disclaimer in the
00019 // documentation and/or other materials provided with the distribution.
00020 //
00021 // 3. Neither the name of the Corporation nor the names of the
00022 // contributors may be used to endorse or promote products derived from
00023 // this software without specific prior written permission.
00024 //
00025 // THIS SOFTWARE IS PROVIDED BY SANDIA CORPORATION "AS IS" AND ANY
00026 // EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
00027 // IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
00028 // PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL SANDIA CORPORATION OR THE
00029 // CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
00030 // EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
00031 // PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
00032 // PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
00033 // LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
00034 // NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
00035 // SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
00036 //
00037 // Questions? Contact Kevin Long (kevin.long@ttu.edu)
00038 // 
00039 
00040 /* @HEADER@ */
00041 
00042 #ifndef PLAYA_SINGLECHUNKVECTOR_HPP
00043 #define PLAYA_SINGLECHUNKVECTOR_HPP
00044 
00045 #include "PlayaDefs.hpp"
00046 #include "PlayaVectorBaseDecl.hpp"
00047 
00048 extern "C"
00049 {
00050 void daxpy_(int*, double*, double*, int*, double*, int*);
00051 }
00052 
00053 
00054 namespace Playa
00055 {
00056 /**
00057  * Base class for vector types that have all on-processor data in a single
00058  * contiguous chunk
00059  *
00060  * @author Kevin Long (kevin.long@ttu.edu)
00061  */
00062 template <class Scalar>
00063 class SingleChunkVector : public VectorBase<Scalar>
00064 {
00065 public:
00066   /** */
00067   SingleChunkVector() : rewound_(true) {}
00068   /** virtual dtor */
00069   virtual ~SingleChunkVector() {}
00070 
00071   /** */
00072   virtual ConstDataChunk<Scalar> nextConstChunk() const 
00073     {rewound_ = false; return ConstDataChunk<Scalar>(chunkSize(), dataPtr());}
00074 
00075   /** */
00076   virtual NonConstDataChunk<Scalar> nextChunk() 
00077     {rewound_ = false; return NonConstDataChunk<Scalar>(chunkSize(), dataPtr());}
00078 
00079   /** */
00080   virtual bool hasMoreChunks() const 
00081     {return rewound_;}
00082 
00083   /** */
00084   virtual void rewind() const 
00085     {rewound_=true;}
00086 
00087   /** \name Access to local elements */
00088   //@{
00089   /** read the element at the given local index */
00090   virtual const double& operator[](int localIndex) const 
00091     {return dataPtr()[localIndex];}
00092 
00093   /** writable access to the element at the given local index */
00094   virtual double& operator[](int localIndex) 
00095     {return dataPtr()[localIndex];}
00096   //@}
00097 
00098   /** */
00099   virtual int chunkSize() const = 0 ;
00100   /** */
00101   virtual const Scalar* dataPtr() const = 0 ;
00102   /** */
00103   virtual Scalar* dataPtr() = 0 ;
00104 
00105   virtual void update(const Scalar& alpha, const VectorBase<Scalar>* other,
00106     const Scalar& gamma)
00107     {
00108       const SingleChunkVector<Scalar>* sco 
00109         = dynamic_cast<const SingleChunkVector<Scalar>* >(other);
00110       TEUCHOS_TEST_FOR_EXCEPT(sco==0);
00111 
00112       Scalar* const myVals = this->dataPtr();
00113       const Scalar* const yourVals = sco->dataPtr();
00114       int n = chunkSize();
00115       int stride = 1;
00116       if (gamma==1.0)
00117       {
00118         daxpy_(&n, (double*) &alpha, (double*) yourVals, &stride, 
00119           myVals, &stride);
00120       }
00121       else
00122       {
00123         for (int i=0; i<n; i++)
00124         {
00125           myVals[i] = gamma*myVals[i] + alpha*yourVals[i];
00126         }
00127       }
00128     }
00129 
00130   /** */
00131   virtual void update(
00132     const Scalar& alpha, const VectorBase<Scalar>* x,
00133     const Scalar& beta, const VectorBase<Scalar>* y,
00134     const Scalar& gamma) 
00135     {
00136       const SingleChunkVector<Scalar>* scx 
00137         = dynamic_cast<const SingleChunkVector<Scalar>* >(x);
00138       TEUCHOS_TEST_FOR_EXCEPT(scx==0);
00139       const SingleChunkVector<Scalar>* scy 
00140         = dynamic_cast<const SingleChunkVector<Scalar>* >(y);
00141       TEUCHOS_TEST_FOR_EXCEPT(scy==0);
00142 
00143       Scalar* const myVals = this->dataPtr();
00144       const Scalar* const xVals = scx->dataPtr();
00145       const Scalar* const yVals = scy->dataPtr();
00146       int n = chunkSize();
00147       if (gamma==1.0)
00148       {
00149         for (int i=0; i<n; i++)
00150         {
00151           myVals[i] += alpha*xVals[i] + beta*yVals[i];
00152         }
00153       }
00154       else
00155       {
00156         for (int i=0; i<n; i++)
00157         {
00158           myVals[i] = gamma*myVals[i] + alpha*xVals[i] + beta*yVals[i];
00159         }
00160       }
00161     }
00162 
00163   /** */
00164   virtual void update(
00165     const Scalar& alpha, const VectorBase<Scalar>* x,
00166     const Scalar& beta, const VectorBase<Scalar>* y,
00167     const Scalar& gamma, const VectorBase<Scalar>* z,
00168     const Scalar& delta) 
00169     {
00170       const SingleChunkVector<Scalar>* scx 
00171         = dynamic_cast<const SingleChunkVector<Scalar>* >(x);
00172       TEUCHOS_TEST_FOR_EXCEPT(scx==0);
00173       const SingleChunkVector<Scalar>* scy 
00174         = dynamic_cast<const SingleChunkVector<Scalar>* >(y);
00175       TEUCHOS_TEST_FOR_EXCEPT(scy==0);
00176       const SingleChunkVector<Scalar>* scz
00177         = dynamic_cast<const SingleChunkVector<Scalar>* >(z);
00178       TEUCHOS_TEST_FOR_EXCEPT(scz==0);
00179 
00180       Scalar* const myVals = this->dataPtr();
00181       const Scalar* const xVals = scx->dataPtr();
00182       const Scalar* const yVals = scy->dataPtr();
00183       const Scalar* const zVals = scz->dataPtr();
00184 
00185       int n = chunkSize();
00186       if (delta==1.0)
00187       {
00188         for (int i=0; i<n; i++)
00189         {
00190           myVals[i] += alpha*xVals[i] + beta*yVals[i] + gamma*zVals[i];
00191         }
00192       }
00193       else
00194       {
00195         for (int i=0; i<n; i++)
00196         {
00197           myVals[i] = delta*myVals[i] + alpha*xVals[i] + beta*yVals[i] 
00198             + gamma*zVals[i];
00199         }
00200       }
00201     }
00202 
00203   
00204 
00205   /** */
00206   virtual Scalar dot(const VectorBase<Scalar>* other) const 
00207     {
00208       const SingleChunkVector<Scalar>* const sco 
00209         = dynamic_cast<const SingleChunkVector<Scalar>* >(other);    
00210       TEUCHOS_TEST_FOR_EXCEPT(sco==0);  
00211 
00212       const Scalar* const yourVals = sco->dataPtr();
00213       const Scalar* const myVals = this->dataPtr();
00214 
00215       Scalar rtn = 0.0;
00216       int n = this->chunkSize();
00217       for (int i=0; i<n; i++) rtn += myVals[i]*yourVals[i];
00218       return rtn;
00219     }
00220 
00221   /** */
00222   virtual Scalar norm2() const 
00223     {
00224       const Scalar* const myVals = this->dataPtr();
00225 
00226       Scalar rtn = 0.0;
00227       int n = this->chunkSize();
00228       for (int i=0; i<n; i++) rtn += myVals[i]*myVals[i];
00229       return ::sqrt(rtn);
00230     }
00231 
00232 private:
00233   mutable bool rewound_;
00234 };
00235 }
00236 
00237 
00238 #endif

Site Contact