import dataflow as df
import numpy as np
import torch
import torch.nn as nn
class SimpleNet(nn.Module):
def __init__(self):
super(SimpleNet, self).__init__()
self.conv_relu = nn.Sequential(
nn.Conv2d(in_channels=3, out_channels=3, kernel_size=3, stride=1, padding=1),
nn.ReLU(),
)
def forward(self, x):
out = self.conv_relu(x)
return out
class MatMulNetwork(nn.Module):
def __init__(self, num_matrices):
super(MatMulNetwork, self).__init__()
self.matrices = nn.ModuleList([nn.Linear(32, 32) for _ in range(num_matrices)])
def forward(self, x):
result = x
for matrix in self.matrices:
result = torch.matmul(result, matrix.weight.T)
return result
@df.pyflow()
class ConvFunc:
def __init__(self):
self.model = SimpleNet().eval()
@df.method(num_returns=1)
@torch.inference_mode()
def compute(self, data):
return torch.mean(data.to(torch.float), dim=(0, 2, 3))
@df.pyflow()
class MatmulFunc:
def __init__(self):
self.model = MatMulNetwork(num_matrices=1).eval()
@df.method(num_returns=1)
@torch.inference_mode()
def compute(self, data):
return torch.mean(data.to(torch.float), dim=(0, 2, 3))
@df.pyflow(num_returns=1)
def convert_data(data):
return df.Tensor(data.numpy().astype(np.int32))
r"""
FlowData FlowData FlowData
| | /
| | /
| | /
SimpleNet MatMulNetwork /
\ / /
\ / /
\ / /
\ / /
FlowNode(onnx) /
GraphProcessPoint /
\ /
\ /
\ /
\ /
\/
FlowNode(pb)
GraphProcessPoint
"""
class SampleFlowGraph:
def __init__(self):
self.data0 = None
self.data1 = None
self.data2 = None
self.flow_graph = None
self.options = {
"ge.exec.deviceId": "0",
"ge.experiment.data_flow_deploy_info_path": "./config/multi_model_deploy.json",
}
def init(self):
df.init(self.options)
self.build_flow_graph()
def build_flow_graph(self):
self.data0 = df.FlowData()
self.data1 = df.FlowData()
self.data2 = df.FlowData()
conv_node = ConvFunc.fnode().set_alias("conv_model")
matmul_node = MatmulFunc.fnode().set_alias("matmul_model")
graph_pp0 = df.GraphProcessPoint(
df.Framework.ONNX,
"config/simple_model.onnx",
load_params={"input_data_names": "X1,X2"},
compile_config_path="config/add_graph.json",
)
onnx_node = df.FlowNode(input_num=2, output_num=1, name="onnx_node")
onnx_node.add_process_point(graph_pp0)
graph_pp1 = df.GraphProcessPoint(
df.Framework.TENSORFLOW,
"config/add.pb",
load_params={"input_data_names": "Placeholder,Placeholder_1"},
compile_config_path="config/add_graph.json",
)
pb_node = df.FlowNode(input_num=2, output_num=1, name="pb_node")
pb_node.add_process_point(graph_pp1)
conv_result = conv_node(self.data0)
matmul_result = matmul_node(self.data1)
convert_data0 = convert_data.fnode().set_alias("convert_data0")(conv_result)
convert_data1 = convert_data.fnode().set_alias("convert_data1")(matmul_result)
onnx_result = onnx_node(convert_data0, convert_data1)
pb_result = pb_node(onnx_result, self.data2)
self.flow_graph = df.FlowGraph([pb_result])
def feed(self, inputs):
feed_dict = {
self.data0: inputs["data0"],
self.data1: inputs["data1"],
self.data2: inputs["data2"],
}
self.flow_graph.feed(feed_dict, timeout=-1)
def fetch(self, indexes=None, timeout=1000 * 6 * 5):
return self.flow_graph.fetch(indexes=indexes, timeout=timeout)
def finalize(self):
df.finalize()
def main():
runner = SampleFlowGraph()
runner.init()
shape = (1, 3, 32, 32)
low = 0
high = 101
input0_tensor = torch.randint(low, high, shape, dtype=torch.int32)
input1_tensor = torch.randint(low, high, shape, dtype=torch.int32)
input2_tensor = df.Tensor(np.ones([3], dtype=np.int32))
inputs = {"data0": input0_tensor, "data1": input1_tensor, "data2": input2_tensor}
runner.feed(inputs)
output = runner.fetch()
print(f"Flow graph execute success. result is: {output}", flush=True)
runner.finalize()
if __name__ == "__main__":
main()