00001 #include "SundanceFileIOChacoPartitioner.hpp"
00002 #include "Teuchos_StrUtils.hpp"
00003 
00004 using namespace Sundance;
00005 using namespace Sundance;
00006 
00007 using namespace Teuchos;
00008 using namespace Sundance;
00009 
00010 using std::ofstream;
00011 using std::ifstream;
00012 using std::endl;
00013 
00014 
00015 FileIOChacoPartitioner::FileIOChacoPartitioner(const std::string& filename,
00016   bool ignoreGhosts)
00017   : SerialPartitionerBase(ignoreGhosts), filename_(filename)
00018 {}
00019 
00020 void FileIOChacoPartitioner::writeGraph(const Mesh& mesh) const 
00021 {
00022   Array<Array<int> > neighbors;
00023   int nEdges;
00024 
00025   getNeighbors(mesh, neighbors, nEdges);
00026 
00027   std::string gf = filename_ + ".graph";
00028   ofstream os(gf.c_str());
00029 
00030   os << neighbors.size() << " " << nEdges << std::endl;
00031 
00032   for (int i=0; i<neighbors.size(); i++)
00033   {
00034     for (int j=0; j<neighbors[i].size(); j++) 
00035     {
00036       if (j > 0) os << " ";
00037       os << neighbors[i][j]+1; 
00038     }
00039     os << "\n";
00040   }
00041 }
00042 
00043 
00044 void FileIOChacoPartitioner::runChaco(int np) const 
00045 {
00046   ofstream pf("User_Params");
00047   pf << 
00048     "OUTPUT_ASSIGN=true\n"
00049     "PROMPT=false\n"
00050     "ARCHITECTURE=1\n"
00051     "REFINE_PARTITION=4\n"
00052     "REFINE_MAP=true\n"
00053     "KL_BAD_MOVES=20\n"
00054     "KL_NTRIES_BAD=10\n"
00055     "KL_IMBALANCE=0.02\n"
00056     "INTERNAL_VERTICES=true\n"
00057     "MATCH_TYPE=2\n"
00058     "HEAVY_MATCH=true\n"
00059     "TERM_PROP=true\n"
00060     "COARSE_NLEVEL_KL=1\n"
00061     "COARSEN_RATIO_MIN=0.7\n"
00062     "CUT_TO_HOP_COST=1.0\n"
00063     "RANDOM_SEED=12345\n" << std::endl;
00064 
00065   ofstream chIn("chacoInput");
00066   chIn << filename_ + ".graph\n" << filename_ + ".assign\n1\n100\n"
00067        << np << "\n1\nn" << std::endl;
00068 
00069   int status = system("chaco < chacoInput");
00070   TEUCHOS_TEST_FOR_EXCEPTION(status < 0, std::runtime_error, "error detected in system call to run chaco");
00071 }
00072 
00073 bool FileIOChacoPartitioner::isEmptyLine(const std::string& x) const 
00074 {
00075   return x.length()==0 || StrUtils::isWhite(x);
00076 }
00077 
00078 bool FileIOChacoPartitioner::getNextLine(std::istream& is, std::string& line,
00079                                          Array<string>& tokens,
00080                                          char comment) const 
00081 {
00082   bool rtn = false;
00083   while ((rtn=StrUtils::readLine(is, line)))
00084     {
00085       if (line.length() > 0) line = StrUtils::before(line,comment);
00086       if (isEmptyLine(line)) continue;
00087       if (line.length() > 0) break;
00088     }
00089   tokens = StrUtils::stringTokenizer(line);
00090   return rtn;
00091 }
00092 
00093 void FileIOChacoPartitioner::getAssignments(const Mesh& mesh, int np,
00094   Array<int>& assignments) const 
00095 {
00096   writeGraph(mesh);
00097   runChaco(np);
00098 
00099   std::string af = filename_ + ".assign";
00100   ifstream is(af.c_str());
00101 
00102   std::string line;
00103   Array<string> tokens;
00104     
00105   while (getNextLine(is, line, tokens, '#'))
00106   {
00107     assignments.append(StrUtils::atoi(tokens[0]));
00108   }
00109 }
00110