00001 #ifdef CH_LANG_CC
00002
00003
00004
00005
00006
00007
00008
00009 #endif
00010
00011 #ifndef _BLOCKWRITEI_H_
00012 #define _BLOCKWRITEI_H_
00013
00014 #include "LevelData.H"
00015 #include "HDF5Portable.H"
00016 #include "CH_HDF5.H"
00017 #include <string>
00018 #include <map>
00019 #include "RealVect.H"
00020 #include "CH_Timer.H"
00021 #include "LoadBalance.H"
00022 #include "LayoutIterator.H"
00023 #include "Vector.H"
00024 #include "memtrack.H"
00025 #include "FluxBox.H"
00026 #include "SPMD.H"
00027
00028
00029 template <class T> void
00030 blockLocalOffsets(Vector<long long>& a_localSizes,
00031
00032 long long & a_localTotalSize,
00033 Vector<Box> & a_localBoxes,
00034 const BoxLayoutData<T>& a_data,
00035 const Interval& a_comps,
00036 const IntVect& a_outputGhost)
00037 {
00038 if (!(T::preAllocatable()==0))
00039 {
00040 MayDay::Error("non static preallocatable data not covered yet.");
00041 }
00042
00043 Vector<int> thisSize(1);
00044 const BoxLayout& layout = a_data.boxLayout();
00045 T dummy;
00046 unsigned int curIndex = 0;
00047 DataIterator it(layout.dataIterator());
00048
00049 a_localTotalSize = 0;
00050 a_localSizes.resize(it.size());
00051 a_localBoxes.resize(it.size());
00052 for (it.reset(); it.ok(); ++it)
00053 {
00054 long long curSize = 0;
00055 const Box& curBox = layout[it()];
00056 Box region = curBox;
00057 region.grow(a_outputGhost);
00058 dataSize(dummy, thisSize, region, a_comps);
00059
00060 curSize = thisSize[0];
00061 a_localSizes[curIndex] = curSize;
00062 a_localBoxes[curIndex] = curBox;
00063
00064 a_localTotalSize += thisSize[0];
00065 curIndex += 1;
00066 }
00067 }
00068
00069 template <class T> void
00070 blockWriteToBuffer(void* a_buffer,
00071 const Vector<long long>& a_sizes,
00072 const BoxLayoutData<T>& a_data,
00073 const Interval& a_comps,
00074 const IntVect& a_outputGhost)
00075 {
00076 int* curPtr = (int*)(a_buffer);
00077 int curIndex = 0;
00078 for (DataIterator it = a_data.dataIterator(); it.ok(); ++it)
00079 {
00080 Vector<void*> buffers(1, (void*) curPtr);
00081 const T& data = a_data[it()];
00082
00083 Box box = a_data.box(it());
00084 box.grow(a_outputGhost);
00085 write(data, buffers, box, a_comps);
00086
00087 curPtr += a_sizes[curIndex];
00088 curIndex += 1;
00089 }
00090
00091 }
00092
00093 int
00094 gatherBoxesAndOffsets(long long& a_offsetThisProc,
00095 long long& a_allProcSize,
00096 Vector<long long>& a_globalOffsets,
00097 Vector<Box>& a_globalBoxes,
00098 const Vector<long long>& a_localBoxSizes,
00099 const Vector<Box>& a_localBoxes,
00100 const long long& a_localAllBoxSize)
00101
00102 {
00103 Vector<Vector<Box > > allBoxes;
00104 Vector<Vector<long long> > allBoxSizes;
00105 Vector<long long> allSizes;
00106 int iprocdest = 0;
00107 gather(allBoxes, a_localBoxes, iprocdest);
00108 gather(allBoxSizes, a_localBoxSizes, iprocdest);
00109 gather(allSizes, a_localAllBoxSize, iprocdest);
00110 Vector<long long> offsetsProcs(numProc());
00111 if (procID() == iprocdest)
00112 {
00113 a_allProcSize = 0;
00114 long long numBoxes = 0;
00115 for (int iproc = 0; iproc < numProc(); iproc++)
00116 {
00117 a_allProcSize += allSizes[iproc];
00118 numBoxes += allBoxes[iproc].size();
00119 }
00120 a_globalBoxes. resize(numBoxes);
00121 a_globalOffsets.resize(numBoxes+1);
00122
00123 long long curOffset = 0;
00124 int curIndex = 0;
00125 for (int iproc = 0; iproc < numProc(); iproc++)
00126 {
00127 for (int ivec = 0; ivec < allBoxSizes[iproc].size(); ivec++)
00128 {
00129 if (ivec == 0)
00130 {
00131 offsetsProcs[iproc] = curOffset;
00132 }
00133 long long boxSize = allBoxSizes[iproc][ivec];
00134 Box curBox = allBoxes[iproc][ivec];
00135
00136 a_globalBoxes [curIndex] = curBox;
00137 a_globalOffsets[curIndex] = curOffset;
00138
00139 curIndex += 1;
00140 curOffset += boxSize;
00141 }
00142 }
00143 if (curOffset != a_allProcSize)
00144 {
00145 return -43;
00146 }
00147 a_globalOffsets[curIndex] = curOffset;
00148
00149 }
00150 a_offsetThisProc = offsetsProcs[procID()];
00151 broadcast(a_allProcSize, iprocdest);
00152 broadcast(a_globalOffsets, iprocdest);
00153 broadcast(a_globalBoxes, iprocdest);
00154 return 0;
00155 }
00156
00157 int
00158 blockWriteBufferToFile(HDF5Handle& a_handle,
00159 void* a_buffer,
00160 const std::string& a_name,
00161 Vector<Box>& a_boxes,
00162 Vector<long long>& a_sizes,
00163 const Vector<hid_t>& a_types,
00164 const BoxLayout& a_layout,
00165 const long long& a_thisprocsize)
00166 {
00167
00168 herr_t err;
00169
00170 long long offsetthisproc, sumprocsize;
00171 Vector<Box> globalBoxes;
00172 Vector<long long> globalOffsets;
00173
00174
00175 int ret = gatherBoxesAndOffsets(offsetthisproc, sumprocsize, globalOffsets, globalBoxes, a_sizes, a_boxes, a_thisprocsize);
00176 if (ret!=0)
00177 {
00178 return ret;
00179 }
00180
00181 if (globalBoxes.size() != a_layout.size())
00182 {
00183 return -12;
00184 }
00185
00186 {
00187 char offsetname[1024];
00188 sprintf(offsetname, "%s:offsets=0",a_name.c_str());
00189
00190 hsize_t flatdims[1];
00191 flatdims[0] = globalOffsets.size();
00192 hid_t offsetspace = H5Screate_simple(1, flatdims, NULL);
00193 hid_t offsetdata = H5Dcreate(a_handle.groupID(), offsetname,
00194 H5T_NATIVE_LLONG, offsetspace, H5P_DEFAULT);
00195
00196 if (procID() == 0)
00197 {
00198 hid_t memdataspace = H5Screate_simple(1, flatdims, NULL);
00199 err = H5Dwrite(offsetdata, H5T_NATIVE_LLONG, memdataspace, offsetspace,
00200 H5P_DEFAULT, &(globalOffsets[0]));
00201 if (err < 0) return err;
00202 H5Sclose(memdataspace);
00203 }
00204
00205 H5Sclose(offsetspace);
00206 H5Dclose(offsetdata);
00207 }
00208 {
00209 hsize_t hs_procsize[1];
00210 hsize_t hs_allprocsize[1];
00211 ch_offset_t ch_offset[1];
00212
00213 ch_offset[0] = offsetthisproc;
00214 hs_procsize[0] = a_thisprocsize;
00215 hs_allprocsize[0] = sumprocsize;
00216
00217 char dataname[1024];
00218 sprintf(dataname, "%s:datatype=0",a_name.c_str());
00219
00220 hid_t dataspace = H5Screate_simple(1, hs_allprocsize, NULL);
00221 hid_t memdataspace = H5Screate_simple(1, hs_procsize, NULL);
00222
00223 hid_t dataset = H5Dcreate(a_handle.groupID(), dataname,
00224 a_types[0], dataspace, H5P_DEFAULT);
00225
00226
00227 err = H5Sselect_hyperslab(dataspace, H5S_SELECT_SET,
00228 ch_offset, NULL,
00229 hs_procsize, NULL);
00230 if (err < 0) return err;
00231
00232 err = H5Dwrite(dataset, a_types[0], memdataspace, dataspace,
00233 H5P_DEFAULT, a_buffer);
00234 if (err < 0) return err;
00235
00236 H5Sclose(memdataspace);
00237 H5Sclose(dataspace);
00238 H5Dclose(dataset);
00239 }
00240 return 0;
00241 }
00242
00243 template <class T>
00244 int blockWrite(HDF5Handle& a_handle,
00245 const LevelData<T>& a_data,
00246 const std::string& a_name,
00247 const IntVect& a_outputGhost,
00248 const Interval& a_in_comps)
00249 {
00250 HDF5HeaderData info;
00251 info.m_intvect["ghost"] = a_data.ghostVect();
00252 IntVect og(a_outputGhost);
00253 og.min(a_data.ghostVect());
00254 info.m_intvect["outputGhost"] = og;
00255 std::string group = a_handle.getGroup();
00256 a_handle.setGroup(group+"/"+a_name+"_attributes");
00257 info.writeToFile(a_handle);
00258 a_handle.setGroup(group);
00259 return blockWrite(a_handle, (const BoxLayoutData<T>&)a_data, a_name, og, a_in_comps);
00260 }
00261
00262
00263 template <class T> int
00264 blockWrite(HDF5Handle& a_handle,
00265 const BoxLayoutData<T>& a_data,
00266 const std::string& a_name,
00267 const IntVect& a_outputGhost,
00268 const Interval& a_comps)
00269 {
00270 CH_TIME("block write Level");
00271 int ret = 0;
00272
00273 const BoxLayout& layout = a_data.boxLayout();
00274 T dummy;
00275
00276 Vector<hid_t> types;
00277 dataTypes(types, dummy);
00278 if (types.size() != 1)
00279 {
00280 MayDay::Error("premature generality, I only deal with types of size 1");
00281 }
00282
00283
00284 Vector<long long> sizes;
00285 Vector<Box> boxes;
00286 long long totalsize;
00287
00288
00289
00290 blockLocalOffsets(sizes, totalsize, boxes, a_data, a_comps, a_outputGhost);
00291
00292
00293 size_t type_size = H5Tget_size(types[0]);
00294
00295
00296 void* buffer = mallocMT(totalsize*type_size);
00297
00298
00299 blockWriteToBuffer(buffer, sizes, a_data, a_comps, a_outputGhost);
00300
00301
00302 HDF5HeaderData info;
00303 info.m_int["comps"] = a_comps.size();
00304 info.m_string["objectType"] = name(dummy);
00305 std::string group = a_handle.getGroup();
00306
00307 a_handle.setGroup(group+"/"+a_name+"_attributes");
00308 info.writeToFile(a_handle);
00309 a_handle.setGroup(group);
00310
00311
00312
00313 ret = blockWriteBufferToFile(a_handle,
00314 buffer,
00315 a_name,
00316 boxes,
00317 sizes,
00318 types,
00319 layout,
00320 totalsize);
00321 if (ret != 0)
00322 {
00323 return ret;
00324 }
00325
00326
00327
00328 freeMT(buffer);
00329 buffer = NULL;
00330
00331 return ret;
00332 }
00333
00334 template <class T> int
00335 blockWriteLevel(HDF5Handle& a_handle,
00336 const int& a_level,
00337 const LevelData<T>& a_data,
00338 const Real& a_dx,
00339 const Real& a_dt,
00340 const Real& a_time,
00341 const Box& a_domain,
00342 const int& a_refRatio,
00343 const IntVect& a_outputGhost,
00344 const Interval& a_comps)
00345 {
00346 int error;
00347 char levelName[10];
00348 std::string currentGroup = a_handle.getGroup();
00349 sprintf(levelName, "/level_%i",a_level);
00350 error = a_handle.setGroup(currentGroup + levelName);
00351 if (error != 0) return 1;
00352
00353 HDF5HeaderData meta;
00354 meta.m_real["dx"] = a_dx;
00355 meta.m_real["dt"] = a_dt;
00356 meta.m_real["time"] = a_time;
00357 meta.m_box["prob_domain"] = a_domain;
00358 meta.m_int["ref_ratio"] = a_refRatio;
00359
00360 error = meta.writeToFile(a_handle);
00361 if (error != 0) return 2;
00362
00363 error = write(a_handle, a_data.boxLayout());
00364 if (error != 0) return 3;
00365
00366 error = blockWrite(a_handle, a_data, std::string("data"), a_outputGhost, a_comps);
00367 if (error != 0) return 4;
00368
00369 a_handle.setGroup(currentGroup);
00370
00371 return 0;
00372 }
00373
00374 template <class T> int
00375 blockReadLevel(HDF5Handle& a_handle,
00376 const int& a_level,
00377 LevelData<T>& a_data,
00378 Real& a_dx,
00379 Real& a_dt,
00380 Real& a_time,
00381 Box& a_domain,
00382 int& a_refRatio,
00383 const Interval& a_comps,
00384 bool a_setGhost)
00385 {
00386 HDF5HeaderData header;
00387 header.readFromFile(a_handle);
00388
00389
00390
00391 int error;
00392 char levelName[10];
00393 std::string currentGroup = a_handle.getGroup();
00394 sprintf(levelName, "/level_%i",a_level);
00395 error = a_handle.setGroup(currentGroup + levelName);
00396 if (error != 0) return 1;
00397
00398 HDF5HeaderData meta;
00399 error = meta.readFromFile(a_handle);
00400 if (error != 0) return 2;
00401 a_dx = meta.m_real["dx"];
00402 a_dt = meta.m_real["dt"];
00403 a_time = meta.m_real["time"];
00404 a_domain = meta.m_box["prob_domain"];
00405 a_refRatio = meta.m_int["ref_ratio"];
00406
00407
00408 Vector<Box> boxes;
00409 error = read(a_handle, boxes);
00410 Vector<int> procIDs;
00411 LoadBalance(procIDs, boxes);
00412
00413
00414 DisjointBoxLayout layout(boxes, procIDs);
00415
00416 layout.close();
00417 if (error != 0) return 3;
00418
00419 error = blockRead(a_handle, a_data, "data", layout, a_comps);
00420
00421 if (error != 0) return 4;
00422
00423
00424 a_handle.setGroup(currentGroup);
00425
00426 return 0;
00427 }
00428
00429
00430 template <class T> int
00431 blockRead(HDF5Handle& a_handle, LevelData<T>& a_data, const std::string& a_name,
00432 const DisjointBoxLayout& a_layout, const Interval& a_comps, bool a_redefineData)
00433 {
00434 if (a_redefineData)
00435 {
00436 HDF5HeaderData info;
00437 std::string group = a_handle.getGroup();
00438 if (a_handle.setGroup(group+"/"+a_name+"_attributes"))
00439 {
00440 std::string message = "error opening "
00441 +a_handle.getGroup()+"/"+a_name+"_attributes" ;
00442 MayDay::Warning(message.c_str());
00443 return 1;
00444 }
00445 info.readFromFile(a_handle);
00446 a_handle.setGroup(group);
00447 int ncomp = info.m_int["comps"];
00448 IntVect ghost = info.m_intvect["ghost"];
00449 if (a_comps.end() > 0 && ncomp < a_comps.end())
00450 {
00451 MayDay::Error("attempt to read component interval that is not available");
00452 }
00453 if (a_comps.size() == 0)
00454 a_data.define(a_layout, ncomp, ghost);
00455 else
00456 a_data.define(a_layout, a_comps.size(), ghost);
00457 }
00458 return blockRead(a_handle, (BoxLayoutData<T>&)a_data, a_name, a_layout, a_comps, false);
00459
00460 }
00461
00462 template <class T>
00463 int
00464 blockRead(HDF5Handle& a_handle, BoxLayoutData<T>& a_data, const std::string& a_name,
00465 const BoxLayout& a_layout, const Interval& a_comps, bool a_redefineData)
00466 {
00467
00468 int ret = read(a_handle, a_data, a_name, a_layout, a_comps, a_redefineData);
00469 return ret;
00470 }
00471
00472 #endif