Skip to content
Snippets Groups Projects
CartDecomposition.hpp 58.5 KiB
Newer Older
Pietro Incardona's avatar
Pietro Incardona committed
/*
 * CartDecomposition.hpp
 *
 *  Created on: Oct 07, 2015
 *      Author: Pietro Incardona, Antonio Leo
Pietro Incardona's avatar
Pietro Incardona committed
 */

#ifndef CARTDECOMPOSITION_HPP
#define CARTDECOMPOSITION_HPP

#include "config.h"
#include "VCluster/VCluster.hpp"
#include "Graph/CartesianGraphFactory.hpp"
Pietro Incardona's avatar
Pietro Incardona committed
#include "Decomposition.hpp"
Pietro Incardona's avatar
Pietro Incardona committed
#include "Vector/map_vector.hpp"
Pietro Incardona's avatar
Pietro Incardona committed
#include <vector>
#include <initializer_list>
#include "SubdomainGraphNodes.hpp"
#include "dec_optimizer.hpp"
#include "Space/Shape/Box.hpp"
Pietro Incardona's avatar
Pietro Incardona committed
#include "Space/Shape/Point.hpp"
Pietro Incardona's avatar
Pietro Incardona committed
#include "NN/CellList/CellDecomposer.hpp"
#include <unordered_map>
#include "NN/CellList/CellList.hpp"
#include "Space/Ghost.hpp"
#include "common.hpp"
#include "ie_loc_ghost.hpp"
#include "ie_ghost.hpp"
#include "nn_processor.hpp"
#include "GraphMLWriter/GraphMLWriter.hpp"
#include "Distribution/ParMetisDistribution.hpp"
#include "Distribution/DistParMetisDistribution.hpp"
#include "Distribution/MetisDistribution.hpp"
#include "DLB/DLB.hpp"
#include "util/se_util.hpp"
#include "util/mathutil.hpp"
Pietro Incardona's avatar
Pietro Incardona committed
#include "CartDecomposition_ext.hpp"
#include "data_type/aggregate.hpp"
#include "Domain_NN_calculator_cart.hpp"
Pietro Incardona's avatar
Pietro Incardona committed
#include "cuda/CartDecomposition_gpu.cuh"
Pietro Incardona's avatar
Pietro Incardona committed
#include "Domain_icells_cart.hpp"
#define CARTDEC_ERROR 2000lu

/*! \brief It spread the sub-sub-domain on a regular cartesian grid of size dim
 *
 * \warning this function only guarantee that the division on each direction is
 *          2^n with some n and does not guarantee that the number of
 *          sub-sub-domain is preserved
 *
 * \param div number of division on each direction as output
 * \param n_sub number of sub-domain
 * \param dim_r dimension reduction
 *
 */
template<unsigned int dim> static void nsub_to_div2(size_t (& div)[dim], size_t n_sub, size_t dim_r)
{
	for (size_t i = 0; i < dim; i++)
	{
		if (i < dim_r)
		{div[i] = openfpm::math::round_big_2(pow(n_sub, 1.0 / dim_r));}
		else
		{div[i] = 1;}
	}
}

/*! \brief It spread the sub-sub-domain on a regular cartesian grid of size dim
 *
 * \warning this function only guarantee that the division on each direction is
 *          2^n with some n and does not guarantee that the number of
 *          sub-sub-domain is preserved
 *
 * \param div number of division on each direction as output
 * \param n_sub number of sub-domain
 * \param dim_r dimension reduction
 *
 */
template<unsigned int dim> static void nsub_to_div(size_t (& div)[dim], size_t n_sub, size_t dim_r)
{
	for (size_t i = 0; i < dim; i++)
	{
		if (i < dim_r)
		{div[i] = std::floor(pow(n_sub, 1.0 / dim_r));}
		else
		{div[i] = 1;}
	}
}

#define COMPUTE_SKIN_SUB 1

