Skip to content

Commit

Permalink
include tracker: lazy creation
Browse files Browse the repository at this point in the history
  • Loading branch information
Grok Compression committed Dec 21, 2024
1 parent d3e3ea4 commit fdab5ac
Show file tree
Hide file tree
Showing 4 changed files with 121 additions and 54 deletions.
5 changes: 1 addition & 4 deletions src/lib/core/t2/PacketIter.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -617,10 +617,7 @@ uint16_t PacketIter::getLayno(void) const
{
return layno;
}
uint8_t* PacketIter::get_include(uint16_t layerno)
{
return packetManager->getIncludeTracker()->get_include(layerno, resno);
}

bool PacketIter::update_include(void)
{
if(singleProgression_)
Expand Down
150 changes: 111 additions & 39 deletions src/lib/core/t2/PacketIter.h
Original file line number Diff line number Diff line change
Expand Up @@ -38,37 +38,135 @@ enum J2K_T2_MODE
FINAL_PASS = 1 /** Function called in Tier 2 process*/
};

constexpr size_t GRK_INCLUDE_TRACKER_CHUNK_SIZE = 1024; // Define the size of each chunk

struct ResIncludeBuffers
{
ResIncludeBuffers()
{
for(uint8_t i = 0; i < GRK_MAXRLVLS; ++i)
buffers[i] = nullptr;
{
buffers[i] = nullptr; // Buffers start as nullptr
}
}

~ResIncludeBuffers()
{
clear();
}

// Lazily get or allocate the specific byte within a chunk for a given resolution
uint8_t* get_byte(uint8_t resno, uint64_t index)
{
if(resno >= GRK_MAXRLVLS)
{
throw std::out_of_range("Resolution index out of range");
}

if(!buffers[resno])
{
buffers[resno] = new std::map<size_t, uint8_t*>(); // Lazily allocate the map
}

auto& chunks = *buffers[resno];
uint64_t byteIndex = index / 8; // Byte index within the resolution's buffer
uint64_t chunkIndex =
byteIndex / GRK_INCLUDE_TRACKER_CHUNK_SIZE; // Determine which chunk to access
uint64_t offset = byteIndex % GRK_INCLUDE_TRACKER_CHUNK_SIZE; // Offset within the chunk

// Lazily allocate the chunk
if(chunks.find(chunkIndex) == chunks.end())
{
chunks[chunkIndex] =
new uint8_t[GRK_INCLUDE_TRACKER_CHUNK_SIZE](); // Allocate chunk lazily
}

return chunks[chunkIndex] + offset;
}

// Clear all allocated memory
void clear()
{
for(uint8_t i = 0; i < GRK_MAXRLVLS; ++i)
delete[] buffers[i];
{
if(buffers[i])
{
for(auto& chunk : *buffers[i])
{
delete[] chunk.second; // Delete each chunk
}
delete buffers[i]; // Delete the map
buffers[i] = nullptr;
}
}
}
uint8_t* buffers[GRK_MAXRLVLS];

private:
std::map<size_t, uint8_t*>*
buffers[GRK_MAXRLVLS]; // Lazily allocated maps of chunks for each resolution
};

