Amesos2 - Direct Sparse Solver Interfaces Version of the Day
Amesos2_MultiVecAdapter_def.hpp
00001 // @HEADER
00002 //
00003 // ***********************************************************************
00004 //
00005 //           Amesos2: Templated Direct Sparse Solver 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 //
00042 // @HEADER
00043 
00044 
00045 #ifndef AMESOS2_MULTIVECADAPTER_DEF_HPP
00046 #define AMESOS2_MULTIVECADAPTER_DEF_HPP
00047 
00048 #include "Amesos2_TpetraMultiVecAdapter_def.hpp"
00049 // EpetraMultiVecAdapter_def.hpp not included because the specialization is not a template
00050 
00051 #include "Amesos2_Util.hpp" // for getDistributionMap
00052 
00053 namespace Amesos2{
00054 
00055   namespace Util {
00056 
00058     // Copy-getting utilities //
00060     
00061     /*
00062      * If the multivector scalar type and the desired scalar tpye are
00063      * the same, then we can do a simple straight copy.
00064      */
00065     template <typename MV>
00066     void same_type_get_copy<MV>::apply(const Teuchos::Ptr<const MV>& mv,
00067                const Teuchos::ArrayView<typename MV::scalar_t>& v,
00068                const size_t ldx,
00069                Teuchos::Ptr<const Tpetra::Map<typename MV::local_ordinal_t, typename MV::global_ordinal_t, typename MV::node_t> > distribution_map )
00070     {
00071       mv->get1dCopy(v, ldx, distribution_map);
00072     }
00073 
00074     /*
00075      * In the case where the scalar type of the multi-vector and the
00076      * corresponding S type are different, then we need to first get a
00077      * copy of the scalar values, then convert each one into the S
00078      * type before inserting into the vals array.
00079      */
00080     template <typename MV, typename S>
00081     void diff_type_get_copy<MV,S>::apply(const Teuchos::Ptr<const MV>& mv,
00082            const Teuchos::ArrayView<S>& v,
00083            const size_t& ldx,
00084            Teuchos::Ptr<const Tpetra::Map<typename MV::local_ordinal_t, typename MV::global_ordinal_t, typename MV::node_t> > distribution_map )
00085     {
00086       typedef typename MV::scalar_t mv_scalar_t;
00087     
00088       int vals_length = v.size();
00089       Teuchos::Array<mv_scalar_t> vals_tmp(vals_length);
00090     
00091       mv->get1dCopy(vals_tmp(), ldx, distribution_map);
00092 
00093       for ( int i = 0; i < vals_length; ++i ){
00094   v[i] = Teuchos::as<S>(vals_tmp[i]);
00095       }
00096     }
00097 
00104     template <class MV, typename S>
00105     void get_1d_copy_helper<MV,S>::do_get(const Teuchos::Ptr<const MV>& mv,
00106             const Teuchos::ArrayView<S>& vals,
00107             const size_t ldx,
00108             Teuchos::Ptr<const Tpetra::Map<typename MV::local_ordinal_t, typename MV::global_ordinal_t, typename MV::node_t> > distribution_map )
00109     {
00110       // Dispatch to the copy function appropriate for the type
00111       if_then_else<is_same<typename MV::scalar_t,S>::value,
00112   same_type_get_copy<MV>,
00113   diff_type_get_copy<MV,S> >::type::apply(mv, vals, ldx, distribution_map);
00114     }
00115     
00116     template <class MV, typename S>
00117     void get_1d_copy_helper<MV,S>::do_get(const Teuchos::Ptr<const MV>& mv,
00118             const Teuchos::ArrayView<S>& vals,
00119             const size_t ldx,
00120             EDistribution distribution)
00121     {
00122       typedef typename MV::local_ordinal_t lo_t;
00123       typedef typename MV::global_ordinal_t go_t;
00124       typedef typename MV::global_size_t gs_t;
00125       typedef typename MV::node_t node_t;
00126   
00127       const Teuchos::RCP<const Tpetra::Map<lo_t,go_t,node_t> > map
00128   = Amesos2::Util::getDistributionMap<lo_t,go_t,gs_t,node_t>(distribution,
00129                    mv->getGlobalLength(),
00130                    mv->getComm());
00131       do_get(mv, vals, ldx, Teuchos::ptrInArg(*map));
00132     }
00133 
00134     template <class MV, typename S>
00135     void get_1d_copy_helper<MV,S>::do_get(const Teuchos::Ptr<const MV>& mv,
00136             const Teuchos::ArrayView<S>& vals,
00137             const size_t ldx)
00138     {
00139       const Teuchos::RCP<const Tpetra::Map<typename MV::local_ordinal_t,
00140   typename MV::global_ordinal_t,
00141   typename MV::node_t> > map
00142   = mv->getMap();
00143       do_get(mv, vals, ldx, Teuchos::ptrInArg(*map));
00144     }
00145     
00146     
00148     // Copy-puting utilities //
00150     
00151     template <typename MV>
00152     void same_type_data_put<MV>::apply(const Teuchos::Ptr<MV>& mv,
00153                const Teuchos::ArrayView<typename MV::scalar_t>& data,
00154                const size_t ldx,
00155                Teuchos::Ptr<const Tpetra::Map<typename MV::local_ordinal_t, typename MV::global_ordinal_t, typename MV::node_t> > distribution_map )
00156     {
00157       mv->put1dData(data, ldx, distribution_map);
00158     }
00159     
00160     /*
00161      * In the case where the scalar type of the multi-vector and the
00162      * corresponding S type are different, then we need to first get a
00163      * copy of the scalar values, then convert each one into the S
00164      * type before inserting into the vals array.
00165      */
00166     template <typename MV, typename S>
00167     void diff_type_data_put<MV,S>::apply(const Teuchos::Ptr<MV>& mv,
00168            const Teuchos::ArrayView<S>& data,
00169            const size_t& ldx,
00170            Teuchos::Ptr<const Tpetra::Map<typename MV::local_ordinal_t, typename MV::global_ordinal_t, typename MV::node_t> > distribution_map )
00171     {
00172       typedef typename MV::scalar_t mv_scalar_t;
00173       
00174       int vals_length = data.size();
00175       Teuchos::Array<mv_scalar_t> data_tmp(vals_length);
00176       
00177       for ( int i = 0; i < vals_length; ++i ){
00178   data_tmp[i] = Teuchos::as<mv_scalar_t>(data[i]);
00179       }
00180       
00181       mv->put1dData(data_tmp(), ldx, distribution_map);
00182     }
00183     
00184     
00191     template <class MV, typename S>
00192     void put_1d_data_helper<MV,S>::do_put(const Teuchos::Ptr<MV>& mv,
00193             const Teuchos::ArrayView<S>& data,
00194             const size_t ldx,
00195             Teuchos::Ptr<const Tpetra::Map<typename MV::local_ordinal_t, typename MV::global_ordinal_t, typename MV::node_t> > distribution_map )
00196     {
00197       // Dispatch to the copy function appropriate for the type
00198       if_then_else<is_same<typename MV::scalar_t,S>::value,
00199   same_type_data_put<MV>,
00200   diff_type_data_put<MV,S> >::type::apply(mv, data, ldx, distribution_map);
00201     }
00202     
00203     template <class MV, typename S>
00204     void put_1d_data_helper<MV,S>::do_put(const Teuchos::Ptr<MV>& mv,
00205             const Teuchos::ArrayView<S>& data,
00206             const size_t ldx,
00207             EDistribution distribution)
00208     {
00209       typedef typename MV::local_ordinal_t lo_t;
00210       typedef typename MV::global_ordinal_t go_t;
00211       typedef typename MV::global_size_t gs_t;
00212       typedef typename MV::node_t node_t;
00213       
00214       const Teuchos::RCP<const Tpetra::Map<lo_t,go_t,node_t> > map
00215   = Amesos2::Util::getDistributionMap<lo_t,go_t,gs_t,node_t>(distribution,
00216                    mv->getGlobalLength(),
00217                    mv->getComm());
00218       do_put(mv, data, ldx, Teuchos::ptrInArg(*map));
00219     }
00220     
00221     template <class MV, typename S>
00222     void put_1d_data_helper<MV,S>::do_put(const Teuchos::Ptr<MV>& mv,
00223             const Teuchos::ArrayView<S>& data,
00224             const size_t ldx)
00225     {
00226       const Teuchos::RCP<const Tpetra::Map<typename MV::local_ordinal_t,
00227   typename MV::global_ordinal_t,
00228   typename MV::node_t> > map
00229   = mv->getMap();
00230       do_put(mv, data, ldx, Teuchos::ptrInArg(*map));
00231     }
00232     
00233   } // end namespace Util
00234   
00235 } // end namespace Amesos2
00236 
00237 #endif  // AMESOS2_EPETRAMULTIVECADAPTER_DEF