|
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_COLORINGPROBLEM_HPP_ 00051 #define _ZOLTAN2_COLORINGPROBLEM_HPP_ 00052 00053 #include <Zoltan2_Standards.hpp> 00054 00055 #include <Zoltan2_Problem.hpp> 00056 #include <Zoltan2_ColoringAlgorithms.hpp> 00057 #include <Zoltan2_ColoringSolution.hpp> 00058 00059 #include <Zoltan2_GraphModel.hpp> 00060 #include <string> 00061 00062 #include <bitset> 00063 00064 using Teuchos::rcp_dynamic_cast; 00065 00066 namespace Zoltan2{ 00067 00069 00089 template<typename Adapter> 00090 class ColoringProblem : public Problem<Adapter> 00091 { 00092 public: 00093 00094 typedef typename Adapter::scalar_t scalar_t; 00095 typedef typename Adapter::zgid_t zgid_t; 00096 typedef typename Adapter::gno_t gno_t; 00097 typedef typename Adapter::lno_t lno_t; 00098 typedef typename Adapter::user_t user_t; 00099 typedef typename Adapter::base_adapter_t base_adapter_t; 00100 00101 #ifdef HAVE_ZOLTAN2_MPI 00102 typedef Teuchos::OpaqueWrapper<MPI_Comm> mpiWrapper_t; 00103 #endif 00104 00107 virtual ~ColoringProblem() {}; 00108 00109 00110 #ifdef HAVE_ZOLTAN2_MPI 00111 00113 ColoringProblem(Adapter *A, ParameterList *p, MPI_Comm comm) 00114 : Problem<Adapter>(A, p, comm) 00115 { 00116 HELLO; 00117 createColoringProblem(); 00118 }; 00119 #endif 00120 00123 ColoringProblem(Adapter *A, ParameterList *p) : Problem<Adapter>(A, p) 00124 { 00125 HELLO; 00126 createColoringProblem(); 00127 }; 00128 00130 // 00131 // \param updateInputData If true this indicates that either 00132 // this is the first attempt at solution, or that we 00133 // are computing a new solution and the input data has 00134 // changed since the previous solution was computed. 00135 // If false, this indicates that we are computing a 00136 // new solution using the same input data was used for 00137 // the previous solution, even though the parameters 00138 // may have been changed. 00139 // 00140 // For the sake of performance, we ask the caller to set \c updateInputData 00141 // to false if he/she is computing a new solution using the same input data, 00142 // but different problem parameters, than that which was used to compute 00143 // the most recent solution. 00144 00145 void solve(bool updateInputData=true); 00146 00148 // 00149 // \return a reference to the solution to the most recent solve(). 00150 00151 ColoringSolution<Adapter> *getSolution() { 00152 // Get the raw ptr from the rcp 00153 return solution_.getRawPtr(); 00154 }; 00155 00156 private: 00157 void createColoringProblem(); 00158 00159 RCP<ColoringSolution<Adapter> > solution_; 00160 00161 RCP<Comm<int> > problemComm_; 00162 RCP<const Comm<int> > problemCommConst_; 00163 00164 #ifdef HAVE_ZOLTAN2_MPI 00165 MPI_Comm mpiComm_; 00166 #endif 00167 }; 00168 00169 00171 template <typename Adapter> 00172 void ColoringProblem<Adapter>::solve(bool newData) 00173 { 00174 HELLO; 00175 00176 size_t nVtx = this->baseModel_->getLocalNumObjects(); 00177 00178 try 00179 { 00180 this->solution_ = rcp(new ColoringSolution<Adapter>(nVtx)); 00181 } 00182 Z2_FORWARD_EXCEPTIONS; 00183 00184 // Determine which algorithm to use based on defaults and parameters. 00185 // Need some exception handling here, too. 00186 00187 std::string method = this->params_->template get<std::string>("color_method", "SerialGreedy"); 00188 00189 try 00190 { 00191 // TODO: Ignore case 00192 if (method.compare("SerialGreedy") == 0) 00193 { 00194 AlgSerialGreedy<Adapter> alg(this->graphModel_, this->params_, 00195 this->env_, problemComm_); 00196 alg.color(this->solution_); 00197 } 00198 #if 0 // TODO later 00199 else if (method.compare("speculative") == 0) // Gebremedhin-Manne 00200 { 00201 AlgGM<base_adapter_t> alg(this->graphModel_, problemComm_); 00202 alg.color(this->solution_, this->params_); 00203 } 00204 #endif 00205 } 00206 Z2_FORWARD_EXCEPTIONS; 00207 00208 #ifdef HAVE_ZOLTAN2_MPI 00209 00210 // The algorithm may have changed the communicator. Change it back. 00211 // EGB: This seems excessive. Algorithms should never change the comm?! 00212 00213 RCP<const mpiWrapper_t > wrappedComm = rcp(new mpiWrapper_t(mpiComm_)); 00214 problemComm_ = rcp(new Teuchos::MpiComm<int>(wrappedComm)); 00215 problemCommConst_ = rcp_const_cast<const Comm<int> > (problemComm_); 00216 00217 #endif 00218 00219 } 00220 00222 //template <typename Adapter> 00223 //void ColoringProblem<Adapter>::redistribute() 00224 //{ 00225 // HELLO; 00226 //} 00227 00230 // Method with common functionality for creating a ColoringProblem. 00231 // Individual constructors do appropriate conversions of input, etc. 00232 // This method does everything that all constructors must do. 00233 00234 template <typename Adapter> 00235 void ColoringProblem<Adapter>::createColoringProblem() 00236 { 00237 HELLO; 00238 using Teuchos::ParameterList; 00239 00240 // cout << __func__zoltan2__ << " input adapter type " 00241 // << this->inputAdapter_->inputAdapterType() << " " 00242 // << this->inputAdapter_->inputAdapterName() << endl; 00243 00244 // Create a copy of the user's communicator. 00245 00246 problemComm_ = this->comm_->duplicate(); 00247 problemCommConst_ = rcp_const_cast<const Comm<int> > (problemComm_); 00248 00249 00250 #ifdef HAVE_ZOLTAN2_MPI 00251 00252 // TPLs may want an MPI communicator 00253 00254 Comm<int> *c = problemComm_.getRawPtr(); 00255 Teuchos::MpiComm<int> *mc = dynamic_cast<Teuchos::MpiComm<int> *>(c); 00256 if (mc){ 00257 RCP<const mpiWrapper_t> wrappedComm = mc->getRawMpiComm(); 00258 mpiComm_ = (*wrappedComm.getRawPtr())(); 00259 } 00260 else{ 00261 mpiComm_ = MPI_COMM_SELF; // or would this be an error? 00262 } 00263 00264 #endif 00265 00266 // Only graph model supported. 00267 // TODO: Allow hypergraph later? 00268 00269 ModelType modelType = GraphModelType; 00270 00271 // Select Model based on parameters and InputAdapter type 00272 00273 std::bitset<NUM_MODEL_FLAGS> graphFlags; 00274 std::bitset<NUM_MODEL_FLAGS> idFlags; 00275 00276 switch (modelType) { 00277 00278 case GraphModelType: 00279 graphFlags.set(SELF_EDGES_MUST_BE_REMOVED); 00280 graphFlags.set(IDS_MUST_BE_GLOBALLY_CONSECUTIVE); 00281 this->graphModel_ = rcp(new GraphModel<base_adapter_t>( 00282 this->baseInputAdapter_, this->envConst_, problemCommConst_, graphFlags)); 00283 00284 this->baseModel_ = rcp_implicit_cast<const Model<base_adapter_t> >( 00285 this->graphModel_); 00286 00287 break; 00288 00289 00290 case IdentifierModelType: 00291 case HypergraphModelType: 00292 case CoordinateModelType: 00293 cout << __func__zoltan2__ << " Model type " << modelType << " not yet supported." 00294 << endl; 00295 break; 00296 00297 default: 00298 cout << __func__zoltan2__ << " Invalid model" << modelType << endl; 00299 break; 00300 } 00301 } 00302 } //namespace Zoltan2 00303 00304 #endif
1.7.6.1