Commit 2eb3065f authored by Pietro Incardona's avatar Pietro Incardona

added examples

parent abe7ea11
[pack]
files = main.cpp Makefile
/*
* ### WIKI 1 ###
*
* ## Security enhancement example
*
* This example show several basic functionalities of Security Enhancements
*
*/
#define SE_CLASS1
#define SE_CLASS2
#define SE_CLASS3
#define THROW_ON_ERROR
#include "Memleak_check.hpp"
#include "Vector/vector_dist.hpp"
#include "Decomposition/CartDecomposition.hpp"
#include "Point_test.hpp"
/*
* ### WIKI END ###
*/
int main(int argc, char* argv[])
{
//
// ### WIKI 2 ###
//
// With print_unalloc we can check how much memory has been allocated and which structure
// has been allocated, initially there are not
//
std::cout << "Allocated memory before initializing \n";
print_alloc();
std::cout << "\n";
std::cout << "\n";
std::cout << "\n";
//
// ### WIKI 3 ###
//
// Here we Initialize the library, than we create a uniform random generator between 0 and 1 to to generate particles
// randomly in the domain, we create a Box that define our domain
//
init_global_v_cluster(&argc,&argv);
Vcluster & v_cl = *global_v_cluster;
typedef Point<2,float> s;
Box<2,float> box({0.0,0.0},{1.0,1.0});
//
// ### WIKI 4 ###
//
// Here we ask again for the used memory, as we can see Vcluster and several other structures encapsulated inside
// Vcluster register itself
//
if (v_cl.getProcessUnitID() == 0)
{
std::cout << "Allocated memory after initialization \n";
print_alloc();
std::cout << "\n";
std::cout << "\n";
std::cout << "\n";
}
//
// ### WIKI 5 ###
//
// Here we are creating a distributed vector defined by the following parameters
//
// * Dimensionality of the space where the objects live 2D (1° template parameters)
// * Type of the space, float (2° template parameters)
// * Information stored by each object (3* template parameters), in this case a Point_test store 4 scalars
// 1 vector and an asymmetric tensor of rank 2
// * Strategy used to decompose the space
//
// The Constructor instead require:
//
// * Number of particles 4096 in this case
// * Domain where is defined this structure
//
// The following construct a vector where each processor has 4096 / N_proc (N_proc = number of processor)
// objects with an undefined position in space. This non-space decomposition is also called data-driven
// decomposition
//
{
vector_dist<2,float, Point_test<float>, CartDecomposition<2,float> > vd(4096,box);
//
// ### WIKI 6 ###
//
// we create a key that for sure overflow the local datastructure, 2048 with this program is started with more than 3
// processors, try and catch are optionals in case you want to recover from a buffer overflow
//
try
{
vect_dist_key_dx vt(0,5048);
auto it = vd.getPos<0>(vt);
}
catch (size_t e)
{
std::cerr << "Error notification of overflow \n";
}
}
//
// ### WIKI 7 ###
//
// At this point the vector went out of the scope and if destroyed
// we create, now two of them using new
//
vector_dist<2,float, Point_test<float>, CartDecomposition<2,float> > * vd1 = new vector_dist<2,float, Point_test<float>, CartDecomposition<2,float> >(4096,box);
vector_dist<2,float, Point_test<float>, CartDecomposition<2,float> > * vd2 = new vector_dist<2,float, Point_test<float>, CartDecomposition<2,float> >(4096,box);
//
// ### WIKI 8 ###
//
// we can check that these two structure produce an explicit allocation checking
// for registered pointers and structures with print_alloc, in the list we see 2 additional
// entry for distributed vector in yellow, pdata to work use the data structures that register
// itself in magenta, the same things happen for the real memory allocation from devices in
// fully green
//
if (v_cl.getProcessUnitID() == 0)
{
std::cout << "Allocated memory with 2 vectors \n";
print_alloc();
std::cout << "\n";
std::cout << "\n";
std::cout << "\n";
}
//
// ### WIKI 9 ###
//
// we can also ask to the structure to identify their-self in the list
//
std::cout << "Vector id: " << vd1->who() << "\n";
std::cout << "Vector id: " << vd2->who() << "\n";
//
// ### WIKI 10 ###
//
// delete vd1 and print allocated memory, one distributed vector disappear
//
delete vd1;
if (v_cl.getProcessUnitID() == 0)
{
std::cout << "Allocated memory with 1 vector \n";
print_alloc();
std::cout << "\n";
std::cout << "\n";
std::cout << "\n";
}
//
// ### WIKI 11 ###
//
// delete vd2 and print allocated memory, all distributed vector de-register
//
delete vd2;
if (v_cl.getProcessUnitID() == 0)
{
std::cout << "Allocated memory with 1 vector \n";
print_alloc();
std::cout << "\n";
std::cout << "\n";
std::cout << "\n";
}
//
// ### WIKI 12 ###
//
// Try to use a deleted object
//
try
{
vect_dist_key_dx vt(0,0);
auto it = vd1->getPos<0>(vt);
}
catch (size_t e)
{
std::cerr << "Error notification of invalid usage of deleted object \n";
}
//
// ### WIKI 13 ###
//
// Deinitialize the library
//
delete_global_v_cluster();
if (v_cl.getProcessUnitID() == 0)
{
std::cout << "Allocated memory at the end \n";
print_alloc();
std::cout << "\n";
std::cout << "\n";
std::cout << "\n";
}
}
[pack]
files = main.cpp Makefile
/*
* ### WIKI 1 ###
*
* ## Security enhancement example
*
* This example show how to see where an allocation or corruption happen offline and online.
* Every time an error occur, the library output where the detection happen filename and line,
* in order to debug, there is an online option and an offline option
*
* * online: put a breakpoint on the indicated line with your preferred debugger
* * offline: set ulimit -c unlimited to activate the core dump file and open the core dump with your debugger
*
*/
#define SE_CLASS1
#define SE_CLASS2
#define SE_CLASS3
#define THROW_ON_ERROR
#include "Memleak_check.hpp"
#include "data_type/scalar.hpp"
#include "Grid/grid_dist_id.hpp"
#include "Decomposition/CartDecomposition.hpp"
#include "Point_test.hpp"
/*
* ### WIKI END ###
*/
int main(int argc, char* argv[])
{
//
// ### WIKI 2 ###
//
// Here we Initialize the library,
// * message_on_allocation set a message to print when one allocation is reached, the filename and line number can be used to set a breakpoint and analyze the stacktrace.
// * throw_on_allocation throw when one allocation is reached, producing the termination of the program and a core dump (if no try catch is set-up)
//
init_global_v_cluster(&argc,&argv);
Vcluster & v_cl = *global_v_cluster;
throw_on_alloc(10);
// message_on_alloc(10);
//
// ### WIKI 3 ###
//
// 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
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
Ghost<3,float> g(0.01);
//
// ### WIKI 4 ###
//
// Create a distributed grid in 3D (1° template parameter) defined in R^3 with float precision (2° template parameter)
// using a CartesianDecomposition strategy (3° 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
//
//
grid_dist_id<3, float, scalar<float[3]>, CartDecomposition<3,float>> * g_dist = new grid_dist_id<3, float, scalar<float[3]>, CartDecomposition<3,float>>(sz,domain,g);
//
// ### WIKI 6 ###
//
// print allocated structures
//
if (v_cl.getProcessUnitID() == 0)
print_alloc();
//
// ### WIKI 5 ###
//
// delete g_dist
//
delete g_dist;
//
// ### WIKI 6 ###
//
// On purpose we try to access a deleted object
//
g_dist->getGridInfo();
//
// ### WIKI 13 ###
//
// Deinitialize the library
//
delete_global_v_cluster();
}
[pack]
files = main.cpp Makefile
#include "Grid/grid_dist_id.hpp"
#include "data_type/aggregate.hpp"
#include "Decomposition/CartDecomposition.hpp"
#include "VCluster.hpp"
/*
* ### WIKI 1 ###
*
* ## Simple example
*
* This example show several basic functionalities of VCluster
*
* ### WIKI END ###
*
*/
int main(int argc, char* argv[])
{
//
// ### WIKI 2 ###
//
// Initialize the library and several objects
//
init_global_v_cluster(&argc,&argv);
//
// ### WIKI 3 ###
//
// Get the vcluster object and the number of processor
//
Vcluster & v_cl = *global_v_cluster;
size_t N_prc = v_cl.getProcessingUnits();
//
// ### WIKI 3 ###
//
// We find the maximum of the processors rank, that should be the Number of
// processora minus one, only processor 0 print on terminal
//
size_t id = v_cl.getProcessUnitID();
v_cl.max(id);
v_cl.execute();
if (v_cl.getProcessUnitID() == 0)
std::cout << "Maximum processor rank: " << id << "\n";
//
// ### WIKI 4 ###
//
// We sum all the processor ranks the maximum, the result should be that should
// be $\frac{(n-1)n}{2}$, only processor 0 print on terminal
//
size_t id2 = v_cl.getProcessUnitID();
v_cl.sum(id2);
v_cl.execute();
if (v_cl.getProcessUnitID() == 0)
std::cout << "Sum of all processors rank: " << id2 << "\n";
//
// ### WIKI 5 ###
//
// we can collect information from all processors using the function gather
//
size_t id3 = v_cl.getProcessUnitID();
openfpm::vector<size_t> v;
v_cl.allGather(id3,v);
v_cl.execute();
if (v_cl.getProcessUnitID() == 0)
{
std::cout << "Collected ids: ";
for(size_t i = 0 ; i < v.size() ; i++)
std::cout << " " << v.get(i) << " ";
std::cout << "\n";
}
//
// ### WIKI 5 ###
//
// we can also send messages to specific processors, with the condition that the receiving
// processors know we want to communicate with them, if you are searching for a more
// free way to communicate where the receiving processors does not know which one processor
// want to communicate with us, see the example 1_dsde
//
std::stringstream ss_message_1;
std::stringstream ss_message_2;
ss_message_1 << "Hello from " << std::setw(8) << v_cl.getProcessUnitID() << "\n";
ss_message_2 << "Hello from " << std::setw(8) << v_cl.getProcessUnitID() << "\n";
std::string message_1 = ss_message_1.str();
std::string message_2 = ss_message_2.str();
size_t msg_size = message_1.size();
// Processor 0 send to processors 1,2 , 1 to 2,1, 2 to 0,1
v_cl.send(((id3+1)%N_prc + N_prc)%N_prc,0,message_1.c_str(),msg_size);
v_cl.send(((id3+2)%N_prc + N_prc)%N_prc,0,message_2.c_str(),msg_size);
openfpm::vector<char> v_one;
v_one.resize(msg_size);
openfpm::vector<char> v_two(msg_size);
v_two.resize(msg_size);
v_cl.recv(((id3-1)%N_prc + N_prc)%N_prc,0,(void *)v_one.getPointer(),msg_size);
v_cl.recv(((id3-2)%N_prc + N_prc)%N_prc,0,(void *)v_two.getPointer(),msg_size);
v_cl.execute();
if (v_cl.getProcessUnitID() == 0)
{
for (size_t i = 0 ; i < msg_size ; i++)
std::cout << v_one.get(i);
for (size_t i = 0 ; i < msg_size ; i++)
std::cout << v_two.get(i);
}
//
// ### WIKI 5 ###
//
// we can also do what we did before in one shot
//
id = v_cl.getProcessUnitID();
id2 = v_cl.getProcessUnitID();
id3 = v_cl.getProcessUnitID();
v.clear();
// convert the string into a vector
openfpm::vector<char> message_1_v(msg_size);
openfpm::vector<char> message_2_v(msg_size);
for (size_t i = 0 ; i < msg_size ; i++)
message_1_v.get(i) = message_1[i];
for (size_t i = 0 ; i < msg_size ; i++)
message_2_v.get(i) = message_2[i];
v_cl.max(id);
v_cl.sum(id2);
v_cl.allGather(id3,v);
// in the case of vector we have special functions that avoid to specify the size
v_cl.send(((id+1)%N_prc + N_prc)%N_prc,0,message_1_v);
v_cl.send(((id+2)%N_prc + N_prc)%N_prc,0,message_2_v);
v_cl.recv(((id-1)%N_prc + N_prc)%N_prc,0,v_one);
v_cl.recv(((id-2)%N_prc + N_prc)%N_prc,0,v_two);
v_cl.execute();
if (v_cl.getProcessUnitID() == 0)
{
std::cout << "Maximum processor rank: " << id << "\n";
std::cout << "Sum of all processors rank: " << id << "\n";
std::cout << "Collected ids: ";
for(size_t i = 0 ; i < v.size() ; i++)
std::cout << " " << v.get(i) << " ";
std::cout << "\n";
for (size_t i = 0 ; i < msg_size ; i++)
std::cout << v_one.get(i);
for (size_t i = 0 ; i < msg_size ; i++)
std::cout << v_two.get(i);
}
delete_global_v_cluster();
}
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment