Commit b116804e authored by Pietro Incardona's avatar Pietro Incardona
Browse files

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
......
#include "Grid/grid_dist_id.hpp"
#include "data_type/aggregate.hpp"
#include "Decomposition/CartDecomposition.hpp"
/*
* ### WIKI 1 ###
/*! \page grid Grid
*
* \subpage grid_0_simple
* \subpage Grid_1_stencil
* \subpage Grid_2_solve_eq
*
* ## Simple example
*
* This example show several basic functionalities of the distributed grid
*
* ### WIKI END ###
*
*/
/*! \page grid_0_simple Grid 0 simple
[TOC]
# Simple grid example # {#simple_grid_example}
This example show several basic functionalities of the distributed grid
\htmlonly
<a href="#" onclick="if (document.getElementById('grid-video-1').style.display == 'none') {document.getElementById('grid-video-1').style.display = 'block'} else {document.getElementById('grid-video-1').style.display = 'none'}" >Video</a>
<div style="display:none" id="grid-video-1">
<video id="vid1" width="1200" height="576" controls> <source src="http://ppmcore.mpi-cbg.de/upload/video/Lesson1-1.mp4" type="video/mp4"></video><script>document.getElementById('vid1').addEventListener('loadedmetadata', function() {this.currentTime = 236;}, false);</script>
</div>
\endhtmlonly
*/
int main(int argc, char* argv[])
{
//
// ### WIKI 2 ###
//
// Initialize the library and several objects
//
openfpm_init(&argc,&argv);
//
// ### WIKI 3 ###
//
// Create
// * A 3D box that define the domain
// * an array of 3 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 physical units
/*! \page grid_0_simple Grid 0 simple
*
* ## Initialization ## {#e0_s_initialization}
*
* Here we:
* * Initialize the library
* * Create A 3D box that define our the domain
* * an array of 3 unsigned integer that will define the size of the grid on each dimensions
* * A Ghost object that will define the extension of the ghost part in physical units
*
* \snippet Grid/0_simple/main.cpp initialization
*
*/
//! \cond [initialization] \endcond
// Initialize the library
openfpm_init(&argc,&argv);
// 3D physical 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 size on eaxh dimension
size_t sz[3] = {100,100,100};
// Ghost part
Ghost<3,float> g(0.01);
//
// ### 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 [initialization] \endcond
/*! \page grid_0_simple Grid 0 simple
*
* ## Grid instantiation ## {#e0_s_grid_inst}
*
* Here we are creating a distributed grid in defined by the following parameters
*
* * 3 dimensionality of the grid
* * float Type used for the spatial coordinates
* * each grid point contain a vector of dimension 3 (float[3]),
* * float[3] is the information stored by each grid point a float[3]
* the list of properties must be put into an aggregate data structure aggregate<prop1,prop2,prop3, ... >
*
* Constructor parameters:
*
* * sz: size of the grid on each dimension
* * domain: where the grid is defined
* * g: ghost extension
*
* \snippet Grid/0_simple/main.cpp grid instantiation
*
*/
//! \cond [grid instantiation] \endcond
grid_dist_id<3, float, aggregate<float[3]>> g_dist(sz,domain,g);
// ### WIKI 5 ###
//
// Get an iterator that go through the points of the grid (No ghost)
//
auto dom = g_dist.getDomainIterator();
//! \cond [grid instantiation] \endcond
/*!
* \page grid_0_simple Grid 0 simple
*
* ## Loop over grid points ## {#e0_s_loop_gp}
*
* Get an iterator that go through all the grid points. In this
* example we use iterators. Iterators are convenient way to explore/iterate data-structures in an
* convenient and easy way.
*
* \snippet Grid/0_simple/main.cpp get iterator
* \snippet Grid/0_simple/main.cpp get iterator2
*
*/
//! \cond [get iterator] \endcond
// ### WIKI END ###
// Get the iterator (No ghost)
auto dom = g_dist.getDomainIterator();
// Counter
size_t count = 0;
// Iterate over all the points
// Iterate over all the grid points
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 [get iterator] \endcond
/*!
* \page grid_0_simple Grid 0 simple
*
* ## Grid coordinates ## {#e0_s_grid_coord}
*
* Get the local grid key, one local grid key* identify one point in the grid and store the local grid coordinates of such point
*
* <sub><sup>(*)Internally a local grid store 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().</sup></sub>
*
* \snippet Grid/0_simple/main.cpp local grid
*
*/
//! \cond [local grid] \endcond
// local grid key from iterator
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 grid] \endcond
/*!
* \page grid_0_simple Grid 0 simple
*
* **Short explanation**
*
* In oder to get the real/global coordinates of the grid point we have to convert the object key with getGKey
*
*/
/*!
*
* \page grid_0_simple Grid 0 simple
*
\htmlonly <a href="#" onclick="if (document.getElementById('long-explanation-div').style.display == 'none') {document.getElementById('long-explanation-div').style.display = 'block'} else {document.getElementById('long-explanation-div').style.display = 'none'}" >Long Explanation</a> \endhtmlonly
*
*
\htmlonly
<div style="display:none" id="long-explanation-div">
<p>Even if the local grid key identify an unique point in the grid, it does not store the real/global coordinates of the points in grid units.</p>
<p>Consider this scheme</p>
<pre class="fragment">
+-----+-----+--*--+-----+-----+-----+ (6,6)
| | P1,3 |
| P1,1 *--------------------*
| | P1,2 |
+ + + | + + + +
| *--------------------*
*--------------* |
| | |
+ + + | + + + +
| | |
| P0,2 | P1,0 |
| | |
+ + + | # + + +
| | |
*--------------* |
| *--------------------*
+ + + | + + + +
| | |
| P0,0 | P0,1 |
| | |
+-----+-----+--*--+-----+-----+-----+
(0,0) (6,0)
+,# = grid point
*--*
| | = uderline decomposition in sub-domain
*--*
PX,Y Processor X, sub-domain Y</pre><p>The point # has</p>
<ul>
<li>Global/Real coordinates are (3,2)</li>
<li>Local grid coordinates are Sub-domain = 0, grid position = (0,0)</li>
</ul>
<p>Here we convert the local grid coordinates, into global coordinates. key_g internally store 3 integers that identify the position of the grid point in global coordinates</p>
<p>
</div>
\endhtmlonly
*/
/*! \page grid_0_simple Grid 0 simple
*
* \snippet Grid/0_simple/main.cpp global coord
*
*/
//! \cond [global coord] \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);
// ### WIKI END ###
//! \cond [global coord] \endcond
/*!
* \page grid_0_simple Grid 0 simple
*
* ## Assign properties ## {#grid_assign}
*
* Each grid point has a vector property we write on the vector coordinates the global coordinate of the grid point.
* At the same time we also count the points
*
* \snippet Grid/0_simple/main.cpp assign
*
*/
//! \cond [assign] \endcond
g_dist.template get<0>(key)[0] = key_g.get(0);
g_dist.template get<0>(key)[1] = key_g.get(1);
g_dist.template get<0>(key)[2] = key_g.get(2);
// Count the points
count++;
//
// ### WIKI 9 ###
//
//! \cond [assign] \endcond
//! \cond [get iterator2] \endcond
//! ...
// next point
++dom;
// ### WIKI END ###
}
//
// ### 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
//
//
//! \cond [get iterator2] \endcond
/*!
* \page grid_0_simple Grid 0 simple
*
* Each sub-domain has an extended part, that is materially contained in
* another processor. The function ghost_get guarantee (after return) that this extended part
* is perfectly synchronized with the other processor.
*
* \snippet Grid/0_simple/main.cpp ghost get
*
*/
//! \cond [ghost get] \endcond
g_dist.template ghost_get<0>();
//
// ### WIKI 11 ###
//
// count contain the number of points the local processor contain, if we are interested to count the total number across the processor
// we can use the function add, to sum across processors. First we have to get an instance of Vcluster, queue an operation of add with
// the variable count and finally execute. All the operation are asynchronous, execute work like a barrier and ensure that all the
// queued operations are executed
//
Vcluster & vcl = g_dist.getVC();
//! \cond [ghost get] \endcond
/*!
* \page grid_0_simple Grid 0 simple
*
* count contain the number of points the local processor contain, if we are interested to count the total number across the processor
* we can use the function sum, to sum numbers across processors. First we have to get an instance of Vcluster, queue an operation of sum with
* the variable count and finally execute. All the operation are asynchronous, execute work like a barrier and ensure that all the
* queued operations are executed
*
* \snippet Grid/0_simple/main.cpp reduce
*
*/
//! \cond [reduce] \endcond
// Get the VCluster object
Vcluster & vcl = create_vcluster();
// queue an operation of sum for the counter count
vcl.sum(count);
// execute the operation
vcl.execute();
// only master output
if (vcl.getProcessUnitID() == 0)
std::cout << "Number of points: " << count << "\n";
//
// ### WIKI 12 ###
//
// Finally we want a nice output to visualize the information stored by the distributed grid
//
//! \cond [reduce] \endcond
/*!
* \page grid_0_simple Grid 0 simple
*
* ## VTK and visualization ## {#e0_s_VTK_vis}
*
* Finally we want a nice output to visualize the information stored by the distributed grid.
* The function write by default produce VTK files. One for each processor that can be visualized
* with the programs like paraview
*
* \snippet Grid/0_simple/main.cpp write
*
*/
//! \cond [write] \endcond
g_dist.write("output");
//
// ### WIKI 13 ###
//
// For debugging purpose and demonstration we output the decomposition
//
//! \cond [write] \endcond
/*!
* \page grid_0_simple Grid 0 simple
*
* ## Decomposition ## {#grid_dec}
*
* For debugging purpose and demonstration we also output the decomposition of the
* space across processor. This function produce VTK files that can be visualized with Paraview
*
* \snippet Grid/0_simple/main.cpp out_dec
*
*/
//! \cond [out_dec] \endcond
g_dist.getDecomposition().write("out_dec");
//
// ### WIKI 14 ###
//
// Deinitialize the library
//
//! \cond [out_dec] \endcond
/*!
* \page grid_0_simple Grid 0 simple
*
* ## Finalize ## {#finalize}
*
* At the very end of the program we have always to de-initialize the library
*
* \snippet Vector/0_simple/main.cpp finalize
*
*/
//! \cond [finalize] \endcond
openfpm_finalize();
//! \cond [finalize] \endcond
/*!
* \page grid_0_simple Grid 0 simple
*
* # Full code # {#code}
*
* \include Grid/0_simple/main.cpp
*
*/
}
......@@ -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
*
*/