AFEPack
MPI_UGeometry_archive.h
浏览该文件的文档。
00001 
00011 #ifndef __MPI_UGeometry_archive_h__
00012 #define __MPI_UGeometry_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           if (! (lb().is_on_this_new_rank(*p_geo, new_rank()))) {
00124             type = 0;
00125             base_t::save_override(boost::serialization::make_binary_object(&type, sizeof(int)), 0);
00126           } else if (lb().is_save_on_this_rank(*p_geo, new_rank())) {
00127             unsigned long * global_idx = lb().get_global_idx(*p_geo);
00128             if (global_idx == NULL) { 
00129               type = (1<<0);
00130               base_t::save_override(boost::serialization::make_binary_object(&type, sizeof(int)), 0);
00131               base_t::save_override(p_geo, 0);
00132             } else { 
00133               type = (1<<1);
00134               base_t::save_override(boost::serialization::make_binary_object(&type, sizeof(int)), 0);
00135               base_t::save_override(p_geo, 0);
00136               base_t::save_override(boost::serialization::make_binary_object(global_idx, sizeof(unsigned long)), 0);
00137 
00138               typename LB::rank_map_t * p_map = lb().get_rank_map(*p_geo);
00139               int n_share = p_map->size() - 1;
00140               base_t::save_override(boost::serialization::make_binary_object(&n_share, sizeof(int)), 0);
00141               if (n_share > 0) {
00142                 typename LB::rank_map_t::iterator
00143                   the_pair = p_map->begin(),
00144                   end_pair = p_map->end();
00145                 for (;the_pair != end_pair;++ the_pair) {
00146                   int new_rank = the_pair->first;
00147                   if (new_rank == this->new_rank()) continue;
00148                   base_t::save_override(boost::serialization::make_binary_object(&new_rank, sizeof(int)), 0);
00149                 }
00150               }
00151             }
00152           } else { 
00153             type = (1<<2);
00154             base_t::save_override(boost::serialization::make_binary_object(&type, sizeof(int)), 0);
00155             unsigned long * global_idx = lb().get_global_idx(*p_geo);
00156             assert (global_idx != NULL);
00157             base_t::save_override(boost::serialization::make_binary_object(global_idx, sizeof(unsigned long)), 0);
00158           }
00159         }
00160       }
00161     public:
00162     HGeometry_oarchive(LB& lb, int new_rank, std::ostream& os, unsigned flags = 0) : 
00163       base_t(os, flags), _lb(&lb), _new_rank(new_rank) {}
00164     public:
00165       LB& lb() const { return *_lb; }
00166       int new_rank() const { return _new_rank; }
00167     private:
00168       LB * _lb;
00169       int _new_rank;
00170     };
00171 
00172 
00173 #if BOOST_VERSION>=103400
00174     template <class LB,
00175       class Elem = std::istream::char_type, 
00176       class Tr = std::istream::traits_type>
00177       class HGeometry_iarchive :
00178     public binary_iarchive_impl<HGeometry_iarchive<LB,Elem,Tr>,Elem,Tr> {
00179       typedef HGeometry_iarchive<LB,Elem,Tr> derived_t;
00180       typedef binary_iarchive_impl<derived_t,Elem,Tr> base_t;
00181 #else
00182     template <class LB>
00183       class HGeometry_iarchive :
00184     public binary_iarchive_impl<HGeometry_iarchive<LB> > {
00185       typedef HGeometry_iarchive<LB> derived_t;
00186       typedef binary_iarchive_impl<derived_t> base_t;
00187 #endif
00188 #ifndef BOOST_NO_MEMBER_TEMPLATE_FRIENDS
00189     public:
00190 #else
00191       friend class boost::archive::detail::interface_iarchive<derived_t>;
00192       friend class basic_binary_iarchive<derived_t>;
00193       friend class basic_binary_iprimitive<derived_t, std::istream>;
00194       friend class boost::archive::load_access;
00195 #endif
00196       template<class T>
00197         void load_override(T& t, int){
00198         base_t::load_override(t, 0);
00199         BOOST_STATIC_ASSERT(! (boost::_is_HGeometry_type<T>::value) );
00200       }
00201       template<int DIM, int DOW>
00202         void load_override(HGeometry<DIM,DOW> &geo, int){
00203         base_t::load_override(geo.buffer, 0);
00204         base_t::load_override(geo.index, 0);
00205         base_t::load_override(geo.bmark, 0);
00206         this->load_override(geo.parent, 0);
00207         for (u_int i = 0;i < geo.n_vertex;++ i) {
00208           this->load_override(geo.vertex[i], 0);
00209         }
00210         for (u_int i = 0;i < geo.n_boundary;++ i) {
00211           this->load_override(geo.boundary[i], 0);
00212         }
00213         for (u_int i = 0;i < geo.n_child;++ i) {
00214           this->load_override(geo.child[i], 0);
00215         }
00216       }
00217       template <int DOW>
00218         void load_override(HGeometry<0,DOW>& geo, int) {
00219         base_t::load_override(geo.buffer, 0);
00220         base_t::load_override(boost::serialization::base_object<Point<DOW> >(geo), 0);
00221         base_t::load_override(geo.index, 0);
00222         base_t::load_override(geo.bmark, 0);
00223       }
00224       template <int DIM, int DOW>
00225         void load_override(HGeometry<DIM,DOW> *& p_geo, int) {
00226         int type;
00227         unsigned long global_idx;
00228         base_t::load_override(boost::serialization::make_binary_object(&type, sizeof(int)), 0);
00229         if (type == 0) { 
00230           p_geo = NULL;
00231         } else if (type == (1<<0)) { 
00232           base_t::load_override(p_geo, 0);
00233         } else if (type == (1<<1)) { 
00234           base_t::load_override(p_geo, 0);
00235 
00236           base_t::load_override(boost::serialization::make_binary_object(&global_idx, sizeof(unsigned long)), 0);
00237           lb().merge_global_pointer(type, global_idx, p_geo);
00238 
00239           int n_share;
00240           base_t::load_override(boost::serialization::make_binary_object(&n_share, sizeof(int)), 0);
00241           if (n_share > 0) {
00242             for (int i = 0;i < n_share;++ i) {
00243               int rank;
00244               base_t::load_override(boost::serialization::make_binary_object(&rank, sizeof(int)), 0);
00245               assert (rank != this->new_rank());
00246               lb().share_global_pointer(rank, global_idx, p_geo);
00247             }
00248           }
00249         } else { 
00250           assert (type == (1<<2));
00251           base_t::load_override(boost::serialization::make_binary_object(&global_idx, sizeof(unsigned long)), 0);
00252           lb().merge_global_pointer(type, global_idx, p_geo);
00253         }
00254       }
00255     public:
00256     HGeometry_iarchive(LB& lb, int new_rank, std::istream & is, unsigned flags = 0) :
00257       base_t(is, flags), _lb(&lb), _new_rank(new_rank) {}
00258     public:
00259       LB& lb() const { return *_lb; }
00260       int new_rank() const { return _new_rank; }
00261     private:
00262       LB * _lb;
00263       int _new_rank;
00264     };
00265 
00266   }
00267 }
00268 
00269 #endif // __MPI_UGeometry_archive_h__
00270