Commit b116804e authored by Pietro Incardona's avatar Pietro Incardona

Refactoring examples

parent 9ecb9ab2
Common Mistake
1) Overshoot aggregate
2) Forget .template
3) Missing const
* Try to install OpenFPM I get "cannot recover from this error"
It mean that the configuration phase has failed. Something has failed, what has failed should be reported some line before. We are trying to track the causes to understand if it is possible to produce a better error message but it seem that most of the time this error has been seen on OSX having a very old X-Code.
* I get a huge number of error
It can happen in compilation phase. The installation system in general should detect potential known incompatibility and try in the best case to silently workaround the problem, in the middle case provide an automatic solution and ask to the user the permission to perform it, in the worst case report to the user for manual fixation. Unfortunately the number of systems and possible configuration/missconfiguration make this task impossible to control.
* The program generate the file openfpm_vars in my "holy" home folder. why ?
If you show the hidden folder in your "holy" home, you will see how many program actually "violate" your home folder. They do costantly Creating/Reading/Writing such folder every time you open them, they are just hiding. OpenFPM create such text file only one time in installation and report it, mooving such file somewhere else after installation will bring the home folder to be "virgin" from OpenFPM forever.
* The examples does not scale on my 4 - x core PC.
Not all example are made for scalability. In particular example that do not have computation inside like the 0_simple_ ... . If instead is an example that has computation inside, when you are benchmarking in particular using all the cores of your PC, close all applications, like Browser, IDE, pdf reader, ..., unusefull shell running command (anything that could consume resources, consider that the Desktop environment consume resources, in particular if you have OpenGL/3D effects, disable them. The best would be close the X-server/Desktop environment). Check also that no program are running in background using resources, use top/Task manager to check this. Consider also that 99.9% of Laptop/Desktop today can adjust their frequency dynamically. In particular it is common that the system increase the CPU frequency at higher level when only one-core is used compared to N-core, and this can significantly affect scalability.
Openfpm is a library for computer simulation, but with our documentation it is also a valid resource
to drive people to do simulation.
There are at the moment 3 way to try openfpm.
1) Without installation: We provide ready to use Docker image compatible with codenvy and IDE on browser. More ...
2) We provide Docker image, Ubuntu Virtual Machine and OSX Virtual Machine with OpenFPM preinstalled. More ...
3) Installation from source. More ...
......@@ -280,19 +280,17 @@ BOOST_CPPFLAGS=$(echo "$BOOST_CPPFLAGS" | sed -e 's/-I\/usr\/include[ \b]//g')
AC_SUBST(BOOST_LDFLAGS)
AC_SUBST(BOOST_CPPFLAGS)
###### Checking for OpenBLAS (used to make sure than EIGEN can use such package)
AX_BLAS([],[])
#AX_BLAS([],[echo "blas not found"])
#AX_LAPACK([],[echo "lapack not found"])
AX_LAPACK([],[])
###### Checking for SUITESPARSE (used to make sure that EIGEN can use such package)
###### Checking for SUITESPARSE
#AX_SUITESPARSE([],[echo "suitesparse not found"])
AX_SUITESPARSE([],[])
###### Checking for EIGEN
#AX_EIGEN([],[echo "eigen not found"
# exit 206])
AX_EIGEN([],[])
###### RT runtime lib
......
This diff is collapsed.
......@@ -2,25 +2,29 @@
#include "data_type/aggregate.hpp"
#include "Decomposition/CartDecomposition.hpp"
/*
* ### WIKI 1 ###
/*!
* \page Grid_1_stencil Grid 1 stencil
*
* ## Simple example
*
* This example show how to move grid_key in order to create a Laplacian stencil,
* be careful, the function move are convenient, but not the fastest implementation
* # Stencil example and ghost # {#e1_st}
*
* ### WIKI END ###
* This example show how to move grid_key in order to create a Laplacian stencil,
* be careful, the function move is convenient, but not the fastest implementation.
* We also show how to do ghost communications
*
*/
/*
*
* ### WIKI 2 ###
/*!
* \page Grid_1_stencil Grid 1 stencil
*
* Define some convenient constants and types
*
* \snippet Grid/1_stencil/main.cpp useful constant
*
*/
//! \cond [useful constant] \endcond
constexpr size_t x = 0;
constexpr size_t y = 1;
constexpr size_t z = 2;
......@@ -28,109 +32,176 @@ constexpr size_t z = 2;
constexpr size_t A = 0;
constexpr size_t B = 0;
typedef aggregate<float[3],float[3]> grid_point;
//! \cond [useful constant] \endcond
int main(int argc, char* argv[])
{
//
// ### WIKI 3 ###
//
// Initialize the library and several objects
//
openfpm_init(&argc,&argv);
/*!
* \page Grid_1_stencil Grid 1 stencil
*
* ## Initialization ## {#e1_st_init}
*
* Initialize the library and several objects
*
* \see \ref e0_s_initialization
*
* \snippet Grid/1_stencil/main.cpp parameters
*
*
*/
//! \cond [parameters] \endcond
//
// ### WIKI 4 ###
//
// Create several object needed later, in particular
// * A 3D box that define the domain
// * an array of 3 unsigned integer that define the size of the grid on each dimension
// * A Ghost object that will define the extension of the ghost part for each sub-domain in physical units
openfpm_init(&argc,&argv);
// domain
Box<3,float> domain({0.0,0.0,0.0},{1.0,1.0,1.0});
size_t sz[3];
sz[0] = 100;
sz[1] = 100;
sz[2] = 100;
// Ghost
// grid sizes
size_t sz[3] = {100,100,100};
// ghost extension
Ghost<3,float> g(0.03);
//
// ### WIKI 4 ###
//
// Create a distributed grid in 3D (1° template parameter) space in with float precision (2° template parameter)
// each grid point contain a vector of dimension 3 (float[3]),
// using a CartesianDecomposition strategy (4° parameter) (the parameter 1° and 2° inside CartDecomposition must match 1° and 2°
// of grid_dist_id)
//
// Constructor parameters:
//
// * sz: size of the grid on each dimension
// * domain: where the grid is defined
// * g: ghost extension
//
//! \cond [parameters] \endcond
/*!
* \page Grid_1_stencil Grid 1 stencil
*
* ## Grid create ## {#e1_st_inst}
*
* Create a distributed grid in 3D. With typedef we create an alias name for aggregate<float[3],float[3]>.
* In practice the type of grid_point == aggregate<float[3],float[3]>
*
* \see \ref e0_s_grid_inst
*
* \snippet Grid/1_stencil/main.cpp grid
*
*/
//! \cond [grid] \endcond
// a convenient alias for aggregate<...>
typedef aggregate<float,float> grid_point;
grid_dist_id<3, float, grid_point> g_dist(sz,domain,g);
// ### WIKI 5 ###
//
// Get an iterator that go throught the point of the domain (No ghost)
//
//! \cond [grid] \endcond
/*!
* \page Grid_1_stencil Grid 1 stencil
*
* ## Loop over grid points ## {#e1_s_loop_gp}
*
* Get an iterator that go through the point of the domain (No ghost)
*
* \see \ref e0_s_loop_gp
*
* \snippet Grid/1_stencil/main.cpp iterator
* \snippet Grid/1_stencil/main.cpp iterator2
*
*/
//! \cond [iterator] \endcond
auto dom = g_dist.getDomainIterator();
// ### WIKI END ###
while (dom.isNext())
{
//
// ### WIKI 6 ###
//
// Get the local grid key, the local grid key store internally the sub-domain id (each sub-domain contain a grid)
// and the local grid point id identified by 2 integers in 2D 3 integer in 3D and so on. These two distinct elements are
// available with key.getSub() and key.getKey()
//
//! \cond [iterator] \endcond
/*!
* \page Grid_1_stencil Grid 1 stencil
*
* Inside the cycle we get the local grid key
*
* \see \ref e0_s_grid_coord
*
* \snippet Grid/1_stencil/main.cpp local key
*
*/
//! \cond [local key] \endcond
auto key = dom.get();
//
// ### WIKI 7 ###
//
// Here we convert the local grid position, into global position, key_g contain 3 integers that identify the position
// of the grid point in global coordinates
//
//
//! \cond [local key] \endcond
/*!
* \page Grid_1_stencil Grid 1 stencil
*
* We convert the local grid position, into global position, key_g contain 3 integers that identify the position
* of the grid point in global coordinates
*
* \see \ref e0_s_grid_coord
*
* \snippet Grid/1_stencil/main.cpp global key
*
*/
//! \cond [global key] \endcond
auto key_g = g_dist.getGKey(key);
//
// ### WIKI 8 ###
//
// we write on the grid point of position (i,j,k) the value i*i + j*j + k*k on the component [0] of the vector
g_dist.template get<0>(key)[0] = key_g.get(0)*key_g.get(0) + key_g.get(1)*key_g.get(1) + key_g.get(2)*key_g.get(2);
//! \cond [global key] \endcond
//
// ### WIKI 9 ###
//
// next point
/*!
* \page Grid_1_stencil Grid 1 stencil
*
* we write on the grid point of position (i,j,k) the value i*i + j*j + k*k on the property A.
* Mathematically is equivalent to the function
*
* \f$ f(x,y,z) = x^2 + y^2 + z^2 \f$
*
* \snippet Grid/1_stencil/main.cpp function
*
*/
++dom;
//! \cond [function] \endcond
g_dist.template get<A>(key) = key_g.get(0)*key_g.get(0) + key_g.get(1)*key_g.get(1) + key_g.get(2)*key_g.get(2);
//! \cond [function] \endcond
// ### WIKI END ###
//! \cond [iterator2] \endcond
++dom;
}
//
// ### WIKI 10 ###
//
// Each sub-domain has an extended part, that is materially contained from another processor that in general is not synchronized
// ghost_get<0> synchronize the property 0 (the vector) in the ghost part
//
//
g_dist.template ghost_get<0>();
//! \cond [iterator2] \endcond
/*!
* \page Grid_1_stencil Grid 1 stencil
*
* ## Ghost ## {#e1_s_ghost}
*
* Each sub-domain has an extended part, that is materially contained into another processor.
* In general is not synchronized
* ghost_get<A> synchronize the property A in the ghost part
*
* \snippet Grid/1_stencil/main.cpp ghost
*
*/
//! \cond [ghost] \endcond
g_dist.template ghost_get<A>();
//
// ### WIKI 11 ###
//
// Get again another iterator, iterate across all the domain points, calculating a Laplace stencil
//
//
//! \cond [ghost] \endcond
/*!
* \page Grid_1_stencil Grid 1 stencil
*
* Get again another iterator, iterate across all the domain points, calculating a Laplace stencil. Write the
* result on B
*
* \snippet Grid/1_stencil/main.cpp laplacian
*
*/
//! \cond [laplacian] \endcond
auto dom2 = g_dist.getDomainIterator();
while (dom2.isNext())
......@@ -138,26 +209,53 @@ int main(int argc, char* argv[])
auto key = dom2.get();
// Laplace stencil
g_dist.template get<B>(key)[1] = g_dist.template get<A>(key.move(x,1))[0] + g_dist.template get<A>(key.move(x,-1))[0] +
g_dist.template get<A>(key.move(y,1))[0] + g_dist.template get<A>(key.move(y,-1))[0] +
g_dist.template get<A>(key.move(z,1))[0] + g_dist.template get<A>(key.move(z,-1))[0] -
6*g_dist.template get<A>(key)[0];
g_dist.template get<B>(key) = g_dist.template get<A>(key.move(x,1)) + g_dist.template get<A>(key.move(x,-1)) +
g_dist.template get<A>(key.move(y,1)) + g_dist.template get<A>(key.move(y,-1)) +
g_dist.template get<A>(key.move(z,1)) + g_dist.template get<A>(key.move(z,-1)) -
6*g_dist.template get<A>(key);
++dom2;
}
//
// ### WIKI 12 ###
//
// Finally we want a nice output to visualize the information stored by the distributed grid
//
//! \cond [laplacian] \endcond
/*!
* \page Grid_1_stencil Grid 1 stencil
*
*
* Finally we want a nice output to visualize the information stored by the distributed grid
*
* \snippet Grid/1_stencil/main.cpp output
*
*/
//! \cond [output] \endcond
g_dist.write("output");
//
// ### WIKI 14 ###
//
// Deinitialize the library
//
//! \cond [output] \endcond
/*!
* \page Grid_1_stencil Grid 1 stencil
*
* Deinitialize the library
*
* \snippet Grid/1_stencil/main.cpp finalize
*
*/
//! \cond [finalize] \endcond
openfpm_finalize();
//! \cond [finalize] \endcond
/*!
* \page Grid_1_stencil Grid 1 stencil
*
* # Full code # {#code}
*
* \include Grid/1_stencil/main.cpp
*
*/
}
......@@ -9,13 +9,13 @@ OBJ = main.o
%.o: %.cpp
$(CC) -O3 -c --std=c++11 -o $@ $< $(INCLUDE_PATH)
verlet: $(OBJ)
periodic: $(OBJ)
$(CC) -o $@ $^ $(CFLAGS) $(LIBS_PATH) $(LIBS)
all: verlet
all: periodic
.PHONY: clean all
clean:
rm -f *.o *~ core verlet
rm -f *.o *~ core periodic
This diff is collapsed.
include ../../example.mk
CC=mpic++
LDIR =
OBJ = main.o
%.o: %.cpp
$(CC) -O3 -c --std=c++11 -o $@ $< $(INCLUDE_PATH)
gray_scott: $(OBJ)
$(CC) -o $@ $^ $(CFLAGS) $(LIBS_PATH) $(LIBS)
all: gray_scott
.PHONY: clean all
clean:
rm -f *.o *~ core gray_scott
#include "Grid/grid_dist_id.hpp"
#include "data_type/aggregate.hpp"
#include "timer.hpp"
/*
* ### WIKI 1 ###
*
* ## Simple example of grid usage for solving gray scott-system
*
* This example show the usage of periodic grid with ghost part given in grid units to solve
* the following system of equations
*
* \frac{\partial u}{\partial t} = D_u \laplacian u -uv^2 + F(1-u)
* \frac{\partial v}{\partial t} = D_v \laplacian v -uv^2 - (F + k)v
*
* ### WIKI END ###
*
*/
constexpr int U = 0;
constexpr int V = 1;
/*
* ### WIKI 2 ###
*
* Initialize the field U
*
*/
void init(grid_dist_id<2,double,aggregate<double,double> > & Old, grid_dist_id<2,double,aggregate<double,double> > & New, Box<2,double> & domain)
{
//
// ### WIKI ###
//
// Here we initialize the full domain + boundary conditions
//
auto it = Old.getDomainGhostIterator();
while (it.isNext())
{
//
// ### WIKI 6 ###
//
// Get the local grid key
//
auto key = it.get();
// Old values U and V
Old.template get<U>(key) = 1.0;
Old.template get<V>(key) = 0.0;
// Old values U and V
New.template get<U>(key) = 0.0;
New.template get<V>(key) = 0.0;
++it;
}
//
// ### WIKI 20 ###
//
// We initialize a box in the center of the domain with different values
//
grid_key_dx<2> start({(long int)std::floor(Old.size(0)*1.55f/domain.getHigh(0)),(long int)std::floor(Old.size(1)*1.55f/domain.getHigh(1))});
grid_key_dx<2> stop ({(long int)std::ceil (Old.size(0)*1.85f/domain.getHigh(0)),(long int)std::ceil (Old.size(1)*1.85f/domain.getHigh(1))});
auto it_init = Old.getSubDomainIterator(start,stop);
while (it_init.isNext())
{
auto key = it_init.get();
Old.template get<U>(key) = 0.5 + (((double)std::rand())/RAND_MAX -0.5)/100.0;
Old.template get<V>(key) = 0.25 + (((double)std::rand())/RAND_MAX -0.5)/200.0;
++it_init;
}
//
// ### WIKI END ###
}
//
// ### WIKI 4 ###
//
// Usefull constant
//
constexpr int x = 0;
constexpr int y = 1;
int main(int argc, char* argv[])
{
//
// ### WIKI 2 ###
//
// Initialize the library
//
openfpm_init(&argc,&argv);
//
// ### WIKI 3 ###
//
// Create
// * A 2D box that define the domain
// * an array of 2 unsigned integer that will define the size of the grid on each dimension
// * A Ghost object that will define the extension of the ghost part for each sub-domain in grid point unit
Box<2,double> domain({0.0,0.0},{2.5,2.5});
size_t sz[2];
sz[0] = 128;
sz[1] = 128;
// Define periodicity of the grid
periodicity<2> bc = {PERIODIC,PERIODIC};
// Ghost in grid unit
Ghost<2,long int> g(1);
// deltaT
double deltaT = 1;
// Diffusion constant for specie U
double du = 2*1e-5;
// Diffusion constant for specie V
double dv = 1*1e-5;
// Number of timesteps
size_t timeSteps = 15000;
// K and F (Physical constant in the equation)
double K = 0.055;
double F = 0.03;
//
// ### WIKI 4 ###
//
// Create a distributed grid in 2D (1° template parameter) space in with double precision (2° template parameter)
// each grid point contain a scalar (double),
//
// Constructor parameters:
//
// * sz: size of the grid on each dimension
// * domain: where the grid is defined
// * g: ghost extension
// * bc: boundary conditions
//
grid_dist_id<2, double, aggregate<double,double>> Old(sz,domain,g,bc);
grid_dist_id<2, double, aggregate<double,double>> New(Old.getDecomposition(),sz,domain,g);
// spacing
double spacing[2] = {Old.spacing(0),Old.spacing(1)};
//
// ### WIKI 6 ###
//
// Initialize U and fill the boundary conditions
//
init(Old,New,domain);
timer time;
time.start();
// ### WIKI 7 ###
//
// Do 10000 iteration of Red-Black Gauss-Siedel
//
// sync the ghost
size_t count;
Old.template ghost_get<0,1>();
double uFactor = deltaT * du/(spacing[0]*spacing[0]);
double vFactor = deltaT * dv/(spacing[0]*spacing[0]);
for (size_t i = 0; i < timeSteps; ++i)
{
auto it = Old.getDomainIterator();
while (it.isNext())
{
auto key = it.get();
New.get<U>(key) = Old.get<U>(key) + uFactor * (
Old.get<U>(key.move(x,1)) +
Old.get<U>(key.move(x,-1)) +
Old.get<U>(key.move(y,1)) +
Old.get<U>(key.move(y,-1)) +
-4.0*Old.get<U>(key)) +
- deltaT * Old.get<U>(key) * Old.get<V>(key) * Old.get<V>(key) +
- deltaT * F * (Old.get<U>(key) - 1.0);
New.get<V>(key) = Old.get<V>(key) + vFactor * (
Old.get<V>(key.move(x,1)) +
Old.get<V>(key.move(x,-1)) +
Old.get<V>(key.move(y,1)) +
Old.get<V>(key.move(y,-1)) -
4*Old.get<V>(key)) +
deltaT * Old.get<U>(key) * Old.get<V>(key) * Old.get<V>(key) +
- deltaT * (F+K) * Old.get<V>(key);
++it;
}
Old.copy(New);
Old.ghost_get<0,1>();
if (i % 100 == 0)
{
Old.write("output",count);
count++;
}
}
//
// ### WIKI 14 ###
//
// Deinitialize the library
//
openfpm_finalize();
}
include ../../../example.mk
CC=mpic++
LDIR =
OBJ = main.o
%.o: %.cpp
$(CC) -O3 -g -c --std=c++11 -o $@ $< $(INCLUDE_PATH) -I/home/i-bird/HDF5/include
agsim: $(OBJ)
$(CC) -o $@ $^ $(CFLAGS) $(LIBS_PATH) $(LIBS)
all: agsim
.PHONY: clean all
clean:
rm -f *.o *~ core agsim
include ../../../example.mk
CC=mpic++
LDIR =
OBJ_EIGEN = main_eigen.o
OBJ_PETSC = main_petsc.o
%.o: %.cpp
$(CC) -O3 -c --std=c++11 -o $@ $< $(INCLUDE_PATH)
all: stokes_2d_eigen stokes_2d_petsc