Commit bf50b7d5 authored by Paal Kvamme's avatar Paal Kvamme
Browse files

Unit test for reading samples in the padding area.

parent 6710b5b4
Pipeline #50235 passed with stages
in 12 minutes and 41 seconds
......@@ -888,7 +888,7 @@ fillMe(void* data, const std::array<std::int64_t,3>& size, double value, RawData
case RawDataType::Float32: fillMeT<float>(data, size, value); break;
case RawDataType::SignedInt16:fillMeT<std::int16_t>(data, size, value); break;
case RawDataType::SignedInt8: fillMeT<std::int8_t>(data, size, value); break;
default: throw OpenZGY::Errors::ZgyInternalError("Unrecognized valuetype." + std::to_string(int(dtype)));
default: throw OpenZGY::Errors::ZgyInternalError("Unrecognized valuetype.");
}
}
}
......@@ -908,8 +908,12 @@ ZgyInternalBulk::expeditedRead(const std::array<std::int64_t,3>& start, const st
// This ought to work but will require more testing.
if (!expedited_read())
return false;
// Not posible due to 8x8 subtiling.
if (this->_metadata->fh().version() == 1)
return false;
// TODO-Performance: Might implement in-place integral to float conversion.
if (result_type != this->_metadata->ih().datatype())
return false;
const std::array<std::int64_t,3> bs = this->_metadata->ih().bricksize();
......@@ -948,10 +952,11 @@ ZgyInternalBulk::expeditedRead(const std::array<std::int64_t,3>& start, const st
}
_logger(2, "Expedited read regular");
this->_file->xx_read(data, brick.offset_in_file, brick.size_in_file, UsageHint::Data);
// TODO-High: Fill area outside survey with defaultstorage.
// TODO-Low: If _deliverOneBrick() clears padding samples, do likewise here.
break;
case BrickStatus::Compressed:
// TODO-Performance: Also support decompression.
_logger(2, "Expedited read compressed (not implemented)");
return false;
......@@ -1576,6 +1581,8 @@ ZgyInternalBulk::_deliverOneBrick(
// does a flood-fill of the entire survey to a given value and
// later sees that the content is different in the padding area.
// But, the caller should ignore the padding.
// TODO-Worry: Keep this decision in sync with what is done in
// the shortcut in expeditedRead().
//
// On write the padding samples should also be forced to contain
// the same value. If nothing else, to help compression. But for
......
......@@ -32,6 +32,7 @@
#include <thread>
#include <chrono>
#include <algorithm>
#include <functional>
using namespace OpenZGY;
using namespace OpenZGY::Formatters;
......@@ -2357,6 +2358,128 @@ namespace {
}
}
/**
* Make sure the contents of the padding area is not visible to the
* application, and that the behavior is predictable and the same
* regardless of whether the one brick at a time shortcut is active.
* The contents on disk is an implementation detail, currently it will
* have replication up to the next multiple of 4 and defaultvalue
* after that.
*
* See ZgyInternalBulk::expeditedRead() and _deliverOneBrick().
* Currently the feature is NOT enabled, and the current behavior
* (replication up to a multiple of 4, then defaultvalue) is
* explicitly tested for.
*
* Test data size 2*3*7 bricks, (1*64)+43, (2*64)+34, (6*64)+21
* In the last column, Brick 2 is missing and brick 3 is a constvalue
* Use an int16 file with real 0 mapping to (default-)storage 10000
*/
static void
test_edgebricks()
{
typedef IZgyWriter::size3i_t size3i_t;
LocalFileAutoDelete lad("edgebricks.zgy");
const size3i_t bs{64, 64, 64};
const size3i_t size{(1*64)+43, (2*64)+34, (6*64)+21};
ZgyWriterArgs args = ZgyWriterArgs()
.size(size[0], size[1], size[2])
.bricksize(bs[0], bs[1], bs[2])
.datatype(SampleDataType::int16)
.datarange(-32768-10000, +32767-10000)
.filename(lad.name());
std::shared_ptr<OpenZGY::IZgyWriter> writer = IZgyWriter::open(args);
if (!TEST_CHECK(bool(writer)))
return;
std::vector<std::int16_t> data(bs[0]*bs[1]*bs[2]);
for (std::size_t pos=0, end=data.size(); pos < end; ++pos)
data[pos] = ((pos * 947) % 4057) + 42;
writer->write(size3i_t{1*64, 2*64, 0*64}, bs, data.data());
writer->writeconst(size3i_t{1*64, 2*64, 1*64}, bs, data.data()); // const
//writer->write(size3i_t{1*64, 2*64, 2*64}, bs, data.data()); // skip
writer->write(size3i_t{1*64, 2*64, 3*64}, bs, data.data());
writer->write(size3i_t{1*64, 2*64, 4*64}, bs, data.data());
writer->write(size3i_t{1*64, 2*64, 5*64}, bs, data.data());
writer->write(size3i_t{1*64, 2*64, 6*64}, bs, data.data());
writer->finalize(std::vector<OpenZGY::DecimationType>{
OpenZGY::DecimationType::Average
}, nullptr);
writer->close();
writer.reset();
std::shared_ptr<OpenZGY::IZgyReader> reader = IZgyReader::open(lad.name());
if (!TEST_CHECK(bool(reader)))
return;
if (verbose())
reader->filestats()->dump(std::cout, "");
// Read the last brick column.
std::vector<std::int16_t> check(64*64*7*64, 888);
std::function<std::size_t(int, int, int)> offset;
offset = [](int ii, int jj, int kk){return (ii*64 + jj) * 7*64 + kk;};
reader->read(size3i_t{1*64, 2*64, 0}, size3i_t{64, 64, 7*64},check.data());
TEST_EQUAL(check[offset(0,0,1)], ((1 * 947) % 4057) + 42); // inside
TEST_EQUAL(check[offset(0,0,67)], 42); // inside in const
TEST_EQUAL(check[offset(0,0,131)], 10000); // inside in miss
// The normal, general API does *not* hide the real contents of the brick.
// The chech should return 1000 for all three samples, instead it will
// return 2754 (replicating last sample inside) for the first three.
TEST_EQUAL(check[offset(0,0,6*64+21)], 2754); // outside in Z
TEST_EQUAL(check[offset(0,0,6*64+22)], 2754); // outside in Z
TEST_EQUAL(check[offset(0,0,6*64+23)], 2754); // outside in Z
TEST_EQUAL(check[offset(0,0,6*64+24)], 10000); // well outside in Z
TEST_EQUAL(check[offset(0,34,0)], 4062); // outside in J
TEST_EQUAL(check[offset(0,35,0)], 4062); // outside in J
TEST_EQUAL(check[offset(0,36,0)], 10000); // well outside in J
TEST_EQUAL(check[offset(0,36,0)], 10000); // well outside in J
TEST_EQUAL(check[offset(43,0,0)], 1454); // outside in I
TEST_EQUAL(check[offset(44,0,0)], 10000); // well outside in I
TEST_EQUAL(check[offset(45,0,0)], 10000); // well outside in I
TEST_EQUAL(check[offset(46,0,0)], 10000); // well outside in I
TEST_EQUAL(check[offset(43,34,1*64)], 42); // outside but in constvalue
TEST_EQUAL(check[offset(43,34,2*64)], 10000); // outside but in missing
// Read one brick at a time: constvalue, missing, normal.
std::vector<std::int16_t> check1(64*64*64);
std::vector<std::int16_t> check2(64*64*64);
std::vector<std::int16_t> check3(64*64*64);
reader->read(size3i_t{1*64, 2*64, 1*64}, bs, check1.data());
reader->read(size3i_t{1*64, 2*64, 2*64}, bs, check2.data());
reader->read(size3i_t{1*64, 2*64, 6*64}, bs, check3.data());
offset = [](int ii, int jj, int kk){return (ii*64 + jj) * 64 + kk;};
TEST_EQUAL(check3[offset(0,0,0)], 42); // inside
TEST_EQUAL(check3[offset(0,0,1)], ((1 * 947) % 4057) + 42); // inside
TEST_EQUAL(check3[offset(0,0,21)], 2754); // outside in Z
TEST_EQUAL(check3[offset(0,0,22)], 2754); // outside in Z
TEST_EQUAL(check3[offset(0,0,23)], 2754); // outside in Z
TEST_EQUAL(check3[offset(0,0,24)], 10000); // outside in Z
TEST_EQUAL(check3[offset(0,34,0)], 4062); // outside in J
TEST_EQUAL(check3[offset(0,35,0)], 4062); // outside in J
TEST_EQUAL(check3[offset(0,36,0)], 10000); // outside in J
TEST_EQUAL(check3[offset(0,37,0)], 10000); // outside in J
TEST_EQUAL(check3[offset(43,0,0)], 1454); // outside in I
TEST_EQUAL(check3[offset(44,0,0)], 10000); // outside in I
TEST_EQUAL(check3[offset(45,0,0)], 10000); // outside in I
TEST_EQUAL(check3[offset(46,0,0)], 10000); // outside in I
for (const auto it : check1) // padding in const brick is the constant.
if (it != 42)
if (!TEST_EQUAL(it, 42))
break;
for (const auto it : check2) // empty brick.
if (it != 10000)
if (!TEST_EQUAL(it, 10000))
break;
}
/**
* Test that reading a file BAT i.e. one brick at a time works.
* These now trigger some performance tweaks in the accessor.
......@@ -2631,6 +2754,7 @@ public:
#ifdef HAVE_SD
register_test("api.readwrite_cloud", test_readwrite_cloud);
#endif
register_test("api.edgebricks", test_edgebricks);
register_test("api.bat_local_1", test_bat_local_1);
register_test("api.bat_local_2", test_bat_local_2);
register_test("api.bat_local_4", test_bat_local_4);
......
Markdown is supported
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