26#include <boost/program_options.hpp>
28#include "arccore/alina/AlinaUtils.h"
29#include "arccore/alina/IO.h"
36using Alina::precondition;
39void pointwise_graph(
int n,
int block_size,
40 const std::vector<int>& ptr,
41 const std::vector<int>& col,
42 std::vector<idx_t>& pptr,
43 std::vector<idx_t>& pcol)
45 int np = n / block_size;
47 assert(np * block_size == n);
50 std::vector<int> ptr1(np + 1, 0);
51 std::vector<int> marker(np, -1);
52 for (
int ip = 0, i = 0; ip < np; ++ip) {
53 for (
int k = 0; k < block_size; ++k, ++i) {
54 for (
int j = ptr[i]; j < ptr[i + 1]; ++j) {
55 int cp = col[j] / block_size;
56 if (marker[cp] != ip) {
64 std::partial_sum(ptr1.begin(), ptr1.end(), ptr1.begin());
65 std::fill(marker.begin(), marker.end(), -1);
67 std::vector<int> col1(ptr1.back());
69 for (
int ip = 0, i = 0; ip < np; ++ip) {
70 int row_beg = ptr1[ip];
71 int row_end = row_beg;
73 for (
int k = 0; k < block_size; ++k, ++i) {
74 for (
int j = ptr[i]; j < ptr[i + 1]; ++j) {
75 int cp = col[j] / block_size;
77 if (marker[cp] < row_beg) {
86 int nnz = ptr1.back();
88 std::vector<int> ptr2(np + 1, 0);
89 std::vector<int> col2(nnz);
91 for (
int i = 0; i < nnz; ++i)
92 ++(ptr2[col1[i] + 1]);
94 std::partial_sum(ptr2.begin(), ptr2.end(), ptr2.begin());
96 for (
int i = 0; i < np; ++i)
97 for (
int j = ptr1[i]; j < ptr1[i + 1]; ++j)
98 col2[ptr2[col1[j]]++] = i;
100 std::rotate(ptr2.begin(), ptr2.end() - 1, ptr2.end());
104 std::fill(marker.begin(), marker.end(), -1);
105 pptr.resize(np + 1, 0);
107 for (
int i = 0; i < np; ++i) {
108 for (
int j = ptr1[i]; j < ptr1[i + 1]; ++j) {
110 if (marker[c] != i) {
116 for (
int j = ptr2[i]; j < ptr2[i + 1]; ++j) {
118 if (marker[c] != i) {
125 std::partial_sum(pptr.begin(), pptr.end(), pptr.begin());
126 std::fill(marker.begin(), marker.end(), -1);
128 pcol.resize(pptr.back());
130 for (
int i = 0; i < np; ++i) {
131 int row_beg = pptr[i];
132 int row_end = row_beg;
134 for (
int j = ptr1[i]; j < ptr1[i + 1]; ++j) {
137 if (marker[c] < row_beg) {
143 for (
int j = ptr2[i]; j < ptr2[i + 1]; ++j) {
146 if (marker[c] < row_beg) {
156pointwise_partition(idx_t npart,
157 const std::vector<idx_t>& ptr,
158 const std::vector<idx_t>& col)
160 idx_t nrows = ptr.size() - 1;
162 std::vector<idx_t> part(nrows);
165 std::fill(part.begin(), part.end(), 0);
170#if defined(METIS_VER_MAJOR) && (METIS_VER_MAJOR >= 5)
171 idx_t nconstraints = 1;
175 const_cast<idx_t*
>(ptr.data()),
176 const_cast<idx_t*
>(col.data()),
193 const_cast<int*
>(ptr.data()),
194 const_cast<int*
>(col.data()),
211partition(
int n,
int nparts,
int block_size,
212 const std::vector<int>& ptr,
const std::vector<int>& col)
215 std::vector<idx_t> pptr;
216 std::vector<idx_t> pcol;
217 pointwise_graph(n, block_size, ptr, col, pptr, pcol);
220 std::vector<idx_t> ppart = pointwise_partition(nparts, pptr, pcol);
222 std::vector<int> part(n);
223 for (
int i = 0; i < n; ++i)
224 part[i] = ppart[i / block_size];
230int main(
int argc,
char* argv[])
232 namespace po = boost::program_options;
236 std::string ofile =
"partition.mtx";
238 int nparts, block_size;
240 po::options_description desc(
"Options");
242 desc.add_options()(
"help,h",
"show help");
243 desc.add_options()(
"input,i", po::value<std::string>(&ifile)->required(),
"Input matrix");
244 desc.add_options()(
"output,o", po::value<std::string>(&ofile)->default_value(ofile),
"Output file");
245 desc.add_options()(
"binary,B",
246 po::bool_switch()->default_value(
false),
247 "When specified, treat input files as binary instead of as MatrixMarket. ");
248 desc.add_options()(
"nparts,n", po::value<int>(&nparts)->required(),
"Number of parts");
249 desc.add_options()(
"block_size,b", po::value<int>(&block_size)->default_value(1),
"Block size");
251 po::positional_options_description pd;
254 po::variables_map vm;
255 po::store(po::command_line_parser(argc, argv).options(desc).positional(pd).run(), vm);
257 if (vm.count(
"help")) {
258 std::cout << desc << std::endl;
265 std::vector<int> ptr, col;
267 bool binary = vm[
"binary"].as<
bool>();
270 std::ifstream f(ifile, std::ios::binary);
271 precondition(f.read((
char*)&rows,
sizeof(rows)),
"Wrong file format?");
272 ptr.resize(rows + 1);
273 for (
size_t i = 0; i <= rows; ++i) {
275 precondition(f.read((
char*)&p,
sizeof(p)),
"Wrong file format?");
278 col.resize(ptr.back());
279 for (ptrdiff_t i = 0; i < ptr.back(); ++i) {
281 precondition(f.read((
char*)&p,
sizeof(p)),
"Wrong file format?");
286 std::vector<double> val;
289 precondition(rows == cols,
"Non-square system matrix");
292 std::vector<int> part = partition(rows, nparts, block_size, ptr, col);
295 std::ofstream p(ofile.c_str(), std::ios::binary);
297 Alina::IO::write(p, rows);
298 Alina::IO::write(p,
size_t(1));
299 Alina::IO::write(p, part);
302 Alina::IO::mm_write(ofile, &part[0], part.size());
305 catch (
const std::exception& e) {
306 std::cerr <<
"Error: " << e.what() << std::endl;
-*- tab-width: 2; indent-tabs-mode: nil; coding: utf-8-with-signature -*-