/* * VCluster_meta_function.hpp * * Created on: Dec 8, 2016 * Author: i-bird */ #ifndef OPENFPM_VCLUSTER_SRC_VCLUSTER_VCLUSTER_META_FUNCTION_HPP_ #define OPENFPM_VCLUSTER_SRC_VCLUSTER_VCLUSTER_META_FUNCTION_HPP_ #include "memory/BHeapMemory.hpp" #include "Packer_Unpacker/has_max_prop.hpp" template struct unpack_selector_with_prp { template class layout_base, int ... prp> static void call_unpack(S & recv, openfpm::vector & recv_buf, openfpm::vector * sz, openfpm::vector * sz_byte, op & op_param) { if (sz_byte != NULL) sz_byte->resize(recv_buf.size()); for (size_t i = 0 ; i < recv_buf.size() ; i++) { T unp; ExtPreAlloc & mem = *(new ExtPreAlloc(recv_buf.get(i).size(),recv_buf.get(i))); mem.incRef(); Unpack_stat ps; Unpacker::template unpack<>(mem, unp, ps); size_t recv_size_old = recv.size(); // Merge the information op_param.template execute(recv,unp,i); size_t recv_size_new = recv.size(); if (sz_byte != NULL) sz_byte->get(i) = recv_buf.get(i).size(); if (sz != NULL) sz->get(i) = recv_size_new - recv_size_old; mem.decRef(); delete &mem; } } }; // template struct unpack_selector_with_prp { template class layout_base, unsigned int ... prp> static void call_unpack(S & recv, openfpm::vector & recv_buf, openfpm::vector * sz, openfpm::vector * sz_byte, op & op_param) { if (sz_byte != NULL) sz_byte->resize(recv_buf.size()); for (size_t i = 0 ; i < recv_buf.size() ; i++) { // 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::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(); op_param.template execute(recv,v2,i); size_t recv_size_new = recv.size(); if (sz_byte != NULL) sz_byte->get(i) = recv_buf.get(i).size(); if (sz != NULL) sz->get(i) = recv_size_new - recv_size_old; } } }; template struct call_serialize_variadic {}; template struct call_serialize_variadic> { template inline static void call_pr(T & send, size_t & tot_size) { Packer::template packRequest(send,tot_size); } template inline static void call_pack(ExtPreAlloc & mem, T & send, Pack_stat & sts) { Packer::template pack(mem,send,sts); } template class layout_base> inline static void call_unpack(S & recv, openfpm::vector & recv_buf, openfpm::vector * sz, openfpm::vector * sz_byte, op & op_param) { const bool result = has_pack_gen::value == false && is_vector::value == true; unpack_selector_with_prp::template call_unpack(recv, recv_buf, sz, sz_byte, op_param); } }; //! There is max_prop inside template class layout_base, unsigned int ... prp> struct pack_unpack_cond_with_prp { static void packingRequest(T & send, size_t & tot_size, openfpm::vector & sz) { typedef typename ::generate_indexes::value>::number, MetaFuncOrd>::result ind_prop_to_pack; if (has_pack_gen::value == false && is_vector::value == true) //if (has_pack::type::value == false && has_pack_agg::result::value == false && is_vector::value == true) { sz.add(send.size()*sizeof(typename T::value_type)); } else { call_serialize_variadic::call_pr(send,tot_size); sz.add(tot_size); } } static void packing(ExtPreAlloc & mem, T & send, Pack_stat & sts, openfpm::vector & send_buf) { typedef typename ::generate_indexes::value>::number, MetaFuncOrd>::result ind_prop_to_pack; if (has_pack_gen::value == false && is_vector::value == true) //if (has_pack::type::value == false && has_pack_agg::result::value == false && is_vector::value == true) { //std::cout << demangle(typeid(T).name()) << std::endl; send_buf.add(send.getPointer()); } else { send_buf.add(mem.getPointerEnd()); call_serialize_variadic::call_pack(mem,send,sts); } } static void unpacking(S & recv, openfpm::vector & recv_buf, openfpm::vector * sz, openfpm::vector * sz_byte, op & op_param) { typedef index_tuple ind_prop_to_pack; call_serialize_variadic::template call_unpack(recv, recv_buf, sz, sz_byte, op_param); } }; ///////////////////////////// //! Helper class to add data without serialization template struct op_ssend_recv_add_sr { //! Add data template class layout_base, int ... prp> static void execute(D & recv,S & v2, size_t i) { // Merge the information recv.template add_prp::value, layout_base, prp...>(v2); } }; //! Helper class to add data with serialization template<> struct op_ssend_recv_add_sr { //! Add data template class layout_base, int ... prp> static void execute(D & recv,S & v2, size_t i) { // Merge the information recv.template add_prp::value, layout_base, prp...>(v2); } }; //! Helper class to add data template struct op_ssend_recv_add { //! Add data template class layout_base, int ... prp> static void execute(D & recv,S & v2, size_t i) { // Merge the information op_ssend_recv_add_sr::template execute(recv,v2,i); } }; //! Helper class to merge data without serialization template class op> struct op_ssend_recv_merge_impl { //! Merge the template class layout_base, int ... prp> inline static void execute(D & recv,S & v2,size_t i,openfpm::vector>> & opart) { // Merge the information recv.template merge_prp_v(v2,opart.get(i)); } }; //! Helper class to merge data with serialization template class op> struct op_ssend_recv_merge_impl { //! merge the data template class layout_base, int ... prp> inline static void execute(D & recv,S & v2,size_t i,openfpm::vector>> & opart) { // Merge the information recv.template merge_prp_v(v2,opart.get(i)); } }; //! Helper class to merge data template class op> struct op_ssend_recv_merge { //! For each processor contain the list of the particles with which I must merge the information openfpm::vector>> & opart; //! constructor op_ssend_recv_merge(openfpm::vector>> & opart) :opart(opart) {} //! execute the merge template class layout_base, int ... prp> void execute(D & recv,S & v2,size_t i) { op_ssend_recv_merge_impl::template execute(recv,v2,i,opart); } }; //! Helper class to merge data without serialization template struct op_ssend_gg_recv_merge_impl { //! Merge the template class layout_base, int ... prp> inline static void execute(D & recv,S & v2,size_t i,size_t & start) { // Merge the information recv.template merge_prp_v(v2,start); start += v2.size(); } }; //! Helper class to merge data with serialization template<> struct op_ssend_gg_recv_merge_impl { //! merge the data template class layout_base, int ... prp> inline static void execute(D & recv,S & v2,size_t i,size_t & start) { // Merge the information recv.template merge_prp_v(v2,start); // from start += v2.size(); } }; //! Helper class to merge data struct op_ssend_gg_recv_merge { //! starting marker size_t start; //! constructor op_ssend_gg_recv_merge(size_t start) :start(start) {} //! execute the merge template class layout_base, int ... prp> void execute(D & recv,S & v2,size_t i) { op_ssend_gg_recv_merge_impl::template execute(recv,v2,i,start); } }; ////////////////////////////////////////////////// #endif /* OPENFPM_VCLUSTER_SRC_VCLUSTER_VCLUSTER_META_FUNCTION_HPP_ */