Commit 91de3907 authored by Pietro Incardona's avatar Pietro Incardona

Resolving merge conflict

parents e4b8762c 09a83aea
......@@ -18,6 +18,7 @@
#endif
#include "util/Vcluster_log.hpp"
#include "memory/BHeapMemory.hpp"
#include "Packer_Unpacker/has_max_prop.hpp"
#ifdef HAVE_PETSC
#include <petscvec.h>
......
......@@ -9,6 +9,232 @@
private:
// Structures that do an unpack, depending on the existence of max_prop inside 'send'
//
template<bool result, typename T, typename S>
struct unpack_selector
{
template<int ... prp> static void call_unpack(S & recv, openfpm::vector<BHeapMemory> & recv_buf, openfpm::vector<size_t> * sz = NULL)
{
#ifdef DEBUG
std::cout << "Sz.size(): " << sz->size() << std::endl;
#endif
for (size_t i = 0 ; i < recv_buf.size() ; i++)
{
#ifdef DEBUG
std::cout << "Recv_buf.get(i).size(): " << recv_buf.get(i).size() << std::endl;
#endif
T unp;
ExtPreAlloc<HeapMemory> & mem = *(new ExtPreAlloc<HeapMemory>(recv_buf.get(i).size(),recv_buf.get(i)));
mem.incRef();
Unpack_stat ps;
Unpacker<T,HeapMemory>::template unpack<prp...>(mem, unp, ps);
size_t recv_size_old = recv.size();
// Merge the information
recv.add(unp);
size_t recv_size_new = recv.size();
if (sz != NULL)
sz->get(i) = recv_size_new - recv_size_old;
}
}
};
//
template<typename T, typename S>
struct unpack_selector<true, T, S>
{
template<int ... prp> static void call_unpack(S & recv, openfpm::vector<BHeapMemory> & recv_buf, openfpm::vector<size_t> * sz = NULL)
{
for (size_t i = 0 ; i < recv_buf.size() ; i++)
{
/*ExtPreAlloc<HeapMemory> & mem = *(new ExtPreAlloc<HeapMemory>(recv_buf.get(i).size(),recv_buf.get(i)));
mem.incRef();
Unpack_stat ps;
size_t n_ele = 0;
Unpacker<size_t, HeapMemory>::unpack(mem,n_ele,ps);*/
// calculate the number of received elements
size_t n_ele = recv_buf.get(i).size() / sizeof(typename T::value_type);
// add the received particles to the vector
PtrMemory * ptr1 = new PtrMemory(recv_buf.get(i).getPointer(),recv_buf.get(i).size());
// create vector representation to a piece of memory already allocated
openfpm::vector<typename T::value_type,PtrMemory,typename memory_traits_lin<typename T::value_type>::type, memory_traits_lin,openfpm::grow_policy_identity> v2;
v2.setMemory(*ptr1);
// resize with the number of elements
v2.resize(n_ele);
// Merge the information
size_t recv_size_old = recv.size();
// Merge the information
recv.add(v2);
size_t recv_size_new = recv.size();
if (sz != NULL)
sz->get(i) = recv_size_new - recv_size_old;
}
}
};
template<typename T>
struct call_serialize_variadic {};
template<int ... prp>
struct call_serialize_variadic<index_tuple<prp...>>
{
template<typename T> inline static void call_pr(T & send, size_t & tot_size)
{
Packer<T,HeapMemory>::template packRequest<prp...>(send,tot_size);
}
template<typename T> inline static void call_pack(ExtPreAlloc<HeapMemory> & mem, T & send, Pack_stat & sts)
{
Packer<T,HeapMemory>::template pack<prp...>(mem,send,sts);
}
template<typename T, typename S> inline static void call_unpack(S & recv, openfpm::vector<BHeapMemory> & recv_buf, openfpm::vector<size_t> * sz = NULL)
{
const bool result = has_pack_gen<typename T::value_type>::value == false && is_vector<T>::value == true;
//const bool result = has_pack<typename T::value_type>::type::value == false && has_pack_agg<typename T::value_type>::result::value == false && is_vector<T>::value == true;
unpack_selector<result, T, S>::template call_unpack<prp...>(recv, recv_buf, sz);
}
};
// Structures that do a pack request, depending on the existence of max_prop inside 'send'
//There is max_prop inside
template<bool cond, typename T, typename S>
struct pack_unpack_cond
{
static void packingRequest(T & send, size_t & tot_size, openfpm::vector<size_t> & sz)
{
typedef typename ::generate_indexes<int, has_max_prop<T, has_value_type<T>::value>::number, MetaFuncOrd>::result ind_prop_to_pack;
if (has_pack_gen<typename T::value_type>::value == false && is_vector<T>::value == true)
//if (has_pack<typename T::value_type>::type::value == false && has_pack_agg<typename T::value_type>::result::value == false && is_vector<T>::value == true)
{
#ifdef DEBUG
std::cout << "Inside SGather pack request (has prp) (vector case) " << std::endl;
#endif
sz.add(send.size()*sizeof(typename T::value_type));
}
else
{
call_serialize_variadic<ind_prop_to_pack>::call_pr(send,tot_size);
#ifdef DEBUG
std::cout << "Inside SGather pack request (has prp) (general case) " << std::endl;
#endif
sz.add(tot_size);
}
}
static void packing(ExtPreAlloc<HeapMemory> & mem, T & send, Pack_stat & sts, openfpm::vector<const void *> & send_buf)
{
typedef typename ::generate_indexes<int, has_max_prop<T, has_value_type<T>::value>::number, MetaFuncOrd>::result ind_prop_to_pack;
if (has_pack_gen<typename T::value_type>::value == false && is_vector<T>::value == true)
//if (has_pack<typename T::value_type>::type::value == false && has_pack_agg<typename T::value_type>::result::value == false && is_vector<T>::value == true)
{
#ifdef DEBUG
std::cout << "Inside SGather pack (has prp) (vector case) " << std::endl;
#endif
//std::cout << demangle(typeid(T).name()) << std::endl;
send_buf.add(send.getPointer());
}
else
{
#ifdef DEBUG
std::cout << "Inside SGather pack (has prp) (general case) " << std::endl;
#endif
send_buf.add(mem.getPointerEnd());
call_serialize_variadic<ind_prop_to_pack>::call_pack(mem,send,sts);
}
}
static void unpacking(S & recv, openfpm::vector<BHeapMemory> & recv_buf, openfpm::vector<size_t> * sz = NULL)
{
typedef typename ::generate_indexes<int, has_max_prop<T, has_value_type<T>::value>::number, MetaFuncOrd>::result ind_prop_to_pack;
call_serialize_variadic<ind_prop_to_pack>::template call_unpack<T,S>(recv, recv_buf, sz);
}
};
//There is no max_prop inside
template<typename T, typename S>
struct pack_unpack_cond<false, T, S>
{
static void packingRequest(T & send, size_t & tot_size, openfpm::vector<size_t> & sz)
{
if (has_pack<typename T::value_type>::type::value == false && is_vector<T>::value == true)
{
#ifdef DEBUG
std::cout << "Inside SGather pack request (no prp) (vector case) " << std::endl;
#endif
sz.add(send.size()*sizeof(typename T::value_type));
}
else
{
Packer<T,HeapMemory>::packRequest(send,tot_size);
#ifdef DEBUG
std::cout << "Tot_size: " << tot_size << std::endl;
#endif
sz.add(tot_size);
}
}
static void packing(ExtPreAlloc<HeapMemory> & mem, T & send, Pack_stat & sts, openfpm::vector<const void *> & send_buf)
{
if (has_pack<typename T::value_type>::type::value == false && is_vector<T>::value == true)
{
#ifdef DEBUG
std::cout << "Inside SGather pack (no prp) (vector case)" << std::endl;
#endif
send_buf.add(send.getPointer());
}
else
{
#ifdef DEBUG
std::cout << "Inside SGather pack (no prp) (genaral case) " << std::endl;
#endif
send_buf.add(mem.getPointerEnd());
Packer<T,HeapMemory>::pack(mem,send,sts);
}
}
static void unpacking(S & recv, openfpm::vector<BHeapMemory> & recv_buf, openfpm::vector<size_t> * sz = NULL)
{
#ifdef DEBUG
std::cout << "Inside SGather unpack (no prp) " << std::endl;
#endif
const bool result = has_pack<typename T::value_type>::type::value == false && is_vector<T>::value == true;
unpack_selector<result, T, S>::template call_unpack<>(recv, recv_buf, sz);
}
};
/*! \brief Reset the receive buffer
*
*
......@@ -88,29 +314,7 @@ template<typename T, typename S> void process_receive_buffer(S & recv, openfpm::
if (sz != NULL)
sz->resize(recv_buf.size());
for (size_t i = 0 ; i < recv_buf.size() ; i++)
{
// for each received buffer create a memory reppresentation
// calculate the number of received elements
size_t n_ele = recv_buf.get(i).size() / sizeof(typename T::value_type);
// add the received particles to the vector
PtrMemory * ptr1 = new PtrMemory(recv_buf.get(i).getPointer(),recv_buf.get(i).size());
// create vector representation to a piece of memory already allocated
openfpm::vector<typename T::value_type,PtrMemory,typename memory_traits_lin<typename T::value_type>::type, memory_traits_lin,openfpm::grow_policy_identity> v2;
v2.setMemory(*ptr1);
// resize with the number of elements
v2.resize(n_ele);
// Merge the information
recv.add(v2);
if (sz != NULL)
sz->get(i) = v2.size();
}
pack_unpack_cond<has_max_prop<T, has_value_type<T>::value>::value, T, S>::unpacking(recv, recv_buf, sz);
}
public:
......@@ -150,6 +354,10 @@ template<typename T, typename S> bool SGather(T & send, S & recv,size_t root)
return SGather(send,recv,prc,sz,root);
}
template<size_t index, size_t N> struct MetaFuncOrd {
enum { value = index };
};
/*! \brief Semantic Gather, gather the data from all processors into one node
*
* Semantic communication differ from the normal one. They in general
......@@ -187,6 +395,9 @@ template<typename T, typename S> bool SGather(T & send, S & recv, openfpm::vecto
// If we are on master collect the information
if (getProcessUnitID() == root)
{
#ifdef DEBUG
std::cout << "Inside root " << root << std::endl;
#endif
// send buffer (master does not send anything) so send req and send_buf
// remain buffer with size 0
openfpm::vector<size_t> send_req;
......@@ -197,10 +408,6 @@ template<typename T, typename S> bool SGather(T & send, S & recv, openfpm::vecto
// Send and recv multiple messages
sendrecvMultipleMessagesNBX(send_req.size(),NULL,NULL,NULL,msg_alloc,&bi);
// Convert the received byte into number of elements
for (size_t i = 0 ; i < sz.size() ; i++)
sz.get(i) /= sizeof(typename T::value_type);
// process the received information
process_receive_buffer<T,S>(recv,&sz);
......@@ -210,14 +417,34 @@ template<typename T, typename S> bool SGather(T & send, S & recv, openfpm::vecto
}
else
{
#ifdef DEBUG
std::cout << "Inside slave " << getProcessUnitID() << std::endl;
#endif
// send buffer (master does not send anything) so send req and send_buf
// remain buffer with size 0
openfpm::vector<size_t> send_prc;
send_prc.add(root);
openfpm::vector<const void *> send_buf;
send_buf.add(send.getPointer());
openfpm::vector<size_t> sz;
sz.add(send.size()*sizeof(typename T::value_type));
openfpm::vector<const void *> send_buf;
//Pack requesting
size_t tot_size = 0;
pack_unpack_cond<has_max_prop<T, has_value_type<T>::value>::value, T, S>::packingRequest(send, tot_size, sz);
HeapMemory pmem;
ExtPreAlloc<HeapMemory> & mem = *(new ExtPreAlloc<HeapMemory>(tot_size,pmem));
mem.incRef();
//Packing
Pack_stat sts;
pack_unpack_cond<has_max_prop<T, has_value_type<T>::value>::value, T, S>::packing(mem, send, sts, send_buf);
// receive information
base_info bi(NULL,prc,sz);
......@@ -348,12 +575,31 @@ template<typename T, typename S> bool SSendRecv(openfpm::vector<T> & send, S & r
openfpm::vector<const void *> send_buf;
openfpm::vector<size_t> sz_byte;
sz_byte.resize(send.size());
size_t tot_size = 0;
for (size_t i = 0; i < send.size() ; i++)
{
size_t req = 0;
//Pack requesting
pack_unpack_cond<has_max_prop<T, has_value_type<T>::value>::value, T, S>::packingRequest(send.get(i), req, sz_byte);
tot_size += req;
}
HeapMemory pmem;
ExtPreAlloc<HeapMemory> & mem = *(new ExtPreAlloc<HeapMemory>(tot_size,pmem));
mem.incRef();
for (size_t i = 0; i < send.size() ; i++)
{
send_buf.add((char *)send.get(i).getPointer());
sz_byte.get(i) = send.get(i).size() * sizeof(typename T::value_type);
//Packing
Pack_stat sts;
pack_unpack_cond<has_max_prop<T, has_value_type<T>::value>::value, T, S>::packing(mem, send.get(i), sts, send_buf);
}
// receive information
......
/*
* VCluster_semantic_unit_test.hpp
*
* Created on: Feb 8, 2016
* Author: i-bird
*/
#ifndef OPENFPM_VCLUSTER_SRC_VCLUSTER_SEMANTIC_UNIT_TESTS_HPP_
#define OPENFPM_VCLUSTER_SRC_VCLUSTER_SEMANTIC_UNIT_TESTS_HPP_
struct Aexample
{
size_t a;
float b;
double c;
};
BOOST_AUTO_TEST_SUITE( VCluster_semantic_test )
BOOST_AUTO_TEST_CASE (Vcluster_semantic_gather)
{
for (size_t i = 0 ; i < 100 ; i++)
{
Vcluster & vcl = create_vcluster();
if (vcl.getProcessingUnits() >= 32)
return;
openfpm::vector<size_t> v1;
v1.resize(vcl.getProcessUnitID());
for(size_t i = 0 ; i < vcl.getProcessUnitID() ; i++)
v1.get(i) = 5;
openfpm::vector<size_t> v2;
vcl.SGather(v1,v2,(i%vcl.getProcessingUnits()));
if (vcl.getProcessUnitID() == (i%vcl.getProcessingUnits()))
{
size_t n = vcl.getProcessingUnits();
BOOST_REQUIRE_EQUAL(v2.size(),n*(n-1)/2);
bool is_five = true;
for (size_t i = 0 ; i < v2.size() ; i++)
is_five &= (v2.get(i) == 5);
BOOST_REQUIRE_EQUAL(is_five,true);
}
}
}
BOOST_AUTO_TEST_CASE (Vcluster_semantic_struct_gather)
{
for (size_t i = 0 ; i < 100 ; i++)
{
Vcluster & vcl = create_vcluster();
if (vcl.getProcessingUnits() >= 32)
return;
openfpm::vector<Aexample> v1;
v1.resize(vcl.getProcessUnitID());
for(size_t i = 0 ; i < vcl.getProcessUnitID() ; i++)
{
v1.get(i).a = 5;
v1.get(i).b = 10.0;
v1.get(i).c = 11.0;
}
openfpm::vector<Aexample> v2;
vcl.SGather(v1,v2,(i%vcl.getProcessingUnits()));
if (vcl.getProcessUnitID() == (i%vcl.getProcessingUnits()))
{
size_t n = vcl.getProcessingUnits();
BOOST_REQUIRE_EQUAL(v2.size(),n*(n-1)/2);
bool is_correct = true;
for (size_t i = 0 ; i < v2.size() ; i++)
{
is_correct &= (v2.get(i).a == 5);
is_correct &= (v2.get(i).b == 10.0);
is_correct &= (v2.get(i).c == 11.0);
}
BOOST_REQUIRE_EQUAL(is_correct,true);
}
}
}
#define SSCATTER_MAX 7
BOOST_AUTO_TEST_CASE (Vcluster_semantic_scatter)
{
for (size_t i = 0 ; i < 100 ; i++)
{
Vcluster & vcl = create_vcluster();
if (vcl.getProcessingUnits() >= 32)
return;
size_t nc = vcl.getProcessingUnits() / SSCATTER_MAX;
size_t nr = vcl.getProcessingUnits() - nc * SSCATTER_MAX;
nr = ((nr-1) * nr) / 2;
size_t n_elements = nc * SSCATTER_MAX * (SSCATTER_MAX - 1) / 2 + nr;
openfpm::vector<size_t> v1;
v1.resize(n_elements);
for(size_t i = 0 ; i < n_elements ; i++)
v1.get(i) = 5;
openfpm::vector<size_t> v2;
openfpm::vector<size_t> prc;
openfpm::vector<size_t> sz;
// Scatter pattern
for (size_t i = 0 ; i < vcl.getProcessingUnits() ; i++)
{
sz.add(i % SSCATTER_MAX);
prc.add(i);
}
vcl.SScatter(v1,v2,prc,sz,(i%vcl.getProcessingUnits()));
BOOST_REQUIRE_EQUAL(v2.size(),vcl.getProcessUnitID() % SSCATTER_MAX);
bool is_five = true;
for (size_t i = 0 ; i < v2.size() ; i++)
is_five &= (v2.get(i) == 5);
BOOST_REQUIRE_EQUAL(is_five,true);
}
}
BOOST_AUTO_TEST_CASE (Vcluster_semantic_struct_scatter)
{
for (size_t i = 0 ; i < 100 ; i++)
{
Vcluster & vcl = create_vcluster();
if (vcl.getProcessingUnits() >= 32)
return;
size_t nc = vcl.getProcessingUnits() / SSCATTER_MAX;
size_t nr = vcl.getProcessingUnits() - nc * SSCATTER_MAX;
nr = ((nr-1) * nr) / 2;
size_t n_elements = nc * SSCATTER_MAX * (SSCATTER_MAX - 1) / 2 + nr;
openfpm::vector<size_t> v1;
v1.resize(n_elements);
for(size_t i = 0 ; i < n_elements ; i++)
v1.get(i) = 5;
openfpm::vector<size_t> v2;
openfpm::vector<size_t> prc;
openfpm::vector<size_t> sz;
// Scatter pattern
for (size_t i = 0 ; i < vcl.getProcessingUnits() ; i++)
{
sz.add(i % SSCATTER_MAX);
prc.add(i);
}
vcl.SScatter(v1,v2,prc,sz,(i%vcl.getProcessingUnits()));
if (vcl.getProcessUnitID() == (i%vcl.getProcessingUnits()))
{
BOOST_REQUIRE_EQUAL(v2.size(),vcl.getProcessUnitID() % SSCATTER_MAX);
bool is_five = true;
for (size_t i = 0 ; i < v2.size() ; i++)
is_five &= (v2.get(i) == 5);
BOOST_REQUIRE_EQUAL(is_five,true);
}
}
}
BOOST_AUTO_TEST_CASE (Vcluster_semantic_sendrecv)
{
for (size_t i = 0 ; i < 100 ; i++)
{
Vcluster & vcl = create_vcluster();
if (vcl.getProcessingUnits() >= 32)
return;
openfpm::vector<size_t> prc_recv2;
openfpm::vector<size_t> prc_recv3;
openfpm::vector<size_t> prc_send;
openfpm::vector<size_t> sz_recv2;
openfpm::vector<size_t> sz_recv3;
openfpm::vector<openfpm::vector<size_t>> v1;
openfpm::vector<size_t> v2;
openfpm::vector<openfpm::vector<size_t>> v3;
v1.resize(vcl.getProcessingUnits());
size_t nc = vcl.getProcessingUnits() / SSCATTER_MAX;
size_t nr = vcl.getProcessingUnits() - nc * SSCATTER_MAX;
nr = ((nr-1) * nr) / 2;
size_t n_ele = nc * SSCATTER_MAX * (SSCATTER_MAX - 1) / 2 + nr;
for(size_t i = 0 ; i < v1.size() ; i++)
{
for (size_t j = 0 ; j < i % SSCATTER_MAX ; j++)
v1.get(i).add(j);
prc_send.add((i + vcl.getProcessUnitID()) % vcl.getProcessingUnits());
}
vcl.SSendRecv(v1,v2,prc_send,prc_recv2,sz_recv2);
vcl.SSendRecv(v1,v3,prc_send,prc_recv3,sz_recv3);
BOOST_REQUIRE_EQUAL(v2.size(),n_ele);
size_t nc_check = (vcl.getProcessingUnits() - 1) / SSCATTER_MAX;
BOOST_REQUIRE_EQUAL(v3.size(),vcl.getProcessingUnits()-1-nc_check);
bool match = true;
size_t s = 0;
for (size_t i = 0 ; i < sz_recv2.size() ; i++)
{
for (size_t j = 0 ; j < sz_recv2.get(i) % SSCATTER_MAX ; j++)
{
match &= v2.get(s+j) == j;
}
s += sz_recv2.get(i) % SSCATTER_MAX;
}
BOOST_REQUIRE_EQUAL(match,true);
for (size_t i = 0 ; i < sz_recv3.size() ; i++)
{
for (size_t j = 0 ; j < sz_recv3.get(i) % SSCATTER_MAX ; j++)
{
match &= v3.get(i).get(j) == j;
}
}
BOOST_REQUIRE_EQUAL(match,true);
}
}
BOOST_AUTO_TEST_CASE (Vcluster_semantic_struct_sendrecv)
{
for (size_t i = 0 ; i < 100 ; i++)
{
Vcluster & vcl = create_vcluster();
if (vcl.getProcessingUnits() >= 32)
return;
openfpm::vector<size_t> prc_recv2;
openfpm::vector<size_t> prc_recv3;
openfpm::vector<size_t> prc_send;
openfpm::vector<size_t> sz_recv2;
openfpm::vector<size_t> sz_recv3;
openfpm::vector<openfpm::vector<Box<3,size_t>>> v1;
openfpm::vector<Box<3,size_t>> v2;
openfpm::vector<openfpm::vector<Box<3,size_t>>> v3;
v1.resize(vcl.getProcessingUnits());