#include <cmath>
#include <diy/master.hpp>
#include <diy/reduce.hpp>
#include <diy/partners/swap.hpp>
#include <diy/decomposition.hpp>
#include <diy/assigner.hpp>
#include "../opts.h"
#include "point.h"
static const unsigned DIM = 3;
typedef PointBlock<DIM> Block;
typedef AddPointBlock<DIM> AddBlock;
void redistribute(Block* b,
{
unsigned round = srp.
round();
for (
int i = 0; i < srp.
in_link().
size(); ++i)
{
int nbr_gid = srp.
in_link().
target(i).
gid;
if (nbr_gid == srp.
gid())
continue;
std::vector<Block::Point> in_points;
fmt::print(stderr, "[{}:{}] Received {} points from [{}]\n",
srp.gid(), round, (int) in_points.size(), nbr_gid);
for (size_t j = 0; j < in_points.size(); ++j)
b->points.push_back(in_points[j]);
}
return;
std::vector< std::vector<Block::Point> > out_points(srp.
out_link().size());
int cur_dim = partners.
dim(round);
for (size_t i = 0; i < b->points.size(); ++i)
{
int loc = floor((b->points[i][cur_dim] - b->box.min[cur_dim]) /
(b->box.max[cur_dim] - b->box.min[cur_dim]) * group_size);
out_points[loc].push_back(b->points[i]);
}
int pos = -1;
for (int i = 0; i < group_size; ++i)
{
if (srp.
out_link().target(i).gid == srp.gid())
{
b->points.swap(out_points[i]);
pos = i;
}
else
{
fmt::print(stderr, "[{}] Sent {} points to [{}]\n",
srp.gid(), (int) out_points[i].size(), srp.
out_link().target(i).gid);
}
}
float new_min = b->box.min[cur_dim] + (b->box.max[cur_dim] -
b->box.min[cur_dim])/group_size*pos;
float new_max = b->box.min[cur_dim] + (b->box.max[cur_dim] -
b->box.min[cur_dim])/group_size*(pos + 1);
b->box.min[cur_dim] = new_min;
b->box.max[cur_dim] = new_max;
}
int main(int argc, char* argv[])
{
int nblocks = world.
size();
size_t num_points = 100;
int mem_blocks = -1;
int threads = -1;
int k = 2;
std::string prefix = "./DIY.XXXXXX";
Bounds domain;
domain.
min[0] = domain.min[1] = domain.min[2] = 0;
domain.max[0] = domain.max[1] = domain.max[2] = 100.;
using namespace opts;
Options ops(argc, argv);
ops
>> Option('n', "number", num_points, "number of points per block")
>> Option('k', "k", k, "use k-ary swap")
>> Option('b', "blocks", nblocks, "number of blocks")
>> Option('t', "thread", threads, "number of threads")
>> Option('m', "memory", mem_blocks, "number of blocks to keep in memory")
>> Option( "prefix", prefix, "prefix for external storage")
;
ops
>> Option('x', "max-x", domain.max[0], "domain max x")
>> Option('y', "max-y", domain.max[1], "domain max y")
>> Option('z', "max-z", domain.max[2], "domain max z")
;
bool verbose = ops >> Present('v', "verbose", "print the block contents");
if (ops >> Present('h', "help", "show help"))
{
{
std::cout << "Usage: " << argv[0] << " [OPTIONS]\n";
std::cout << "Generates random particles in the domain and redistributes them into correct blocks.\n";
std::cout << ops;
}
return 1;
}
threads,
mem_blocks,
&Block::create,
&Block::destroy,
&storage,
AddBlock create(master, num_points);
int dim = DIM;
decomposer.decompose(world.rank(), assigner, create);
k,
false);
assigner,
partners,
&redistribute);
master.foreach(&Block::verify_block);
}