Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Multiple crops #32

Merged
merged 7 commits into from
Aug 1, 2024
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
32 changes: 31 additions & 1 deletion src/libpisp/backend/tiling/crop_stage.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@
using namespace tiling;

CropStage::CropStage(char const *name, Stage *upstream, Config const &config, int struct_offset)
: BasicStage(name, upstream->GetPipeline(), upstream, struct_offset), config_(config)
: BasicStage(name, upstream->GetPipeline(), upstream, struct_offset), config_(config), started_(false)
{
}

Expand All @@ -27,6 +27,11 @@ void CropStage::PushStartUp(int output_start, Dir dir)
PISP_LOG(debug, "(" << name_ << ") Enter with output_start " << output_start);

int input_start = output_start + config_.crop[dir].offset;
// input_start can never be negative here, but it is possible to have output_start
// negative if, for example, a branch starts producing output on the second
// tile in a row (or column) and the resampler requires left (or top) context pixels.
if (input_start < 0)
throw std::runtime_error("input start is negative: " + std::to_string(input_start));
output_interval_.offset = output_start;
input_interval_.offset = input_start;

Expand All @@ -39,6 +44,17 @@ int CropStage::PushEndDown(int input_end, Dir dir)
PISP_LOG(debug, "(" << name_ << ") Enter with input_end " << input_end);

int output_end = input_end - config_.crop[dir].offset;

// If negative, no output will be generated for this tile. Terminate the
// iteration here and don't go futher downstream.
if (output_end < 0)
{
PISP_LOG(debug, "(" << name_ << ") Output branch not started, terminating ");
return 0;
}

started_ = true;

if (output_end > config_.crop[dir].length)
output_end = config_.crop[dir].length;
input_interval_.SetEnd(input_end);
Expand All @@ -63,6 +79,15 @@ void CropStage::PushEndUp(int output_end, Dir dir)
void CropStage::PushCropDown(Interval interval, Dir dir)
{
PISP_LOG(debug, "(" << name_ << ") Enter with interval " << interval);

// Branch has not started producing output. Terminate the iteration here
// and don't go futher downstream.
if (!started_)
{
PISP_LOG(debug, "(" << name_ << ") Output branch not started, terminating ");
return;
}

PISP_ASSERT(interval > input_interval_);

input_interval_ = interval;
Expand All @@ -72,3 +97,8 @@ void CropStage::PushCropDown(Interval interval, Dir dir)
PISP_LOG(debug, "(" << name_ << ") Exit with interval " << output_interval_);
downstream_->PushCropDown(output_interval_, dir);
}

void CropStage::Reset()
{
started_ = false;
}
2 changes: 2 additions & 0 deletions src/libpisp/backend/tiling/crop_stage.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -25,9 +25,11 @@ class CropStage : public BasicStage
virtual int PushEndDown(int input_end, Dir dir);
virtual void PushEndUp(int output_end, Dir dir);
virtual void PushCropDown(Interval interval, Dir dir);
void Reset() override;

private:
Config config_;
bool started_;
};

} // namespace tiling
4 changes: 3 additions & 1 deletion src/libpisp/backend/tiling/pipeline.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@

using namespace tiling;

Pipeline::Pipeline(char const *name, Config const &config) : name_(name), config_(config)
Pipeline::Pipeline(char const *name, Config const &config) : name_(name), config_(config), first_tile_(false)
{
}

Expand Down Expand Up @@ -74,6 +74,7 @@ int Pipeline::tileDirection(Dir dir, void *mem, size_t num_items, size_t item_si
reset();
bool done = false;
unsigned int num_tiles = 0;
first_tile_ = true;
for (; !done; num_tiles++)
{
PISP_LOG(debug, "----------------------------------------------------------------");
Expand All @@ -94,6 +95,7 @@ int Pipeline::tileDirection(Dir dir, void *mem, size_t num_items, size_t item_si
done = true;
for (auto s : outputs_)
done &= s->Done(dir);
first_tile_ = false;
}

PISP_LOG(debug, "Made " << num_tiles << " tiles in direction " << dir);
Expand Down
2 changes: 2 additions & 0 deletions src/libpisp/backend/tiling/pipeline.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,7 @@ class Pipeline
void AddInputStage(InputStage *input_stage);
void AddOutputStage(OutputStage *output_stage);
void Tile(void *mem, size_t num_items, size_t item_size, Length2 *grid);
bool FirstTile() const { return first_tile_; }

private:
int tileDirection(Dir dir, void *mem, size_t num_items, size_t item_size);
Expand All @@ -46,6 +47,7 @@ class Pipeline
std::vector<Stage *> stages_;
std::vector<InputStage *> inputs_;
std::vector<OutputStage *> outputs_;
bool first_tile_;
};

} // namespace tiling
7 changes: 5 additions & 2 deletions src/libpisp/backend/tiling/rescale_stage.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -34,8 +34,11 @@ void RescaleStage::PushStartUp(int output_start, Dir dir)
int input_start_P = output_start * config_.scale[dir];
int input_start = input_start_P >> config_.precision;
int input_start_w_context = input_start - config_.start_context[dir];

if (input_start_w_context < 0)
// input_start_w_context is allowed to go negative here if, for example, the branch starts producing output
// on the second tile in a row/column and the resampler requires left context pixels. In such cases, the left/top
// edge flag will not be set on the tile and the hardware cannot remove the left/top context pixels. So allow
// negative values on all but the left/top edge tile.
if (GetPipeline()->FirstTile() && input_start_w_context < 0)
input_start_w_context = 0;
output_interval_.offset = output_start;
input_interval_.offset = input_start_w_context;
Expand Down