8 #include <Teuchos_RCP.hpp>
9 #include <Teuchos_Array.hpp>
10 #include <Teuchos_ParameterList.hpp>
11 #include "Teuchos_XMLParameterListHelpers.hpp"
13 #include "Tpetra_MultiVector.hpp"
14 #include <Tpetra_CrsGraph.hpp>
15 #include <Tpetra_Map.hpp>
20 typedef Tpetra::CrsGraph<zlno_t, zgno_t, znode_t>
tcrsGraph_t;
21 typedef Tpetra::MultiVector<zscalar_t, zlno_t, zgno_t, znode_t>
tMVector_t;
25 int main(
int narg,
char *arg[]){
27 Tpetra::ScopeGuard tscope(&narg, &arg);
28 Teuchos::RCP<const Teuchos::Comm<int> > tcomm = Tpetra::getDefaultComm();
32 int nx = 2, ny = 2, nz = 2;
33 for (
int i = 1 ; i < narg ; ++i ) {
34 if ( 0 == strcasecmp( arg[i] ,
"NX" ) ) {
35 nx = atoi( arg[++i] );
37 else if ( 0 == strcasecmp( arg[i] ,
"NY" ) ) {
38 ny = atoi( arg[++i] );
40 else if ( 0 == strcasecmp( arg[i] ,
"NZ" ) ) {
41 nz = atoi( arg[++i] );
44 std::cerr <<
"Unrecognized command line argument #" << i <<
": " << arg[i] << std::endl ;
53 int rank = tcomm->getRank();
54 part_t numProcs = tcomm->getSize();
57 zgno_t numGlobalTasks = nx*ny*nz;
59 zgno_t myTasks = numGlobalTasks / numProcs;
60 zgno_t taskLeftOver = numGlobalTasks % numProcs;
61 if (rank < taskLeftOver ) ++myTasks;
63 zgno_t myTaskBegin = (numGlobalTasks / numProcs) * rank;
64 myTaskBegin += (taskLeftOver < rank ? taskLeftOver : rank);
65 zgno_t myTaskEnd = myTaskBegin + myTasks;
69 for(
int i = 0; i < coordDim; ++i){
75 zlno_t *task_communication_xadj_ =
new zlno_t [myTasks+1];
76 zgno_t *task_communication_adj_ =
new zgno_t [myTasks * 6];
79 task_communication_xadj_[0] = 0;
80 for (
zlno_t i = myTaskBegin; i < myTaskEnd; ++i) {
81 task_gnos[i - myTaskBegin] = i;
84 zlno_t y = (i / (nx)) % ny;
85 zlno_t z = (i / (nx)) / ny;
86 partCenters[0][i - myTaskBegin] = x;
87 partCenters[1][i - myTaskBegin] = y;
88 partCenters[2][i - myTaskBegin] = z;
93 task_communication_adj_[prevNCount++] = i - 1;
96 task_communication_adj_[prevNCount++] = i + 1;
99 task_communication_adj_[prevNCount++] = i - nx;
102 task_communication_adj_[prevNCount++] = i + nx;
105 task_communication_adj_[prevNCount++] = i - nx * ny;
108 task_communication_adj_[prevNCount++] = i + nx * ny;
110 task_communication_xadj_[i+1 - myTaskBegin] = prevNCount;
112 using namespace Teuchos;
113 RCP<my_adapter_t> ia;
115 typedef Tpetra::Map<zlno_t, zgno_t, mytest_znode_t> map_t;
116 RCP<const map_t> map = rcp (
new map_t (numGlobalTasks, myTasks, 0, tcomm));
118 RCP<tcrsGraph_t> TpetraCrsGraph(
new tcrsGraph_t (map, 0));
121 for (
zlno_t lclRow = 0; lclRow < myTasks; ++lclRow) {
122 const zgno_t gblRow = map->getGlobalElement (lclRow);
123 zgno_t begin = task_communication_xadj_[lclRow];
124 zgno_t end = task_communication_xadj_[lclRow + 1];
125 const ArrayView< const zgno_t > indices(task_communication_adj_+begin, end-begin);
126 TpetraCrsGraph->insertGlobalIndices(gblRow, indices);
128 TpetraCrsGraph->fillComplete ();
129 RCP<const tcrsGraph_t> const_data = rcp_const_cast<
const tcrsGraph_t>(TpetraCrsGraph);
133 const int coord_dim = 3;
134 Teuchos::Array<Teuchos::ArrayView<const zscalar_t> > coordView(coord_dim);
137 Teuchos::ArrayView<const zscalar_t> a(partCenters[0], myTasks);
139 Teuchos::ArrayView<const zscalar_t> b(partCenters[1], myTasks);
141 Teuchos::ArrayView<const zscalar_t> c(partCenters[2], myTasks);
145 Teuchos::ArrayView<const zscalar_t> a;
150 RCP<tMVector_t> coords(
new tMVector_t(map, coordView.view(0, coord_dim), coord_dim));
151 RCP<const tMVector_t> const_coords = rcp_const_cast<
const tMVector_t>(coords);
153 ia->setCoordinateInput(adapter.getRawPtr());
167 ParameterList zoltan2_parameters;
168 zoltan2_parameters.set(
"compute_metrics",
true);
169 zoltan2_parameters.set(
"imbalance_tolerance", 1.0);
170 zoltan2_parameters.set(
"num_global_parts", tcomm->getSize());
171 zoltan2_parameters.set(
"algorithm",
"multijagged");
172 zoltan2_parameters.set(
"mj_keep_part_boxes",
false);
173 zoltan2_parameters.set(
"mj_recursion_depth", 3);
174 RCP<xcrsGraph_problem_t> partition_problem;
175 partition_problem = RCP<xcrsGraph_problem_t> (
new xcrsGraph_problem_t(ia.getRawPtr(),&zoltan2_parameters,tcomm));
178 partition_problem->solve();
180 RCP<const Zoltan2::Environment> env = partition_problem->getEnvironment();
182 RCP<quality_t>metricObject =
183 rcp(
new quality_t(ia.getRawPtr(), &zoltan2_parameters, tcomm,
184 &partition_problem->getSolution()));
186 if (tcomm->getRank() == 0){
187 metricObject->printMetrics(std::cout);
189 partition_problem->printTimers();
191 part_t *proc_to_task_xadj_ = NULL;
192 part_t *proc_to_task_adj_ = NULL;
200 Teuchos::rcpFromRef(mach),
202 rcpFromRef(partition_problem->getSolution()),
206 ctm.
getProcTask(proc_to_task_xadj_, proc_to_task_adj_);
208 if (tcomm->getRank() == 0){
209 for (part_t i = 0; i < numProcs; ++i){
210 std::cout <<
"\nProc i:" << i <<
" ";
211 for (part_t j = proc_to_task_xadj_[i]; j < proc_to_task_xadj_[i+1]; ++j){
212 std::cout <<
" " << proc_to_task_adj_[j];
215 std::cout << std::endl;
222 zlno_t prevNCount_tmp = 0;
223 zgno_t *task_communication_adj_tmp =
new zgno_t [numGlobalTasks * 6];
224 zlno_t *task_communication_xadj_tmp =
new zlno_t [numGlobalTasks+1];
225 task_communication_xadj_tmp[0] = 0;
226 for (
zlno_t i = 0; i < numGlobalTasks; ++i) {
228 zlno_t y = (i / (nx)) % ny;
229 zlno_t z = (i / (nx)) / ny;
232 task_communication_adj_tmp[prevNCount_tmp++] = i - 1;
235 task_communication_adj_tmp[prevNCount_tmp++] = i + 1;
238 task_communication_adj_tmp[prevNCount_tmp++] = i - nx;
241 task_communication_adj_tmp[prevNCount_tmp++] = i + nx;
244 task_communication_adj_tmp[prevNCount_tmp++] = i - nx * ny;
247 task_communication_adj_tmp[prevNCount_tmp++] = i + nx * ny;
249 task_communication_xadj_tmp[i+1] = prevNCount_tmp;
253 std::vector <int> mach_extent(mach_coord_dim);
256 std::vector <part_t> all_parts(numGlobalTasks), copy(numGlobalTasks, 0);
258 const part_t *parts = partition_problem->getSolution().getPartListView();
263 for (part_t i = 0; i < myTasks; ++i){
264 zgno_t g = map->getGlobalElement(i);
268 reduceAll<int, part_t>(
280 int *machine_extent =
new int [mach_coord_dim];
281 bool *machine_extent_wrap_around =
new bool[mach_coord_dim];
286 for (
zlno_t i = 0; i < numGlobalTasks; ++i){
287 zlno_t b = task_communication_xadj_tmp[i];
288 zlno_t e = task_communication_xadj_tmp[i+1];
292 for (
zlno_t j = b; j < e; ++j){
293 zgno_t n = task_communication_adj_tmp[j];
299 for (
int k = 0 ; k < mach_coord_dim ; ++k){
300 part_t distance =
ZOLTAN2_ABS(proc_coords[k][procId1] - proc_coords[k][procId2]);
301 if (machine_extent_wrap_around[k]){
302 if (machine_extent[k] - distance < distance){
303 distance = machine_extent[k] - distance;
310 delete [] machine_extent_wrap_around;
311 delete [] machine_extent;
313 if (tcomm->getRank() == 0)
314 std::cout <<
"HOPS:" << hops <<
" HOPS2:" << hops2 << std::endl;
316 delete [] task_communication_xadj_tmp;
317 delete [] task_communication_adj_tmp;
345 if (tcomm->getRank() == 0){
346 std::cout <<
"PASS" << std::endl;
350 for (
int i = 0; i < coordDim; i++)
delete [] partCenters[i];
351 delete [] partCenters;
354 catch(std::string &s){
355 std::cerr << s << std::endl;
359 std::cerr << s << std::endl;
Zoltan2::XpetraCrsGraphAdapter< tcrsGraph_t, tMVector_t > my_adapter_t
bool getHopCount(int rank1, int rank2, pcoord_t &hops) const
int main(int narg, char *arg[])
Provides access for Zoltan2 to Xpetra::CrsGraph data.
common code used by tests
Tpetra::Map::node_type mytest_znode_t
part_t getAssignedProcForTask(part_t taskId)
getAssignedProcForTask function, returns the assigned processor id for the given task ...
Defines the XpetraMultiVectorAdapter.
Defines XpetraCrsGraphAdapter class.
SparseMatrixAdapter_t::part_t part_t
int getMachineDim() const
returns the dimension (number of coords per node) in the machine
bool getAllMachineCoordinatesView(pcoord_t **&allCoords) const
getProcDim function set the coordinates of all ranks allCoords[i][j], i=0,...,getMachineDim(), j=0,...,getNumRanks(), is the i-th dimensional coordinate for rank j. return true if coordinates are available for all ranks
void getProcTask(part_t *&proc_to_task_xadj_, part_t *&proc_to_task_adj_)
Tpetra::CrsGraph< zlno_t, zgno_t, znode_t > tcrsGraph_t
bool getMachineExtentWrapArounds(bool *wrap_around) const
if the machine has a wrap-around tourus link in each dimension. return true if the information is ava...
InputTraits< User >::part_t part_t
An adapter for Xpetra::MultiVector.
MachineRepresentation Class Base class for representing machine coordinates, networks, etc.
PartitioningProblem sets up partitioning problems for the user.
Defines the PartitioningProblem class.
A class that computes and returns quality metrics.
bool getMachineExtent(int *nxyz) const
sets the number of unique coordinates in each machine dimension return true if coordinates are availa...