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