-
Notifications
You must be signed in to change notification settings - Fork 0
Using stages
Each GLADOS pipeline is a connection of stages. A single GLADOS stage runs in its own thread and has an I/O interface for communication with other stages. The input side of a single stage can be adressed by multiple predecessors, the output side transfers a data set to exactly one successor stage.
GLADOS stages define a run
function which encapsulates the actual implementation for this stage. They make no assumptions about the implementation itself apart from the restrictions which are mentioned below.
Implementations are passed to the stage
class via template parameters. Each implementation needs to define the following types in its public
or protected
interface:
-
input_type
: The type of the data which is passed to the current stage. Set tovoid
if there is noinput_type
for the current stage. -
output_type
: The type of the data which is passed to the next stage. Set tovoid
if there is nooutput_type
for the current stage.
Additionally, the following function signatures have to be defined in the public
or protected
interface for each stage:
-
void set_input_function(std::function<input_type(void)>)
: This passes an input callback function to the implementation. This callback can then be used to acquire the next element from the stage's input side. If there is noinput_type
(i.e.input_type
isvoid
), this function can be omitted. -
void set_output_function(std::function<void(output_type)>)
: This passes an output callback function to the implementation. This callback can then be used to send the currently processed element to the stage's output side. If there is nooutput_type
(i.e.output_type
isvoid
), this function can be omitted. -
void run()
: The implementation's entry point. This function must not be omitted. It is guaranteed by GLADOS thatset_input_function
andset_output_function
are called beforerun
. -
void assign_task(task_type)
: This function is only necessary if the current stage is part of atask_pipeline
and can be omitted otherwise. It passes the current task to the implementation.
- If your implementation needs setup parameters you should pass them via the implementation's
public
constructor. There is no restriction to the parameter types or number passed via the constructor. - If your implementation needs runtime parameters which cannot be passed via the constructor you need to define a
public
function which takes these paremeters.
An intermediate stage takes data from a predecessor stage, processes the data and then passes it to its successor stage.
#include <cstdint>
#include <functional>
#include <vector>
class some_stage
{
public:
using input_type = std::vector<std::uint8_t>;
using output_type = std::vector<float>;
public:
// setup parameters required for the implementation are passed via constructors
some_stage(std::uint8_t x, std::uint8_t y, std::int32_t v, std::int32_t w);
auto run() -> void;
auto set_input_function(std::function<input_type(void)> input) -> void;
auto set_output_function(std::function<void(output_type)> output) -> void;
private:
// to input data, call 'auto foo = input_()' internally
std::function<input_type(void)> input_;
// to output data, call 'output_(foo)' internally
std::function<void(output_type)> output_;
};
Usually the first stage in a pipeline, a source stage loads or generates the data passed into the pipeline. In most cases it does not need an input_type
.
#include <functional>
#include <string>
#include <vector>
class source_stage
{
public:
// no input_type needed, set it to void
using input_type = void;
using output_type = std::vector<float>;
public:
// setup parameters required for the implementation are passed via constructors
source_stage(const std::string& path);
auto run() -> void;
auto set_output_function(std::function<void(output_type)> output) -> void;
// no input_type: omitted set_input_function
private:
// to output data, call 'output_(foo)' internally
std::function<void(output_type)> output_;
};
Usually the last stage in a pipeline, a sink stage saves the processed data. In most cases it does not need an output_type
.
#include <functional>
#include <string>
#include <vector>
class sink_stage
{
public:
using input_type = std::vector<float>;
// no output_type needed, set it to void
using output_type = void;
public:
// setup parameters required for the implementation are passed via constructors
sink_stage(const std::string& dst);
auto run() -> void;
auto set_input_function(std::function<input_type(void)> input) -> void;
// no output_type: omitted set_output_function
private:
// to input data, call 'auto foo = input_()' internally
std::function<input_type(void)> input_;
};