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 #"
45 << i <<
": " << arg[i] << std::endl ;
52 int rank = tcomm->getRank();
53 part_t numProcs = tcomm->getSize();
56 zgno_t numGlobalTasks = nx*ny*nz;
58 zgno_t myTasks = numGlobalTasks / numProcs;
59 zgno_t taskLeftOver = numGlobalTasks % numProcs;
60 if (rank < taskLeftOver ) ++myTasks;
62 zgno_t myTaskBegin = (numGlobalTasks / numProcs) * rank;
63 myTaskBegin += (taskLeftOver < rank ? taskLeftOver : rank);
64 zgno_t myTaskEnd = myTaskBegin + myTasks;
68 for(
int i = 0; i < coordDim; ++i) {
73 zlno_t *task_communication_xadj_ =
new zlno_t [myTasks + 1];
74 zgno_t *task_communication_adj_ =
new zgno_t [myTasks * 6];
77 task_communication_xadj_[0] = 0;
78 for (
zlno_t i = myTaskBegin; i < myTaskEnd; ++i) {
79 task_gnos[i - myTaskBegin] = i;
82 zlno_t y = (i / (nx)) % ny;
83 zlno_t z = (i / (nx)) / ny;
84 partCenters[0][i - myTaskBegin] = x;
85 partCenters[1][i - myTaskBegin] = y;
86 partCenters[2][i - myTaskBegin] = z;
89 task_communication_adj_[prevNCount++] = i - 1;
92 task_communication_adj_[prevNCount++] = i + 1;
95 task_communication_adj_[prevNCount++] = i - nx;
98 task_communication_adj_[prevNCount++] = i + nx;
101 task_communication_adj_[prevNCount++] = i - nx * ny;
104 task_communication_adj_[prevNCount++] = i + nx * ny;
106 task_communication_xadj_[i + 1 - myTaskBegin] = prevNCount;
108 using namespace Teuchos;
109 RCP<my_adapter_t> ia;
111 typedef Tpetra::Map<zlno_t, zgno_t, mytest_znode_t> map_t;
112 RCP<const map_t> map =
113 rcp(
new map_t (numGlobalTasks, myTasks, 0, tcomm));
115 Teuchos::Array<size_t> adjPerTask(myTasks);
116 for (
zlno_t lclRow = 0; lclRow < myTasks; lclRow++)
117 adjPerTask[lclRow] = task_communication_xadj_[lclRow+1]
118 - task_communication_xadj_[lclRow];
119 RCP<tcrsGraph_t> TpetraCrsGraph(
new tcrsGraph_t (map, adjPerTask()));
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,
127 TpetraCrsGraph->insertGlobalIndices(gblRow, indices);
129 TpetraCrsGraph->fillComplete ();
130 RCP<const tcrsGraph_t> const_data =
135 const int coord_dim = 3;
136 Teuchos::Array<Teuchos::ArrayView<const zscalar_t> > coordView(coord_dim);
139 Teuchos::ArrayView<const zscalar_t> a(partCenters[0], myTasks);
141 Teuchos::ArrayView<const zscalar_t> b(partCenters[1], myTasks);
143 Teuchos::ArrayView<const zscalar_t> c(partCenters[2], myTasks);
147 Teuchos::ArrayView<const zscalar_t> a;
152 RCP<tMVector_t> coords(
new tMVector_t(map, coordView.view(0, coord_dim),
154 RCP<const tMVector_t> const_coords =
156 RCP <Zoltan2::XpetraMultiVectorAdapter<tMVector_t> > adapter(
158 ia->setCoordinateInput(adapter.getRawPtr());
169 ParameterList zoltan2_parameters;
170 zoltan2_parameters.set(
"compute_metrics",
true);
171 zoltan2_parameters.set(
"imbalance_tolerance", 1.0);
172 zoltan2_parameters.set(
"num_global_parts", tcomm->getSize());
173 zoltan2_parameters.set(
"algorithm",
"multijagged");
174 zoltan2_parameters.set(
"mj_keep_part_boxes",
false);
175 zoltan2_parameters.set(
"mj_recursion_depth", 3);
177 RCP<xcrsGraph_problem_t> partition_problem;
179 RCP<xcrsGraph_problem_t> (
new xcrsGraph_problem_t(
180 ia.getRawPtr(),&zoltan2_parameters,tcomm));
183 partition_problem->solve();
185 RCP<const Zoltan2::Environment> env = partition_problem->getEnvironment();
187 RCP<quality_t>metricObject =
188 rcp(
new quality_t(ia.getRawPtr(), &zoltan2_parameters, tcomm,
189 &partition_problem->getSolution()));
191 if (tcomm->getRank() == 0) {
192 metricObject->printMetrics(std::cout);
194 partition_problem->printTimers();
196 part_t *proc_to_task_xadj_ = NULL;
197 part_t *proc_to_task_adj_ = NULL;
205 Teuchos::rcpFromRef(mach),
207 rcpFromRef(partition_problem->getSolution()),
211 ctm.
getProcTask(proc_to_task_xadj_, proc_to_task_adj_);
213 if (tcomm->getRank() == 0) {
214 for (part_t i = 0; i < numProcs; ++i) {
215 std::cout <<
"\nProc i:" << i <<
" ";
216 for (part_t j = proc_to_task_xadj_[i];
217 j < proc_to_task_xadj_[i + 1]; ++j) {
218 std::cout <<
" " << proc_to_task_adj_[j];
221 std::cout << std::endl;
227 zlno_t prevNCount_tmp = 0;
228 zgno_t *task_communication_adj_tmp =
new zgno_t [numGlobalTasks * 6];
229 zlno_t *task_communication_xadj_tmp =
new zlno_t [numGlobalTasks + 1];
230 task_communication_xadj_tmp[0] = 0;
232 for (
zlno_t i = 0; i < numGlobalTasks; ++i) {
234 zlno_t y = (i / (nx)) % ny;
235 zlno_t z = (i / (nx)) / ny;
238 task_communication_adj_tmp[prevNCount_tmp++] = i - 1;
241 task_communication_adj_tmp[prevNCount_tmp++] = i + 1;
244 task_communication_adj_tmp[prevNCount_tmp++] = i - nx;
247 task_communication_adj_tmp[prevNCount_tmp++] = i + nx;
250 task_communication_adj_tmp[prevNCount_tmp++] = i - nx * ny;
253 task_communication_adj_tmp[prevNCount_tmp++] = i + nx * ny;
255 task_communication_xadj_tmp[i + 1] = prevNCount_tmp;
259 std::vector <int> mach_extent(mach_coord_dim);
262 std::vector <part_t> all_parts(numGlobalTasks), copy(numGlobalTasks, 0);
264 const part_t *parts =
265 partition_problem->getSolution().getPartListView();
272 for (part_t i = 0; i < myTasks; ++i) {
273 zgno_t g = map->getGlobalElement(i);
277 reduceAll<int, part_t>(
289 int *machine_extent =
new int [mach_coord_dim];
290 bool *machine_extent_wrap_around =
new bool[mach_coord_dim];
295 for (
zlno_t i = 0; i < numGlobalTasks; ++i) {
296 zlno_t b = task_communication_xadj_tmp[i];
297 zlno_t e = task_communication_xadj_tmp[i + 1];
301 for (
zlno_t j = b; j < e; ++j) {
302 zgno_t n = task_communication_adj_tmp[j];
309 for (
int k = 0 ; k < mach_coord_dim ; ++k) {
311 ZOLTAN2_ABS(proc_coords[k][procId1] - proc_coords[k][procId2]);
312 if (machine_extent_wrap_around[k]) {
313 if (machine_extent[k] - distance < distance) {
314 distance = machine_extent[k] - distance;
321 delete [] machine_extent_wrap_around;
322 delete [] machine_extent;
324 if (tcomm->getRank() == 0)
325 std::cout <<
"HOPS:" << hops <<
" HOPS2:" << hops2 << std::endl;
327 delete [] task_communication_xadj_tmp;
328 delete [] task_communication_adj_tmp;
356 if (tcomm->getRank() == 0) {
357 std::cout <<
"PASS" << std::endl;
361 for (
int i = 0; i < coordDim; i++)
delete [] partCenters[i];
362 delete [] partCenters;
365 catch(std::string &s) {
366 std::cerr << s << std::endl;
370 std::cerr << s << std::endl;
Zoltan2::XpetraCrsGraphAdapter< tcrsGraph_t, tMVector_t > my_adapter_t
bool getHopCount(int rank1, int rank2, pcoord_t &hops) const
return the hop count between rank1 and rank2
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.
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