Commit 2c3cba00 authored by Paal Kvamme's avatar Paal Kvamme
Browse files

Single brick shortcut.

parent 524e4a34
......@@ -598,12 +598,14 @@ public:
virtual void read(const size3i_t& start, const size3i_t& size, float* data, int lod) const override
{
throw_if_not_readable();
std::shared_ptr<float> fakeshared = fake_shared(data);
auto databuffer = std::make_shared<InternalZGY::DataBufferNd<float,3>>(fakeshared, size);
_accessor->readToExistingBuffer(databuffer, start, lod, true);
databuffer.reset();
if (!fakeshared.unique())
throw Errors::ZgyInternalError("A Reference to the user's buffer was retained.");
if (!_accessor->expeditedRead(start, size, data, lod, InternalZGY::RawDataType::Float32)) {
std::shared_ptr<float> fakeshared = fake_shared(data);
auto databuffer = std::make_shared<InternalZGY::DataBufferNd<float,3>>(fakeshared, size);
_accessor->readToExistingBuffer(databuffer, start, lod, true);
databuffer.reset();
if (!fakeshared.unique())
throw Errors::ZgyInternalError("A Reference to the user's buffer was retained.");
}
}
/**
......@@ -615,12 +617,14 @@ public:
virtual void read(const size3i_t& start, const size3i_t& size, std::int16_t* data, int lod) const override
{
throw_if_not_readable();
std::shared_ptr<std::int16_t> fakeshared = fake_shared(data);
auto databuffer = std::make_shared<InternalZGY::DataBufferNd<std::int16_t,3>>(fakeshared, size);
_accessor->readToExistingBuffer(databuffer, start, lod, false);
databuffer.reset();
if (!fakeshared.unique())
throw Errors::ZgyInternalError("A Reference to the user's buffer was retained.");
if (!_accessor->expeditedRead(start, size, data, lod, InternalZGY::RawDataType::SignedInt16)) {
std::shared_ptr<std::int16_t> fakeshared = fake_shared(data);
auto databuffer = std::make_shared<InternalZGY::DataBufferNd<std::int16_t,3>>(fakeshared, size);
_accessor->readToExistingBuffer(databuffer, start, lod, false);
databuffer.reset();
if (!fakeshared.unique())
throw Errors::ZgyInternalError("A Reference to the user's buffer was retained.");
}
}
/**
......@@ -632,12 +636,14 @@ public:
virtual void read(const size3i_t& start, const size3i_t& size, std::int8_t* data, int lod) const override
{
throw_if_not_readable();
std::shared_ptr<std::int8_t> fakeshared = fake_shared(data);
auto databuffer = std::make_shared<InternalZGY::DataBufferNd<std::int8_t,3>>(fakeshared, size);
_accessor->readToExistingBuffer(databuffer, start, lod, false);
databuffer.reset();
if (!fakeshared.unique())
throw Errors::ZgyInternalError("A Reference to the user's buffer was retained.");
if (!_accessor->expeditedRead(start, size, data, lod, InternalZGY::RawDataType::SignedInt8)) {
std::shared_ptr<std::int8_t> fakeshared = fake_shared(data);
auto databuffer = std::make_shared<InternalZGY::DataBufferNd<std::int8_t,3>>(fakeshared, size);
_accessor->readToExistingBuffer(databuffer, start, lod, false);
databuffer.reset();
if (!fakeshared.unique())
throw Errors::ZgyInternalError("A Reference to the user's buffer was retained.");
}
}
/**
......
......@@ -133,6 +133,17 @@ namespace {
return enable > 0;
}
/**
* Return non-zero if there should be special case handling of the trivial
* case of reading exactly one thread. The feature is on by default.
*/
static bool
expedited_read()
{
static int enable = Environment::getNumericEnv("OPENZGY_EXPEDITED_READ", 1);
return enable > 0;
}
/**
* \brief Add or subtract this buffer's samples in the statistics.
*
......@@ -860,6 +871,93 @@ ZgyInternalBulk::trackedBricksTryEnable(bool on)
}
}
namespace {
template<typename T>
static void
fillMeT(void* data, const std::array<std::int64_t,3>& size, double value)
{
std::fill(static_cast<T*>(data),
static_cast<T*>(data) + size[0]*size[1]*size[2],
static_cast<T>(value));
}
static void
fillMe(void* data, const std::array<std::int64_t,3>& size, double value, RawDataType dtype)
{
switch (dtype) {
case RawDataType::Float32: fillMeT<float>(data, size, value);
case RawDataType::SignedInt16:fillMeT<std::int16_t>(data, size, value);
case RawDataType::SignedInt8: fillMeT<std::int8_t>(data, size, value);
default: throw OpenZGY::Errors::ZgyInternalError("Unrecognized valuetype.");
}
}
}
/**
* More efficient read of a region that happes to be exactly one brick,
* not compressed, not converted int to float, and possibly other limitatons.
* This can bypass a lot of logic and will elide at least one memory
* allocation. Return false if the conditions are not met. The caller can
* invoke this function unconditionally as long as readToExistingBuffer()
* is used as a fallback.
*/
bool
ZgyInternalBulk::expeditedRead(const std::array<std::int64_t,3>& start, const std::array<std::int64_t,3>& size, void* data, int lod, RawDataType result_type) const
{
// TODO-Performance: Used in ZgyWriter::read(), not just ZgyReader::read().
// This ought to work but will require more testing.
if (!expedited_read())
return false;
if (this->_metadata->fh().version() == 1)
return false;
if (result_type != this->_metadata->ih().datatype())
return false;
const std::array<std::int64_t,3> bs = this->_metadata->ih().bricksize();
if ((size[0] != bs[0]) ||
(size[1] != bs[1]) ||
(size[2] != bs[2]) ||
(start[0] % bs[0]) != 0 ||
(start[1] % bs[1]) != 0 ||
(start[2] % bs[2]) != 0)
return false;
// TODO-Performance: Could be simplified.
_validateUserPosition(start, size, lod); // Could be simplified.
// TODO-Performance: Could be simplified.
std::vector<LutInfoEx> bricklist = _partsNeeded(start, size, lod);
if (bricklist.size() != 1)
throw OpenZGY::Errors::ZgyInternalError("expeditedRead messed up.");
const LutInfoEx& brick = bricklist.front();
switch (brick.status) {
case BrickStatus::Missing:
fillMe(data, size, this->_metadata->ih().defaultstorage(), result_type);
break;
case BrickStatus::Constant:
fillMe(data, size, brick.double_constvalue, result_type);
break;
case BrickStatus::Normal:
if (brick.size_in_file != size[0] * size[1] * size[2] *
static_cast<std::int64_t>(RawDataTypeDetails(result_type).size)) {
throw OpenZGY::Errors::ZgyInternalError("Bad size in expeditedRead.");
}
this->_file->xx_read(data, brick.offset_in_file, brick.size_in_file, UsageHint::Data);
// TODO-High: Fill area outside survey with defaultstorage.
break;
case BrickStatus::Compressed:
return false;
default:
throw OpenZGY::Errors::ZgyInternalError("Internal error, bad brick status");
}
return true;
}
/**
* \brief Mark bricks as dirty.
*
......
......@@ -110,6 +110,11 @@ public:
const std::array<std::int64_t,3>& size,
int32_t lod, bool as_float, bool check_constant) const;
bool expeditedRead(
const std::array<std::int64_t,3>& start,
const std::array<std::int64_t,3>& size,
void* data, int lod, RawDataType result_type) const;
void writeRegion(
const std::shared_ptr<DataBuffer>& data,
const std::array<std::int64_t,3>& start,
......
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