Commit 1bdd8e70 authored by Paal Kvamme's avatar Paal Kvamme
Browse files

Replace _canread() with _isclean() with slightly different semantics.

parent cf9b4d5b
......@@ -151,13 +151,13 @@ GenLodBase::_willneed() const
}
/**
* Return true if the requested data exists on the file or (for plan D)
* in the application. This is always the case for LOD 0. The method
* may be overridden to implement imcremental rebuild where some
* low reaolution data might also be available on the file.
* \brief Return true if the region exists on file and has not changed.
* \details
* The method may be overridden to implement imcremental rebuild where
* some low resolution data might also be available on the file.
*/
bool
GenLodBase::_canread(
GenLodBase::_isclean(
std::int32_t lod,
const std::array<std::int64_t,3>& /*pos*/,
const std::array<std::int64_t,3>& /*size*/) const
......@@ -300,9 +300,10 @@ GenLodImpl::call()
std::cout << "@ GenLod is running."
<< " Histogram range " << _histogram_range
<< "\n";
index3_t chunksize = this->_bricksize * std::int64_t(_incremental ? 2 : 2);
this->_reporttotal(_willneed());
this->_report(nullptr);
this->_calculate(index3_t{0,0,0}, this->_bricksize * std::int64_t(2), this->_nlods-1);
this->_calculate(index3_t{0,0,0}, chunksize, this->_nlods-1);
return std::make_tuple(this->_stats, this->_histo);
}
......@@ -368,9 +369,23 @@ GenLodImpl::_accumulate(const std::shared_ptr<const DataBuffer>& data)
* the read/write the buffer might be smaller at the survey edge. Note that
* the caller is responsible for storing the decimated data.
*
* If calculate is called with a clean region it will not need to do a
* recursive call and it will not need to write. The code has two choices:
*
* - Read the requested brick, which is normally only done in LOD0, and
* decimate and return as usual. For LOD0 this is business as usual.
* For low resolution data it saves soem I/O and CPU time.
*
* - Read 1/4 of the brick at lod+1 and return this already decimated
* data. This technically reads even less data from the file. But if
* the chunk size is a single brick column this needs to read 1/4
* brick column from file which ends up reading the full columns and
* discarding the surplus. So it saves some CPU but might not save I/O.
*
* If doing an incremental build, readsize is best set to one brick-column
* because this determines the granularity of the "dirty" test and that
* needs to be as small as possible. TODO-@@@
* needs to be as small as possible. But see above; this might mean
* the code will in some cases read data smaller than one brick. TODO-@@@
*
* TODO-Performance: If doing a full build it might we a good idea to allow
* the application to configure how much memory the computation is allowed
......@@ -434,13 +449,13 @@ GenLodImpl::_calculate(const index3_t& readpos_in, const index3_t& readsize_in,
wasread = true;
this->_accumulate(data);
}
else if (this->_canread(readlod, readpos, readsize)) {
else if (this->_isclean(readlod, readpos, readsize)) {
// Lowres bricks can sometimes be read if building incrementally.
// Note that the code always calculates full brick-columns to
// avoid r/m/w cycles. So if any of the 4 brick columns we
// depend on are dirty then all 4 needs to be read or computed.
// And the converse: If _canread() returns true then *all*
// requested data is already in file so there is no write back.
// requested data is already on the file so there is no write back.
// Just like in the LOD 0 case.
data = this->_read(readlod, readpos, readsize);
wasread = true;
......@@ -462,7 +477,8 @@ GenLodImpl::_calculate(const index3_t& readpos_in, const index3_t& readsize_in,
//
// TODO-Performance: A possible exception in algorithm "C" is when
// readlod==1. Caveat: For incremental builds we might not need all 4
// sub-parts. Caveat for multi threading: nested loops, smaller blocks.
// sub-parts. So in that case we should loop normally.
// Caveat for multi threading: nested loops, smaller blocks.
// Caveat for replacing with a single call: more special cases to test.
// In particular handling of crops to survey size.
//
......@@ -900,7 +916,7 @@ GenLodC::_willneed() const
// we need to read 16 brick-columns from lod-1.
const index3_t checkpos{ii,jj,0};
const index3_t checksize = _clipsizetosurvey(lod, checkpos, chosensize);
if (_canread(lod, checkpos, checksize)) {
if (_isclean(lod, checkpos, checksize)) {
const index3_t subsize = _clipsizetosurvey
(lod-1, checkpos + checkpos, checksize + checksize);
const std::int64_t ibricks = (subsize[0] + bs[0] - 1) / bs[0];
......@@ -941,18 +957,27 @@ GenLodC::_willneed() const
}
/**
* See base class for details.
* \brief Return true if the region exists on file and has not changed.
*
* \details
*
* If not doing an incremental build than all data is considered dirty.
* Dirty LOD0 data needs to be read from file (plan C) or app (plan D),
* Dirty LOD>1 data will need to be re-computed by recursively calculating it.
*
* An exception is thrown if any part of the region is outside the survey.
* This can easily be changed to just ignore the parts that are outside
* and to reurn a special status (so the return can no longer be a bool)
* if completely outside. But with current usage the caller handles that
* check anyway.
*/
bool
GenLodC::_canread(
GenLodC::_isclean(
std::int32_t lod,
const std::array<std::int64_t,3>& pos,
const std::array<std::int64_t,3>& size) const
{
if (lod == 0) {
return true; // Fullres always read from file.
}
else if (!_incremental) {
if (!_incremental) {
return false; // Not tracking dirty bits, or caller wants full anyway.
}
else if ((this->_accessor->trackedBricksDirty(pos, size, lod) & 0x01) != 0) {
......
......@@ -84,7 +84,7 @@ public:
bool verbose);
protected:
virtual std::int64_t _willneed() const;
virtual bool _canread(
virtual bool _isclean(
std::int32_t lod, const index3_t& pos, const index3_t& size) const;
virtual std::shared_ptr<DataBuffer> _read(
std::int32_t lod, const index3_t& pos, const index3_t& size) const;
......@@ -165,7 +165,7 @@ public:
bool verbose);
protected:
std::int64_t _willneed() const override;
bool _canread(
bool _isclean(
std::int32_t lod, const index3_t& pos, const index3_t& size) const override;
std::shared_ptr<DataBuffer> _read(
std::int32_t lod, const index3_t& pos, const index3_t& size) const override;
......
Supports Markdown
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment