Sequential
Sequential
can link multiple backends together. In other words, Sequential[DecodeTensor,ResizeTensor,cvtColorTensor,SyncTensor]
and Sequential[DecodeMat,ResizeMat]
are valid backends.
During the forward execution of Sequential[DecodeMat,ResizeMat]
, the data (dict) will go through the following process in sequence:
- Execute
DecodeMat
:DecodeMat
readsdata
and assigns the result toresult
andcolor
. - Conditional control flow: attempts to assign the value of
result
in the data todata
and deletesresult
. - Execute
ResizeMat
:ResizeMat
readsdata
and assigns the result to theresult
key.
Sequential
can be abbreviated as S
. API reference can be found in Sequential
.
Conditional Control Flow Filter
Sequential
itself implements support for control flow syntax extensions. In fact, S[DecodeMat,ResizeMat]
is equivalent to S[(Run)DecodeMat,(swap)ResizeMat]
.
The filters in ()
parentheses can return the following states:
- Run, which means that the current sub-backend can be skipped and wait to enter the next sub-backend (Effective from v0.3.2b1;
Continue
can be used in previous versions.) - Break, which means to exit the execution of
Sequential
- Error, which means an error occurred
- SerialSkip, which means that consecutive serial sub-backends can be skipped, equivalent to Break in
Sequential
- SubGraphSkip, which means that consecutive subgraphs can be skipped, equivalent to Break in
Sequential
Here are some built-in filter definitions:
- Run
- swap
#include "filter.hpp"
class FilterRun : public Filter {
public:
status forward(dict data) override { return Filter::status::Run; }
};
IPIPE_REGISTER(Filter, FilterRun, "Run,run");
class Filter {
public:
enum struct status { Run, Skip, SerialSkip, SubGraphSkip, Break, Error };
virtual bool init(const std::unordered_map<std::string, std::string>& /*config*/,
dict /*dict_config*/) {
return true;
};
virtual status forward(dict input) {
auto iter = input->find(TASK_RESULT_KEY);
if (iter == input->end()) {
return status::Break;
}
(*input)[TASK_DATA_KEY] = (*input)[TASK_RESULT_KEY];
input->erase(iter);
return status::Run;
}
virtual ~Filter() = default;
};
If four data enter this Sequential at the same time, but one of them fails to decode, then
- One data returns
status::Break
inswap
, while the others returnstatus::Run
. Sequential
continues to send the remaining three data to the next stage, while the data inBreak
state terminates the execution in Sequential.
The above describes the response when encountering Break
for some data; similarly, when encountering Skip
for some data, the data will be locally processed in a similar way. However, when a data is in Error
state, Sequential will consider the overall task status as Error
. If this contradicts the user's intention, the user can try to split the sub-backends into different Sequentials to avoid mutual interference. Note that the Error
state is generally extremely rare and unexpected.