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