8 #ifndef SRC_GRID_GRID_DIST_ID_COMM_HPP_
9 #define SRC_GRID_GRID_DIST_ID_COMM_HPP_
11 #include "Vector/vector_dist_ofb.hpp"
12 #include "Grid/copy_grid_fast.hpp"
18 template<
bool result,
typename T,
typename device_gr
id,
typename Memory>
31 std::cerr << __FILE__ <<
":" << __LINE__ <<
" Error: complex properties on grids are not supported yet" << std::endl;
39 template<
typename T,
typename device_gr
id,
typename Memory>
55 size_t sz[device_grid::dims];
57 for (
size_t i = 0 ; i < device_grid::dims ; i++)
62 for (
size_t i = 0 ; i < device_grid::dims ; i++)
70 std::cerr << __FILE__ <<
":" << __LINE__ <<
" Error: overflow in the receiving buffer for ghost_put" << std::endl;
87 auto it_src = gs.getIterator();
92 decltype(gs.get_o(it_src.get())),
93 decltype(gd.get_o(sub2.
get())),
95 (gs.get_o(it_src.get()),
96 gd.get_o(sub2.
get()));
111 template<
typename device_gr
id,
typename Memory,
typename T>
119 template<
typename device_grid,
typename Memory ,
int ... prp>
144 template<
template<
typename,
typename>
class op,
typename T,
typename device_grid,
typename Memory>
176 template<
unsigned int dim,
typename St,
typename T,
typename Decomposition = CartDecomposition<dim,St>,
typename Memory=HeapMemory ,
typename device_gr
id=gr
id_cpu<dim,T> >
219 std::unordered_map<size_t,size_t> & g_id_to_external_ghost_box)
225 for (
size_t i = 0 ; i < loc_ig_box.size() ; i++)
228 for (
size_t j = 0 ; j < loc_ig_box.get(i).bid.size() ; j++)
232 bx_src -= gdb_ext.get(i).origin;
235 size_t sub_id_dst = loc_ig_box.get(i).bid.get(j).sub;
238 size_t k = loc_ig_box.get(i).bid.get(j).k;
243 bx_dst -= gdb_ext.get(sub_id_dst).origin;
250 const auto & gs = loc_grid.get(i);
251 auto & gd = loc_grid.get(sub_id_dst);
255 if (loc_eg_box.get(sub_id_dst).bid.get(k).sub != i)
256 {std::cerr <<
"Error " << __FILE__ <<
":" << __LINE__ <<
" source and destination are not correctly linked" <<
"\n";}
259 {std::cerr <<
"Error " << __FILE__ <<
":" << __LINE__ <<
" source and destination does not match in size" <<
"\n";}
261 auto bxs = gs.getGrid().getBoxKey();
262 auto bxd = gd.getGrid().getBoxKey();
264 if (bxs.isContained(bx_src) ==
false)
265 {std::cerr <<
"Error " << __FILE__ <<
":" << __LINE__ <<
" the source box is out of bound of the local grid" <<
"\n";}
267 if (bxd.isContained(bx_dst) ==
false)
268 {std::cerr <<
"Error " << __FILE__ <<
":" << __LINE__ <<
" the destination box is out of bound of the local grid" <<
"\n";}
272 typedef typename std::remove_reference<decltype(gd)>::type grid_cp;
273 typedef typename std::remove_reference<decltype(loc_grid.get(i).getGrid())>::type grid_info_cp;
278 grid_info_cp>::copy(loc_grid.get(i).getGrid(),
279 loc_grid.get(sub_id_dst).getGrid(),
302 openfpm::vector<std::unordered_map<size_t,size_t>> & g_id_to_external_ghost_box)
305 for (
size_t i = 0 ; i < loc_eg_box.size() ; i++)
308 for (
size_t j = 0 ; j < loc_eg_box.get(i).bid.size() ; j++)
310 if (loc_eg_box.get(i).bid.get(j).initialized ==
false)
315 bx_src -= gdb_ext.get(i).origin;
318 size_t sub_id_dst = loc_eg_box.get(i).bid.get(j).sub;
321 size_t k = loc_eg_box.get(i).bid.get(j).k;
326 bx_dst -= gdb_ext.get(sub_id_dst).origin;
338 if (loc_ig_box.get(sub_id_dst).bid.get(k).sub != i)
339 std::cerr <<
"Error " << __FILE__ <<
":" << __LINE__ <<
" source and destination are not correctly linked" <<
"\n";
341 if (sub_src.getVolume() != sub_dst.getVolume())
342 std::cerr <<
"Error " << __FILE__ <<
":" << __LINE__ <<
" source and destination does not match in size" <<
"\n";
346 const auto & gs = loc_grid.get(i);
347 auto & gd = loc_grid.get(sub_id_dst);
349 while (sub_src.isNext())
352 object_s_di_op<op,decltype(gs.get_o(sub_src.get())),decltype(gd.get_o(sub_dst.get())),OBJ_ENCAP,prp...>(gs.get_o(sub_src.get()),gd.get_o(sub_dst.get()));
377 typedef object<
typename object_creator<
typename T::type,prp...>::type> prp_object;
380 for (
size_t i = 0 ; i < ig_box.size() ; i++ )
383 for (
size_t j = 0 ; j < ig_box.get(i).bid.size() ; j++)
386 size_t sub_id = ig_box.get(i).bid.get(j).sub;
390 if (g_ig_box.
isValid() ==
false)
393 g_ig_box -= gdb_ext.get(sub_id).origin.template convertPoint<size_t>();
417 for (
size_t i = 0 ; i < ig_box.size() ; i++ )
421 void * pointer = (*prAlloc_prp)->getPointerEnd();
424 for (
size_t j = 0 ; j < ig_box.get(i).bid.size() ; j++)
427 if (ig_box.get(i).bid.get(j).box.isValid() ==
false)
431 size_t sub_id = ig_box.get(i).bid.get(j).sub;
434 g_ig_box -= gdb_ext.get(sub_id).origin.template convertPoint<size_t>();
436 size_t g_id = ig_box.get(i).bid.get(j).g_id;
448 void * pointer2 = (*prAlloc_prp)->getPointerEnd();
450 v_cl.
send(ig_box.get(i).prc,0,pointer,(
char *)pointer2 - (
char *)pointer);
454 std::vector<size_t> prp_recv;
457 for (
size_t i = 0 ; i < eg_box.size() ; i++ )
459 prp_recv.push_back(0);
462 for (
size_t j = 0 ; j < eg_box.get(i).bid.size() ; j++)
466 prp_recv[prp_recv.size()-1] += g_eg_box.
getVolumeKey() *
sizeof(prp_object) +
sizeof(
size_t);
480 for (
size_t i = 0 ; i < eg_box.size() ; i++ )
482 (*prRecv_prp)->allocate(prp_recv[i]);
483 v_cl.
recv(eg_box.get(i).prc,0,(*prRecv_prp)->getPointer(),prp_recv[i]);
496 std::unordered_map<size_t,size_t> & g_id_to_external_ghost_box)
501 for (
size_t i = 0 ; i < eg_box.size() ; i++ )
504 for (
size_t j = 0 ; j < eg_box.get(i).bid.size() ; j++)
513 auto key = g_id_to_external_ghost_box.find(g_id);
514 if (
key != g_id_to_external_ghost_box.end())
524 std::cerr <<
"Error: " << __FILE__ <<
":" << __LINE__ <<
" Critical, cannot unpack object, because received data cannot be interpreted\n";
531 size_t sub_id = eg_box.get(i).bid.get(l_id).sub;
558 for (
size_t a = 0; a < m_oGrid_recv.size(); a++)
560 for (
size_t k = 0; k < m_oGrid_recv.get(a).size(); k++)
562 device_grid g = m_oGrid_recv.get(a).template get<0>(k);
567 auto it = g.getIterator();
578 for (
size_t n = 0; n < dim; n++)
579 {p.
get(n) = g.getGrid().getBox().getHigh(n);}
582 for (
size_t n = 0; n < dim; n++)
585 for (
size_t j = 0; j < gdb_ext.size(); j++)
589 sub += gdb_ext.get(j).origin;
599 auto it = loc_grid.get(j).getSubIterator(start,stop);
605 std::string str =
key.to_string();
608 loc_grid.get(j).get_o(
key) = g.get_o(key2);
641 lbl_b.resize(v_cl.getProcessingUnits());
647 for (
size_t i = 0; i < gdb_ext_old.size(); i++)
651 sub_dom += gdb_ext_old.get(i).origin;
653 for (
size_t j = 0; j < gdb_ext_global.size(); j++)
662 sub_dom_new += gdb_ext_global.get(j).origin;
664 bool intersect =
false;
667 intersect = sub_dom.
Intersect(sub_dom_new, inte_box);
669 if (intersect ==
true)
672 auto inte_box_cont = cd_sm.convertCellUnitsIntoDomainSpace(inte_box);
676 for (
size_t n = 0; n < dim; n++)
677 p.
get(n) = (inte_box_cont.getHigh(n) + inte_box_cont.getLow(n))/2;
679 p_id = dec.processorID(p);
683 auto inte_box_local = inte_box;
685 inte_box_local -= gdb_ext_old.get(i).origin;
688 device_grid & gr = loc_grid_old.get(i);
692 for (
size_t l = 0; l < dim; l++)
694 sz[l] = inte_box_local.getHigh(l) - inte_box_local.getLow(l) + 1;
699 device_grid gr_send(sz);
707 for (
size_t n = 0; n < dim; n++)
708 p1.
get(n) = gr_send.getGrid().getBox().getLow(n);
711 for (
size_t n = 0; n < dim; n++)
712 p2.
get(n) = gr_send.getGrid().getBox().getHigh(n);
717 auto it = gr.getSubIterator(start,stop);
724 std::string str =
key.to_string();
726 gr_send.get_o(key2) = gr.get_o(
key);
733 aggr.template get<0>() = gr_send;
734 aggr.template get<1>() = inte_box;
737 lbl_b.get(p_id).add(aggr);
768 labelIntersectionGridsProcessor(dec,cd_sm,loc_grid_old,gdb_ext,gdb_ext_old,gdb_ext_global,m_oGrid,prc_sz);
772 p_map_req.resize(v_cl.getProcessingUnits());
779 for (
size_t i = 0; i < v_cl.getProcessingUnits(); i++)
781 if (m_oGrid.get(i).size() != 0)
783 p_map_req.get(i) = prc_r.
size();
785 prc_sz_r.add(m_oGrid.get(i).size());
789 decltype(m_oGrid) m_oGrid_new;
790 for (
size_t i = 0; i < v_cl.getProcessingUnits(); i++)
792 if (m_oGrid.get(i).size() != 0)
793 m_oGrid_new.add(m_oGrid.get(i));
800 v_cl.SSendRecv(m_oGrid_new,m_oGrid_recv,prc_r,prc_recv_map,recv_sz_map);
803 grids_reconstruct(m_oGrid_recv,loc_grid,gdb_ext,cd_sm);
823 std::unordered_map<size_t,size_t> & g_id_to_external_ghost_box)
830 if (v_cl.getProcessingUnits() != 1)
831 {send_and_receive_ghost<prp...>(&prAlloc_prp,&prRecv_prp, ig_box,eg_box,gdb_ext,loc_grid,req);}
836 ghost_get_local<prp...>(loc_ig_box,loc_eg_box,gdb_ext,loc_grid,g_id_to_external_ghost_box);
841 if (v_cl.getProcessingUnits() != 1)
842 {process_received<prp...>(prRecv_prp,eg_box,loc_grid,g_id_to_external_ghost_box);}
859 template<
template<
typename,
typename>
class op,
int... prp>
866 openfpm::vector<std::unordered_map<size_t,size_t>> & g_id_to_internal_ghost_box)
869 typedef object<
typename object_creator<
typename T::type,prp...>::type> prp_object;
874 for (
size_t i = 0 ; i < eg_box.size() ; i++ )
877 for (
size_t j = 0 ; j < eg_box.get(i).bid.size() ; j++)
880 size_t sub_id = eg_box.get(i).bid.get(j).sub;
884 if (g_eg_box.
isValid() ==
false)
887 g_eg_box -= gdb_ext.get(sub_id).origin.template convertPoint<size_t>();
900 g_send_prp_mem.resize(req);
911 for (
size_t i = 0 ; i < eg_box.size() ; i++ )
918 for (
size_t j = 0 ; j < eg_box.get(i).bid.size() ; j++)
921 if (eg_box.get(i).bid.get(j).g_e_box.isValid() ==
false)
925 size_t sub_id = eg_box.get(i).bid.get(j).sub;
928 g_eg_box -= gdb_ext.get(sub_id).origin.template convertPoint<size_t>();
930 size_t g_id = eg_box.get(i).bid.get(j).g_id;
944 v_cl.send(ig_box.get(i).prc,0,pointer,(
char *)pointer2 - (
char *)pointer);
948 std::vector<size_t> prp_recv;
951 for (
size_t i = 0 ; i < ig_box.size() ; i++ )
953 prp_recv.push_back(0);
956 for (
size_t j = 0 ; j < ig_box.get(i).bid.size() ; j++)
960 prp_recv[prp_recv.size()-1] += g_ig_box.
getVolumeKey() *
sizeof(prp_object) +
sizeof(
size_t);
967 g_recv_prp_mem.resize(tot_recv);
974 for (
size_t i = 0 ; i < ig_box.size() ; i++ )
977 v_cl.recv(ig_box.get(i).prc,0,prRecv_prp.
getPointer(),prp_recv[i]);
983 ghost_put_local<op,prp...>(loc_ig_box,loc_eg_box,gdb_ext,loc_grid,g_id_to_internal_ghost_box);
991 for (
size_t i = 0 ; i < ig_box.size() ; i++ )
994 for (
size_t j = 0 ; j < ig_box.get(i).bid.size() ; j++)
1003 auto key = g_id_to_internal_ghost_box.get(i).find(g_id);
1004 if (
key != g_id_to_internal_ghost_box.get(i).end())
1014 std::cerr <<
"Error: " << __FILE__ <<
":" << __LINE__ <<
" Critical, cannot unpack object, because received data cannot be interpreted\n";
1021 size_t sub_id = ig_box.get(i).bid.get(l_id).sub;
1022 box -= gdb_ext.get(sub_id).origin.template convertPoint<size_t>();
1037 :v_cl(create_vcluster())
size_t getOffset()
Return the actual counter.
This class represent an N-dimensional box.
void ghost_get_local(const openfpm::vector< i_lbox_grid< dim >> &loc_ig_box, const openfpm::vector< e_lbox_grid< dim >> &loc_eg_box, const openfpm::vector< GBoxes< device_grid::dims >> &gdb_ext, openfpm::vector< device_grid > &loc_grid, std::unordered_map< size_t, size_t > &g_id_to_external_ghost_box)
Sync the local ghost part.
void ghost_put_(const openfpm::vector< ip_box_grid< dim >> &ig_box, const openfpm::vector< ep_box_grid< dim >> &eg_box, const openfpm::vector< i_lbox_grid< dim >> &loc_ig_box, const openfpm::vector< e_lbox_grid< dim >> &loc_eg_box, const openfpm::vector< GBoxes< device_grid::dims >> &gdb_ext, openfpm::vector< device_grid > &loc_grid, openfpm::vector< std::unordered_map< size_t, size_t >> &g_id_to_internal_ghost_box)
It merge the information in the ghost with the real information.
openfpm::vector< size_t > recv_sz_map
Stores the size of the elements added for each processor that communicate with us (local processor) ...
T getLow(int i) const
get the i-coordinate of the low bound interval of the box
This class is an helper for the communication of grid_dist_id.
bool isValid() const
Check if the Box is a valid box P2 >= P1.
grid_key_dx is the key to access any element in the grid
Memory g_send_prp_mem
Memory for the ghost sending buffer.
bool isInside(const Point< dim, T > &p) const
Check if the point is inside the box.
Memory g_recv_prp_mem
Memory for the ghost sending buffer.
grid_key_dx< dim > getKP2() const
Get the point p12 as grid_key_dx.
const grid_key_dx< dim > & getStop() const
Stop point.
virtual void * getPointer()
Return the pointer of the last allocation.
T getHigh(int i) const
get the high interval of the box
Per-processor Internal ghost box.
std::string to_string()
convert the information into a string
void labelIntersectionGridsProcessor(Decomposition &dec, CellDecomposer_sm< dim, St, shift< dim, St >> &cd_sm, openfpm::vector< device_grid > &loc_grid_old, openfpm::vector< GBoxes< device_grid::dims >> &gdb_ext, openfpm::vector< GBoxes< device_grid::dims >> &gdb_ext_old, openfpm::vector< GBoxes< device_grid::dims >> &gdb_ext_global, openfpm::vector< openfpm::vector< aggregate< device_grid, SpaceBox< dim, long int >>>> &lbl_b, openfpm::vector< size_t > &prc_sz)
Label intersection grids for mappings.
This class implement the point shape in an N-dimensional space.
void grids_reconstruct(openfpm::vector< openfpm::vector< aggregate< device_grid, SpaceBox< dim, long int >>>> &m_oGrid_recv, openfpm::vector< device_grid > &loc_grid, openfpm::vector< GBoxes< device_grid::dims >> &gdb_ext, CellDecomposer_sm< dim, St, shift< dim, St >> &cd_sm)
Reconstruct the local grids.
This is a way to quickly copy a grid into another grid.
grid_key_dx< dim > getKP1() const
Get the point p1 as grid_key_dx.
static void call_unpack(ExtPreAlloc< Memory > &recv_buf, grid_key_dx_iterator_sub< device_grid::dims > &sub2, device_grid &gd, Unpack_stat &ps)
Unpack.
bool send(size_t proc, size_t tag, const void *mem, size_t sz)
Send data to a processor.
virtual bool allocate(size_t sz)
Allocate a chunk of memory.
Implementation of VCluster class.
This structure store the Box that define the domain inside the Ghost + domain box.
This class define the domain decomposition interface.
bool Intersect(const Box< dim, T > &b, Box< dim, T > &b_out) const
Intersect.
void ghost_get_(const openfpm::vector< ip_box_grid< dim >> &ig_box, const openfpm::vector< ep_box_grid< dim >> &eg_box, const openfpm::vector< i_lbox_grid< dim >> &loc_ig_box, const openfpm::vector< e_lbox_grid< dim >> &loc_eg_box, const openfpm::vector< GBoxes< device_grid::dims >> &gdb_ext, openfpm::vector< device_grid > &loc_grid, std::unordered_map< size_t, size_t > &g_id_to_external_ghost_box)
It fill the ghost part of the grids.
static void unpacking(ExtPreAlloc< Memory > &recv_buf, grid_key_dx_iterator_sub< device_grid::dims > &sub2, device_grid &dg, Unpack_stat &ps)
Unpack.
static size_t packRequest(const T &obj, size_t &req)
Error, no implementation.
It copy the properties from one object to another applying an operation.
static void call_unpack(ExtPreAlloc< Memory > &recv_buf, grid_key_dx_iterator_sub< device_grid::dims > &sub2, device_grid &gd, Unpack_stat &ps)
Error i do not know how to unpack.
void send_and_receive_ghost(ExtPreAlloc< Memory > **prAlloc_prp, ExtPreAlloc< Memory > **prRecv_prp, const openfpm::vector< ip_box_grid< dim >> &ig_box, const openfpm::vector< ep_box_grid< dim >> &eg_box, const openfpm::vector< GBoxes< device_grid::dims >> &gdb_ext, openfpm::vector< device_grid > &loc_grid, size_t &req)
this function create send and receive asynchronously to receive ghosts part
void zero()
Set to zero the key.
bool recv(size_t proc, size_t tag, void *v, size_t sz)
Recv data from a processor.
void addOffset(size_t off)
Increment the offset pointer by off.
virtual void incRef()
Increment the reference counter.
const T & get(size_t i) const
Get coordinate.
These set of classes generate an array definition at compile-time.
grid_key_dx< dim > get() const
Return the actual grid key iterator.
This class is a trick to indicate the compiler a specific specialization pattern. ...
void * getPointerBase()
The the base pointer of the preallocate memory.
static void unpack(ExtPreAlloc< Mem >, T &obj)
Error, no implementation.
openfpm::vector< openfpm::vector< aggregate< device_grid, SpaceBox< dim, long int > > > > m_oGrid
openfpm::vector< size_t > prc_recv_map
Stores the list of processors that communicate with us (local processor)
openfpm::vector< size_t > p_map_req
Maps the processor id with the communication request into map procedure.
Per-processor external ghost box.
It return true if the object T require complex serialization.
void map_(Decomposition &dec, CellDecomposer_sm< dim, St, shift< dim, St >> &cd_sm, openfpm::vector< device_grid > &loc_grid, openfpm::vector< device_grid > &loc_grid_old, openfpm::vector< GBoxes< device_grid::dims >> &gdb_ext, openfpm::vector< GBoxes< device_grid::dims >> &gdb_ext_old, openfpm::vector< GBoxes< device_grid::dims >> &gdb_ext_global)
Moves all the grids that does not belong to the local processor to the respective processor...
Per-processor external ghost box.
Declaration grid_key_dx_iterator_sub.
It create a boost::fusion vector with the selected properties.
static void call_unpack(ExtPreAlloc< Memory > &recv_buf, grid_key_dx_iterator_sub< device_grid::dims > &sub2, device_grid &dg, Unpack_stat &ps)
Unpack.
void process_received(ExtPreAlloc< Memory > *prRecv_prp, const openfpm::vector< ep_box_grid< dim >> &eg_box, openfpm::vector< device_grid > &loc_grid, std::unordered_map< size_t, size_t > &g_id_to_external_ghost_box)
Process the received data.
aggregate of properties, from a list of object if create a struct that follow the OPENFPM native stru...
T getVolumeKey() const
Get the volume spanned by the Box P1 and P2 interpreted as grid key.
bool isNext()
Check if there is the next element.
virtual size_t size() const
Get the size of the LAST allocated memory.
static void pack(ExtPreAlloc< Mem >, const T &obj)
Error, no implementation.
const grid_key_dx< dim > & getStart() const
Starting point.
static size_t calculateMem(std::vector< size_t > &mm)
Calculate the total memory required to pack the message.
void * getPointerEnd()
Return the end pointer of the previous allocated memory.
grid_dist_id_comm()
Constructor.
void ghost_put_local(const openfpm::vector< i_lbox_grid< dim >> &loc_ig_box, const openfpm::vector< e_lbox_grid< dim >> &loc_eg_box, const openfpm::vector< GBoxes< device_grid::dims >> &gdb_ext, openfpm::vector< device_grid > &loc_grid, openfpm::vector< std::unordered_map< size_t, size_t >> &g_id_to_external_ghost_box)
Sync the local ghost part.
This class give memory from a preallocated memory, memory destruction is not performed.