16 #include <Teuchos_RCP.hpp>
17 #include <Teuchos_Array.hpp>
18 #include <Teuchos_ParameterList.hpp>
19 #include "Teuchos_XMLParameterListHelpers.hpp"
21 #include "Tpetra_MultiVector.hpp"
22 #include <Tpetra_CrsGraph.hpp>
23 #include <Tpetra_Map.hpp>
28 typedef Tpetra::CrsGraph<zlno_t, zgno_t, znode_t>
tcrsGraph_t;
29 typedef Tpetra::MultiVector<zscalar_t, zlno_t, zgno_t, znode_t>
tMVector_t;
33 int main(
int narg,
char *arg[]) {
35 Tpetra::ScopeGuard tscope(&narg, &arg);
36 Teuchos::RCP<const Teuchos::Comm<int> > tcomm = Tpetra::getDefaultComm();
40 int nx = 2, ny = 2, nz = 2;
41 for (
int i = 1 ; i < narg ; ++i) {
42 if (0 == strcasecmp( arg[i] ,
"NX")) {
43 nx = atoi( arg[++i] );
45 else if (0 == strcasecmp( arg[i] ,
"NY")) {
46 ny = atoi( arg[++i] );
48 else if (0 == strcasecmp( arg[i] ,
"NZ")) {
49 nz = atoi( arg[++i] );
52 std::cerr <<
"Unrecognized command line argument #"
53 << i <<
": " << arg[i] << std::endl ;
60 int rank = tcomm->getRank();
61 part_t numProcs = tcomm->getSize();
64 zgno_t numGlobalTasks = nx*ny*nz;
66 zgno_t myTasks = numGlobalTasks / numProcs;
67 zgno_t taskLeftOver = numGlobalTasks % numProcs;
68 if (rank < taskLeftOver ) ++myTasks;
70 zgno_t myTaskBegin = (numGlobalTasks / numProcs) * rank;
71 myTaskBegin += (taskLeftOver < rank ? taskLeftOver : rank);
72 zgno_t myTaskEnd = myTaskBegin + myTasks;
76 for(
int i = 0; i < coordDim; ++i) {
81 zlno_t *task_communication_xadj_ =
new zlno_t [myTasks + 1];
82 zgno_t *task_communication_adj_ =
new zgno_t [myTasks * 6];
85 task_communication_xadj_[0] = 0;
86 for (
zlno_t i = myTaskBegin; i < myTaskEnd; ++i) {
87 task_gnos[i - myTaskBegin] = i;
90 zlno_t y = (i / (nx)) % ny;
91 zlno_t z = (i / (nx)) / ny;
92 partCenters[0][i - myTaskBegin] = x;
93 partCenters[1][i - myTaskBegin] = y;
94 partCenters[2][i - myTaskBegin] = z;
97 task_communication_adj_[prevNCount++] = i - 1;
100 task_communication_adj_[prevNCount++] = i + 1;
103 task_communication_adj_[prevNCount++] = i - nx;
106 task_communication_adj_[prevNCount++] = i + nx;
109 task_communication_adj_[prevNCount++] = i - nx * ny;
112 task_communication_adj_[prevNCount++] = i + nx * ny;
114 task_communication_xadj_[i + 1 - myTaskBegin] = prevNCount;
116 using namespace Teuchos;
117 RCP<my_adapter_t> ia;
119 typedef Tpetra::Map<zlno_t, zgno_t, mytest_znode_t>
map_t;
120 RCP<const map_t> map =
121 rcp(
new map_t (numGlobalTasks, myTasks, 0, tcomm));
123 Teuchos::Array<size_t> adjPerTask(myTasks);
124 for (
zlno_t lclRow = 0; lclRow < myTasks; lclRow++)
125 adjPerTask[lclRow] = task_communication_xadj_[lclRow+1]
126 - task_communication_xadj_[lclRow];
127 RCP<tcrsGraph_t> TpetraCrsGraph(
new tcrsGraph_t (map, adjPerTask()));
129 for (
zlno_t lclRow = 0; lclRow < myTasks; ++lclRow) {
130 const zgno_t gblRow = map->getGlobalElement (lclRow);
131 zgno_t begin = task_communication_xadj_[lclRow];
132 zgno_t end = task_communication_xadj_[lclRow + 1];
133 const ArrayView< const zgno_t > indices(task_communication_adj_ + begin,
135 TpetraCrsGraph->insertGlobalIndices(gblRow, indices);
137 TpetraCrsGraph->fillComplete ();
138 RCP<const tcrsGraph_t> const_data =
143 const int coord_dim = 3;
144 Teuchos::Array<Teuchos::ArrayView<const zscalar_t> > coordView(coord_dim);
147 Teuchos::ArrayView<const zscalar_t> a(partCenters[0], myTasks);
149 Teuchos::ArrayView<const zscalar_t> b(partCenters[1], myTasks);
151 Teuchos::ArrayView<const zscalar_t> c(partCenters[2], myTasks);
155 Teuchos::ArrayView<const zscalar_t> a;
160 RCP<tMVector_t> coords(
new tMVector_t(map, coordView.view(0, coord_dim),
162 RCP<const tMVector_t> const_coords =
164 RCP <Zoltan2::XpetraMultiVectorAdapter<tMVector_t> > adapter(
166 ia->setCoordinateInput(adapter.getRawPtr());
177 ParameterList zoltan2_parameters;
178 zoltan2_parameters.set(
"compute_metrics",
true);
179 zoltan2_parameters.set(
"imbalance_tolerance", 1.0);
180 zoltan2_parameters.set(
"num_global_parts", tcomm->getSize());
181 zoltan2_parameters.set(
"algorithm",
"multijagged");
182 zoltan2_parameters.set(
"mj_keep_part_boxes",
false);
183 zoltan2_parameters.set(
"mj_recursion_depth", 3);
185 RCP<xcrsGraph_problem_t> partition_problem;
187 RCP<xcrsGraph_problem_t> (
new xcrsGraph_problem_t(
188 ia.getRawPtr(),&zoltan2_parameters,tcomm));
191 partition_problem->solve();
193 RCP<const Zoltan2::Environment> env = partition_problem->getEnvironment();
195 RCP<quality_t>metricObject =
196 rcp(
new quality_t(ia.getRawPtr(), &zoltan2_parameters, tcomm,
197 &partition_problem->getSolution()));
199 if (tcomm->getRank() == 0) {
200 metricObject->printMetrics(std::cout);
202 partition_problem->printTimers();
204 part_t *proc_to_task_xadj_ = NULL;
205 part_t *proc_to_task_adj_ = NULL;
213 Teuchos::rcpFromRef(mach),
215 rcpFromRef(partition_problem->getSolution()),
219 ctm.
getProcTask(proc_to_task_xadj_, proc_to_task_adj_);
221 if (tcomm->getRank() == 0) {
222 for (part_t i = 0; i < numProcs; ++i) {
223 std::cout <<
"\nProc i:" << i <<
" ";
224 for (part_t j = proc_to_task_xadj_[i];
225 j < proc_to_task_xadj_[i + 1]; ++j) {
226 std::cout <<
" " << proc_to_task_adj_[j];
229 std::cout << std::endl;
235 zlno_t prevNCount_tmp = 0;
236 zgno_t *task_communication_adj_tmp =
new zgno_t [numGlobalTasks * 6];
237 zlno_t *task_communication_xadj_tmp =
new zlno_t [numGlobalTasks + 1];
238 task_communication_xadj_tmp[0] = 0;
240 for (
zlno_t i = 0; i < numGlobalTasks; ++i) {
242 zlno_t y = (i / (nx)) % ny;
243 zlno_t z = (i / (nx)) / ny;
246 task_communication_adj_tmp[prevNCount_tmp++] = i - 1;
249 task_communication_adj_tmp[prevNCount_tmp++] = i + 1;
252 task_communication_adj_tmp[prevNCount_tmp++] = i - nx;
255 task_communication_adj_tmp[prevNCount_tmp++] = i + nx;
258 task_communication_adj_tmp[prevNCount_tmp++] = i - nx * ny;
261 task_communication_adj_tmp[prevNCount_tmp++] = i + nx * ny;
263 task_communication_xadj_tmp[i + 1] = prevNCount_tmp;
267 std::vector <int> mach_extent(mach_coord_dim);
270 std::vector <part_t> all_parts(numGlobalTasks), copy(numGlobalTasks, 0);
272 const part_t *parts =
273 partition_problem->getSolution().getPartListView();
280 for (part_t i = 0; i < myTasks; ++i) {
281 zgno_t g = map->getGlobalElement(i);
285 reduceAll<int, part_t>(
297 int *machine_extent =
new int [mach_coord_dim];
298 bool *machine_extent_wrap_around =
new bool[mach_coord_dim];
301 for(
int n = 0; n < mach_coord_dim; ++n) {
302 machine_extent_wrap_around[n] =
false;
308 for (
zlno_t i = 0; i < numGlobalTasks; ++i) {
309 zlno_t b = task_communication_xadj_tmp[i];
310 zlno_t e = task_communication_xadj_tmp[i + 1];
314 for (
zlno_t j = b; j < e; ++j) {
315 zgno_t n = task_communication_adj_tmp[j];
322 for (
int k = 0 ; k < mach_coord_dim ; ++k){
323 part_t distance = std::abs(proc_coords[k][procId1] - proc_coords[k][procId2]);
324 if (machine_extent_wrap_around[k]){
325 if (machine_extent[k] - distance < distance){
326 distance = machine_extent[k] - distance;
333 delete [] machine_extent_wrap_around;
334 delete [] machine_extent;
336 if (tcomm->getRank() == 0)
337 std::cout <<
"HOPS:" << hops <<
" HOPS2:" << hops2 << std::endl;
339 delete [] task_communication_xadj_tmp;
340 delete [] task_communication_adj_tmp;
368 if (tcomm->getRank() == 0) {
369 std::cout <<
"PASS" << std::endl;
373 for (
int i = 0; i < coordDim; i++)
delete [] partCenters[i];
374 delete [] partCenters;
377 catch(std::string &s) {
378 std::cerr << s << std::endl;
382 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
Provides access for Zoltan2 to Xpetra::CrsGraph data.
Zoltan2::EvaluatePartition< matrixAdapter_t > quality_t
int main(int narg, char **arg)
common code used by tests
typename InputTraits< User >::part_t part_t
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_)
bool getMachineExtentWrapArounds(bool *wrap_around) const
if the machine has a wrap-around tourus link in each dimension.
An adapter for Xpetra::MultiVector.
MachineRepresentation Class Base class for representing machine coordinates, networks, etc.
Tpetra::Map::local_ordinal_type zlno_t
Tpetra::CrsGraph< zlno_t, zgno_t, znode_t > tcrsGraph_t
PartitioningProblem sets up partitioning problems for the user.
Defines the PartitioningProblem class.
A class that computes and returns quality metrics.
Tpetra::MultiVector< zscalar_t, zlno_t, zgno_t, znode_t > tMVector_t
bool getMachineExtent(int *nxyz) const
sets the number of unique coordinates in each machine dimension
Tpetra::Map::global_ordinal_type zgno_t