struct IncludeTracker
{
IncludeTracker(uint16_t numcomponents)
: numcomps(numcomponents), currentLayer(0), currentResBuf(nullptr),
include(new std::map<uint16_t, ResIncludeBuffers*>())
{
for(uint8_t i = 0; i < GRK_MAXRLVLS; ++i)
numPrecinctsPerRes[i] = 0;
resetNumPrecinctsPerRes();
}

~IncludeTracker()
{
clear();
delete include;
}

bool update(uint16_t layno, uint8_t resno, uint16_t compno, uint64_t precno)
{
auto include = get_include(layno, resno);
auto numprecs = numPrecinctsPerRes[resno];
uint64_t index = compno * numprecs + precno;
uint64_t include_index = (index >> 3);
uint32_t shift = (index & 7);
uint8_t val = include[include_index];
if(((val >> shift) & 1) == 0)
{
include[include_index] = (uint8_t)(val | (1 << shift));
return true;
}

return false;
}

void clear()
{
for(auto it = include->begin(); it != include->end(); ++it)
{
delete it->second;
}
include->clear();
}

void resetNumPrecinctsPerRes(void)
{
for(uint8_t i = 0; i < GRK_MAXRLVLS; ++i)
numPrecinctsPerRes[i] = 0;
}

void updateNumPrecinctsPerRes(uint8_t resno, uint64_t numPrecincts)
{
if(numPrecincts > numPrecinctsPerRes[resno])
{
numPrecinctsPerRes[resno] = numPrecincts;
}
}

private:
uint8_t* get_include(uint16_t layerno, uint8_t resno)
{
ResIncludeBuffers* resBuf = nullptr;

// Retrieve or create the ResIncludeBuffers for the current layer
if(layerno == currentLayer && currentResBuf)
{
resBuf = currentResBuf;
Expand All @@ -87,43 +185,18 @@ struct IncludeTracker
currentResBuf = resBuf;
currentLayer = layerno;
}
auto buf = resBuf->buffers[resno];
if(!buf)
{
auto numprecs = numPrecinctsPerRes[resno];
auto len = (numprecs * numcomps + 7) / 8;
assert(len <= std::numeric_limits<size_t>::max());
buf = new uint8_t[(size_t)len];
memset(buf, 0, (size_t)len);
resBuf->buffers[resno] = buf;
}
return buf;
}
bool update(uint16_t layno, uint8_t resno, uint16_t compno, uint64_t precno)
{
auto include = get_include(layno, resno);

// Calculate the index in bits
auto numprecs = numPrecinctsPerRes[resno];
uint64_t index = compno * numprecs + precno;
uint64_t include_index = (index >> 3);
uint32_t shift = (index & 7);
uint8_t val = include[include_index];
if(((val >> shift) & 1) == 0)
{
include[include_index] = (uint8_t)(val | (1 << shift));
return true;
}
auto len = (numprecs * numcomps + 7); // Total number of bits
assert(len <= std::numeric_limits<size_t>::max());

return false;
}
void clear()
{
for(auto it = include->begin(); it != include->end(); ++it)
delete it->second;
include->clear();
// Use get_byte to allocate lazily
return resBuf->get_byte(resno,
len - 1); // Access the last byte to ensure the chunk is allocated
}
uint64_t numPrecinctsPerRes[GRK_MAXRLVLS];

private:
uint64_t numPrecinctsPerRes[GRK_MAXRLVLS];
uint16_t numcomps;
uint16_t currentLayer;
ResIncludeBuffers* currentResBuf;
Expand Down Expand Up @@ -236,7 +309,6 @@ struct PacketIter
void genPrecinctInfo();
void genPrecinctInfo(PiComp* comp, PiResolution* res, uint8_t resNumber);

uint8_t* get_include(uint16_t layerIndex);
bool update_include(void);
void destroy_include(void);

Expand Down
18 changes: 8 additions & 10 deletions src/lib/core/t2/PacketManager.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -43,8 +43,8 @@ PacketManager::PacketManager(bool compression, GrkImage* img, CodingParams* cpar
uint64_t max_precincts;
uint32_t dx_min;
uint32_t dy_min;
getParams(image, cp, tileno, &tileBounds_, &dx_min, &dy_min, includeTracker->numPrecinctsPerRes,
&max_precincts, &max_res, precinctByComponent);
getParams(image, cp, tileno, &tileBounds_, &dx_min, &dy_min, includeTracker, &max_precincts,
&max_res, precinctByComponent);

pi_ = new PacketIter[numProgressions];
for(uint32_t pino = 0; pino < numProgressions; ++pino)
Expand Down Expand Up @@ -107,7 +107,7 @@ void PacketManager::enable_tile_part_generation(uint32_t pino, bool first_poc_ti
}
void PacketManager::getParams(const GrkImage* image, const CodingParams* p_cp, uint16_t tileno,
grk_rect32* tileBounds, uint32_t* dx_min, uint32_t* dy_min,
uint64_t* numPrecinctsPerRes, uint64_t* max_precincts,
IncludeTracker* includeTracker, uint64_t* max_precincts,
uint8_t* max_res, uint32_t** precinctInfoByComponent)
{
assert(p_cp != nullptr);
Expand All @@ -123,11 +123,9 @@ void PacketManager::getParams(const GrkImage* image, const CodingParams* p_cp, u
*dx_min = UINT_MAX;
*dy_min = UINT_MAX;

if(numPrecinctsPerRes)
{
for(uint32_t i = 0; i < GRK_MAXRLVLS; ++i)
numPrecinctsPerRes[i] = 0;
}
// reset number of precincts per resolution
if(includeTracker)
includeTracker->resetNumPrecinctsPerRes();
auto tcp = &p_cp->tcps[tileno];
for(uint16_t compno = 0; compno < image->numcomps; ++compno)
{
Expand Down Expand Up @@ -171,8 +169,8 @@ void PacketManager::getParams(const GrkImage* image, const CodingParams* p_cp, u
*precinctInfo++ = precinctGridHeight;
}
uint64_t num_precincts = (uint64_t)precinctGridWidth * precinctGridHeight;
if(numPrecinctsPerRes && num_precincts > numPrecinctsPerRes[resno])
numPrecinctsPerRes[resno] = num_precincts;
if(includeTracker)
includeTracker->updateNumPrecinctsPerRes(resno, num_precincts);
if(num_precincts > *max_precincts)
*max_precincts = num_precincts;

Expand Down
2 changes: 1 addition & 1 deletion src/lib/core/t2/PacketManager.h
Original file line number Diff line number Diff line change
Expand Up @@ -89,7 +89,7 @@ class PacketManager
*/
static void getParams(const GrkImage* image, const CodingParams* p_cp, uint16_t tileno,
grk_rect32* tileBounds, uint32_t* dx_min, uint32_t* dy_min,
uint64_t* precincts, uint64_t* max_precincts, uint8_t* max_res,
IncludeTracker* tracker, uint64_t* max_precincts, uint8_t* max_res,
uint32_t** precinctByComponent);
GrkImage* image;
CodingParams* cp;
Expand Down

0 comments on commit fdab5ac

Please sign in to comment.