Tpetra Matrix/Vector Services  Version of the Day
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Defines
lesson02_read_modify_vec.cpp
00001 // @HEADER
00002 // ***********************************************************************
00003 //
00004 //          Tpetra: Templated Linear Algebra Services Package
00005 //                 Copyright (2008) 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 Michael A. Heroux (maherou@sandia.gov)
00038 //
00039 // ************************************************************************
00040 // @HEADER
00041 
00050 #include <Tpetra_DefaultPlatform.hpp>
00051 #include <Tpetra_Vector.hpp>
00052 #include <Tpetra_Version.hpp>
00053 #include <Teuchos_GlobalMPISession.hpp>
00054 #include <Teuchos_oblackholestream.hpp>
00055 
00056 void
00057 exampleRoutine (const Teuchos::RCP<const Teuchos::Comm<int> >& comm,
00058                 std::ostream& out)
00059 {
00060   using std::endl;
00061   using Teuchos::Array;
00062   using Teuchos::ArrayRCP;
00063   using Teuchos::ArrayView;
00064   using Teuchos::outArg;
00065   using Teuchos::RCP;
00066   using Teuchos::rcp;
00067   using Teuchos::reduceAll;
00068 
00069   // Print out the Tpetra software version information.
00070   out << Tpetra::version() << endl << endl;
00071 
00072   // The "Scalar" type is the type of the values stored in the Tpetra::Vector.
00073   typedef double scalar_type;
00074 
00075   // The "LocalOrdinal" (LO) type is the type of "local" indices.
00076   typedef int local_ordinal_type;
00077 
00078   // The "GlobalOrdinal" (GO) type is the type of "global" indices.
00079   typedef long global_ordinal_type;
00080 
00081   // The Kokkos "Node" type describes the type of shared-memory
00082   // parallelism that Tpetra will use _within_ an MPI process.
00083   typedef Kokkos::DefaultNode::DefaultNodeType node_type;
00084 
00085   // Type of the Map used to describe a parallel distribution.
00086   typedef Tpetra::Map<local_ordinal_type, global_ordinal_type, node_type> map_type;
00087 
00088   // Get a pointer to the default Kokkos Node.  This creates an
00089   // instance of the Node if it hasn't yet been created.  We'll
00090   // need this when creating the Tpetra::Map objects.
00091   RCP<node_type> node = Kokkos::DefaultNode::getDefaultNode ();
00092 
00094   // Create a Tpetra Map
00096 
00097   // The total (global, i.e., over all MPI processes) number of
00098   // entries in the Map.
00099   //
00100   // For this example, we scale the global number of entries in the
00101   // Map with the number of MPI processes.  That way, you can run this
00102   // example with any number of MPI processes and every process will
00103   // still have a positive number of entries.
00104   const Tpetra::global_size_t numGlobalEntries = comm->getSize() * 5;
00105 
00106   // Index base of the Map.  We choose zero-based (C-style) indexing.
00107   const global_ordinal_type indexBase = 0;
00108 
00109   // Construct a Map that puts the same number of equations on each
00110   // MPI process.  Pass in the Kokkos Node, so that this line of code
00111   // will work with any Kokkos Node type.
00112   RCP<const map_type> contigMap =
00113     rcp (new map_type (numGlobalEntries, indexBase, comm,
00114                        Tpetra::GloballyDistributed, node));
00115 
00117   // Create a Tpetra Vector
00119 
00120   // The type of the Tpetra::Vector specialization.
00121   typedef Tpetra::Vector<scalar_type, local_ordinal_type,
00122     global_ordinal_type, node_type> vector_type;
00123 
00124   // Create a Vector with the Map we created above.
00125   // This version of the constructor will fill in the vector with zeros.
00126   RCP<vector_type> x = rcp (new vector_type (contigMap));
00127 
00129   // Fill the Vector with a single number, or with random numbers
00131 
00132   // Set all entries of x to 42.0.
00133   x->putScalar (42.0);
00134 
00135   // Print the norm of x.
00136   out << "Norm of x (all entries are 42.0): " << x->norm2 () << endl;
00137 
00138   // Set the entries of x to (pseudo)random numbers.  Please don't
00139   // consider this a good parallel pseudorandom number generator.
00140   x->randomize ();
00141 
00142   // Print the norm of x.
00143   out << "Norm of x (random numbers): " << x->norm2 () << endl;
00144 
00146   // Read the entries of the Vector
00148 
00149   {
00150     // Get a const persisting view of the entries in the Vector.
00151     // "Const" means that you cannot modify the entries.
00152     // "Persisting" means that the view persists beyond the lifetime of the Vector.
00153     // Even after the Vector's destructor is called, the view won't go away.
00154     // If the Vector's entries change during the lifetime of a persisting view,
00155     // the entries of the persisting view are undefined.
00156     //
00157     // An ArrayRCP acts like an array or std::vector,
00158     // but is reference-counted like std::shared_ptr or Teuchos::RCP.
00159     // You may decrement the reference count manually by assigning Teuchos::null to it.
00160     // We put this code in an inner scope (in an extra pair of {})
00161     // so that the ArrayRCP will fall out of scope before the next example,
00162     // which modifies the entries of the Vector.
00163 
00164     ArrayRCP<const scalar_type> x_data = x->get1dView ();
00165 
00166     // x_data.size () may be longer than the number of local rows in the Vector,
00167     // so be sure to ask the Vector for its dimensions, rather than the ArrayRCP.
00168     const size_t localLength = x->getLocalLength ();
00169 
00170     // Count the local number of entries less than 0.5.
00171     // Use local indices to access the entries of x_data.
00172     size_t localCount = 0;
00173     for (size_t k = 0; k < localLength; ++k) {
00174       if (x_data[k] < 0.5) {
00175         ++localCount;
00176       }
00177     }
00178 
00179     // "reduceAll" is a type-safe templated version of MPI_Allreduce.
00180     // "outArg" is like taking the address using &, but it makes it
00181     // more clear that its argument is an output argument of a function.
00182     size_t globalCount = 0;
00183     reduceAll<int, size_t> (*comm, Teuchos::REDUCE_SUM, localCount, outArg (globalCount));
00184 
00185     // Find the total number of entries less than 0.5,
00186     // over all processes in the Vector's communicator.
00187     out << "x has " << globalCount << " entr" << (globalCount != 1 ? "ies" : "y")
00188         << " less than 0.5." << endl;
00189   }
00190 
00192   // Modify the entries of the Vector
00194 
00195   {
00196     // Get a nonconst persisting view of the entries in the Vector.
00197     // "Nonconst" means that you may modify the entries.
00198     // "Persisting" means that the view persists beyond the lifetime of the Vector.
00199     // Even after the Vector's destructor is called, the view won't go away.
00200     // If you create two nonconst persisting views of the same Vector,
00201     // and modify the entries of one view during the lifetime of the other view,
00202     // the entries of the other view are undefined.
00203     ArrayRCP<scalar_type> x_data = x->get1dViewNonConst ();
00204 
00205     // Use local indices to access the entries of x_data.
00206     // x_data.size () may be longer than the number of local rows in the Vector,
00207     // so be sure to ask the Vector for its dimensions, rather than the ArrayRCP.
00208     const size_t localLength = x->getLocalLength ();
00209     for (size_t k = 0; k < localLength; ++k) {
00210       // Add k (the local index) to every entry of x.
00211       x_data[k] += scalar_type (k);
00212     }
00213 
00214     // Print the norm of x.
00215     out << "Norm of x (modified random numbers): " << x->norm2 () << endl;
00216   }
00217 }
00218 
00219 //
00220 // The same main() driver routine as in the first Tpetra lesson.
00221 //
00222 int
00223 main (int argc, char *argv[])
00224 {
00225   using std::endl;
00226   using Teuchos::RCP;
00227 
00228   Teuchos::oblackholestream blackHole;
00229   Teuchos::GlobalMPISession mpiSession (&argc, &argv, &blackHole);
00230   RCP<const Teuchos::Comm<int> > comm =
00231     Tpetra::DefaultPlatform::getDefaultPlatform().getComm();
00232 
00233   const int myRank = comm->getRank();
00234   std::ostream& out = (myRank == 0) ? std::cout : blackHole;
00235 
00236   // We have a communicator and an output stream.
00237   // Let's do something with them!
00238   exampleRoutine (comm, out);
00239 
00240   // This tells the Trilinos test framework that the test passed.
00241   if (myRank == 0) {
00242     std::cout << "End Result: TEST PASSED" << std::endl;
00243   }
00244 
00245   return 0;
00246 }
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Defines