|
Zoltan2
|
00001 // @HEADER 00002 // 00003 // *********************************************************************** 00004 // 00005 // Zoltan2: A package of combinatorial algorithms for scientific computing 00006 // Copyright 2012 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 Karen Devine (kddevin@sandia.gov) 00039 // Erik Boman (egboman@sandia.gov) 00040 // Siva Rajamanickam (srajama@sandia.gov) 00041 // 00042 // *********************************************************************** 00043 // 00044 // @HEADER 00045 00050 #ifndef _ZOLTAN2_PROBLEM_HPP_ 00051 #define _ZOLTAN2_PROBLEM_HPP_ 00052 00053 #include <Zoltan2_Standards.hpp> 00054 #include <Zoltan2_GraphModel.hpp> 00055 #include <Zoltan2_IdentifierModel.hpp> 00056 #include <Zoltan2_CoordinateModel.hpp> 00057 #include <Zoltan2_Algorithm.hpp> 00058 #include <Zoltan2_TimerManager.hpp> 00059 00060 using std::cout; 00061 using std::endl; 00062 00063 namespace Zoltan2{ 00064 00068 00069 template<typename Adapter> 00070 class Problem { 00071 public: 00072 00073 #ifdef HAVE_ZOLTAN2_MPI 00074 00076 Problem(Adapter *input, ParameterList *params, MPI_Comm comm): 00077 inputAdapter_(input), 00078 baseInputAdapter_(dynamic_cast<base_adapter_t *>(input)), 00079 graphModel_(), identifierModel_(), baseModel_(), algorithm_(), 00080 params_(), comm_(), env_(), envConst_(), timer_() 00081 { 00082 RCP<Teuchos::OpaqueWrapper<MPI_Comm> > wrapper = 00083 Teuchos::opaqueWrapper(comm); 00084 comm_ = rcp<const Comm<int> >(new Teuchos::MpiComm<int>(wrapper)); 00085 setupProblemEnvironment(params); 00086 } 00087 #endif 00088 00089 00092 Problem(Adapter *input, ParameterList *params): 00093 inputAdapter_(input), 00094 baseInputAdapter_(dynamic_cast<base_adapter_t *>(input)), 00095 graphModel_(), identifierModel_(), baseModel_(), algorithm_(), 00096 params_(), comm_(), env_(), envConst_(), timer_() 00097 { 00098 comm_ = DefaultComm<int>::getComm(); 00099 setupProblemEnvironment(params); 00100 } 00101 00102 00105 Problem(Adapter *input, ParameterList *params, RCP<const Comm<int> > &comm): 00106 inputAdapter_(input), 00107 baseInputAdapter_(dynamic_cast<base_adapter_t *>(input)), 00108 graphModel_(), identifierModel_(), baseModel_(), algorithm_(), 00109 params_(), comm_(comm), env_(), envConst_(), timer_() 00110 { 00111 setupProblemEnvironment(params); 00112 } 00113 00116 virtual ~Problem() {}; 00117 00120 RCP<const Comm<int> > getComm() { return comm_; } 00121 00124 void resetParameters(ParameterList *params); 00125 00128 virtual void solve(bool updateInputData) = 0; 00129 00146 #ifdef Z2_OMIT_ALL_ERROR_CHECKING 00147 void printTimers() const {return;} 00148 #else 00149 void printTimers() const 00150 { 00151 if (!timer_.is_null()) 00152 timer_->printAndResetToZero(); 00153 } 00154 #endif 00155 00156 00157 protected: 00158 00159 // The Problem is templated on the input adapter. We interact 00160 // with the input adapter through the base class interface. 00161 // The Model objects are also templated on the input adapter and 00162 // are explicitly instantiated for each base input type (vector, 00163 // graph, matrix, mesh, identifier list, and coordinate list). 00164 00165 typedef typename Adapter::base_adapter_t base_adapter_t; 00166 00167 Adapter* inputAdapter_; 00168 base_adapter_t *baseInputAdapter_; 00169 00170 RCP<GraphModel<base_adapter_t> > graphModel_; 00171 RCP<IdentifierModel<base_adapter_t> > identifierModel_; 00172 RCP<CoordinateModel<base_adapter_t> > coordinateModel_; 00173 00174 // Algorithms are passed a base model class, and query 00175 // the model through the base class interface (graph, hypergraph, 00176 // identifiers, or coordinates). 00177 00178 RCP<const Model<base_adapter_t> > baseModel_; 00179 00180 // Every problem needs an algorithm, right? 00181 RCP<Algorithm<Adapter> > algorithm_; 00182 00183 RCP<ParameterList> params_; 00184 RCP<const Comm<int> > comm_; 00185 00186 // The Problem has a non const Environment object. This is because 00187 // the Problem creates the Environment and may update it before 00188 // finally calling the algorithm. 00189 00190 RCP<Environment> env_; 00191 00192 // The Problem needs a const version of the Environment. No other 00193 // methods are permitted to change the Environment. 00194 00195 RCP<const Environment> envConst_; 00196 00197 // If the user requested timing, this is the TimerManager. 00198 00199 RCP<TimerManager> timer_; 00200 00201 private: 00202 void setupProblemEnvironment(ParameterList *pl); 00203 00204 }; 00205 00206 template <typename Adapter> 00207 void Problem<Adapter>::setupProblemEnvironment(ParameterList *params) 00208 { 00209 try{ 00210 env_ = rcp(new Environment(*params, Teuchos::DefaultComm<int>::getComm())); 00211 } 00212 Z2_FORWARD_EXCEPTIONS 00213 00214 envConst_ = rcp_const_cast<const Environment>(env_); 00215 00216 ParameterList &processedParameters = env_->getParametersNonConst(); 00217 params_ = rcp<ParameterList>(&processedParameters, false); 00218 00219 #ifndef Z2_OMIT_ALL_PROFILING 00220 ParameterList pl = *params_; 00221 00222 // Give a timer to the Environment if requested. 00223 bool haveType=false, haveStream=false, haveFile=false; 00224 int choice = MACRO_TIMERS; // default timer type 00225 00226 const Teuchos::ParameterEntry *pe = pl.getEntryPtr("timer_type"); 00227 00228 if (pe){ 00229 choice = pe->getValue<int>(&choice); 00230 haveType = true; 00231 } 00232 00233 TimerType tt = static_cast<TimerType>(choice); 00234 00235 std::string fname; 00236 pe = pl.getEntryPtr("timer_output_file"); 00237 if (pe){ 00238 haveFile = true; 00239 fname = pe->getValue<std::string>(&fname); 00240 std::ofstream *dbgFile = new std::ofstream; 00241 if (comm_->getRank()==0){ 00242 // Using Teuchos::TimeMonitor, node 0 prints global timing info. 00243 try{ 00244 dbgFile->open(fname.c_str(), std::ios::out|std::ios::trunc); 00245 } 00246 catch(std::exception &e){ 00247 throw std::runtime_error(e.what()); 00248 } 00249 } 00250 timer_ = rcp(new TimerManager(comm_, dbgFile, tt)); 00251 } 00252 else{ 00253 choice = COUT_STREAM; // default output stream 00254 pe = pl.getEntryPtr("timer_output_stream"); 00255 if (pe){ 00256 choice = pe->getValue<int>(&choice); 00257 haveStream = true; 00258 } 00259 00260 OSType outputStream = static_cast<OSType>(choice); 00261 00262 if (haveStream || haveType){ 00263 if (outputStream == COUT_STREAM) 00264 timer_ = rcp(new TimerManager(comm_, &std::cout, tt)); 00265 else if (outputStream == CERR_STREAM) 00266 timer_ = rcp(new TimerManager(comm_, &std::cerr, tt)); 00267 else if (outputStream == NULL_STREAM){ 00268 std::ofstream *of = NULL; 00269 timer_ = rcp(new TimerManager(comm_, of, tt)); 00270 } 00271 } 00272 } 00273 00274 if (haveType || haveStream || haveFile) 00275 env_->setTimer(timer_); 00276 00277 #endif 00278 00279 } 00280 00281 template <typename Adapter> 00282 void Problem<Adapter>::resetParameters(ParameterList *params) 00283 { 00284 env_ = rcp(new Environment(*params, Teuchos::DefaultComm<int>::getComm())); 00285 envConst_ = rcp_const_cast<const Environment>(env_); 00286 00287 ParameterList &processedParameters = env_->getParametersNonConst(); 00288 params_ = rcp<ParameterList>(&processedParameters, false); 00289 00290 // We assume the timing output parameters have not changed, 00291 // and carry on with the same timer. 00292 00293 if (!timer_.is_null()) 00294 env_->setTimer(timer_); 00295 } 00296 00297 } // namespace Zoltan2 00298 00299 #endif
1.7.6.1