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