AFEPack
MPI_HGeometry_archive.h
浏览该文件的文档。
00001 
00011 #ifndef __MPI_HGeometry_archive_h__
00012 #define __MPI_HGeometry_archive_h__
00013 
00014 #include <sstream>
00015 
00016 #include <boost/static_assert.hpp>
00017 #include <boost/type_traits/is_array.hpp>
00018 
00019 #define BOOST_ARCHIVE_SOURCE
00020 #include <boost/archive/binary_oarchive.hpp>
00021 #include <boost/archive/binary_iarchive.hpp>
00022 #include <boost/serialization/binary_object.hpp>
00023 
00024 #if BOOST_VERSION >= 103801
00025 #include <boost/serialization/pfto.hpp>
00026 #include <boost/archive/detail/register_archive.hpp>
00027 #include <boost/archive/impl/archive_serializer_map.ipp>
00028 #else
00029 #include <boost/pfto.hpp>
00030 #include <boost/archive/impl/archive_pointer_oserializer.ipp>
00031 #include <boost/archive/impl/archive_pointer_iserializer.ipp>
00032 #endif 
00033 
00034 #include <boost/archive/impl/basic_binary_oprimitive.ipp>
00035 #include <boost/archive/impl/basic_binary_iprimitive.ipp>
00036 #include <boost/archive/impl/basic_binary_oarchive.ipp>
00037 #include <boost/archive/impl/basic_binary_iarchive.ipp>
00038 
00039 #include <AFEPack/Serialization.h>
00040 
00041 namespace boost {
00042   template <class T>
00043     struct _is_HGeometry_type {
00044       enum { value = false };
00045     };
00046   template <int DIM, int DOW>
00047     struct _is_HGeometry_type<HGeometry<DIM,DOW> > {
00048     enum { value = true };
00049   };
00050   template <int DIM, int DOW>
00051     struct _is_HGeometry_type<HGeometry<DIM,DOW> *> {
00052     enum { value = true };
00053   };
00054   template <int DIM, int DOW>
00055     struct _is_HGeometry_type<const HGeometry<DIM,DOW> > {
00056     enum { value = true };
00057   };
00058   template <int DIM, int DOW>
00059     struct _is_HGeometry_type<HGeometry<DIM,DOW>* const> {
00060     enum { value = true };
00061   };
00062 
00063   namespace archive {
00064 
00065 #if BOOST_VERSION>=103400
00066     template <class LB, 
00067       class Elem = std::ostream::char_type, 
00068       class Tr = std::ostream::traits_type>
00069       class HGeometry_oarchive : 
00070     public binary_oarchive_impl<HGeometry_oarchive<LB,Elem,Tr>, Elem, Tr> {
00071       typedef HGeometry_oarchive<LB,Elem,Tr> derived_t;
00072       typedef binary_oarchive_impl<derived_t,Elem,Tr> base_t;
00073 #else
00074     template <class LB>
00075       class HGeometry_oarchive : 
00076     public binary_oarchive_impl<HGeometry_oarchive<LB> > {
00077       typedef HGeometry_oarchive<LB> derived_t;
00078       typedef binary_oarchive_impl<derived_t> base_t;
00079 #endif
00080 #ifndef BOOST_NO_MEMBER_TEMPLATE_FRIENDS
00081     public:
00082 #else
00083       friend class boost::archive::detail::interface_oarchive<derived_t>;
00084       friend class basic_binary_oarchive<derived_t>;
00085       friend class basic_binary_oprimitive<derived_t, std::ostream>;
00086       friend class boost::archive::save_access;
00087 #endif
00088       template <class T>
00089         void save_override(T& t, int) {
00090         base_t::save_override(t, 0);
00091         BOOST_STATIC_ASSERT(! (boost::_is_HGeometry_type<T>::value) );
00092       }
00093       template <int DIM, int DOW>
00094         void save_override(const HGeometry<DIM,DOW>& geo, int) {
00095         base_t::save_override(geo.buffer, 0);
00096         base_t::save_override(geo.index, 0);
00097         base_t::save_override(geo.bmark, 0);
00098         this->save_override(geo.parent, 0);
00099         for (u_int i = 0;i < geo.n_vertex;++ i) {
00100           this->save_override(geo.vertex[i], 0);
00101         }
00102         for (u_int i = 0;i < geo.n_boundary;++ i) {
00103           this->save_override(geo.boundary[i], 0);
00104         }
00105         for (u_int i = 0;i < geo.n_child;++ i) {
00106           this->save_override(geo.child[i], 0);
00107         }
00108       }
00109       template <int DOW>
00110         void save_override(const HGeometry<0,DOW>& geo, int) {
00111         base_t::save_override(geo.buffer, 0);
00112         base_t::save_override(boost::serialization::base_object<Point<DOW> >(geo), 0);
00113         base_t::save_override(geo.index, 0);
00114         base_t::save_override(geo.bmark, 0);
00115       }
00116       template <int DIM, int DOW>
00117         void save_override(HGeometry<DIM,DOW>* const& p_geo, int) {
00118         int type = 0;
00119         if (p_geo == NULL) { 
00120           type = 0;
00121           base_t::save_override(boost::serialization::make_binary_object(&type, sizeof(int)), 0);
00122         } else {
00123           std::map<int,int> * p_map = lb().get_rank_map(*p_geo);
00124           if (lb().is_save_on_this_rank(p_map, new_rank())) {
00125             unsigned long * global_idx = lb().get_global_idx(*p_geo);
00126             if (global_idx == NULL) { 
00127               type = (1<<0);
00128               base_t::save_override(boost::serialization::make_binary_object(&type, sizeof(int)), 0);
00129               base_t::save_override(p_geo, 0);
00130             } else { 
00131               type = (1<<1);
00132               base_t::save_override(boost::serialization::make_binary_object(&type, sizeof(int)), 0);
00133               base_t::save_override(p_geo, 0);
00134               base_t::save_override(boost::serialization::make_binary_object(global_idx, sizeof(unsigned long)), 0);
00135 
00136               int n_share = p_map->size() - 1;
00137               base_t::save_override(boost::serialization::make_binary_object(&n_share, sizeof(int)), 0);
00138               if (n_share > 0) {
00139                 typename std::map<int,int>::iterator
00140                   the_pair = p_map->begin(),
00141                   end_pair = p_map->end();
00142                 for (;the_pair != end_pair;++ the_pair) {
00143                   int new_rank = the_pair->first;
00144                   if (new_rank == this->new_rank()) continue;
00145                   base_t::save_override(boost::serialization::make_binary_object(&new_rank, sizeof(int)), 0);
00146                 }
00147               }
00148             }
00149           } else { 
00150             type = (1<<2);
00151             base_t::save_override(boost::serialization::make_binary_object(&type, sizeof(int)), 0);
00152             unsigned long * global_idx = lb().get_global_idx(*p_geo);
00153             assert (global_idx != NULL);
00154             base_t::save_override(boost::serialization::make_binary_object(global_idx, sizeof(unsigned long)), 0);
00155           }
00156         }
00157       }
00158     public:
00159     HGeometry_oarchive(LB& lb, int new_rank, std::ostream& os, unsigned flags = 0) : 
00160       _lb(&lb), _new_rank(new_rank), base_t(os, flags) {}
00161     public:
00162       LB& lb() const { return *_lb; }
00163       int new_rank() const { return _new_rank; }
00164     private:
00165       LB * _lb;
00166       int _new_rank;
00167     };
00168 
00169 
00170 #if BOOST_VERSION>=103400
00171     template <class LB,
00172       class Elem = std::istream::char_type, 
00173       class Tr = std::istream::traits_type>
00174       class HGeometry_iarchive :
00175     public binary_iarchive_impl<HGeometry_iarchive<LB,Elem,Tr>,Elem,Tr> {
00176       typedef HGeometry_iarchive<LB,Elem,Tr> derived_t;
00177       typedef binary_iarchive_impl<derived_t,Elem,Tr> base_t;
00178 #else
00179     template <class LB>
00180       class HGeometry_iarchive :
00181     public binary_iarchive_impl<HGeometry_iarchive<LB> > {
00182       typedef HGeometry_iarchive<LB> derived_t;
00183       typedef binary_iarchive_impl<derived_t> base_t;
00184 #endif
00185 #ifndef BOOST_NO_MEMBER_TEMPLATE_FRIENDS
00186     public:
00187 #else
00188       friend class boost::archive::detail::interface_iarchive<derived_t>;
00189       friend class basic_binary_iarchive<derived_t>;
00190       friend class basic_binary_iprimitive<derived_t, std::istream>;
00191       friend class boost::archive::load_access;
00192 #endif
00193       template<class T>
00194         void load_override(T& t, int){
00195         base_t::load_override(t, 0);
00196         BOOST_STATIC_ASSERT(! (boost::_is_HGeometry_type<T>::value) );
00197       }
00198       template<int DIM, int DOW>
00199         void load_override(HGeometry<DIM,DOW> &geo, int){
00200         base_t::load_override(geo.buffer, 0);
00201         base_t::load_override(geo.index, 0);
00202         base_t::load_override(geo.bmark, 0);
00203         this->load_override(geo.parent, 0);
00204         for (u_int i = 0;i < geo.n_vertex;++ i) {
00205           this->load_override(geo.vertex[i], 0);
00206         }
00207         for (u_int i = 0;i < geo.n_boundary;++ i) {
00208           this->load_override(geo.boundary[i], 0);
00209         }
00210         for (u_int i = 0;i < geo.n_child;++ i) {
00211           this->load_override(geo.child[i], 0);
00212         }
00213       }
00214       template <int DOW>
00215         void load_override(HGeometry<0,DOW>& geo, int) {
00216         base_t::load_override(geo.buffer, 0);
00217         base_t::load_override(boost::serialization::base_object<Point<DOW> >(geo), 0);
00218         base_t::load_override(geo.index, 0);
00219         base_t::load_override(geo.bmark, 0);
00220       }
00221       template <int DIM, int DOW>
00222         void load_override(HGeometry<DIM,DOW> *& p_geo, int) {
00223         int type;
00224         unsigned long global_idx;
00225         base_t::load_override(boost::serialization::make_binary_object(&type, sizeof(int)), 0);
00226         if (type == 0) { 
00227           p_geo = NULL;
00228         } else if (type == (1<<0)) { 
00229           base_t::load_override(p_geo, 0);
00230         } else if (type == (1<<1)) { 
00231           base_t::load_override(p_geo, 0);
00232 
00233           base_t::load_override(boost::serialization::make_binary_object(&global_idx, sizeof(unsigned long)), 0);
00234           lb().merge_global_pointer(type, global_idx, p_geo);
00235 
00236           int n_share;
00237           base_t::load_override(boost::serialization::make_binary_object(&n_share, sizeof(int)), 0);
00238           if (n_share > 0) {
00239             for (int i = 0;i < n_share;++ i) {
00240               int rank;
00241               base_t::load_override(boost::serialization::make_binary_object(&rank, sizeof(int)), 0);
00242               assert (rank != this->new_rank());
00243               lb().share_global_pointer(rank, global_idx, p_geo);
00244             }
00245           }
00246         } else { 
00247           assert (type == (1<<2));
00248           base_t::load_override(boost::serialization::make_binary_object(&global_idx, sizeof(unsigned long)), 0);
00249           lb().merge_global_pointer(type, global_idx, p_geo);
00250         }
00251       }
00252     public:
00253     HGeometry_iarchive(LB& lb, int new_rank, std::istream & is, unsigned flags = 0) :
00254       _lb(&lb), _new_rank(new_rank), base_t(is, flags) {}
00255     public:
00256       LB& lb() const { return *_lb; }
00257       int new_rank() const { return _new_rank; }
00258     private:
00259       LB * _lb;
00260       int _new_rank;
00261     };
00262 
00263   }
00264 }
00265 
00266 #endif // __MPI_HGeometry_archive_h__
00267