Skip to main content

图的跳转

多级结构化

考虑在计算机视觉中的如下任务:

乍看之下似乎它形成了完整的有向无环图,然而实际中存在如下问题:

  • A. 目标检测产生了多个子目标(子上下文)进入了CDE,多个子目标又在F中发生了合并
  • B. 子目标在CDE中应该是相互独立的,不应该相互等待跑完某个节点再去跑下一个节点

关于A,我们认为是上下文发生了变化;子上下文流经了CED构成的独立的图。关于B,我们认为同级别的多个上下文在节点上不一定需要进行同步。

CDE形成了事实上的子图,然而我们发现很难用子图的视角进行通用的设计。本质上我们要处理一个以有向无环图为节点的有向无环图,并且可以是递归的。

我们需要用户将图拆为多个部分,进行图间跳转。

图的拆分

原始图可以拆成两部分。 主干:

其中MapReduce是一个功能性的后端,它将数据分裂为子上下文,送入以下图:

然后将E中的多个子上下文合并起来。

整体如下所示,跳转目标被当作了一个节点:

Jump

跳转到另外一个节点(需要是根节点)

上下文切换

对于不连通的两个图,多节点调度系统不共享节点的数据上下文。

初始化

说明备注
jump需要跳转到的目标图的根节点节点名;只能有一个

min()/max()

[1, UINT32_MAX]

MapReduce

MapReduce是Jump的子类,重新实现了split和merge操作。 MapReduce将一个输入数据拆分为多个(split操作), 跳转到其他图后进行计算,待所有计算完成后,将多个数据合并为一个(merge操作)。

初始化

说明备注
split待分裂的键值,多个以逗号分开默认值: "data", 为空时把自身作为分裂后的对象
merge待合并的键值,多个以逗号分开默认值: "result",不能为空
jump需要跳转到的目标图的根节点;只能有一个继承自基类Jump

前向计算

map

拷贝输入数据dict,将split键值对应的数据进行拆分。要求原始数据中split键值对应的数据类型是std::vector<T>.

reduce

根据merge参数进行结果合并,合并后的类型是std::vector<any>

警告

如果一个子任务失败(结果中没有result),那么以这种方式进行合并result时,将抛出异常,导致相关联的子任务都异常。一般来说,这种行为是可以接受的;但是如果需要允许子任务无result时,不影响关联子任务,可以考虑如下措施:

  • 自定义后端重新实现merge操作。
  • 使用context语法糖(MapReduce不会在执行split/merge时自动拷贝context)

min()/max()

[1, UINT32_MAX]

split和merge自定义扩展

默认的split和merge操作不一定能满足要求,我们可继承Jump进行自定义扩展:

#include "Jump.hpp"

class YourMapReduce : public ipipe::Jump{

virtual std::vector<dict> split(dict data) override{
return {data}; // <== Revise this implementation.
}
virtual dict merge(const std::vector<dict>& data) override{
return data[0];// <== Revise this implementation.
}

// 如果有自定义初始化参数需要接收,实现以下函数:
virtual bool post_init(const std::unordered_map<std::string, std::string>& config,
dict dict_config) override{
return true;
}
};

限制

目前跳转到多个节点是不支持的,多个节点合并也是不支持的,也就是目标图的根节点和叶子节点数量都需要是1.

以下图如果用户不增加中间节点,是没法处理的。