Pietro Incardona's avatar
Pietro Incardona committed
/**
Pietro Incardona's avatar
Pietro Incardona committed
 * \brief This class decompose a space into sub-sub-domains and distribute them across processors
Pietro Incardona's avatar
Pietro Incardona committed
 *
 * \tparam dim is the dimensionality of the physical domain we are going to decompose.
 * \tparam T type of the space we decompose, Real, Integer, Complex ...
 * \tparam Memory Memory factory used to allocate memory
 * \tparam Distribution type of distribution, can be ParMetisDistribution or MetisDistribution
Pietro Incardona's avatar
Pietro Incardona committed
 *
 * Given an N-dimensional space, this class decompose the space into a Cartesian grid of small
Pietro Incardona's avatar
Pietro Incardona committed
 * sub-sub-domain. To each sub-sub-domain is assigned an id that identify at which processor is
 * assigned (in general the union of all the sub-sub-domain assigned to a processor is
 * simply connected space), a second step merge several sub-sub-domain with same id into bigger region
 *  sub-domain. Each sub-domain has an extended space called ghost part
 *
 * Assuming that VCluster.getProcessUnitID(), equivalent to the MPI processor rank, return the processor local
 * processor id, we define
 *
 * * local processor: processor rank
 * * local sub-domain: sub-domain given to the local processor
 * * external ghost box: (or ghost box) are the boxes that compose the ghost space of the processor, or the
 *   boxes produced expanding every local sub-domain by the ghost extension and intersecting with the sub-domain
 *   of the other processors
 * * Near processors are the processors adjacent to the local processor, where with adjacent we mean all the processor
 *   that has a non-zero intersection with the ghost part of the local processor, or all the processors that
 *   produce non-zero external boxes with the local processor, or all the processor that should communicate
 *   in case of ghost data synchronization
 * * internal ghost box: is the part of ghost of the near processor that intersect the space of the
 *       processor, or the boxes produced expanding the sub-domain of the near processors with the local sub-domain
 * * Near processor sub-domain: is a sub-domain that live in the a near (or contiguous) processor
 * * Near processor list: the list of all the near processor of the local processor (each processor has a list
 *                        of the near processor)
Pietro Incardona's avatar
Pietro Incardona committed
 * * Local ghosts internal or external are all the ghosts that does not involve inter-processor communications
 *
 * \see calculateGhostBoxes() for a visualization of internal and external ghost boxes
 * ### Create a Cartesian decomposition object on a Box space, distribute, calculate internal and external ghost boxes
Pietro Incardona's avatar
Pietro Incardona committed
 *
 * \snippet CartDecomposition_unit_test.hpp Create CartDecomposition
 *
Pietro Incardona's avatar
Pietro Incardona committed
template<unsigned int dim, typename T, typename Memory, template <typename> class layout_base, typename Distribution>
Pietro Incardona's avatar
Pietro Incardona committed
class CartDecomposition: public ie_loc_ghost<dim, T,layout_base, Memory>,
						 public nn_prcs<dim, T,layout_base,Memory>,
						 public ie_ghost<dim,T,Memory,layout_base>,
						 public domain_nn_calculator_cart<dim>,
						 public domain_icell_calculator<dim,T,layout_base,Memory>
Pietro Incardona's avatar
Pietro Incardona committed
{
public:
Pietro Incardona's avatar
Pietro Incardona committed
	//! Type of the domain we are going to decompose
	typedef T domain_type;

	//! It simplify to access the SpaceBox element
	typedef SpaceBox<dim, T> Box;
Pietro Incardona's avatar
Pietro Incardona committed
	//! This class is base of itself
Pietro Incardona's avatar
Pietro Incardona committed
	typedef CartDecomposition<dim,T,Memory,layout_base,Distribution> base_type;
Pietro Incardona's avatar
Pietro Incardona committed

	//! This class admit a class defined on an extended domain
Pietro Incardona's avatar
Pietro Incardona committed
	typedef CartDecomposition_ext<dim,T,Memory,layout_base,Distribution> extended_type;
Pietro Incardona's avatar
Pietro Incardona committed

protected:
Pietro Incardona's avatar
Pietro Incardona committed
	//! bool that indicate whenever the buffer has been already transfer to device
	bool host_dev_transfer = false;

	//! Indicate the communication weight has been set
	bool commCostSet = false;

Pietro Incardona's avatar
Pietro Incardona committed
	//! This is the key type to access  data_s, for example in the case of vector
Pietro Incardona's avatar
Pietro Incardona committed
	//! acc_key is size_t
Pietro Incardona's avatar
Pietro Incardona committed
	typedef typename openfpm::vector<SpaceBox<dim, T>,
			Memory,
			typename memory_traits_lin<SpaceBox<dim, T>>::type,
			memory_traits_lin,
			openfpm::vector_grow_policy_default,
			openfpm::vect_isel<SpaceBox<dim, T>>::value>::access_key acc_key;
Pietro Incardona's avatar
Pietro Incardona committed

	//! the set of all local sub-domain as vector
Pietro Incardona's avatar
Pietro Incardona committed
	openfpm::vector<SpaceBox<dim, T>,Memory,typename layout_base<SpaceBox<dim, T>>::type,layout_base> sub_domains;
	//! the remote set of all sub-domains as vector of 'sub_domains' vectors
Pietro Incardona's avatar
Pietro Incardona committed
	mutable openfpm::vector<Box_map<dim, T>,Memory,typename layout_base<Box_map<dim, T>>::type,layout_base> sub_domains_global;
	//! for each sub-domain, contain the list of the neighborhood processors
	openfpm::vector<openfpm::vector<long unsigned int> > box_nn_processor;

Pietro Incardona's avatar
Pietro Incardona committed
	//! Structure that contain for each sub-sub-domain box the processor id
Pietro Incardona's avatar
Pietro Incardona committed
	//! exist for efficient global communication
Pietro Incardona's avatar
Pietro Incardona committed
	CellList<dim,T,Mem_fast<Memory,int>,shift<dim,T>> fine_s;
Pietro Incardona's avatar
Pietro Incardona committed
	//! Structure that store the cartesian grid information
	grid_sm<dim, void> gr;
	//! Structure that store the cartesian grid information
	grid_sm<dim, void> gr_dist;

Pietro Incardona's avatar
Pietro Incardona committed
	//! Structure that decompose the space into cells without creating them
Pietro Incardona's avatar
Pietro Incardona committed
	//! useful to convert positions to CellId or sub-domain id in this case
	CellDecomposer_sm<dim, T, shift<dim,T>> cd;
Pietro Incardona's avatar
Pietro Incardona committed

	//! rectangular domain to decompose
	::Box<dim,T> domain;
Pietro Incardona's avatar
Pietro Incardona committed

	//! Box Spacing
	T spacing[dim];

	//! Magnification factor between distribution and
Loading
Loading full blame...