Java开发方式

开发前请先准备好ModelBox开发环境,详见环境准备章节。

Java SDK API接口说明

ModelBox提供了流程图的创建、运行、关闭等基础接口。下面是Java中使用的API列表:

API接口 参数说明 函数说明
Flow.init configfile: 指定config文件的路径
初始化ModelBox服务,主要包含功能如下:
1. 读取driver参数,获取driver的扫描路径
2. 扫描指定路径下的driver文件,并创建driver实例
3. 加载流程图并转换为ModelBox可识别的模型
4. 初始化设备信息,性能跟踪和数据统计单元
Flow.init name: 指定的图的名称
graph: 存储图的字符串
format:指定图的格式
与上面Init的区别是,上面通过读取文件的方式,而此函数通过读取字符串的方式,其他功能相同
Flow.RegisterFlowUnit flowunit_builder: 功能单元创建工厂 创建内联功能单元
Flow.startRun / 图的运行: 异步运行, 调用后直接返回, 通过调用Wait()函数判断运行是否结束
Flow.waitFor millisecond: 超时时间, 以毫秒为单位
ret_val: 图运行的结果
等待图运行结束,当图的运行时间超过millisecond表示的时间时,则强制停止图的运行,并返回TIMEOUT
Flow.stop() / 强制停止运行中的图
Flow.createExternalDataMap / 当图中的第一个节点为input节点时, 使用此函数可以创建一个输入的ExternalDataMap, 开发者可以通过向ExternalDataMap数据中赋值并传递数据给Input节点。
Flow.createStreamIO / 功能类似createExternalDataMap, 但更加简单易用。当图中的第一个节点为input节点时, 使用此函数可以创建一个输入的FlowStreamIO, 开发者可以通过向FlowStreamIO数据中赋值并传递数据给Input节点。

Java开发调用流程图时,需要先安装Java的运行包,然后再编写Java函数,调用Flow执行API执行流程图。

  1. 安装Java SDK包
  2. 开发流程图,配置基础部分和图部分。
  3. 调用Flow::init接口,输入流程图文件。
  4. 调用Flow::startRun初始化,并执行流程图。
  5. 数据输入,数据处理,结果获取。
  6. 调用Flow::stop释放图资源。

Java SDK包

java SDK包包含两部分,一个是libmodelbox-jni.so, 一个是modelbox-1.0.0.jar,通过编译modelbox源代码可以生成上述文件

cmake .. -DWITH_JAVA=on
make package

流程图配置

SDK模式的流程图的开发和标准模式基本一样,具体开发介绍见流程图开发章节。SDK模型区别可以通过设置input和output端口作为外部数据的输入和输出。具体配置如下:

[driver]
dir=""
[graph]
graphconf = '''digraph demo {
  input1[type=input] # 定义input类型端口,端口名为input1,用于外部输入数据
  resize[type=flowunit, flowunit=resize, device=cuda]
  model_detect[type=flowunit, flowunit=model_detect, device=cuda]
  yolobox_post[type=flowunit, flowunit=yolobox_post, device=cpu]
  output1[type=output] # 定义output类型端口,端口名为output1,用于外部获取输出结果

  input1 -> resize:in_image
  resize:out_image -> model_detect:in
  model_detect:output -> yolobox_post:in
  yolobox_post:out -> output1
}'''
format = "graphviz"

如上图,input1和output1端口作为图的输入和输出,如果需要设置多个外部输入输出端口,可按照图配置规则配置多个。

