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>::
00082     apply (const Teuchos::Ptr<const MV>& mv,
00083            const Teuchos::ArrayView<S>& v,
00084            const size_t& ldx,
00085            Teuchos::Ptr<const Tpetra::Map<typename MV::local_ordinal_t, typename MV::global_ordinal_t, typename MV::node_t> > distribution_map)
00086     {
00087       typedef typename MV::scalar_t mv_scalar_t;
00088       typedef typename Teuchos::Array<mv_scalar_t>::size_type size_type;
00089 
00090       TEUCHOS_TEST_FOR_EXCEPTION(
00091         mv.getRawPtr () == NULL, std::invalid_argument,
00092         "Amesos2::diff_type_get_copy::apply: mv is null.");
00093       TEUCHOS_TEST_FOR_EXCEPTION(
00094         distribution_map.getRawPtr () == NULL, std::invalid_argument,
00095         "Amesos2::diff_type_get_copy::apply: distribution_map is null.");
00096 
00097       const size_type vals_length = v.size ();
00098       Teuchos::Array<mv_scalar_t> vals_tmp (vals_length);
00099 
00100       mv->get1dCopy (vals_tmp (), ldx, distribution_map);
00101       for (size_type i = 0; i < vals_length; ++i) {
00102         v[i] = Teuchos::as<S> (vals_tmp[i]);
00103       }
00104     }
00105 
00112     template <class MV, typename S>
00113     void get_1d_copy_helper<MV,S>::
00114     do_get (const Teuchos::Ptr<const MV>& mv,
00115             const Teuchos::ArrayView<S>& vals,
00116             const size_t ldx,
00117             Teuchos::Ptr<const Tpetra::Map<typename MV::local_ordinal_t, typename MV::global_ordinal_t, typename MV::node_t> > distribution_map)
00118     {
00119       // Dispatch to the copy function appropriate for the type
00120       if_then_else<is_same<typename MV::scalar_t,S>::value,
00121         same_type_get_copy<MV>,
00122         diff_type_get_copy<MV,S> >::type::apply (mv, vals, ldx, distribution_map);
00123     }
00124 
00125     template <class MV, typename S>
00126     void get_1d_copy_helper<MV,S>::
00127     do_get (const Teuchos::Ptr<const MV>& mv,
00128             const Teuchos::ArrayView<S>& vals,
00129             const size_t ldx,
00130             EDistribution distribution,
00131             typename MV::global_ordinal_t indexBase)
00132     {
00133       typedef typename MV::local_ordinal_t lo_t;
00134       typedef typename MV::global_ordinal_t go_t;
00135       typedef typename MV::global_size_t gs_t;
00136       typedef typename MV::node_t node_t;
00137 
00138       TEUCHOS_TEST_FOR_EXCEPTION(
00139         mv.getRawPtr () == NULL, std::invalid_argument,
00140         "Amesos2::get_1d_copy_helper::do_get(5 args): mv is null.");
00141 
00142       Teuchos::RCP<const Tpetra::Map<lo_t,go_t,node_t> > map
00143         = Amesos2::Util::getDistributionMap<lo_t,go_t,gs_t,node_t> (distribution,
00144                                                                     mv->getGlobalLength (),
00145                                                                     mv->getComm (), indexBase);
00146       do_get (mv, vals, ldx, Teuchos::ptrInArg (*map));
00147     }
00148 
00149     template <class MV, typename S>
00150     void get_1d_copy_helper<MV,S>::do_get(const Teuchos::Ptr<const MV>& mv,
00151                                           const Teuchos::ArrayView<S>& vals,
00152                                           const size_t ldx)
00153     {
00154       typedef Tpetra::Map<typename MV::local_ordinal_t,
00155                           typename MV::global_ordinal_t,
00156                           typename MV::node_t> map_type;
00157       TEUCHOS_TEST_FOR_EXCEPTION(
00158         mv.getRawPtr () == NULL, std::invalid_argument,
00159         "Amesos2::get_1d_copy_helper::do_get(3 args): mv is null.");
00160 
00161       Teuchos::RCP<const map_type> map = mv->getMap ();
00162       TEUCHOS_TEST_FOR_EXCEPTION(
00163         map.is_null (), std::invalid_argument,
00164         "Amesos2::get_1d_copy_helper::do_get(3 args): mv->getMap() is null.");
00165 
00166       do_get (mv, vals, ldx, Teuchos::ptrInArg (*map));
00167     }
00168 
00169 
00171     // Copy-puting utilities //
00173 
00174     template <typename MV>
00175     void same_type_data_put<MV>::apply(const Teuchos::Ptr<MV>& mv,
00176                                        const Teuchos::ArrayView<typename MV::scalar_t>& data,
00177                                        const size_t ldx,
00178                                        Teuchos::Ptr<const Tpetra::Map<typename MV::local_ordinal_t, typename MV::global_ordinal_t, typename MV::node_t> > distribution_map )
00179     {
00180       mv->put1dData (data, ldx, distribution_map);
00181     }
00182 
00183     /*
00184      * In the case where the scalar type of the multi-vector and the
00185      * corresponding S type are different, then we need to first get a
00186      * copy of the scalar values, then convert each one into the S
00187      * type before inserting into the vals array.
00188      */
00189     template <typename MV, typename S>
00190     void diff_type_data_put<MV,S>::apply(const Teuchos::Ptr<MV>& mv,
00191                                          const Teuchos::ArrayView<S>& data,
00192                                          const size_t& ldx,
00193                                          Teuchos::Ptr<const Tpetra::Map<typename MV::local_ordinal_t, typename MV::global_ordinal_t, typename MV::node_t> > distribution_map )
00194     {
00195       typedef typename MV::scalar_t mv_scalar_t;
00196       typedef typename Teuchos::Array<mv_scalar_t>::size_type size_type;
00197 
00198       TEUCHOS_TEST_FOR_EXCEPTION(
00199         mv.getRawPtr () == NULL, std::invalid_argument,
00200         "Amesos2::diff_type_data_put(4 args): mv is null.");
00201 
00202       const size_type vals_length = data.size ();
00203       Teuchos::Array<mv_scalar_t> data_tmp (vals_length);
00204 
00205       for (size_type i = 0; i < vals_length; ++i) {
00206         data_tmp[i] = Teuchos::as<mv_scalar_t> (data[i]);
00207       }
00208 
00209       mv->put1dData (data_tmp (), ldx, distribution_map);
00210     }
00211 
00212 
00219     template <class MV, typename S>
00220     void put_1d_data_helper<MV,S>::do_put(const Teuchos::Ptr<MV>& mv,
00221                                           const Teuchos::ArrayView<S>& data,
00222                                           const size_t ldx,
00223                                           Teuchos::Ptr<const Tpetra::Map<typename MV::local_ordinal_t, typename MV::global_ordinal_t, typename MV::node_t> > distribution_map )
00224     {
00225       // Dispatch to the copy function appropriate for the type
00226       if_then_else<is_same<typename MV::scalar_t,S>::value,
00227         same_type_data_put<MV>,
00228         diff_type_data_put<MV,S> >::type::apply(mv, data, ldx, distribution_map);
00229     }
00230 
00231     template <class MV, typename S>
00232     void put_1d_data_helper<MV,S>::do_put(const Teuchos::Ptr<MV>& mv,
00233                                           const Teuchos::ArrayView<S>& data,
00234                                           const size_t ldx,
00235                                           EDistribution distribution,  typename MV::global_ordinal_t indexBase)
00236     {
00237       typedef typename MV::local_ordinal_t lo_t;
00238       typedef typename MV::global_ordinal_t go_t;
00239       typedef typename MV::global_size_t gs_t;
00240       typedef typename MV::node_t node_t;
00241 
00242       const Teuchos::RCP<const Tpetra::Map<lo_t,go_t,node_t> > map
00243         = Amesos2::Util::getDistributionMap<lo_t,go_t,gs_t,node_t>(distribution,
00244                                                                    mv->getGlobalLength(),
00245                                                                    mv->getComm(), indexBase);
00246       do_put(mv, data, ldx, Teuchos::ptrInArg(*map));
00247     }
00248 
00249     template <class MV, typename S>
00250     void put_1d_data_helper<MV,S>::do_put (const Teuchos::Ptr<MV>& mv,
00251                                            const Teuchos::ArrayView<S>& data,
00252                                            const size_t ldx)
00253     {
00254       const Teuchos::RCP<const Tpetra::Map<typename MV::local_ordinal_t,
00255         typename MV::global_ordinal_t,
00256         typename MV::node_t> > map
00257         = mv->getMap();
00258       do_put (mv, data, ldx, Teuchos::ptrInArg (*map));
00259     }
00260 
00261   } // end namespace Util
00262 
00263 } // end namespace Amesos2
00264 
00265 #endif  // AMESOS2_EPETRAMULTIVECADAPTER_DEF