AFEPack
|
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