Commit 4dc4c499 authored by Pietro Incardona's avatar Pietro Incardona

Small changes to the build script

parent d3e355ee
# Change Log
All notable changes to this project will be documented in this file.
## [0.2.0] - 2015-02-17
### Added
- PSE 1D example with multiple precision
- Plot example for GoogleChart plotting
- Distributed data structure now support 128bit floating point precision (on Beta)
- OpenFPM support for Microsoft Windows (Cygwin) compilation
### Fixed
- Detection 32 bit system and report as an error
### Changed
- Nothing to report
## [0.1.0] - 2015-02-05
### Added
- PSE 1D example
......
SUBDIRS = src vtk openfpm_data openfpm_io openfpm_devices openfpm_vcluster
SUBDIRS = src vtk openfpm_data openfpm_io openfpm_devices openfpm_vcluster openfpm_numerics
bin_PROGRAMS =
......@@ -39,7 +39,17 @@ m4_ifdef([AX_SUITESPARSE],,[m4_include([m4/ax_suitesparse.m4])])
m4_ifdef([AX_EIGEN],,[m4_include([m4/ax_eigen.m4])])
CXXFLAGS+=" --std=c++11 "
case $host_os in
*cygwin*)
# Do something specific for cygwin
CXXFLAGS+=" --std=gnu++11 "
;;
*)
#Default Case
CXXFLAGS+=" --std=c++11 "
;;
esac
NVCCFLAGS=" "
INCLUDES_PATH=" "
......
......@@ -11,7 +11,7 @@
#include "Vector/vector_dist.hpp"
#include "Decomposition/CartDecomposition.hpp"
#include "Kernels.hpp"
#include "PSE/Kernels.hpp"
#include "data_type/aggregate.hpp"
#include <cmath>
......@@ -63,10 +63,10 @@ int main(int argc, char* argv[])
//
// Number of particles
const size_t Npart = 1000;
const size_t Npart = 125;
// Number of padding particles (At least)
const size_t Npad = 20;
const size_t Npad = 40;
// The domain
Box<1,double> box({0.0},{4.0});
......@@ -212,7 +212,7 @@ int main(int argc, char* argv[])
// get and construct the Cell list
Ghost<1,double> gp(enlarge);
auto cl = vd.getCellList(8*eps,gp);
auto cl = vd.getCellList(12*eps,gp);
// Maximum infinity norm
double linf = 0.0;
......
......@@ -7,7 +7,7 @@ LDIR =
OBJ = main.o
%.o: %.cpp
$(CC) -O0 -g3 -c --std=c++11 -o $@ $< $(INCLUDE_PATH)
$(CC) -O3 -g3 -c --std=c++11 -o $@ $< $(INCLUDE_PATH)
se_classes: $(OBJ)
$(CC) -o $@ $^ $(CFLAGS) $(LIBS_PATH) $(LIBS)
......
openfpm_data @ a3893b83
Subproject commit 8168a90ccd39ef504ba8699d6d0ed9aed46a3f31
Subproject commit a3893b83c4dc8288dc851661f77d499d0f0742a9
openfpm_devices @ 79ecba78
Subproject commit 68d2e016d10ddcdf201bbc6cd4270ff0e4623d02
Subproject commit 79ecba78fae6fce3f797c81393c9c8023a4208fe
......@@ -15,8 +15,6 @@ platform=unknown
platform=osx
elif [[ "$OSTYPE" == "cygwin" ]]; then
echo -e "We are on\033[1;34m CYGWIN \033[0m"
echo "This platform is not supported"
exit 1
elif [[ "$OSTYPE" == "msys" ]]; then
echo -e "We are on\033[1;34m Microsoft Window \033[0m"
echo "This platform is not supported"
......
......@@ -10,6 +10,20 @@ fi
wget http://www.open-mpi.de/software/ompi/v1.8/downloads/openmpi-1.8.7.tar.bz2
tar -xvf openmpi-1.8.7.tar.bz2
cd openmpi-1.8.7
#
# --disable-mca-dso \
# --disable-sysv-shmem \
# --enable-cxx-exceptions \
# --with-threads=posix \
# --without-cs-fs \
# --with-mpi-param_check=always \
# --enable-contrib-no-build=vt,libompitrace \
#
#--enable-mca-no-build=paffinity,installdirs-windows,timer-windows,shmem-sysv
#
#
sh ./configure --prefix=$1/MPI --enable-opal-multi-threads --enable-mpi-f90 $2 $3
make -j 4
mkdir $1/MPI
......
......@@ -351,6 +351,122 @@ private:
}
}
/*! \brief It copy the sub-domains into another CartesianDecomposition object extending them
*
* \see duplicate (in case of extended domain)
*
* \param cart Cartesian decomposition object
* \param box Extended domain
*
*/
void extend_subdomains(CartDecomposition<dim,T> & cart, const ::Box<dim,T> & ext_dom) const
{
// Box
typedef ::Box<dim,T> b;
cart.bbox = ext_dom;
cart.ss_box = ext_dom;
for (size_t i = 0 ; i < sub_domains.size() ; i++)
{
::Box<dim,T> box;
// Calculate the extended box
for (size_t j = 0 ; j < dim ; j++)
{
if (sub_domains.template get<b::p1>(i)[j] == domain.getLow(j))
box.setLow(j,ext_dom.getLow(j));
else
box.setLow(j,sub_domains.template get<b::p1>(i)[j]);
if (sub_domains.template get<b::p2>(i)[j] == domain.getHigh(j))
box.setHigh(j,ext_dom.getHigh(j));
else
box.setHigh(j,sub_domains.template get<b::p2>(i)[j]);
}
// add the subdomain
cart.sub_domains.add(box);
// Calculate the bound box
cart.bbox.enclose(box);
// Create the smallest box contained in all sub-domain
cart.ss_box.contained(box);
}
}
/*! \brief Extend the fines for the new Cartesian decomposition
*
* \param new_fines extended fine_s
* \param old_fines old fine_s
*
*/
void extend_fines(CartDecomposition<dim,T> & cart) const
{
// Extension, first we calculate the extensions of the new domain compared
// to the old one in cell units (each cell unit is a sub-sub-domain)
::Box<dim,size_t> ext;
// Extension of the new fines structure
::Box<dim,size_t> n_fines_ext;
// Extension of the old fines structure
::Box<dim,size_t> o_fines_ext;
size_t sz_new[dim];
size_t sz_old[dim];
for (size_t i = 0; i < dim ; i++)
{
size_t p1 = (domain.getLow(i) - this->domain.getLow(i)) / cd.getCellBox().getHigh(i) + 1;
size_t p2 = (domain.getLow(i) - this->domain.getLow(i)) / cd.getCellBox().getHigh(i) + 1;
ext.setLow(i,p1);
ext.setHigh(i,p2);
sz_new[i] = p1+p2+cd.getGrid().size(i);
sz_old[i] = cd.getGrid().size(i);
}
grid_sm<dim,void> info_new(sz_new);
grid_sm<dim,void> info_old(sz_old);
// resize the new fines
cart.fine_s.resize(info_new.size());
// we create an iterator that iterate across the full new fines
grid_key_dx_iterator<dim> fines_t(info_new);
while (fines_t.isNext())
{
auto key = fines_t.get();
// new_fines is bigger than old_fines structure
// out of bound key must be adjusted
// The adjustment produce a natural extension
// a representation can be seen in the figure of
// CartDecomposition duplicate function with extended domains
grid_key_dx<dim> key_old;
for (size_t i = 0 ; i < dim ; i++)
{
key_old.set_d(i,(long int)key.get(i) - ext.getLow(i));
if (key_old.get(i) < 0)
key_old.set_d(i,0);
else if(key_old.get(i) >= (long int)info_old.size(i) )
key_old.set_d(i,info_old.size(i)-1);
}
cart.fine_s.get(info_new.LinId(key)) = fine_s.get(info_old.LinId(key_old));
++fines_t;
}
cart.gr.setDimensions(sz_new);
// the new extended CellDecomposer must be consistent with the old cellDecomposer.
cart.cd.setDimensions(cd,ext);
}
public:
static constexpr int dims = dim;
......@@ -699,6 +815,83 @@ p1[0]<-----+ +----> p2[0]
return cart;
}
/*! \brief It create another object that contain the same decomposition information but with different ghost boxes and an extended domain
*
* The domain extension is produced extending the boxes at the border like in figure
*
* \verbatim
*
+--------------^--------^----------^----------+
| | | | |
| A | E | F | N |
| +-----------------------------------+---->
| | | | | | |
| A | A | | F | | |
| | | | | | |
| | | E +----------+ N | N |
<--------------+ | | | |
| | | | | | |
| | | | G | | |
| | | | +---------->
| B | B | +----------+ | |
| | +--------+ | M | M |
| | | | H | | |
| | | +-----+----+---------->
<--------------+ D | | | |
| | | | I | L | L |
| C | C | | | | |
| | | | | | |
| +-----------------------------------+ |
| | | | |
| C | D | I | L |
+--------------v--------v-----v---------------+
*
* \endverbatim
*
* \param g ghost
* \param domain extended domain (MUST be extended)
*
* \return a duplicated decomposition with different ghost boxes and an extended domain
*
*/
CartDecomposition<dim,T,Memory> duplicate(const Ghost<dim,T> & g, const ::Box<dim,T> & ext_domain) const
{
CartDecomposition<dim,T,Memory> cart(v_cl);
cart.box_nn_processor = box_nn_processor;
// Calculate new sub-domains for extended domain
extend_subdomains(cart,ext_domain);
// Calculate fine_s structure for the extended domain
// update the cell decomposer and gr
extend_fines(cart);
// Get the old sub-sub-domain grid extension
cart.domain = ext_domain;
// spacing does not change
std::copy(spacing,spacing+3,cart.spacing);
//! Runtime virtual cluster
cart.v_cl = v_cl;
cart.ghost = g;
for (size_t i = 0 ; i < dim ; i++)
cart.bc[i] = bc[i];
(static_cast<nn_prcs<dim,T> &>(cart)).create(cart.box_nn_processor, cart.sub_domains);
(static_cast<nn_prcs<dim,T> &>(cart)).applyBC(ext_domain,ghost,bc);
cart.Initialize_geo_cell_lists();
cart.calculateGhostBoxes();
return cart;
}
/*! \brief It create another object that contain the same information and act in the same way
*
* \return a duplicated decomposition
......
......@@ -173,6 +173,7 @@ BOOST_AUTO_TEST_CASE( CartDecomposition_periodic_test)
}
// Check the consistency
bool val = dec.check_consistency();
BOOST_REQUIRE_EQUAL(val,true);
......@@ -203,6 +204,141 @@ BOOST_AUTO_TEST_CASE( CartDecomposition_periodic_test)
BOOST_REQUIRE_EQUAL(ret,true);
}
BOOST_AUTO_TEST_CASE( CartDecomposition_extend_test)
{
// Initialize the global VCluster
init_global_v_cluster(&boost::unit_test::framework::master_test_suite().argc,&boost::unit_test::framework::master_test_suite().argv);
// Vcluster
Vcluster & vcl = *global_v_cluster;
//! [Create CartDecomposition]
CartDecomposition<3,float> dec(vcl);
// Physical domain
Box<3,float> box({0.0,0.0,0.0},{1.0,1.0,1.0});
Box<3,float> bulk({0.05,0.05,0.05},{0.95,0.95,0.95});
Box<3,float> bulk_g({0.01,0.01,0.01},{0.95,0.95,0.95});
size_t div[3];
// Get the number of processor and calculate the number of sub-domain
// for each processor (SUB_UNIT_FACTOR=64)
size_t n_proc = vcl.getProcessingUnits();
size_t n_sub = n_proc * SUB_UNIT_FACTOR;
// Set the number of sub-sub-domains on each dimension (in a scalable way)
for (int i = 0 ; i < 3 ; i++)
{div[i] = openfpm::math::round_big_2(pow(n_sub,1.0/3));}
// Define ghost size
Ghost<3,float> g(0.01);
// Boundary conditions
size_t bc[] = {PERIODIC,PERIODIC,PERIODIC};
// Decompose
dec.setParameters(div,box,bc,g);
// Internally create the ghosts
dec.calculateGhostBoxes();
// Duplicate the decomposition extending the domain
Box<3,float> box_ext({-0.1,-0.1,-0.1},{1.1,1.1,1.1});
CartDecomposition<3,float> dec2 = dec.duplicate(g,box_ext);
// than we create a grid iterator that iterate across the
// Create a grid based iterator on the smaller decomposition
size_t sz[3] = {128,128,128};
grid_dist_id_iterator_dec<CartDecomposition<3,float>> git(dec,sz);
// iterate across the grid points and we check that the results are consistent
while (git.isNext())
{
auto key = git.get();
Point<3,float> p = key.toPoint();
if (bulk_g.isInside(p) == false)
{
++git;
continue;
}
for (size_t i = 0 ; i < 3 ; i++)
p.get(i) = key.get(i) * git.getSpacing(i);
const openfpm::vector<size_t> & pr_pid = dec.template ghost_processorID<CartDecomposition<3,float>::processor_id>(p);
const openfpm::vector<size_t> & pr2_pid = dec2.template ghost_processorID<CartDecomposition<3,float>::processor_id>(p);
BOOST_REQUIRE(pr_pid == pr2_pid);
const openfpm::vector<size_t> & pr_bid = dec.template ghost_processorID<CartDecomposition<3,float>::box_id>(p);
const openfpm::vector<size_t> & pr2_bid = dec2.template ghost_processorID<CartDecomposition<3,float>::box_id>(p);
BOOST_REQUIRE(pr_bid == pr2_bid);
const openfpm::vector<size_t> & pr_lid = dec.template ghost_processorID<CartDecomposition<3,float>::lc_processor_id>(p);
const openfpm::vector<size_t> & pr2_lid = dec2.template ghost_processorID<CartDecomposition<3,float>::lc_processor_id>(p);
BOOST_REQUIRE(pr_lid == pr2_lid);
size_t n_test = 0;
// Given a point p, if the point is near the boundary
if (bulk.isInside(p) == false)
{
// we can move p in one direction and check that dec2 return the same result
for (size_t i = 0 ; i < 3 ; i++)
{
Point<3,float> q = p;
q.get(i) = p.get(i) + 0.05;
if (box.isInside(q) == false)
{
const openfpm::vector<size_t> & pr3_pid = dec2.template ghost_processorID<CartDecomposition<3,float>::processor_id>(q);
const openfpm::vector<size_t> & pr3_bid = dec2.template ghost_processorID<CartDecomposition<3,float>::box_id>(q);
const openfpm::vector<size_t> & pr3_lid = dec2.template ghost_processorID<CartDecomposition<3,float>::lc_processor_id>(q);
BOOST_REQUIRE(pr2_pid == pr3_pid);
BOOST_REQUIRE(pr2_bid == pr3_bid);
BOOST_REQUIRE(pr2_lid == pr3_lid);
n_test++;
}
q = p;
q.get(i) = p.get(i) - 0.05;
if (box.isInside(q) == false)
{
const openfpm::vector<size_t> & pr3_pid = dec2.template ghost_processorID<CartDecomposition<3,float>::processor_id>(q);
const openfpm::vector<size_t> & pr3_bid = dec2.template ghost_processorID<CartDecomposition<3,float>::box_id>(q);
const openfpm::vector<size_t> & pr3_lid = dec2.template ghost_processorID<CartDecomposition<3,float>::lc_processor_id>(q);
if (pr2_pid != pr3_pid)
{
const openfpm::vector<size_t> & pr3_pid = dec2.template ghost_processorID<CartDecomposition<3,float>::processor_id>(q);
int debug = 0;
debug++;
}
BOOST_REQUIRE(pr2_pid == pr3_pid);
BOOST_REQUIRE(pr2_bid == pr3_bid);
BOOST_REQUIRE(pr2_lid == pr3_lid);
n_test++;
}
}
}
BOOST_REQUIRE(n_test != 0);
++git;
}
}
BOOST_AUTO_TEST_SUITE_END()
......
......@@ -133,12 +133,11 @@ class ie_loc_ghost
}
}
/*! \brief In case of periodic boundary conditions we have to add boxes
* at the borders
/*! \brief In case of periodic boundary conditions we replicate the sub-domains at the border
*
* \param list of sub-domains
* \param domain Domain box
* \param boundary boundary conditions
* \param boundary conditions
* \param ghost ghost part
*
*/
......@@ -167,7 +166,7 @@ class ie_loc_ghost
case 1:
bp.setLow(k,domain.getHigh(k)+ghost.getLow(k));
bp.setHigh(k,domain.getHigh(k));
shift.get(k) = -domain.getHigh(k);
shift.get(k) = -domain.getHigh(k)+domain.getLow(k);
break;
case 0:
bp.setLow(k,domain.getLow(k));
......@@ -177,7 +176,7 @@ class ie_loc_ghost
case -1:
bp.setLow(k,domain.getLow(k));
bp.setHigh(k,ghost.getHigh(k));
shift.get(k) = domain.getHigh(k);
shift.get(k) = domain.getHigh(k)-domain.getLow(k);
break;
}
}
......@@ -527,7 +526,10 @@ public:
for (size_t j = 0 ; j < loc_ghost_box.get(i).ibx.size() ; j++)
{
if (loc_ghost_box.get(i).ibx.get(j).k == -1)
{
std::cout << "No ibx link" << "\n";
return false;
}
}
}
......@@ -536,9 +538,15 @@ public:
for (size_t i = 0 ; i < loc_ghost_box.size() ; i++)
{
if (loc_ghost_box.get(i).ibx.size() == 0)
{
std::cout << "Zero ibx" << "\n";
return false;
}
if (loc_ghost_box.get(i).ebx.size() == 0)
{
std::cout << "Zero ebx" << "\n";
return false;
}
}
}
......
......@@ -86,8 +86,7 @@ class nn_prcs
nnpst.pos.add(c);
}
/*! \brief In case of periodic boundary conditions we have to add boxes
* at the borders
/*! \brief In case of periodic boundary conditions we replicate the sub-domains at the border
*
* \param domain Domain box
* \param boundary boundary conditions
......@@ -109,6 +108,7 @@ class nn_prcs
if (check_valid(cmbs[j],bc) == false)
continue;
// Calculate the sector box
Box<dim,T> bp;
Point<dim,T> shift;
......@@ -119,7 +119,7 @@ class nn_prcs
case 1:
bp.setLow(k,domain.getHigh(k)+ghost.getLow(k));
bp.setHigh(k,domain.getHigh(k));
shift.get(k) = -domain.getHigh(k);
shift.get(k) = -domain.getHigh(k)+domain.getLow(k);
break;
case 0:
bp.setLow(k,domain.getLow(k));
......@@ -129,7 +129,7 @@ class nn_prcs
case -1:
bp.setLow(k,domain.getLow(k));
bp.setHigh(k,ghost.getHigh(k));
shift.get(k) = domain.getHigh(k);
shift.get(k) = domain.getHigh(k)-domain.getLow(k);
break;
}
}
......@@ -211,6 +211,10 @@ public:
*/
static bool inline check_valid(comb<dim> cmb,const size_t (& bc)[dim])
{
// the combination 0 is not valid
if (cmb.n_zero() == dim)
return false;
for (size_t i = 0 ; i < dim ; i++)
{
if (bc[i] == NON_PERIODIC && cmb.getComb()[i] != 0)
......
......@@ -3,6 +3,7 @@
#include "grid_dist_id.hpp"
#include "data_type/scalar.hpp"
#include "data_type/aggregate.hpp"
BOOST_AUTO_TEST_SUITE( grid_dist_id_test )
......@@ -587,6 +588,113 @@ void Test3D_gg(const Box<3,float> & domain, long int k, long int gk)
}
}
/*! \brief Test when the domain is not from 0.0 to 1.0
*
*
*/
void Test3D_domain(const Box<3,float> & domain, long int k)
{
long int big_step = k / 30;
big_step = (big_step == 0)?1:big_step;
long int small_step = 21;
print_test( "Testing 3D grid k<=",k);
// 3D test
for ( ; k >= 2 ; k-= (k > 2*big_step)?big_step:small_step )
{
BOOST_TEST_CHECKPOINT( "Testing 3D grid k=" << k );
// grid size
size_t sz[3];
sz[0] = k;
sz[1] = k;
sz[2] = k;
// factor
float factor = pow(global_v_cluster->getProcessingUnits()/2.0f,1.0f/3.0f);
// Ghost
Ghost<3,float> g(0.01 / factor);
// Distributed grid with id decomposition
grid_dist_id<3, float, aggregate<long int,long int>, CartDecomposition<3,float>> g_dist(sz,domain,g);