流程图运行

  • maven引入modelboxSDK包

      <dependency>
        <groupId>com.modelbox</groupId>
        <artifactId>modelbox</artifactId>
        <version>1.0.0</version>
      </dependency>
    
  • 导入ModelBox包

    编写时,需要引入头文件,并在编译时链接ModelBox库。

    import com.modelbox.Buffer;
    import com.modelbox.Flow;
    import com.modelbox.FlowStreamIO;
    import com.modelbox.Log;
    
    • 图创建初始化和启动
    public Flow CreateFlow(String file) throws ModelBoxException {
      // 创建Flow执行对象
      Flow flow = new Flow();
    
      // 输入流程图配置文件
      Log.info("run flow " + file);
      flow.init(file);
      // 异步执行
      flow.startRun();
      return flow;
    }
    
  • 外部数据交互

    发送数据到Modelbox框架处理:

    public void Process() {
      try {
        // 创建Flow执行对象
        Flow flow = CreateFlow("path/to/graph.toml")
    
        // 初始化输入流对象
        FlowStreamIO streamio = flow.CreateStreamIO();
    
        // 发送数据到Modelbox框架
        JSONObject json_data = new JSONObject("{\"msg\":\"hello world\"}");
        Log.info("send message: " + json_data.toString());
        streamio.send("input", json_data.toString().getBytes());
        // 结束输入
        streamio.closeInput();
    
        // 接收处理结果
        while (true) {
          // 获取处理结果。
          Buffer outdata = streamio.recv("output", 1000 * 10);
          if (outdata == null) {
            // 处理结束,返回
            break;
          }
    
          // 处理出错
          if (outdata.hasError()) {
            Log.error("recv error: " + outdata.getErrorCode());
            break;
          }
    
          // 获取到结果
          String str = new String(outdata.getData());
          Log.info("Message is: " + str);
        }
      } catch (ModelBoxException e) {
        // 错误处理
        Log.error(e.getMessage());
      }
    

开发者可以根据自身业务,选择在合适的地方调用图的启动停止和数据发送。如果用户业务是多线程时,可以将flow对象可作为多线程共享对象,每个线程都往同一流程图发生数据,这样可以充分利用ModelBox的bacth并发能力。

内联功能单元

在某些情况下,开发人员需要快速实现功能单元并参与流程图执行;Flow.RegisterFlowUnit接口提供了注册内联功能单元的功能,开发者人员可以使用此接口注册内联功能单元,具体方法如下:

  • 创建内联FlowUnit

    // 自定义功能单元
    public class CustomFlowUnit extends FlowUnit {
        // 工厂类
        public static class Builder extends FlowUnitBuilder {
            // 功能单元注册信息回调函数
            @Override
            public void probe(FlowUnitDesc desc) {
                // 功能单元类型: cpu
                desc.SetFlowUnitType("cpu");
                // 功能单元名称:参与流程图编排的时候使用
                desc.SetFlowUnitName("CustomFlowUnit");
                // 功能单元数据处理类型,NORMAL,或STREAM
                desc.SetFlowType(FlowUnitDesc.FlowType.NORMAL);
                // 输入端口
                desc.AddFlowUnitInput(new FlowUnitInput("in_data"));
                // 输出端口
                desc.AddFlowUnitOutput(new FlowUnitOutput("out_data"));
            }
    
            @Override
            public FlowUnit build() {
                // 创建对应的功能单元实例。
                return new CustomFlowUnit();
            }
        }
    
        @Override
        public void open(Configuration opt) throws ModelBoxException {
          // 功能单元open处理函数
        }
    
        @Override
        public Status process(DataContext context) throws ModelBoxException {
            // 功能单元处理函数
            BufferList in = context.input("in_data");
            BufferList out = context.output("out_data");
    
            // 处理每一个buffer。
            for (int i = 0; i < in.size(); i++) {
                out.pushBack(in.at(i));
            }
    
            return Status.OK();
        }
    
    }
    
  • 注册到Flow流程图中

    public void CreateFlow() {
      try {
        Flow flow = new Flow();
        // 注册功能单元
        flow.RegisterFlowUnit(new HelloWorldFlowUnit.Builder());
        ...
      } catch (ModelBoxException e) {
        // 错误处理
      }
    

Java日志

默认情况,ModelBox的SDK输出日志到console,业务需要注册相关的日志处理函数,注册方法可参考日志章节。

Java样例工程

本例提供了Java的HelloWorld样例工程,可以直接下载后使用。

http://download.modelbox-ai.com/example/project/java/hello-world.tar.gz

©2022 ModelBox Team all right reserved,powered by Gitbook文件修订时间: 2022-11-18 01:21:29

results matching ""

    No results matching ""