Browse Source

Add xmodel prototype

Lutz Roeder 4 years ago
parent
commit
a8225fa5dd
8 changed files with 2042 additions and 2 deletions
  1. 1 0
      Makefile
  2. 2 0
      electron-builder.yml
  3. 1 1
      source/app.js
  4. 1 1
      source/index.html
  5. 1 0
      source/view.js
  6. 1649 0
      source/xmodel-proto.js
  7. 351 0
      source/xmodel.js
  8. 36 0
      tools/xmodel

+ 1 - 0
Makefile

@@ -32,6 +32,7 @@ update: install
 	@./tools/sklearn sync install metadata
 	@./tools/tf sync install schema metadata
 	@./tools/uff schema
+	@./tools/xmodel sync schema
 
 build_python: install
 	python -m pip install --user wheel

+ 2 - 0
electron-builder.yml

@@ -67,6 +67,8 @@ fileAssociations:
     ext: pdparams
   - name: "RKNN"
     ext: rknn
+  - name: "Vitis-AI xmodel"
+    ext: xmodel
 afterSign: "./publish/notarize.js"
 publish:
   - provider: github

+ 1 - 1
source/app.js

@@ -158,7 +158,7 @@ class Application {
                     'pdmodel', 'pdparams',
                     'meta',
                     'tflite', 'lite', 'tfl',
-                    'armnn', 'mnn', 'nn', 'uff', 'uff.txt', 'rknn',
+                    'armnn', 'mnn', 'nn', 'uff', 'uff.txt', 'rknn', 'xmodel',
                     'ncnn', 'param', 'tnnproto', 'tmfile', 'ms',
                     'pt', 'pth', 't7',
                     'pkl', 'joblib',

+ 1 - 1
source/index.html

@@ -345,7 +345,7 @@ body { touch-action: none; overflow: hidden; width: 100%; height: 100%; margin:
     <button id="consent-accept-button" class="center consent-accept-button">Accept</button>
     <button id="open-file-button" class="center open-file-button">Open Model&hellip;</button>
     <button id="github-button" class="center github-button">GitHub</button>
-    <input type="file" id="open-file-dialog" class="open-file-dialog" multiple="false" accept=".onnx, .pb, .meta, .tflite, .lite, .tfl, .keras, .h5, .hd5, .hdf5, .json, .model, .mar, .params, .param, .armnn, .mnn, .ncnn, .tnnproto, .tmfile, .ms, .nn, .uff, .rknn, .paddle, .pdmodel, .pdparams, .dnn, .cmf, .mlmodel, .caffemodel, .pbtxt, .prototxt, .pkl, .pt, .pth, .t7, .joblib, .cfg, .xml, .zip, .tar">
+    <input type="file" id="open-file-dialog" class="open-file-dialog" multiple="false" accept=".onnx, .pb, .meta, .tflite, .lite, .tfl, .keras, .h5, .hd5, .hdf5, .json, .model, .mar, .params, .param, .armnn, .mnn, .ncnn, .tnnproto, .tmfile, .ms, .nn, .uff, .rknn, .xmodel, .paddle, .pdmodel, .pdparams, .dnn, .cmf, .mlmodel, .caffemodel, .pbtxt, .prototxt, .pkl, .pt, .pth, .t7, .joblib, .cfg, .xml, .zip, .tar">
     <!-- Preload fonts to workaround Chrome SVG layout issue -->
     <div style="font-weight: normal; color: rgba(0, 0, 0, 0.01); user-select: none;">.</div>
     <div style="font-weight: bold; color: rgba(0, 0, 0, 0.01); user-select: none;">.</div>

+ 1 - 0
source/view.js

@@ -1409,6 +1409,7 @@ view.ModelFactoryService = class {
         this.register('./mslite', [ '.ms']);
         this.register('./barracuda', [ '.nn' ]);
         this.register('./dnn', [ '.dnn' ]);
+        this.register('./xmodel', [ '.xmodel' ]);
         this.register('./openvino', [ '.xml', '.bin' ]);
         this.register('./flux', [ '.bson' ]);
         this.register('./dl4j', [ '.zip' ]);

+ 1649 - 0
source/xmodel-proto.js

@@ -0,0 +1,1649 @@
+var $root = protobuf.get('xmodel');
+
+$root.serial_v2 = {};
+
+$root.serial_v2.Graph = class Graph {
+
+    constructor() {
+        this.op_node = [];
+        this.graph_attr = {};
+        this.op_defs = [];
+    }
+
+    static decode(reader, length) {
+        const message = new $root.serial_v2.Graph();
+        const end = length !== undefined ? reader.position + length : reader.length;
+        while (reader.position < end) {
+            const tag = reader.uint32();
+            switch (tag >>> 3) {
+                case 1:
+                    message.graph_name = reader.string();
+                    break;
+                case 5:
+                    message.op_node.push($root.serial_v2.OPNode.decode(reader, reader.uint32()));
+                    break;
+                case 10:
+                    message.subg_root = $root.serial_v2.SubGraph.decode(reader, reader.uint32());
+                    break;
+                case 11:
+                    reader.entry(message.graph_attr, () => reader.string(), () => $root.serial_v2.AttrValue.decode(reader, reader.uint32()));
+                    break;
+                case 101:
+                    message.op_defs.push($root.serial_v2.OpDef.decode(reader, reader.uint32()));
+                    break;
+                default:
+                    reader.skipType(tag & 7);
+                    break;
+            }
+        }
+        return message;
+    }
+
+    static decodeText(reader) {
+        const message = new $root.serial_v2.Graph();
+        reader.start();
+        while (!reader.end()) {
+            const tag = reader.tag();
+            switch (tag) {
+                case "graph_name":
+                    message.graph_name = reader.string();
+                    break;
+                case "op_node":
+                    message.op_node.push($root.serial_v2.OPNode.decodeText(reader));
+                    break;
+                case "subg_root":
+                    message.subg_root = $root.serial_v2.SubGraph.decodeText(reader);
+                    break;
+                case "graph_attr":
+                    reader.entry(message.graph_attr, () => reader.string(), () => $root.serial_v2.AttrValue.decodeText(reader));
+                    break;
+                case "op_defs":
+                    message.op_defs.push($root.serial_v2.OpDef.decodeText(reader));
+                    break;
+                default:
+                    reader.field(tag, message);
+                    break;
+            }
+        }
+        return message;
+    }
+};
+
+$root.serial_v2.Graph.prototype.graph_name = "";
+$root.serial_v2.Graph.prototype.subg_root = null;
+
+$root.serial_v2.OPNode = class OPNode {
+
+    constructor() {
+        this.op_attr = {};
+        this.args = [];
+    }
+
+    static decode(reader, length) {
+        const message = new $root.serial_v2.OPNode();
+        const end = length !== undefined ? reader.position + length : reader.length;
+        while (reader.position < end) {
+            const tag = reader.uint32();
+            switch (tag >>> 3) {
+                case 1:
+                    message.op_name = reader.string();
+                    break;
+                case 2:
+                    message.op_type = reader.string();
+                    break;
+                case 3:
+                    reader.entry(message.op_attr, () => reader.string(), () => $root.serial_v2.AttrValue.decode(reader, reader.uint32()));
+                    break;
+                case 4:
+                    message.args.push($root.serial_v2.OpArg.decode(reader, reader.uint32()));
+                    break;
+                case 5:
+                    message.output_tensor = $root.serial_v2.Tensor.decode(reader, reader.uint32());
+                    break;
+                default:
+                    reader.skipType(tag & 7);
+                    break;
+            }
+        }
+        return message;
+    }
+
+    static decodeText(reader) {
+        const message = new $root.serial_v2.OPNode();
+        reader.start();
+        while (!reader.end()) {
+            const tag = reader.tag();
+            switch (tag) {
+                case "op_name":
+                    message.op_name = reader.string();
+                    break;
+                case "op_type":
+                    message.op_type = reader.string();
+                    break;
+                case "op_attr":
+                    reader.entry(message.op_attr, () => reader.string(), () => $root.serial_v2.AttrValue.decodeText(reader));
+                    break;
+                case "args":
+                    message.args.push($root.serial_v2.OpArg.decodeText(reader));
+                    break;
+                case "output_tensor":
+                    message.output_tensor = $root.serial_v2.Tensor.decodeText(reader);
+                    break;
+                default:
+                    reader.field(tag, message);
+                    break;
+            }
+        }
+        return message;
+    }
+};
+
+$root.serial_v2.OPNode.prototype.op_name = "";
+$root.serial_v2.OPNode.prototype.op_type = "";
+$root.serial_v2.OPNode.prototype.output_tensor = null;
+
+$root.serial_v2.OpArg = class OpArg {
+
+    constructor() {
+        this.arg_ops = [];
+    }
+
+    static decode(reader, length) {
+        const message = new $root.serial_v2.OpArg();
+        const end = length !== undefined ? reader.position + length : reader.length;
+        while (reader.position < end) {
+            const tag = reader.uint32();
+            switch (tag >>> 3) {
+                case 1:
+                    message.arg_name = reader.string();
+                    break;
+                case 2:
+                    message.arg_ops.push(reader.string());
+                    break;
+                default:
+                    reader.skipType(tag & 7);
+                    break;
+            }
+        }
+        return message;
+    }
+
+    static decodeText(reader) {
+        const message = new $root.serial_v2.OpArg();
+        reader.start();
+        while (!reader.end()) {
+            const tag = reader.tag();
+            switch (tag) {
+                case "arg_name":
+                    message.arg_name = reader.string();
+                    break;
+                case "arg_ops":
+                    reader.array(message.arg_ops, () => reader.string());
+                    break;
+                default:
+                    reader.field(tag, message);
+                    break;
+            }
+        }
+        return message;
+    }
+};
+
+$root.serial_v2.OpArg.prototype.arg_name = "";
+
+$root.serial_v2.Tensor = class Tensor {
+
+    constructor() {
+        this.tensor_dim = [];
+        this.tensor_attr = {};
+    }
+
+    static decode(reader, length) {
+        const message = new $root.serial_v2.Tensor();
+        const end = length !== undefined ? reader.position + length : reader.length;
+        while (reader.position < end) {
+            const tag = reader.uint32();
+            switch (tag >>> 3) {
+                case 1:
+                    message.tensor_name = reader.string();
+                    break;
+                case 2:
+                    message.tensor_dim = reader.array(message.tensor_dim, () => reader.uint32(), tag);
+                    break;
+                case 5:
+                    message.data_type = reader.int32();
+                    break;
+                case 6:
+                    message.tensor_bit_width = reader.int32();
+                    break;
+                case 10:
+                    reader.entry(message.tensor_attr, () => reader.string(), () => $root.serial_v2.AttrValue.decode(reader, reader.uint32()));
+                    break;
+                default:
+                    reader.skipType(tag & 7);
+                    break;
+            }
+        }
+        return message;
+    }
+
+    static decodeText(reader) {
+        const message = new $root.serial_v2.Tensor();
+        reader.start();
+        while (!reader.end()) {
+            const tag = reader.tag();
+            switch (tag) {
+                case "tensor_name":
+                    message.tensor_name = reader.string();
+                    break;
+                case "tensor_dim":
+                    reader.array(message.tensor_dim, () => reader.integer());
+                    break;
+                case "data_type":
+                    message.data_type = reader.integer();
+                    break;
+                case "tensor_bit_width":
+                    message.tensor_bit_width = reader.integer();
+                    break;
+                case "tensor_attr":
+                    reader.entry(message.tensor_attr, () => reader.string(), () => $root.serial_v2.AttrValue.decodeText(reader));
+                    break;
+                default:
+                    reader.field(tag, message);
+                    break;
+            }
+        }
+        return message;
+    }
+};
+
+$root.serial_v2.Tensor.prototype.tensor_name = "";
+$root.serial_v2.Tensor.prototype.data_type = 0;
+$root.serial_v2.Tensor.prototype.tensor_bit_width = 0;
+
+$root.serial_v2.SubGraph = class SubGraph {
+
+    constructor() {
+        this.op_name = [];
+        this.subg_attr = {};
+        this.subg_child = [];
+    }
+
+    static decode(reader, length) {
+        const message = new $root.serial_v2.SubGraph();
+        const end = length !== undefined ? reader.position + length : reader.length;
+        while (reader.position < end) {
+            const tag = reader.uint32();
+            switch (tag >>> 3) {
+                case 1:
+                    message.subgraph_name = reader.string();
+                    break;
+                case 3:
+                    message.op_name.push(reader.string());
+                    break;
+                case 5:
+                    reader.entry(message.subg_attr, () => reader.string(), () => $root.serial_v2.AttrValue.decode(reader, reader.uint32()));
+                    break;
+                case 10:
+                    message.subg_child.push($root.serial_v2.SubGraph.decode(reader, reader.uint32()));
+                    break;
+                default:
+                    reader.skipType(tag & 7);
+                    break;
+            }
+        }
+        return message;
+    }
+
+    static decodeText(reader) {
+        const message = new $root.serial_v2.SubGraph();
+        reader.start();
+        while (!reader.end()) {
+            const tag = reader.tag();
+            switch (tag) {
+                case "subgraph_name":
+                    message.subgraph_name = reader.string();
+                    break;
+                case "op_name":
+                    reader.array(message.op_name, () => reader.string());
+                    break;
+                case "subg_attr":
+                    reader.entry(message.subg_attr, () => reader.string(), () => $root.serial_v2.AttrValue.decodeText(reader));
+                    break;
+                case "subg_child":
+                    message.subg_child.push($root.serial_v2.SubGraph.decodeText(reader));
+                    break;
+                default:
+                    reader.field(tag, message);
+                    break;
+            }
+        }
+        return message;
+    }
+};
+
+$root.serial_v2.SubGraph.prototype.subgraph_name = "";
+
+$root.serial_v2.OpDef = class OpDef {
+
+    constructor() {
+        this.input_args = [];
+        this.attrs = [];
+    }
+
+    static decode(reader, length) {
+        const message = new $root.serial_v2.OpDef();
+        const end = length !== undefined ? reader.position + length : reader.length;
+        while (reader.position < end) {
+            const tag = reader.uint32();
+            switch (tag >>> 3) {
+                case 1:
+                    message.name = reader.string();
+                    break;
+                case 2:
+                    message.input_args.push($root.serial_v2.OpArgDef.decode(reader, reader.uint32()));
+                    break;
+                case 3:
+                    message.attrs.push($root.serial_v2.AttrDef.decode(reader, reader.uint32()));
+                    break;
+                case 4:
+                    message.annotation = reader.string();
+                    break;
+                default:
+                    reader.skipType(tag & 7);
+                    break;
+            }
+        }
+        return message;
+    }
+
+    static decodeText(reader) {
+        const message = new $root.serial_v2.OpDef();
+        reader.start();
+        while (!reader.end()) {
+            const tag = reader.tag();
+            switch (tag) {
+                case "name":
+                    message.name = reader.string();
+                    break;
+                case "input_args":
+                    message.input_args.push($root.serial_v2.OpArgDef.decodeText(reader));
+                    break;
+                case "attrs":
+                    message.attrs.push($root.serial_v2.AttrDef.decodeText(reader));
+                    break;
+                case "annotation":
+                    message.annotation = reader.string();
+                    break;
+                default:
+                    reader.field(tag, message);
+                    break;
+            }
+        }
+        return message;
+    }
+};
+
+$root.serial_v2.OpDef.prototype.name = "";
+$root.serial_v2.OpDef.prototype.annotation = "";
+
+$root.serial_v2.AttrDef = class AttrDef {
+
+    constructor() {
+    }
+
+    static decode(reader, length) {
+        const message = new $root.serial_v2.AttrDef();
+        const end = length !== undefined ? reader.position + length : reader.length;
+        while (reader.position < end) {
+            const tag = reader.uint32();
+            switch (tag >>> 3) {
+                case 1:
+                    message.name = reader.string();
+                    break;
+                case 3:
+                    message.occur_type = reader.int32();
+                    break;
+                case 4:
+                    message.default_value = $root.serial_v2.AttrValue.decode(reader, reader.uint32());
+                    break;
+                case 6:
+                    message.list_length = reader.int32();
+                    break;
+                case 7:
+                    message.annotation = reader.string();
+                    break;
+                default:
+                    reader.skipType(tag & 7);
+                    break;
+            }
+        }
+        return message;
+    }
+
+    static decodeText(reader) {
+        const message = new $root.serial_v2.AttrDef();
+        reader.start();
+        while (!reader.end()) {
+            const tag = reader.tag();
+            switch (tag) {
+                case "name":
+                    message.name = reader.string();
+                    break;
+                case "occur_type":
+                    message.occur_type = reader.enum($root.serial_v2.AttrDef.OccurType);
+                    break;
+                case "default_value":
+                    message.default_value = $root.serial_v2.AttrValue.decodeText(reader);
+                    break;
+                case "list_length":
+                    message.list_length = reader.integer();
+                    break;
+                case "annotation":
+                    message.annotation = reader.string();
+                    break;
+                default:
+                    reader.field(tag, message);
+                    break;
+            }
+        }
+        return message;
+    }
+};
+
+$root.serial_v2.AttrDef.prototype.name = "";
+$root.serial_v2.AttrDef.prototype.occur_type = 0;
+$root.serial_v2.AttrDef.prototype.default_value = null;
+$root.serial_v2.AttrDef.prototype.list_length = 0;
+$root.serial_v2.AttrDef.prototype.annotation = "";
+
+$root.serial_v2.AttrDef.OccurType = {
+    "REQUIRED": 0,
+    "OPTIONAL": 1
+};
+
+$root.serial_v2.OpArgDef = class OpArgDef {
+
+    constructor() {
+    }
+
+    static decode(reader, length) {
+        const message = new $root.serial_v2.OpArgDef();
+        const end = length !== undefined ? reader.position + length : reader.length;
+        while (reader.position < end) {
+            const tag = reader.uint32();
+            switch (tag >>> 3) {
+                case 1:
+                    message.name = reader.string();
+                    break;
+                case 2:
+                    message.occur_type = reader.int32();
+                    break;
+                case 3:
+                    message.data_type = reader.int32();
+                    break;
+                case 4:
+                    message.annotation = reader.string();
+                    break;
+                default:
+                    reader.skipType(tag & 7);
+                    break;
+            }
+        }
+        return message;
+    }
+
+    static decodeText(reader) {
+        const message = new $root.serial_v2.OpArgDef();
+        reader.start();
+        while (!reader.end()) {
+            const tag = reader.tag();
+            switch (tag) {
+                case "name":
+                    message.name = reader.string();
+                    break;
+                case "occur_type":
+                    message.occur_type = reader.enum($root.serial_v2.OpArgDef.OccurType);
+                    break;
+                case "data_type":
+                    message.data_type = reader.integer();
+                    break;
+                case "annotation":
+                    message.annotation = reader.string();
+                    break;
+                default:
+                    reader.field(tag, message);
+                    break;
+            }
+        }
+        return message;
+    }
+};
+
+$root.serial_v2.OpArgDef.prototype.name = "";
+$root.serial_v2.OpArgDef.prototype.occur_type = 0;
+$root.serial_v2.OpArgDef.prototype.data_type = 0;
+$root.serial_v2.OpArgDef.prototype.annotation = "";
+
+$root.serial_v2.OpArgDef.OccurType = {
+    "REQUIRED": 0,
+    "OPTIONAL": 1,
+    "REPEATED": 2,
+    "REQUIRED_AND_REPEATED": 3
+};
+
+$root.serial_v2.AttrValue = class AttrValue {
+
+    constructor() {
+    }
+
+    get value() {
+        $root.serial_v2.AttrValue.valueSet = $root.serial_v2.AttrValue.valueSet || new Set([ "bool_value", "int32_value", "uint32_value", "int64_value", "uint64_value", "float_value", "double_value", "string_value", "bytes_value", "bool_vec_value", "int32_vec_value", "uint32_vec_value", "int64_vec_value", "uint64_vec_value", "float_vec_value", "double_vec_value", "string_vec_value", "bytes_vec_value", "map_string_2_int32_value", "map_string_2_uint32_value", "map_string_2_int64_value", "map_string_2_uint64_value", "map_string_2_string_value", "map_string_2_bytes_value", "map_string_2_int32_vec_value", "map_string_2_uint32_vec_value", "map_string_2_int64_vec_value", "map_string_2_uint64_vec_value", "map_string_2_string_vec_value"]);
+        return Object.keys(this).find((key) => $root.serial_v2.AttrValue.valueSet.has(key) && this[key] != null);
+    }
+
+    static decode(reader, length) {
+        const message = new $root.serial_v2.AttrValue();
+        const end = length !== undefined ? reader.position + length : reader.length;
+        while (reader.position < end) {
+            const tag = reader.uint32();
+            switch (tag >>> 3) {
+                case 4:
+                    message.bool_value = reader.bool();
+                    break;
+                case 5:
+                    message.int32_value = reader.int32();
+                    break;
+                case 6:
+                    message.uint32_value = reader.uint32();
+                    break;
+                case 7:
+                    message.int64_value = reader.int64();
+                    break;
+                case 8:
+                    message.uint64_value = reader.uint64();
+                    break;
+                case 9:
+                    message.float_value = reader.float();
+                    break;
+                case 10:
+                    message.double_value = reader.double();
+                    break;
+                case 11:
+                    message.string_value = reader.string();
+                    break;
+                case 12:
+                    message.bytes_value = $root.serial_v2.Bytes.decode(reader, reader.uint32());
+                    break;
+                case 13:
+                    message.bool_vec_value = $root.serial_v2.BoolVec.decode(reader, reader.uint32());
+                    break;
+                case 14:
+                    message.int32_vec_value = $root.serial_v2.Int32Vec.decode(reader, reader.uint32());
+                    break;
+                case 15:
+                    message.uint32_vec_value = $root.serial_v2.Uint32Vec.decode(reader, reader.uint32());
+                    break;
+                case 16:
+                    message.int64_vec_value = $root.serial_v2.Int64Vec.decode(reader, reader.uint32());
+                    break;
+                case 17:
+                    message.uint64_vec_value = $root.serial_v2.Uint64Vec.decode(reader, reader.uint32());
+                    break;
+                case 18:
+                    message.float_vec_value = $root.serial_v2.FloatVec.decode(reader, reader.uint32());
+                    break;
+                case 19:
+                    message.double_vec_value = $root.serial_v2.DoubleVec.decode(reader, reader.uint32());
+                    break;
+                case 20:
+                    message.string_vec_value = $root.serial_v2.StringVec.decode(reader, reader.uint32());
+                    break;
+                case 21:
+                    message.bytes_vec_value = $root.serial_v2.BytesVec.decode(reader, reader.uint32());
+                    break;
+                case 22:
+                    message.map_string_2_int32_value = $root.serial_v2.MapString2Int32.decode(reader, reader.uint32());
+                    break;
+                case 23:
+                    message.map_string_2_uint32_value = $root.serial_v2.MapString2Uint32.decode(reader, reader.uint32());
+                    break;
+                case 24:
+                    message.map_string_2_int64_value = $root.serial_v2.MapString2Int64.decode(reader, reader.uint32());
+                    break;
+                case 25:
+                    message.map_string_2_uint64_value = $root.serial_v2.MapString2Uint64.decode(reader, reader.uint32());
+                    break;
+                case 26:
+                    message.map_string_2_string_value = $root.serial_v2.MapString2String.decode(reader, reader.uint32());
+                    break;
+                case 27:
+                    message.map_string_2_bytes_value = $root.serial_v2.MapString2Bytes.decode(reader, reader.uint32());
+                    break;
+                case 28:
+                    message.map_string_2_int32_vec_value = $root.serial_v2.MapString2Int32Vec.decode(reader, reader.uint32());
+                    break;
+                case 29:
+                    message.map_string_2_uint32_vec_value = $root.serial_v2.MapString2Uint32Vec.decode(reader, reader.uint32());
+                    break;
+                case 30:
+                    message.map_string_2_int64_vec_value = $root.serial_v2.MapString2Int64Vec.decode(reader, reader.uint32());
+                    break;
+                case 31:
+                    message.map_string_2_uint64_vec_value = $root.serial_v2.MapString2Uint64Vec.decode(reader, reader.uint32());
+                    break;
+                case 32:
+                    message.map_string_2_string_vec_value = $root.serial_v2.MapString2StringVec.decode(reader, reader.uint32());
+                    break;
+                default:
+                    reader.skipType(tag & 7);
+                    break;
+            }
+        }
+        return message;
+    }
+
+    static decodeText(reader) {
+        const message = new $root.serial_v2.AttrValue();
+        reader.start();
+        while (!reader.end()) {
+            const tag = reader.tag();
+            switch (tag) {
+                case "bool_value":
+                    message.bool_value = reader.boolean();
+                    break;
+                case "int32_value":
+                    message.int32_value = reader.integer();
+                    break;
+                case "uint32_value":
+                    message.uint32_value = reader.integer();
+                    break;
+                case "int64_value":
+                    message.int64_value = reader.integer();
+                    break;
+                case "uint64_value":
+                    message.uint64_value = reader.integer();
+                    break;
+                case "float_value":
+                    message.float_value = reader.float();
+                    break;
+                case "double_value":
+                    message.double_value = reader.float();
+                    break;
+                case "string_value":
+                    message.string_value = reader.string();
+                    break;
+                case "bytes_value":
+                    message.bytes_value = $root.serial_v2.Bytes.decodeText(reader);
+                    break;
+                case "bool_vec_value":
+                    message.bool_vec_value = $root.serial_v2.BoolVec.decodeText(reader);
+                    break;
+                case "int32_vec_value":
+                    message.int32_vec_value = $root.serial_v2.Int32Vec.decodeText(reader);
+                    break;
+                case "uint32_vec_value":
+                    message.uint32_vec_value = $root.serial_v2.Uint32Vec.decodeText(reader);
+                    break;
+                case "int64_vec_value":
+                    message.int64_vec_value = $root.serial_v2.Int64Vec.decodeText(reader);
+                    break;
+                case "uint64_vec_value":
+                    message.uint64_vec_value = $root.serial_v2.Uint64Vec.decodeText(reader);
+                    break;
+                case "float_vec_value":
+                    message.float_vec_value = $root.serial_v2.FloatVec.decodeText(reader);
+                    break;
+                case "double_vec_value":
+                    message.double_vec_value = $root.serial_v2.DoubleVec.decodeText(reader);
+                    break;
+                case "string_vec_value":
+                    message.string_vec_value = $root.serial_v2.StringVec.decodeText(reader);
+                    break;
+                case "bytes_vec_value":
+                    message.bytes_vec_value = $root.serial_v2.BytesVec.decodeText(reader);
+                    break;
+                case "map_string_2_int32_value":
+                    message.map_string_2_int32_value = $root.serial_v2.MapString2Int32.decodeText(reader);
+                    break;
+                case "map_string_2_uint32_value":
+                    message.map_string_2_uint32_value = $root.serial_v2.MapString2Uint32.decodeText(reader);
+                    break;
+                case "map_string_2_int64_value":
+                    message.map_string_2_int64_value = $root.serial_v2.MapString2Int64.decodeText(reader);
+                    break;
+                case "map_string_2_uint64_value":
+                    message.map_string_2_uint64_value = $root.serial_v2.MapString2Uint64.decodeText(reader);
+                    break;
+                case "map_string_2_string_value":
+                    message.map_string_2_string_value = $root.serial_v2.MapString2String.decodeText(reader);
+                    break;
+                case "map_string_2_bytes_value":
+                    message.map_string_2_bytes_value = $root.serial_v2.MapString2Bytes.decodeText(reader);
+                    break;
+                case "map_string_2_int32_vec_value":
+                    message.map_string_2_int32_vec_value = $root.serial_v2.MapString2Int32Vec.decodeText(reader);
+                    break;
+                case "map_string_2_uint32_vec_value":
+                    message.map_string_2_uint32_vec_value = $root.serial_v2.MapString2Uint32Vec.decodeText(reader);
+                    break;
+                case "map_string_2_int64_vec_value":
+                    message.map_string_2_int64_vec_value = $root.serial_v2.MapString2Int64Vec.decodeText(reader);
+                    break;
+                case "map_string_2_uint64_vec_value":
+                    message.map_string_2_uint64_vec_value = $root.serial_v2.MapString2Uint64Vec.decodeText(reader);
+                    break;
+                case "map_string_2_string_vec_value":
+                    message.map_string_2_string_vec_value = $root.serial_v2.MapString2StringVec.decodeText(reader);
+                    break;
+                default:
+                    reader.field(tag, message);
+                    break;
+            }
+        }
+        return message;
+    }
+};
+
+$root.serial_v2.Bytes = class Bytes {
+
+    constructor() {
+    }
+
+    static decode(reader, length) {
+        const message = new $root.serial_v2.Bytes();
+        const end = length !== undefined ? reader.position + length : reader.length;
+        while (reader.position < end) {
+            const tag = reader.uint32();
+            switch (tag >>> 3) {
+                case 1:
+                    message.value = reader.bytes();
+                    break;
+                default:
+                    reader.skipType(tag & 7);
+                    break;
+            }
+        }
+        return message;
+    }
+
+    static decodeText(reader) {
+        const message = new $root.serial_v2.Bytes();
+        reader.start();
+        while (!reader.end()) {
+            const tag = reader.tag();
+            switch (tag) {
+                case "value":
+                    message.value = reader.bytes();
+                    break;
+                default:
+                    reader.field(tag, message);
+                    break;
+            }
+        }
+        return message;
+    }
+};
+
+$root.serial_v2.Bytes.prototype.value = new Uint8Array([]);
+
+$root.serial_v2.BoolVec = class BoolVec {
+
+    constructor() {
+        this.value = [];
+    }
+
+    static decode(reader, length) {
+        const message = new $root.serial_v2.BoolVec();
+        const end = length !== undefined ? reader.position + length : reader.length;
+        while (reader.position < end) {
+            const tag = reader.uint32();
+            switch (tag >>> 3) {
+                case 1:
+                    message.value = reader.array(message.value, () => reader.bool(), tag);
+                    break;
+                default:
+                    reader.skipType(tag & 7);
+                    break;
+            }
+        }
+        return message;
+    }
+
+    static decodeText(reader) {
+        const message = new $root.serial_v2.BoolVec();
+        reader.start();
+        while (!reader.end()) {
+            const tag = reader.tag();
+            switch (tag) {
+                case "value":
+                    reader.array(message.value, () => reader.boolean());
+                    break;
+                default:
+                    reader.field(tag, message);
+                    break;
+            }
+        }
+        return message;
+    }
+};
+
+$root.serial_v2.Int32Vec = class Int32Vec {
+
+    constructor() {
+        this.value = [];
+    }
+
+    static decode(reader, length) {
+        const message = new $root.serial_v2.Int32Vec();
+        const end = length !== undefined ? reader.position + length : reader.length;
+        while (reader.position < end) {
+            const tag = reader.uint32();
+            switch (tag >>> 3) {
+                case 1:
+                    message.value = reader.array(message.value, () => reader.int32(), tag);
+                    break;
+                default:
+                    reader.skipType(tag & 7);
+                    break;
+            }
+        }
+        return message;
+    }
+
+    static decodeText(reader) {
+        const message = new $root.serial_v2.Int32Vec();
+        reader.start();
+        while (!reader.end()) {
+            const tag = reader.tag();
+            switch (tag) {
+                case "value":
+                    reader.array(message.value, () => reader.integer());
+                    break;
+                default:
+                    reader.field(tag, message);
+                    break;
+            }
+        }
+        return message;
+    }
+};
+
+$root.serial_v2.Uint32Vec = class Uint32Vec {
+
+    constructor() {
+        this.value = [];
+    }
+
+    static decode(reader, length) {
+        const message = new $root.serial_v2.Uint32Vec();
+        const end = length !== undefined ? reader.position + length : reader.length;
+        while (reader.position < end) {
+            const tag = reader.uint32();
+            switch (tag >>> 3) {
+                case 1:
+                    message.value = reader.array(message.value, () => reader.uint32(), tag);
+                    break;
+                default:
+                    reader.skipType(tag & 7);
+                    break;
+            }
+        }
+        return message;
+    }
+
+    static decodeText(reader) {
+        const message = new $root.serial_v2.Uint32Vec();
+        reader.start();
+        while (!reader.end()) {
+            const tag = reader.tag();
+            switch (tag) {
+                case "value":
+                    reader.array(message.value, () => reader.integer());
+                    break;
+                default:
+                    reader.field(tag, message);
+                    break;
+            }
+        }
+        return message;
+    }
+};
+
+$root.serial_v2.Int64Vec = class Int64Vec {
+
+    constructor() {
+        this.value = [];
+    }
+
+    static decode(reader, length) {
+        const message = new $root.serial_v2.Int64Vec();
+        const end = length !== undefined ? reader.position + length : reader.length;
+        while (reader.position < end) {
+            const tag = reader.uint32();
+            switch (tag >>> 3) {
+                case 1:
+                    message.value = reader.array(message.value, () => reader.int64(), tag);
+                    break;
+                default:
+                    reader.skipType(tag & 7);
+                    break;
+            }
+        }
+        return message;
+    }
+
+    static decodeText(reader) {
+        const message = new $root.serial_v2.Int64Vec();
+        reader.start();
+        while (!reader.end()) {
+            const tag = reader.tag();
+            switch (tag) {
+                case "value":
+                    reader.array(message.value, () => reader.integer());
+                    break;
+                default:
+                    reader.field(tag, message);
+                    break;
+            }
+        }
+        return message;
+    }
+};
+
+$root.serial_v2.Uint64Vec = class Uint64Vec {
+
+    constructor() {
+        this.value = [];
+    }
+
+    static decode(reader, length) {
+        const message = new $root.serial_v2.Uint64Vec();
+        const end = length !== undefined ? reader.position + length : reader.length;
+        while (reader.position < end) {
+            const tag = reader.uint32();
+            switch (tag >>> 3) {
+                case 1:
+                    message.value = reader.array(message.value, () => reader.uint64(), tag);
+                    break;
+                default:
+                    reader.skipType(tag & 7);
+                    break;
+            }
+        }
+        return message;
+    }
+
+    static decodeText(reader) {
+        const message = new $root.serial_v2.Uint64Vec();
+        reader.start();
+        while (!reader.end()) {
+            const tag = reader.tag();
+            switch (tag) {
+                case "value":
+                    reader.array(message.value, () => reader.integer());
+                    break;
+                default:
+                    reader.field(tag, message);
+                    break;
+            }
+        }
+        return message;
+    }
+};
+
+$root.serial_v2.FloatVec = class FloatVec {
+
+    constructor() {
+        this.value = [];
+    }
+
+    static decode(reader, length) {
+        const message = new $root.serial_v2.FloatVec();
+        const end = length !== undefined ? reader.position + length : reader.length;
+        while (reader.position < end) {
+            const tag = reader.uint32();
+            switch (tag >>> 3) {
+                case 1:
+                    message.value = reader.floats(message.value, tag);
+                    break;
+                default:
+                    reader.skipType(tag & 7);
+                    break;
+            }
+        }
+        return message;
+    }
+
+    static decodeText(reader) {
+        const message = new $root.serial_v2.FloatVec();
+        reader.start();
+        while (!reader.end()) {
+            const tag = reader.tag();
+            switch (tag) {
+                case "value":
+                    reader.array(message.value, () => reader.float());
+                    break;
+                default:
+                    reader.field(tag, message);
+                    break;
+            }
+        }
+        return message;
+    }
+};
+
+$root.serial_v2.DoubleVec = class DoubleVec {
+
+    constructor() {
+        this.value = [];
+    }
+
+    static decode(reader, length) {
+        const message = new $root.serial_v2.DoubleVec();
+        const end = length !== undefined ? reader.position + length : reader.length;
+        while (reader.position < end) {
+            const tag = reader.uint32();
+            switch (tag >>> 3) {
+                case 1:
+                    message.value = reader.doubles(message.value, tag);
+                    break;
+                default:
+                    reader.skipType(tag & 7);
+                    break;
+            }
+        }
+        return message;
+    }
+
+    static decodeText(reader) {
+        const message = new $root.serial_v2.DoubleVec();
+        reader.start();
+        while (!reader.end()) {
+            const tag = reader.tag();
+            switch (tag) {
+                case "value":
+                    reader.array(message.value, () => reader.float());
+                    break;
+                default:
+                    reader.field(tag, message);
+                    break;
+            }
+        }
+        return message;
+    }
+};
+
+$root.serial_v2.StringVec = class StringVec {
+
+    constructor() {
+        this.value = [];
+    }
+
+    static decode(reader, length) {
+        const message = new $root.serial_v2.StringVec();
+        const end = length !== undefined ? reader.position + length : reader.length;
+        while (reader.position < end) {
+            const tag = reader.uint32();
+            switch (tag >>> 3) {
+                case 1:
+                    message.value.push(reader.string());
+                    break;
+                default:
+                    reader.skipType(tag & 7);
+                    break;
+            }
+        }
+        return message;
+    }
+
+    static decodeText(reader) {
+        const message = new $root.serial_v2.StringVec();
+        reader.start();
+        while (!reader.end()) {
+            const tag = reader.tag();
+            switch (tag) {
+                case "value":
+                    reader.array(message.value, () => reader.string());
+                    break;
+                default:
+                    reader.field(tag, message);
+                    break;
+            }
+        }
+        return message;
+    }
+};
+
+$root.serial_v2.BytesVec = class BytesVec {
+
+    constructor() {
+        this.value = [];
+    }
+
+    static decode(reader, length) {
+        const message = new $root.serial_v2.BytesVec();
+        const end = length !== undefined ? reader.position + length : reader.length;
+        while (reader.position < end) {
+            const tag = reader.uint32();
+            switch (tag >>> 3) {
+                case 1:
+                    message.value.push($root.serial_v2.Bytes.decode(reader, reader.uint32()));
+                    break;
+                default:
+                    reader.skipType(tag & 7);
+                    break;
+            }
+        }
+        return message;
+    }
+
+    static decodeText(reader) {
+        const message = new $root.serial_v2.BytesVec();
+        reader.start();
+        while (!reader.end()) {
+            const tag = reader.tag();
+            switch (tag) {
+                case "value":
+                    message.value.push($root.serial_v2.Bytes.decodeText(reader));
+                    break;
+                default:
+                    reader.field(tag, message);
+                    break;
+            }
+        }
+        return message;
+    }
+};
+
+$root.serial_v2.MapString2Int32 = class MapString2Int32 {
+
+    constructor() {
+        this.value = {};
+    }
+
+    static decode(reader, length) {
+        const message = new $root.serial_v2.MapString2Int32();
+        const end = length !== undefined ? reader.position + length : reader.length;
+        while (reader.position < end) {
+            const tag = reader.uint32();
+            switch (tag >>> 3) {
+                case 1:
+                    reader.entry(message.value, () => reader.string(), () => reader.int32());
+                    break;
+                default:
+                    reader.skipType(tag & 7);
+                    break;
+            }
+        }
+        return message;
+    }
+
+    static decodeText(reader) {
+        const message = new $root.serial_v2.MapString2Int32();
+        reader.start();
+        while (!reader.end()) {
+            const tag = reader.tag();
+            switch (tag) {
+                case "value":
+                    reader.entry(message.value, () => reader.string(), () => reader.int32());
+                    break;
+                default:
+                    reader.field(tag, message);
+                    break;
+            }
+        }
+        return message;
+    }
+};
+
+$root.serial_v2.MapString2Uint32 = class MapString2Uint32 {
+
+    constructor() {
+        this.value = {};
+    }
+
+    static decode(reader, length) {
+        const message = new $root.serial_v2.MapString2Uint32();
+        const end = length !== undefined ? reader.position + length : reader.length;
+        while (reader.position < end) {
+            const tag = reader.uint32();
+            switch (tag >>> 3) {
+                case 1:
+                    reader.entry(message.value, () => reader.string(), () => reader.uint32());
+                    break;
+                default:
+                    reader.skipType(tag & 7);
+                    break;
+            }
+        }
+        return message;
+    }
+
+    static decodeText(reader) {
+        const message = new $root.serial_v2.MapString2Uint32();
+        reader.start();
+        while (!reader.end()) {
+            const tag = reader.tag();
+            switch (tag) {
+                case "value":
+                    reader.entry(message.value, () => reader.string(), () => reader.uint32());
+                    break;
+                default:
+                    reader.field(tag, message);
+                    break;
+            }
+        }
+        return message;
+    }
+};
+
+$root.serial_v2.MapString2Int64 = class MapString2Int64 {
+
+    constructor() {
+        this.value = {};
+    }
+
+    static decode(reader, length) {
+        const message = new $root.serial_v2.MapString2Int64();
+        const end = length !== undefined ? reader.position + length : reader.length;
+        while (reader.position < end) {
+            const tag = reader.uint32();
+            switch (tag >>> 3) {
+                case 1:
+                    reader.entry(message.value, () => reader.string(), () => reader.int64());
+                    break;
+                default:
+                    reader.skipType(tag & 7);
+                    break;
+            }
+        }
+        return message;
+    }
+
+    static decodeText(reader) {
+        const message = new $root.serial_v2.MapString2Int64();
+        reader.start();
+        while (!reader.end()) {
+            const tag = reader.tag();
+            switch (tag) {
+                case "value":
+                    reader.entry(message.value, () => reader.string(), () => reader.int64());
+                    break;
+                default:
+                    reader.field(tag, message);
+                    break;
+            }
+        }
+        return message;
+    }
+};
+
+$root.serial_v2.MapString2Uint64 = class MapString2Uint64 {
+
+    constructor() {
+        this.value = {};
+    }
+
+    static decode(reader, length) {
+        const message = new $root.serial_v2.MapString2Uint64();
+        const end = length !== undefined ? reader.position + length : reader.length;
+        while (reader.position < end) {
+            const tag = reader.uint32();
+            switch (tag >>> 3) {
+                case 1:
+                    reader.entry(message.value, () => reader.string(), () => reader.uint64());
+                    break;
+                default:
+                    reader.skipType(tag & 7);
+                    break;
+            }
+        }
+        return message;
+    }
+
+    static decodeText(reader) {
+        const message = new $root.serial_v2.MapString2Uint64();
+        reader.start();
+        while (!reader.end()) {
+            const tag = reader.tag();
+            switch (tag) {
+                case "value":
+                    reader.entry(message.value, () => reader.string(), () => reader.uint64());
+                    break;
+                default:
+                    reader.field(tag, message);
+                    break;
+            }
+        }
+        return message;
+    }
+};
+
+$root.serial_v2.MapString2Bytes = class MapString2Bytes {
+
+    constructor() {
+        this.value = {};
+    }
+
+    static decode(reader, length) {
+        const message = new $root.serial_v2.MapString2Bytes();
+        const end = length !== undefined ? reader.position + length : reader.length;
+        while (reader.position < end) {
+            const tag = reader.uint32();
+            switch (tag >>> 3) {
+                case 1:
+                    reader.entry(message.value, () => reader.string(), () => $root.serial_v2.Bytes.decode(reader, reader.uint32()));
+                    break;
+                default:
+                    reader.skipType(tag & 7);
+                    break;
+            }
+        }
+        return message;
+    }
+
+    static decodeText(reader) {
+        const message = new $root.serial_v2.MapString2Bytes();
+        reader.start();
+        while (!reader.end()) {
+            const tag = reader.tag();
+            switch (tag) {
+                case "value":
+                    reader.entry(message.value, () => reader.string(), () => $root.serial_v2.Bytes.decodeText(reader));
+                    break;
+                default:
+                    reader.field(tag, message);
+                    break;
+            }
+        }
+        return message;
+    }
+};
+
+$root.serial_v2.MapString2String = class MapString2String {
+
+    constructor() {
+        this.value = {};
+    }
+
+    static decode(reader, length) {
+        const message = new $root.serial_v2.MapString2String();
+        const end = length !== undefined ? reader.position + length : reader.length;
+        while (reader.position < end) {
+            const tag = reader.uint32();
+            switch (tag >>> 3) {
+                case 1:
+                    reader.entry(message.value, () => reader.string(), () => reader.string());
+                    break;
+                default:
+                    reader.skipType(tag & 7);
+                    break;
+            }
+        }
+        return message;
+    }
+
+    static decodeText(reader) {
+        const message = new $root.serial_v2.MapString2String();
+        reader.start();
+        while (!reader.end()) {
+            const tag = reader.tag();
+            switch (tag) {
+                case "value":
+                    reader.entry(message.value, () => reader.string(), () => reader.string());
+                    break;
+                default:
+                    reader.field(tag, message);
+                    break;
+            }
+        }
+        return message;
+    }
+};
+
+$root.serial_v2.MapString2Int32Vec = class MapString2Int32Vec {
+
+    constructor() {
+        this.value = {};
+    }
+
+    static decode(reader, length) {
+        const message = new $root.serial_v2.MapString2Int32Vec();
+        const end = length !== undefined ? reader.position + length : reader.length;
+        while (reader.position < end) {
+            const tag = reader.uint32();
+            switch (tag >>> 3) {
+                case 1:
+                    reader.entry(message.value, () => reader.string(), () => $root.serial_v2.Int32Vec.decode(reader, reader.uint32()));
+                    break;
+                default:
+                    reader.skipType(tag & 7);
+                    break;
+            }
+        }
+        return message;
+    }
+
+    static decodeText(reader) {
+        const message = new $root.serial_v2.MapString2Int32Vec();
+        reader.start();
+        while (!reader.end()) {
+            const tag = reader.tag();
+            switch (tag) {
+                case "value":
+                    reader.entry(message.value, () => reader.string(), () => $root.serial_v2.Int32Vec.decodeText(reader));
+                    break;
+                default:
+                    reader.field(tag, message);
+                    break;
+            }
+        }
+        return message;
+    }
+};
+
+$root.serial_v2.MapString2Uint32Vec = class MapString2Uint32Vec {
+
+    constructor() {
+        this.value = {};
+    }
+
+    static decode(reader, length) {
+        const message = new $root.serial_v2.MapString2Uint32Vec();
+        const end = length !== undefined ? reader.position + length : reader.length;
+        while (reader.position < end) {
+            const tag = reader.uint32();
+            switch (tag >>> 3) {
+                case 1:
+                    reader.entry(message.value, () => reader.string(), () => $root.serial_v2.Uint32Vec.decode(reader, reader.uint32()));
+                    break;
+                default:
+                    reader.skipType(tag & 7);
+                    break;
+            }
+        }
+        return message;
+    }
+
+    static decodeText(reader) {
+        const message = new $root.serial_v2.MapString2Uint32Vec();
+        reader.start();
+        while (!reader.end()) {
+            const tag = reader.tag();
+            switch (tag) {
+                case "value":
+                    reader.entry(message.value, () => reader.string(), () => $root.serial_v2.Uint32Vec.decodeText(reader));
+                    break;
+                default:
+                    reader.field(tag, message);
+                    break;
+            }
+        }
+        return message;
+    }
+};
+
+$root.serial_v2.MapString2Int64Vec = class MapString2Int64Vec {
+
+    constructor() {
+        this.value = {};
+    }
+
+    static decode(reader, length) {
+        const message = new $root.serial_v2.MapString2Int64Vec();
+        const end = length !== undefined ? reader.position + length : reader.length;
+        while (reader.position < end) {
+            const tag = reader.uint32();
+            switch (tag >>> 3) {
+                case 1:
+                    reader.entry(message.value, () => reader.string(), () => $root.serial_v2.Int64Vec.decode(reader, reader.uint32()));
+                    break;
+                default:
+                    reader.skipType(tag & 7);
+                    break;
+            }
+        }
+        return message;
+    }
+
+    static decodeText(reader) {
+        const message = new $root.serial_v2.MapString2Int64Vec();
+        reader.start();
+        while (!reader.end()) {
+            const tag = reader.tag();
+            switch (tag) {
+                case "value":
+                    reader.entry(message.value, () => reader.string(), () => $root.serial_v2.Int64Vec.decodeText(reader));
+                    break;
+                default:
+                    reader.field(tag, message);
+                    break;
+            }
+        }
+        return message;
+    }
+};
+
+$root.serial_v2.MapString2Uint64Vec = class MapString2Uint64Vec {
+
+    constructor() {
+        this.value = {};
+    }
+
+    static decode(reader, length) {
+        const message = new $root.serial_v2.MapString2Uint64Vec();
+        const end = length !== undefined ? reader.position + length : reader.length;
+        while (reader.position < end) {
+            const tag = reader.uint32();
+            switch (tag >>> 3) {
+                case 1:
+                    reader.entry(message.value, () => reader.string(), () => $root.serial_v2.Uint64Vec.decode(reader, reader.uint32()));
+                    break;
+                default:
+                    reader.skipType(tag & 7);
+                    break;
+            }
+        }
+        return message;
+    }
+
+    static decodeText(reader) {
+        const message = new $root.serial_v2.MapString2Uint64Vec();
+        reader.start();
+        while (!reader.end()) {
+            const tag = reader.tag();
+            switch (tag) {
+                case "value":
+                    reader.entry(message.value, () => reader.string(), () => $root.serial_v2.Uint64Vec.decodeText(reader));
+                    break;
+                default:
+                    reader.field(tag, message);
+                    break;
+            }
+        }
+        return message;
+    }
+};
+
+$root.serial_v2.MapString2BytesVec = class MapString2BytesVec {
+
+    constructor() {
+        this.value = {};
+    }
+
+    static decode(reader, length) {
+        const message = new $root.serial_v2.MapString2BytesVec();
+        const end = length !== undefined ? reader.position + length : reader.length;
+        while (reader.position < end) {
+            const tag = reader.uint32();
+            switch (tag >>> 3) {
+                case 1:
+                    reader.entry(message.value, () => reader.string(), () => $root.serial_v2.BytesVec.decode(reader, reader.uint32()));
+                    break;
+                default:
+                    reader.skipType(tag & 7);
+                    break;
+            }
+        }
+        return message;
+    }
+
+    static decodeText(reader) {
+        const message = new $root.serial_v2.MapString2BytesVec();
+        reader.start();
+        while (!reader.end()) {
+            const tag = reader.tag();
+            switch (tag) {
+                case "value":
+                    reader.entry(message.value, () => reader.string(), () => $root.serial_v2.BytesVec.decodeText(reader));
+                    break;
+                default:
+                    reader.field(tag, message);
+                    break;
+            }
+        }
+        return message;
+    }
+};
+
+$root.serial_v2.MapString2StringVec = class MapString2StringVec {
+
+    constructor() {
+        this.value = {};
+    }
+
+    static decode(reader, length) {
+        const message = new $root.serial_v2.MapString2StringVec();
+        const end = length !== undefined ? reader.position + length : reader.length;
+        while (reader.position < end) {
+            const tag = reader.uint32();
+            switch (tag >>> 3) {
+                case 1:
+                    reader.entry(message.value, () => reader.string(), () => $root.serial_v2.StringVec.decode(reader, reader.uint32()));
+                    break;
+                default:
+                    reader.skipType(tag & 7);
+                    break;
+            }
+        }
+        return message;
+    }
+
+    static decodeText(reader) {
+        const message = new $root.serial_v2.MapString2StringVec();
+        reader.start();
+        while (!reader.end()) {
+            const tag = reader.tag();
+            switch (tag) {
+                case "value":
+                    reader.entry(message.value, () => reader.string(), () => $root.serial_v2.StringVec.decodeText(reader));
+                    break;
+                default:
+                    reader.field(tag, message);
+                    break;
+            }
+        }
+        return message;
+    }
+};

+ 351 - 0
source/xmodel.js

@@ -0,0 +1,351 @@
+/* jshint esversion: 6 */
+
+var xmodel = xmodel || {};
+var protobuf = protobuf || require('./protobuf');
+
+xmodel.ModelFactory = class {
+
+    match(context) {
+        const tags = context.tags('pb');
+        if (tags.get(101) === 2) {
+            return true;
+        }
+        return false;
+    }
+
+    open(context) {
+        return context.require('./xmodel-proto').then(() => {
+            let graph = null;
+            try {
+                xmodel.proto = protobuf.get('xmodel').serial_v2;
+                const reader = protobuf.Reader.create(context.stream.peek());
+                graph = xmodel.proto.Graph.decode(reader);
+            }
+            catch (error) {
+                const message = error && error.message ? error.message : error.toString();
+                throw new xmodel.Error('File format is not serial_v2.Graph (' + message.replace(/\.$/, '') + ').');
+            }
+            return new xmodel.Model(graph);
+        });
+    }
+};
+
+xmodel.Model = class {
+
+    constructor(graph) {
+        this._name = graph.graph_name || '';
+        this._format = 'Vitis-AI xmodel';
+        this._producer = graph && graph.graph_attr && graph.graph_attr.origin && graph.graph_attr.origin.string_value ? graph.graph_attr.origin.string_value : '';
+        this._graphs = [ new xmodel.Graph(graph) ];
+    }
+
+    get name() {
+        return this._name;
+    }
+
+    get format() {
+        return this._format;
+    }
+
+    get producer() {
+        return this._producer;
+    }
+
+    get graphs() {
+        return this._graphs;
+    }
+};
+
+xmodel.Graph = class {
+
+    constructor(graph) {
+        const metadata = new xmodel.GraphMetadata(graph.op_defs);
+        this._inputs = [];
+        this._outputs = [];
+        this._nodes = [];
+        const count = new Map();
+        for (const op_node of graph.op_node) {
+            for (const arg of op_node.args) {
+                for (const arg_op of arg.arg_ops) {
+                    count.set(arg_op, count.has(arg_op) ? count.get(arg_op) + 1 : 1);
+                }
+            }
+        }
+        const initializers = new Map();
+        const nodes = [];
+        for (const op_node of graph.op_node) {
+            if (op_node.op_type === 'const-fix' && op_node.args.length === 0 && count.get(op_node.op_name) === 1) {
+                // const data_type = op_node.op_attr.data_type.string_value;
+                // const shape = op_node.op_attr.shape.int32_vec_value.value
+                initializers.set(op_node.op_name, op_node);
+                continue;
+            }
+            nodes.push(op_node);
+        }
+        for (const op_node of nodes) {
+            this._nodes.push(new xmodel.Node(metadata, op_node));
+        }
+    }
+
+    get inputs() {
+        return this._inputs;
+    }
+
+    get outputs() {
+        return this._outputs;
+    }
+
+    get nodes() {
+        return this._nodes;
+    }
+};
+
+xmodel.Parameter = class {
+
+    constructor(name, args) {
+        this._name = name;
+        this._arguments = args;
+    }
+
+    get name() {
+        return this._name;
+    }
+
+    get arguments() {
+        return this._arguments;
+    }
+};
+
+xmodel.Argument = class {
+
+    constructor(name, type, quantization, initializer) {
+        if (typeof name !== 'string') {
+            throw new xmodel.Error("Invalid argument identifier '" + JSON.stringify(name) + "'.");
+        }
+        this._name = name;
+        this._type = type || null;
+        this._quantization = quantization;
+        this._initializer = initializer || null;
+    }
+
+    get name() {
+        return this._name;
+    }
+
+    get type() {
+        if (this._initializer) {
+            return this._initializer.type;
+        }
+        return this._type;
+    }
+
+    get quantization() {
+        if (this._quantization) {
+            return 'bitwidth: ' + this._quantization.bit_width + ', pos: ' + this._quantization.pos + ', signed: ' + this._quantization.signed;
+        }
+        return null;
+    }
+
+    get initializer() {
+        return this._initializer;
+    }
+};
+
+xmodel.Node = class {
+
+    constructor(metadata, op_node) {
+        this._type = op_node.op_type;
+        this._name = op_node.op_name || '';
+        this._metadata = metadata.type(this._type);
+        this._inputs = [];
+        this._outputs = [];
+        this._attributes = [];
+
+        const in_quant = {};
+        const out_quant = {};
+        for (const name of Object.keys(op_node.op_attr)) {
+            const attribute = xmodel.Utility.attribute(op_node.op_attr[name]);
+            switch (name) {
+                case 'quant_in_bit_width':
+                    in_quant.bit_width = attribute.value;
+                    continue;
+                case 'quant_in_quantize_pos':
+                    in_quant.pos = attribute.value;
+                    continue;
+                case 'quant_in_signed':
+                    in_quant.signed = attribute.value;
+                    continue;
+                case 'quant_out_bit_width':
+                    out_quant.bit_width = attribute.value;
+                    continue;
+                case 'quant_out_quantize_pos':
+                    out_quant.pos = attribute.value;
+                    continue;
+                case 'quant_out_signed':
+                    out_quant.signed = attribute.value;
+                    continue;
+            }
+            this._attributes.push(new xmodel.Attribute(metadata.attribute(this._type, name), name, attribute.type, attribute.value));
+        }
+
+        for (const arg of op_node.args) {
+            const args = arg.arg_ops.map((arg_op) => new xmodel.Argument(arg_op, null, in_quant, null));
+            this._inputs.push(new xmodel.Parameter(arg.arg_name, args));
+        }
+        this._outputs.push(new xmodel.Parameter('output', [
+            new xmodel.Argument(op_node.op_name, null, out_quant, null)
+        ]));
+    }
+
+    get type() {
+        return this._type;
+    }
+
+    get metadata() {
+        return this._metadata;
+    }
+
+    get name() {
+        return this._name;
+    }
+
+    get inputs() {
+        return this._inputs;
+    }
+
+    get outputs() {
+        return this._outputs;
+    }
+
+    get attributes() {
+        return this._attributes;
+    }
+};
+
+xmodel.Attribute = class {
+
+    constructor(metadata, name, type, value) {
+        this._name = name;
+        this._type = type;
+        this._value = value;
+        if (metadata) {
+            if (metadata.default !== undefined) {
+                if (metadata.default === this._value) {
+                    this._visible = false;
+                }
+                if (Array.isArray(metadata.default) && Array.isArray(this._value) &&
+                    metadata.default.length === this._value.length && metadata.default.every((value, index) => value === this._value[index])) {
+                    this._visible = false;
+                }
+            }
+        }
+    }
+
+    get name() {
+        return this._name;
+    }
+
+    get type() {
+        return this._type;
+    }
+
+    get value() {
+        return this._value;
+    }
+
+    get visible() {
+        return this._visible == false ? false : true;
+    }
+};
+
+xmodel.Utility = class {
+
+    static attribute(attr) {
+        const key = attr.value;
+        const value = {
+            value: attr[key],
+            type: key.replace(/_value$/, '')
+        };
+        switch (value.type) {
+            case 'bool': {
+                value.type = 'boolean';
+                break;
+            }
+            case 'int32_vec': {
+                value.type = 'int32[]';
+                value.value = value.value.value;
+                break;
+            }
+        }
+        return value;
+    }
+};
+
+xmodel.GraphMetadata = class {
+
+    constructor(op_defs) {
+        this._map = new Map();
+        this._attributeCache = new Map();
+        const categories = new Map([
+            [ 'conv2d-fix', 'Layer' ],
+            [ 'upsample-fix', 'Layer' ],
+            [ 'pool-fix', 'Pool' ],
+            [ 'batchnorm', 'Normalization' ],
+            [ 'concat-fix', 'Tensor' ],
+            [ 'reshape-fix', 'Shape' ],
+            [ 'softmax', 'Activation' ]
+        ]);
+        for (const op_def of op_defs) {
+            const name = op_def.name;
+            const schema = {};
+            schema.name = name;
+            if (op_def.annotation) {
+                schema.description = op_def.annotation;
+            }
+            schema.inputs = op_def.input_args.map((input_arg) => {
+                const input = {};
+                input.name = input_arg.name;
+                if (input_arg.annotation) {
+                    input.description = input_arg.annotation;
+                }
+                return input_arg;
+            });
+            schema.attributes = op_def.attrs.map((attr) => {
+                const attribute = {};
+                attribute.name = attr.name;
+                const value = xmodel.Utility.attribute(attr.default_value);
+                attribute.default = value.value;
+                if (attr.annotation) {
+                    attr.description = attr.annotation;
+                }
+                this._attributeCache.set(name + ':' + attr.name, attribute);
+                return attr;
+            });
+            if (categories.has(name)) {
+                schema.category = categories.get(name);
+            }
+            this._map.set(name, schema);
+        }
+    }
+
+    type(name) {
+        return this._map.get(name);
+    }
+
+    attribute(type, name) {
+        const key = type + ':' + name;
+        return this._attributeCache.get(key);
+    }
+};
+
+xmodel.Error = class extends Error {
+
+    constructor(message) {
+        super(message);
+        this.name = 'Error loading xmodel.';
+    }
+};
+
+if (typeof module !== 'undefined' && typeof module.exports === 'object') {
+    module.exports.ModelFactory = xmodel.ModelFactory;
+}

+ 36 - 0
tools/xmodel

@@ -0,0 +1,36 @@
+#!/bin/bash
+
+set -e
+
+pushd $(cd $(dirname ${0})/..; pwd) > /dev/null
+
+clean() {
+    echo "xmodel clean"
+    rm -rf "./third_party/source/xmodel"
+}
+
+sync() {
+    echo "xmodel sync"
+    mkdir -p ./third_party/source/xmodel/tools/Vitis-AI-Library/usefultools/src
+    curl --silent --location --output "./third_party/source/xmodel/tools/Vitis-AI-Library/usefultools/src/xir_graph_proto_v2.proto" "https://github.com/Xilinx/Vitis-AI/blob/master/tools/Vitis-AI-Library/usefultools/src/xir_graph_proto_v2.proto?raw=true"
+}
+
+
+schema() {
+    echo "xmodel schema"
+    [[ $(grep -U $'\x0D' ./source/xmodel-proto.js) ]] && crlf=1
+    node ./tools/protoc.js --text --root xmodel --out ./source/xmodel-proto.js ./third_party/source/xmodel/tools/Vitis-AI-Library/usefultools/src/xir_graph_proto_v2.proto
+    rm -rf ${temp}
+    if [[ -n ${crlf} ]]; then
+        unix2dos --quiet --newfile ./source/xmodel-proto.js ./source/xmodel-proto.js
+    fi
+}
+
+while [ "$#" != 0 ]; do
+    command="$1" && shift
+    case "${command}" in
+        "clean") clean;;
+        "sync") sync;;
+        "schema") schema;;
+    esac
+done