00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029 #ifndef TPETRA_DISTOBJECT_HPP
00030 #define TPETRA_DISTOBJECT_HPP
00031
00032 #include "Tpetra_ConfigDefs.hpp"
00033 #include "Tpetra_Map.hpp"
00034 #include "Tpetra_CombineMode.hpp"
00035 #include "Tpetra_Import.hpp"
00036 #include "Tpetra_Export.hpp"
00037 #include "Tpetra_Distributor.hpp"
00038
00039 #include <Teuchos_OrdinalTraits.hpp>
00040 #include <Teuchos_RCP.hpp>
00041 #include <Teuchos_Comm.hpp>
00042
00043 namespace Tpetra {
00044
00046
00066 template<typename Ordinal, typename Scalar>
00067 class DistObject : public Teuchos::Object {
00068
00069 public:
00070
00072
00073
00075 DistObject(const Map<Ordinal>& map, Teuchos::RCP<const Teuchos::Comm<Ordinal> > comm);
00076
00078 DistObject(const Map<Ordinal>& map,
00079 Teuchos::RCP<const Teuchos::Comm<Ordinal> > comm,
00080 const std::string & Label);
00081
00083 DistObject(const DistObject<Ordinal, Scalar>& source);
00084
00086 virtual ~DistObject();
00087
00089
00091
00092
00094 void doImport(const DistObject<Ordinal, Scalar> & source,
00095 const Import<Ordinal> & importer, CombineMode CM);
00096
00098 void doExport(const DistObject<Ordinal, Scalar> & dest,
00099 const Export<Ordinal> & exporter, CombineMode CM);
00100
00102 void doImport(const DistObject<Ordinal, Scalar> & source,
00103 const Export<Ordinal> & exporter, CombineMode CM);
00104
00106 void doExport(const DistObject<Ordinal, Scalar> & dest,
00107 const Import<Ordinal> & importer, CombineMode CM);
00108
00110
00112
00113
00115 inline bool isDistributed() const;
00116
00118 inline const Map<Ordinal> & getMap() const;
00119
00121
00123
00124
00126
00127 void print(std::ostream &os) const;
00128
00130
00131 protected:
00132
00134 virtual void doTransfer(const DistObject<Ordinal,Scalar> &source,
00135 CombineMode CM,
00136 Ordinal numSameIDs,
00137 const Teuchos::ArrayView<const Ordinal> &permuteToLIDs,
00138 const Teuchos::ArrayView<const Ordinal> &permuteFromLIDs,
00139 const Teuchos::ArrayView<const Ordinal> &remoteLIDs,
00140 const Teuchos::ArrayView<const Ordinal> &exportLIDs,
00141 Distributor<Ordinal> &distor,
00142 bool doReverse);
00143
00144
00145
00147
00148 virtual bool checkSizes(const DistObject<Ordinal, Scalar> & source, Ordinal &packetSize) = 0;
00149
00151
00167 virtual void copyAndPermute(const DistObject<Ordinal, Scalar> & source,
00168 Ordinal numSameIDs,
00169 const Teuchos::ArrayView<const Ordinal> &permuteToLIDs,
00170 const Teuchos::ArrayView<const Ordinal> &permuteFromLIDs) = 0;
00171
00173
00184 virtual void packAndPrepare(const DistObject<Ordinal,Scalar> & source,
00185 const Teuchos::ArrayView<const Ordinal> &exportLIDs,
00186 const Teuchos::ArrayView<Scalar> &exports,
00187 Distributor<Ordinal> &distor) = 0;
00188
00190
00201 virtual void unpackAndCombine(const Teuchos::ArrayView<const Ordinal> &importLIDs,
00202 const Teuchos::ArrayView<const Scalar> &imports,
00203 Distributor<Ordinal> &distor,
00204 CombineMode CM) = 0;
00205
00206 private:
00207
00208 const Map<Ordinal> map_;
00209 Teuchos::RCP<const Teuchos::Comm<Ordinal> > Comm_;
00210
00211 Teuchos::Array<Scalar> imports_;
00212
00213 Teuchos::Array<Scalar> exports_;
00214
00215 };
00216
00217 template <typename Ordinal, typename Scalar>
00218 DistObject<Ordinal,Scalar>::DistObject(const Map<Ordinal>& map, Teuchos::RCP<const Teuchos::Comm<Ordinal> > comm)
00219 : Teuchos::Object("Tpetra::DistObject")
00220 , map_(map)
00221 , Comm_(comm)
00222 {}
00223
00224 template <typename Ordinal, typename Scalar>
00225 DistObject<Ordinal,Scalar>::DistObject(const Map<Ordinal>& map,
00226 Teuchos::RCP<const Teuchos::Comm<Ordinal> > comm, const std::string & Label)
00227 : Teuchos::Object(Label.c_str())
00228 , map_(map)
00229 , Comm_(comm)
00230 {}
00231
00232 template <typename Ordinal, typename Scalar>
00233 DistObject<Ordinal,Scalar>::DistObject(const DistObject<Ordinal, Scalar>& source)
00234 : Teuchos::Object(source.label())
00235 , map_(source.map_)
00236 , Comm_(source.Comm_)
00237 {}
00238
00239 template <typename Ordinal, typename Scalar>
00240 DistObject<Ordinal,Scalar>::~DistObject()
00241 {}
00242
00243 template <typename Ordinal, typename Scalar>
00244 void DistObject<Ordinal,Scalar>::doImport(const DistObject<Ordinal,Scalar> & source,
00245 const Import<Ordinal> & importer, CombineMode CM)
00246 {
00247 TEST_FOR_EXCEPTION( getMap() != importer.getTargetMap(), std::runtime_error, "Target Maps don't match.");
00248 TEST_FOR_EXCEPTION( source.getMap() != importer.getSourceMap(), std::runtime_error, "Source Maps don't match.");
00249 Ordinal numSameIDs = importer.getNumSameIDs();
00250 const Teuchos::ArrayView<const Ordinal> exportLIDs = importer.getExportLIDs();
00251 const Teuchos::ArrayView<const Ordinal> remoteLIDs = importer.getRemoteLIDs();
00252 const Teuchos::ArrayView<const Ordinal> permuteToLIDs = importer.getPermuteToLIDs();
00253 const Teuchos::ArrayView<const Ordinal> permuteFromLIDs = importer.getPermuteFromLIDs();
00254 this->doTransfer(source, CM, numSameIDs, permuteToLIDs, permuteFromLIDs, remoteLIDs, exportLIDs,
00255 importer.getDistributor(), false);
00256 }
00257
00258 template <typename Ordinal, typename Scalar>
00259 void DistObject<Ordinal,Scalar>::doExport(const DistObject<Ordinal,Scalar> & dest,
00260 const Export<Ordinal> & exporter, CombineMode CM)
00261 {
00262 TEST_FOR_EXCEPTION( getMap() != exporter.getTargetMap(), std::runtime_error, "Target Maps don't match.");
00263 TEST_FOR_EXCEPTION( dest.getMap() != exporter.getSourceMap(), std::runtime_error, "Source Maps don't match.");
00264 Ordinal numSameIDs = exporter.getNumSameIDs();
00265 Teuchos::ArrayView<const Ordinal> exportLIDs = exporter.getExportLIDs();
00266 Teuchos::ArrayView<const Ordinal> remoteLIDs = exporter.getRemoteLIDs();
00267 Teuchos::ArrayView<const Ordinal> permuteToLIDs = exporter.getPermuteToLIDs();
00268 Teuchos::ArrayView<const Ordinal> permuteFromLIDs = exporter.getPermuteFromLIDs();
00269 doTransfer(dest, CM, numSameIDs, permuteToLIDs, permuteFromLIDs, remoteLIDs, exportLIDs,
00270 exporter.getDistributor(), false);
00271 }
00272
00273 template <typename Ordinal, typename Scalar>
00274 void DistObject<Ordinal,Scalar>::doImport(const DistObject<Ordinal,Scalar> & source,
00275 const Export<Ordinal> & exporter, CombineMode CM)
00276 {
00277 TEST_FOR_EXCEPTION( getMap() != exporter.getTargetMap(), std::runtime_error, "Target Maps don't match.");
00278 TEST_FOR_EXCEPTION( source.getMap() != exporter.getSourceMap(), std::runtime_error, "Source Maps don't match.");
00279 Ordinal numSameIDs = exporter.getNumSameIDs();
00280 Teuchos::ArrayView<const Ordinal> exportLIDs = exporter.getRemoteLIDs();
00281 Teuchos::ArrayView<const Ordinal> remoteLIDs = exporter.getExportLIDs();
00282 Teuchos::ArrayView<const Ordinal> permuteToLIDs = exporter.getPermuteFromLIDs();
00283 Teuchos::ArrayView<const Ordinal> permuteFromLIDs = exporter.getPermuteToLIDs();
00284 doTransfer(source, CM, numSameIDs, permuteToLIDs, permuteFromLIDs, remoteLIDs, exportLIDs,
00285 exporter.getDistributor(), true);
00286 }
00287
00288 template <typename Ordinal, typename Scalar>
00289 void DistObject<Ordinal,Scalar>::doExport(const DistObject<Ordinal, Scalar> & dest,
00290 const Import<Ordinal> & importer, CombineMode CM)
00291 {
00292 TEST_FOR_EXCEPTION( getMap() != importer.getTargetMap(), std::runtime_error, "Target Maps don't match.");
00293 TEST_FOR_EXCEPTION( dest.getMap() != importer.getSourceMap(), std::runtime_error, "Source Maps don't match.");
00294 Ordinal numSameIDs = importer.getNumSameIDs();
00295 Teuchos::ArrayView<const Ordinal> exportLIDs = importer.getRemoteLIDs();
00296 Teuchos::ArrayView<const Ordinal> remoteLIDs = importer.getExportLIDs();
00297 Teuchos::ArrayView<const Ordinal> permuteToLIDs = importer.getPermuteFromLIDs();
00298 Teuchos::ArrayView<const Ordinal> permuteFromLIDs = importer.getPermuteToLIDs();
00299 doTransfer(dest, CM, numSameIDs, permuteToLIDs, permuteFromLIDs, remoteLIDs, exportLIDs,
00300 importer.getDistributor(), true);
00301 }
00302
00303 template <typename Ordinal, typename Scalar>
00304 bool DistObject<Ordinal,Scalar>::isDistributed() const
00305 {
00306 return map_.isDistributed();
00307 }
00308
00309 template <typename Ordinal, typename Scalar>
00310 const Map<Ordinal> & DistObject<Ordinal,Scalar>::getMap() const
00311 {
00312 return map_;
00313 }
00314
00315 template <typename Ordinal, typename Scalar>
00316 void DistObject<Ordinal,Scalar>::doTransfer(
00317 const DistObject<Ordinal, Scalar> & source,
00318 CombineMode CM,
00319 Ordinal numSameIDs,
00320 const Teuchos::ArrayView<const Ordinal> &permuteToLIDs,
00321 const Teuchos::ArrayView<const Ordinal> &permuteFromLIDs,
00322 const Teuchos::ArrayView<const Ordinal> &remoteLIDs,
00323 const Teuchos::ArrayView<const Ordinal> &exportLIDs,
00324 Distributor<Ordinal> &distor, bool doReverse)
00325 {
00326 Ordinal packetSize;
00327 TEST_FOR_EXCEPTION( checkSizes(source,packetSize) == false, std::runtime_error,
00328 "Tpetra::DistObject::doTransfer(): checkSizes() indicates that DistOjbects are not size-compatible.");
00329 Ordinal sbufLen = exportLIDs.size()*packetSize;
00330 Ordinal rbufLen = remoteLIDs.size()*packetSize;
00331 exports_.resize(sbufLen);
00332 imports_.resize(rbufLen);
00333 if (numSameIDs + permuteToLIDs.size()) {
00334 copyAndPermute(source,numSameIDs,permuteToLIDs,permuteFromLIDs);
00335 }
00336 packAndPrepare(source,exportLIDs,exports_(),distor);
00337 if ((isDistributed() && doReverse) || (source.isDistributed() && !doReverse))
00338 {
00339
00340 if (doReverse) {
00341 distor.doReversePostsAndWaits(exports_().getConst(),packetSize,imports_());
00342 }
00343 else {
00344 distor.doPostsAndWaits(exports_().getConst(),packetSize,imports_());
00345 }
00346 unpackAndCombine(remoteLIDs,imports_(),distor,CM);
00347 }
00348 }
00349
00350 template <typename Ordinal, typename Scalar>
00351 void DistObject<Ordinal,Scalar>::print(std::ostream &os) const
00352 {
00353 using std::endl;
00354 os << "Tpetra::DistObject" << endl
00355 << " export buffer size: " << exports_.size() << endl
00356 << " import buffer size: " << imports_.size() << endl
00357 << "Map:" << endl
00358 << map_;
00359 }
00360
00361 }
00362
00363 #endif