Lutz Roeder 2 rokov pred
rodič
commit
ec0cf33bfb
12 zmenil súbory, kde vykonal 87 pridanie a 217 odobranie
  1. 3 3
      source/circle.js
  2. 3 3
      source/coreml.js
  3. 2 5
      source/dlc.js
  4. 2 2
      source/hailo.js
  5. 2 3
      source/mnn.js
  6. 3 3
      source/mxnet.js
  7. 6 6
      source/onnx.js
  8. 2 2
      source/rknn.js
  9. 56 185
      source/tengine.js
  10. 3 3
      source/tflite.js
  11. 2 2
      source/view.js
  12. 3 0
      test/worker.js

+ 3 - 3
source/circle.js

@@ -73,7 +73,7 @@ circle.Model = class {
         this._format = 'Circle';
         this._format = 'Circle';
         this._format = this._format + ' v' + model.version.toString();
         this._format = this._format + ' v' + model.version.toString();
         this._description = model.description || '';
         this._description = model.description || '';
-        this._metadata = [];
+        this._metadata = new Map();
         const builtinOperators = new Map();
         const builtinOperators = new Map();
         const upperCase = new Set([ '2D', 'LSH', 'SVDF', 'RNN', 'L2', 'LSTM' ]);
         const upperCase = new Set([ '2D', 'LSH', 'SVDF', 'RNN', 'L2', 'LSTM' ]);
         for (const key of Object.keys(circle.schema.BuiltinOperator)) {
         for (const key of Object.keys(circle.schema.BuiltinOperator)) {
@@ -114,10 +114,10 @@ circle.Model = class {
                                 this._description = this._description ? [ this._description, modelMetadata.description].join(' ') : modelMetadata.description;
                                 this._description = this._description ? [ this._description, modelMetadata.description].join(' ') : modelMetadata.description;
                             }
                             }
                             if (modelMetadata.author) {
                             if (modelMetadata.author) {
-                                this._metadata.push({ name: 'author', value: modelMetadata.author });
+                                this._metadata.set('author', modelMetadata.author);
                             }
                             }
                             if (modelMetadata.license) {
                             if (modelMetadata.license) {
-                                this._metadata.push({ name: 'license', value: modelMetadata.license });
+                                this._metadata.set('license', modelMetadata.license);
                             }
                             }
                         }
                         }
                         break;
                         break;

+ 3 - 3
source/coreml.js

@@ -191,7 +191,7 @@ coreml.Model = class {
 
 
     constructor(metadata, format, model, weights) {
     constructor(metadata, format, model, weights) {
         this.format = (format || 'Core ML') + ' v' + model.specificationVersion.toString();
         this.format = (format || 'Core ML') + ' v' + model.specificationVersion.toString();
-        this.metadata = [];
+        this.metadata = new Map();
         const context = new coreml.Context(metadata, model, weights);
         const context = new coreml.Context(metadata, model, weights);
         const graph = new coreml.Graph(context);
         const graph = new coreml.Graph(context);
         this.graphs = [ graph ];
         this.graphs = [ graph ];
@@ -204,10 +204,10 @@ coreml.Model = class {
                 this.description = properties.shortDescription;
                 this.description = properties.shortDescription;
             }
             }
             if (properties.author) {
             if (properties.author) {
-                this.metadata.push({ name: 'author', value: properties.author });
+                this.metadata.set('author', properties.author);
             }
             }
             if (properties.license) {
             if (properties.license) {
-                this.metadata.push({ name: 'license', value: properties.license });
+                this.metadata.set('license', properties.license);
             }
             }
             if (metadata.userDefined && Object.keys(properties.userDefined).length > 0) {
             if (metadata.userDefined && Object.keys(properties.userDefined).length > 0) {
                 /* empty */
                 /* empty */

+ 2 - 5
source/dlc.js

@@ -23,7 +23,7 @@ dlc.Model = class {
 
 
     constructor(metadata, target) {
     constructor(metadata, target) {
         this.format = target.format;
         this.format = target.format;
-        this.metadata = [];
+        this.metadata = new Map();
         if (target.metadata.size > 0) {
         if (target.metadata.size > 0) {
             const version = target.metadata.get('model-version');
             const version = target.metadata.get('model-version');
             if (version) {
             if (version) {
@@ -34,10 +34,7 @@ dlc.Model = class {
                 const source = converter.split(' ').shift().trim();
                 const source = converter.split(' ').shift().trim();
                 if (source.length > 0) {
                 if (source.length > 0) {
                     const version = target.metadata.get('converter-version');
                     const version = target.metadata.get('converter-version');
-                    this.metadata.push({
-                        name: 'source',
-                        value: version ? source + ' v' + version : source
-                    });
+                    this.metadata.set('source', version ? source + ' v' + version : source);
                 }
                 }
             }
             }
         }
         }

+ 2 - 2
source/hailo.js

@@ -22,9 +22,9 @@ hailo.Model = class {
         this.graphs = [ new hailo.Graph(metadata, configuration, container.weights) ];
         this.graphs = [ new hailo.Graph(metadata, configuration, container.weights) ];
         this.name = configuration && configuration.name || "";
         this.name = configuration && configuration.name || "";
         this.format = container.format + (container.metadata && container.metadata.sdk_version ? ' v' + container.metadata.sdk_version : '');
         this.format = container.format + (container.metadata && container.metadata.sdk_version ? ' v' + container.metadata.sdk_version : '');
-        this.metadata = [];
+        this.metadata = new Map();
         if (container.metadata && container.metadata.state) {
         if (container.metadata && container.metadata.state) {
-            this.metadata.push({ name: 'state', value: container.metadata.state });
+            this.metadata.set('state', container.metadata.state);
         }
         }
     }
     }
 };
 };

+ 2 - 3
source/mnn.js

@@ -52,9 +52,8 @@ mnn.Model = class {
         if (!sources.has(net.sourceType)) {
         if (!sources.has(net.sourceType)) {
             throw new mnn.Error("Unsupported model source '" + net.sourceType + "'.");
             throw new mnn.Error("Unsupported model source '" + net.sourceType + "'.");
         }
         }
-        this.metadata = [
-            { name: 'source', value: sources.get(net.sourceType) }
-        ];
+        this.metadata = new Map();
+        this.metadata.set('source', sources.get(net.sourceType));
         this.graphs = [ new mnn.Graph(metadata, net) ];
         this.graphs = [ new mnn.Graph(metadata, net) ];
     }
     }
 };
 };

+ 3 - 3
source/mxnet.js

@@ -252,12 +252,12 @@ mxnet.Model = class {
         this._version = manifest.version;
         this._version = manifest.version;
         this._description = manifest.description || '';
         this._description = manifest.description || '';
         this._runtime = manifest.runtime || '';
         this._runtime = manifest.runtime || '';
-        this._metadata = [];
+        this._metadata = new Map();
         if (manifest.author) {
         if (manifest.author) {
-            this._metadata.push({ name: 'author', value: manifest.author });
+            this._metadata.set('author', manifest.author);
         }
         }
         if (manifest.license) {
         if (manifest.license) {
-            this._metadata.push({ name: 'license', value: manifest.license });
+            this._metadata.set('license', manifest.license);
         }
         }
         this._graphs = [ new mxnet.Graph(metadata, manifest, symbol, params) ];
         this._graphs = [ new mxnet.Graph(metadata, manifest, symbol, params) ];
     }
     }

+ 6 - 6
source/onnx.js

@@ -115,7 +115,7 @@ onnx.Model = class {
         const model_version = model.model_version === undefined || typeof model.model_version === 'number' ? model.model_version : model.model_version.toNumber();
         const model_version = model.model_version === undefined || typeof model.model_version === 'number' ? model.model_version : model.model_version.toNumber();
         this._version = model_version ? model_version.toString() : '';
         this._version = model_version ? model_version.toString() : '';
         this._description = model.doc_string;
         this._description = model.doc_string;
-        this._metadata = [];
+        this._metadata = new Map();
         this._imports = null;
         this._imports = null;
         const imports = new Map();
         const imports = new Map();
         if (model.opset_import && model.opset_import.length > 0) {
         if (model.opset_import && model.opset_import.length > 0) {
@@ -138,15 +138,15 @@ onnx.Model = class {
             const metadata = new Map(metadata_props.map((entry) => [ entry.key, entry.value ]));
             const metadata = new Map(metadata_props.map((entry) => [ entry.key, entry.value ]));
             const converted_from = metadata.get('converted_from');
             const converted_from = metadata.get('converted_from');
             if (converted_from) {
             if (converted_from) {
-                this._metadata.push({ name: 'source', value: converted_from });
+                this._metadata.set('source', converted_from);
             }
             }
             const author = metadata.get('author');
             const author = metadata.get('author');
             if (author) {
             if (author) {
-                this._metadata.push({ name: 'author', value: author });
+                this._metadata.set('author', author);
             }
             }
             const company = metadata.get('company');
             const company = metadata.get('company');
             if (company) {
             if (company) {
-                this._metadata.push({ name: 'company', value: company });
+                this._metadata.set('company', company);
             }
             }
             let license = metadata.get('license');
             let license = metadata.get('license');
             const license_url = metadata.get('license_url');
             const license_url = metadata.get('license_url');
@@ -154,7 +154,7 @@ onnx.Model = class {
                 license = '<a href=\'' + license_url + '\'>' + (license ? license : license_url) + '</a>';
                 license = '<a href=\'' + license_url + '\'>' + (license ? license : license_url) + '</a>';
             }
             }
             if (license) {
             if (license) {
-                this._metadata.push({ name: 'license', value: license });
+                this._metadata.set('license', license);
             }
             }
             metadata.delete('author');
             metadata.delete('author');
             metadata.delete('company');
             metadata.delete('company');
@@ -170,7 +170,7 @@ onnx.Model = class {
                         imageMetadata[name] = value;
                         imageMetadata[name] = value;
                         break;
                         break;
                     default:
                     default:
-                        this._metadata.push({ name: name, value: value });
+                        this._metadata.set(name, value);
                         break;
                         break;
                 }
                 }
             }
             }

+ 2 - 2
source/rknn.js

@@ -56,8 +56,8 @@ rknn.Model = class {
                 this._runtime = model.runtime;
                 this._runtime = model.runtime;
                 this._name = model.name || '';
                 this._name = model.name || '';
                 this._graphs = model.graphs.map((graph) => new rknn.Graph(metadata, type, '', graph, null));
                 this._graphs = model.graphs.map((graph) => new rknn.Graph(metadata, type, '', graph, null));
-                this._metadata = [];
-                this._metadata.push({ name: 'source', value: model.source });
+                this._metadata = new Map();
+                this._metadata.set('source', model.source);
                 break;
                 break;
             }
             }
             case 'openvx': {
             case 'openvx': {

+ 56 - 185
source/tengine.js

@@ -13,48 +13,37 @@ tengine.ModelFactory = class {
 
 
     async open(context, target) {
     async open(context, target) {
         const metadata = await tengine.Metadata.open(context);
         const metadata = await tengine.Metadata.open(context);
-        return new tengine.Model(metadata, target);
+        const reader = target;
+        reader.read();
+        return new tengine.Model(metadata, reader);
     }
     }
 };
 };
 
 
 tengine.Model = class {
 tengine.Model = class {
 
 
     constructor(metadata, reader) {
     constructor(metadata, reader) {
-        this._version = reader.version;
-        this._metadata = [
-            { name: 'source', value: reader.source }
-        ];
-        this._graphs = reader.graphs.map((graph) => new tengine.Graph(metadata, graph));
-    }
-
-    get format() {
-        return "Tengine v" + this._version;
-    }
-
-    get metadata() {
-        return this._metadata;
-    }
-
-    get graphs() {
-        return this._graphs;
+        this.format = "Tengine v" + reader.version;
+        this.metadata = new Map();
+        this.metadata.set('source', reader.source);
+        this.graphs = reader.graphs.map((graph) => new tengine.Graph(metadata, graph));
     }
     }
 };
 };
 
 
 tengine.Graph = class {
 tengine.Graph = class {
 
 
     constructor(metadata, graph) {
     constructor(metadata, graph) {
-        this._name = graph.id.toString();
-        this._inputs = [];
-        this._outputs = [];
-        this._nodes = [];
+        this.name = graph.id.toString();
+        this.inputs = [];
+        this.outputs = [];
+        this.nodes = [];
         const tensors = graph.tensors.map((tensor) => new tengine.Value(tensor));
         const tensors = graph.tensors.map((tensor) => new tengine.Value(tensor));
         for (const input of graph.inputs) {
         for (const input of graph.inputs) {
             const node = graph.nodes[input];
             const node = graph.nodes[input];
-            this._inputs.push(new tengine.Argument(node.name, node.outputs.map((output) => tensors[output])));
+            this.inputs.push(new tengine.Argument(node.name, node.outputs.map((output) => tensors[output])));
         }
         }
         for (const output of graph.outputs) {
         for (const output of graph.outputs) {
             const node = graph.nodes[output];
             const node = graph.nodes[output];
-            this._outputs.push(new tengine.Argument(node.name, node.outputs.map((output) => tensors[output])));
+            this.outputs.push(new tengine.Argument(node.name, node.outputs.map((output) => tensors[output])));
         }
         }
         for (const node of graph.nodes) {
         for (const node of graph.nodes) {
             switch (node.type) {
             switch (node.type) {
@@ -62,244 +51,140 @@ tengine.Graph = class {
                 case 'Const':
                 case 'Const':
                     break;
                     break;
                 default:
                 default:
-                    this._nodes.push(new tengine.Node(metadata, node, tensors));
+                    this.nodes.push(new tengine.Node(metadata, node, tensors));
                     break;
                     break;
             }
             }
         }
         }
     }
     }
-
-    get name() {
-        return this._name;
-    }
-
-    get inputs() {
-        return this._inputs;
-    }
-
-    get outputs() {
-        return this._outputs;
-    }
-
-    get nodes() {
-        return this._nodes;
-    }
 };
 };
 
 
 tengine.Argument = class {
 tengine.Argument = class {
 
 
     constructor(name, value) {
     constructor(name, value) {
-        this._name = name;
-        this._value = value;
-    }
-
-    get name() {
-        return this._name;
-    }
-
-    get value() {
-        return this._value;
+        this.name = name;
+        this.value = value;
     }
     }
 };
 };
 
 
 tengine.Value = class {
 tengine.Value = class {
 
 
     constructor(tensor) {
     constructor(tensor) {
-        this._name = tensor.name;
-        this._type = new tengine.TensorType(tensor.dataType, new tengine.TensorShape(tensor.dims));
-        this._initializer = (tensor.type === 2) ? new tengine.Tensor(this._type, tensor.buffer) : null;
-    }
-
-    get name() {
-        return this._name;
-    }
-
-    get type() {
-        if (this._initializer) {
-            return this._initializer.type;
-        }
-        return this._type;
-    }
-
-    get quantization() {
-        return null;
-    }
-
-    get initializer() {
-        return this._initializer;
+        this.name = tensor.name;
+        this.type = new tengine.TensorType(tensor.dataType, new tengine.TensorShape(tensor.dims));
+        this.initializer = (tensor.type === 2) ? new tengine.Tensor(this.type, tensor.buffer) : null;
     }
     }
 };
 };
 
 
-
 tengine.Node = class {
 tengine.Node = class {
 
 
     constructor(metadata, node, tensors) {
     constructor(metadata, node, tensors) {
-        this._name = node.name;
+        this.name = node.name;
         const type = node.type;
         const type = node.type;
         const version = node.version;
         const version = node.version;
-        this._inputs = [];
-        this._outputs = [];
-        this._attributes = [];
-        this._type = metadata.type(type, version) || { name: type };
-
+        this.inputs = [];
+        this.outputs = [];
+        this.attributes = [];
+        this.type = metadata.type(type, version) || { name: type };
         for (let i = 0; i < node.params.length; i++) {
         for (let i = 0; i < node.params.length; i++) {
-            const metadata = (this._type && this._type.attributes && i < this._type.attributes.length) ? this._type.attributes[i] : null;
+            const metadata = (this.type && this.type.attributes && i < this.type.attributes.length) ? this.type.attributes[i] : null;
             const name = metadata ? metadata.name : i.toString();
             const name = metadata ? metadata.name : i.toString();
-            this._attributes.push(new tengine.Attribute(metadata, name, node.params[i]));
+            this.attributes.push(new tengine.Attribute(metadata, name, node.params[i]));
         }
         }
-
         const inputs = node.inputs;
         const inputs = node.inputs;
         let inputIndex = 0;
         let inputIndex = 0;
-        if (this._type && this._type.inputs) {
-            for (const inputDef of this._type.inputs) {
+        if (this.type && this.type.inputs) {
+            for (const inputDef of this.type.inputs) {
                 if (inputIndex < inputs.length || inputDef.option != 'optional') {
                 if (inputIndex < inputs.length || inputDef.option != 'optional') {
                     const inputCount = (inputDef.option == 'variadic') ? (inputs.length - inputIndex) : 1;
                     const inputCount = (inputDef.option == 'variadic') ? (inputs.length - inputIndex) : 1;
                     const inputArguments = inputs.slice(inputIndex, inputIndex + inputCount).filter((id) => id != '' || inputDef.option != 'optional').map((id) => tensors[id]);
                     const inputArguments = inputs.slice(inputIndex, inputIndex + inputCount).filter((id) => id != '' || inputDef.option != 'optional').map((id) => tensors[id]);
-                    this._inputs.push(new tengine.Argument(inputDef.name, inputArguments));
+                    this.inputs.push(new tengine.Argument(inputDef.name, inputArguments));
                     inputIndex += inputCount;
                     inputIndex += inputCount;
                 }
                 }
             }
             }
         } else {
         } else {
-            this._inputs.push(...inputs.slice(inputIndex).map((id, index) => {
+            this.inputs.push(...inputs.slice(inputIndex).map((id, index) => {
                 const inputName = ((inputIndex + index) == 0) ? 'input' : (inputIndex + index).toString();
                 const inputName = ((inputIndex + index) == 0) ? 'input' : (inputIndex + index).toString();
                 return new tengine.Argument(inputName, [ tensors[id] ]);
                 return new tengine.Argument(inputName, [ tensors[id] ]);
             }));
             }));
         }
         }
-
         const outputs = node.outputs;
         const outputs = node.outputs;
         let outputIndex = 0;
         let outputIndex = 0;
-        if (this._type && this._type.outputs) {
-            for (const outputDef of this._type.outputs) {
+        if (this.type && this.type.outputs) {
+            for (const outputDef of this.type.outputs) {
                 if (outputIndex < outputs.length || outputDef.option != 'optional') {
                 if (outputIndex < outputs.length || outputDef.option != 'optional') {
                     const outputCount = (outputDef.option == 'variadic') ? (outputs.length - outputIndex) : 1;
                     const outputCount = (outputDef.option == 'variadic') ? (outputs.length - outputIndex) : 1;
                     const outputArguments = outputs.slice(outputIndex, outputIndex + outputCount).map((id) => tensors[id]);
                     const outputArguments = outputs.slice(outputIndex, outputIndex + outputCount).map((id) => tensors[id]);
-                    this._outputs.push(new tengine.Argument(outputDef.name, outputArguments));
+                    this.outputs.push(new tengine.Argument(outputDef.name, outputArguments));
                     outputIndex += outputCount;
                     outputIndex += outputCount;
                 }
                 }
             }
             }
         } else {
         } else {
-            this._outputs.push(...outputs.slice(outputIndex).map((id, index) => {
+            this.outputs.push(...outputs.slice(outputIndex).map((id, index) => {
                 const outputName = ((outputIndex + index) == 0) ? 'output' : (outputIndex + index).toString();
                 const outputName = ((outputIndex + index) == 0) ? 'output' : (outputIndex + index).toString();
                 return new tengine.Argument(outputName, [ tensors[id] ]);
                 return new tengine.Argument(outputName, [ tensors[id] ]);
             }));
             }));
         }
         }
     }
     }
-
-    get type() {
-        return this._type;
-    }
-
-    get name() {
-        return this._name;
-    }
-
-    get attributes() {
-        return this._attributes;
-    }
-
-    get inputs() {
-        return this._inputs;
-    }
-
-    get outputs() {
-        return this._outputs;
-    }
 };
 };
 
 
 tengine.Attribute = class {
 tengine.Attribute = class {
 
 
     constructor(metadata, key, value) {
     constructor(metadata, key, value) {
-        this._type = '';
-        this._name = key;
-        this._value = value;
+        this.type = '';
+        this.name = key;
+        this.value = value;
         if (metadata) {
         if (metadata) {
-            this._name = metadata.name;
+            this.name = metadata.name;
             if (metadata.type) {
             if (metadata.type) {
-                this._type = metadata.type;
+                this.type = metadata.type;
             }
             }
             if (metadata.visible === false) {
             if (metadata.visible === false) {
-                this._visible = false;
+                this.visible = false;
             } else if (Object.prototype.hasOwnProperty.call(metadata, 'default')) {
             } else if (Object.prototype.hasOwnProperty.call(metadata, 'default')) {
-                if (this._value == metadata.default || (this._value && this._value.toString() == metadata.default.toString())) {
-                    this._visible = false;
+                if (this.value == metadata.default || (this.value && this.value.toString() == metadata.default.toString())) {
+                    this.visible = false;
                 }
                 }
             }
             }
         }
         }
     }
     }
-
-    get type() {
-        return this._type;
-    }
-
-    get name() {
-        return this._name;
-    }
-
-    get value() {
-        return this._value;
-    }
-
-    get visible() {
-        return this._visible == false ? false : true;
-    }
 };
 };
 
 
 tengine.Tensor = class {
 tengine.Tensor = class {
 
 
-    constructor(type, data) {
-        this._type = type;
-        this._data = data;
-    }
-
-    get type() {
-        return this._type;
-    }
-
-    get values() {
-        return this._data;
+    constructor(type, values) {
+        this.type = type;
+        this.values = values;
     }
     }
-
 };
 };
 
 
 tengine.TensorType = class {
 tengine.TensorType = class {
 
 
     constructor(dataType, shape) {
     constructor(dataType, shape) {
         switch (dataType) {
         switch (dataType) {
-            case 0: this._dataType = 'float32'; break;
-            case 1: this._dataType = 'float16'; break;
-            case 2: this._dataType = 'int8'; break;
-            case 3: this._dataType = 'uint8'; break;
-            case 4: this._dataType = 'int32'; break;
-            case 5: this._dataType = 'int16'; break;
+            case 0: this.dataType = 'float32'; break;
+            case 1: this.dataType = 'float16'; break;
+            case 2: this.dataType = 'int8'; break;
+            case 3: this.dataType = 'uint8'; break;
+            case 4: this.dataType = 'int32'; break;
+            case 5: this.dataType = 'int16'; break;
             default: throw new tengine.Error("Unsupported data type'" + dataType + "'.");
             default: throw new tengine.Error("Unsupported data type'" + dataType + "'.");
         }
         }
-        this._shape = shape;
-    }
-
-    get dataType() {
-        return this._dataType;
-    }
-
-    get shape() {
-        return this._shape;
+        this.shape = shape;
     }
     }
 
 
     toString() {
     toString() {
-        return this._dataType + this._shape.toString();
+        return this.dataType + this.shape.toString();
     }
     }
 };
 };
 
 
 tengine.TensorShape = class {
 tengine.TensorShape = class {
 
 
     constructor(dimensions) {
     constructor(dimensions) {
-        this._dimensions = dimensions;
-    }
-
-    get dimensions() {
-        return this._dimensions;
+        this.dimensions = dimensions;
     }
     }
 
 
     toString() {
     toString() {
-        return this._dimensions ? ('[' + this._dimensions.map((dimension) => dimension ? dimension.toString() : '?').join(',') + ']') : '';
+        return this.dimensions ? ('[' + this.dimensions.map((dimension) => dimension ? dimension.toString() : '?').join(',') + ']') : '';
     }
     }
 };
 };
 
 
@@ -370,7 +255,7 @@ tengine.Reader = class {
         // https://github.com/OAID/Tengine/blob/tengine-lite/source/serializer/tmfile/tm2_format.h
         // https://github.com/OAID/Tengine/blob/tengine-lite/source/serializer/tmfile/tm2_format.h
     }
     }
 
 
-    _read() {
+    read() {
         if (this._stream) {
         if (this._stream) {
             const types = new Map();
             const types = new Map();
             const register = (index, version, name, params) => {
             const register = (index, version, name, params) => {
@@ -498,7 +383,6 @@ tengine.Reader = class {
             register(101, 0, 'L2Normalization', []);
             register(101, 0, 'L2Normalization', []);
             register(102, 0, 'PackModel', ['i','i']);
             register(102, 0, 'PackModel', ['i','i']);
             register(103, 0, 'Num', []);
             register(103, 0, 'Num', []);
-
             const buffer = this._stream.peek();
             const buffer = this._stream.peek();
             const reader = new tengine.BinaryReader(buffer);
             const reader = new tengine.BinaryReader(buffer);
             this._majorVersion = reader.uint16();
             this._majorVersion = reader.uint16();
@@ -537,7 +421,6 @@ tengine.Reader = class {
                 subgraph.nodes = [];
                 subgraph.nodes = [];
                 subgraph.tensors = [];
                 subgraph.tensors = [];
                 this._graphs.push(subgraph);
                 this._graphs.push(subgraph);
-
                 // nodes
                 // nodes
                 for (const nodeOffset of nodeOffsets) {
                 for (const nodeOffset of nodeOffsets) {
                     reader.seek(nodeOffset);
                     reader.seek(nodeOffset);
@@ -549,16 +432,13 @@ tengine.Reader = class {
                     node.name = reader.string();
                     node.name = reader.string();
                     const attributeOffsets = reader.uint32s();
                     const attributeOffsets = reader.uint32s();
                     node.dynamicShape = reader.boolean();
                     node.dynamicShape = reader.boolean();
-
                     reader.seek(typeOffset);
                     reader.seek(typeOffset);
                     node.version = reader.int32();
                     node.version = reader.int32();
                     const index = reader.int32();
                     const index = reader.int32();
                     const paramsOffset = reader.uint32();
                     const paramsOffset = reader.uint32();
-
                     const schema = operator(index, node.version);
                     const schema = operator(index, node.version);
                     node.type = schema ? schema.name : index.toString();
                     node.type = schema ? schema.name : index.toString();
                     const paramTypes = schema ? schema.params : [];
                     const paramTypes = schema ? schema.params : [];
-
                     node.params = [];
                     node.params = [];
                     if (paramsOffset) {
                     if (paramsOffset) {
                         reader.seek(paramsOffset);
                         reader.seek(paramsOffset);
@@ -593,11 +473,9 @@ tengine.Reader = class {
                             }
                             }
                         }
                         }
                     }
                     }
-
                     if (node.type === 'Slice') {
                     if (node.type === 'Slice') {
                         node.params[6] = (this._originalFormat == 5) ? node.params[6] : 0;
                         node.params[6] = (this._originalFormat == 5) ? node.params[6] : 0;
                     }
                     }
-
                     node.attributes = attributeOffsets.map((attributeOffset) => {
                     node.attributes = attributeOffsets.map((attributeOffset) => {
                         reader.seek(attributeOffset);
                         reader.seek(attributeOffset);
                         const name = reader.string();
                         const name = reader.string();
@@ -605,10 +483,8 @@ tengine.Reader = class {
                         const type = reader.int32();
                         const type = reader.int32();
                         return { name: name, value: value, type: type };
                         return { name: name, value: value, type: type };
                     });
                     });
-
                     subgraph.nodes.push(node);
                     subgraph.nodes.push(node);
                 }
                 }
-
                 // buffers
                 // buffers
                 const buffers = bufferOffsets.map((bufferOffset) => {
                 const buffers = bufferOffsets.map((bufferOffset) => {
                     reader.seek(bufferOffset);
                     reader.seek(bufferOffset);
@@ -620,7 +496,6 @@ tengine.Reader = class {
                     }
                     }
                     return null;
                     return null;
                 });
                 });
-
                 // tensors
                 // tensors
                 subgraph.tensors = tensorOffsets.map((tensorOffset) => {
                 subgraph.tensors = tensorOffsets.map((tensorOffset) => {
                     reader.seek(tensorOffset);
                     reader.seek(tensorOffset);
@@ -643,7 +518,6 @@ tengine.Reader = class {
                     }
                     }
                     return tensor;
                     return tensor;
                 });
                 });
-
                 for (const node of subgraph.nodes) {
                 for (const node of subgraph.nodes) {
                     if (node.type === 'Convolution') {
                     if (node.type === 'Convolution') {
                         switch (subgraph.graphLayout) {
                         switch (subgraph.graphLayout) {
@@ -668,12 +542,10 @@ tengine.Reader = class {
     }
     }
 
 
     get version() {
     get version() {
-        this._read();
         return this._majorVersion + '.' + this._minorVersion;
         return this._majorVersion + '.' + this._minorVersion;
     }
     }
 
 
     get source() {
     get source() {
-        this._read();
         switch (this._originalFormat) {
         switch (this._originalFormat) {
             case 0: return '';
             case 0: return '';
             case 1: return 'Tengine';
             case 1: return 'Tengine';
@@ -694,7 +566,6 @@ tengine.Reader = class {
     }
     }
 
 
     get graphs() {
     get graphs() {
-        this._read();
         return this._graphs;
         return this._graphs;
     }
     }
 };
 };

+ 3 - 3
source/tflite.js

@@ -86,7 +86,7 @@ tflite.Model = class {
         this._format = 'TensorFlow Lite';
         this._format = 'TensorFlow Lite';
         this._format = this._format + ' v' + model.version.toString();
         this._format = this._format + ' v' + model.version.toString();
         this._description = model.description || '';
         this._description = model.description || '';
-        this._metadata = [];
+        this._metadata = new Map();
         const builtinOperators = new Map();
         const builtinOperators = new Map();
         const upperCase = new Set([ '2D', 'LSH', 'SVDF', 'RNN', 'L2', 'LSTM' ]);
         const upperCase = new Set([ '2D', 'LSH', 'SVDF', 'RNN', 'L2', 'LSTM' ]);
         for (const key of Object.keys(tflite.schema.BuiltinOperator)) {
         for (const key of Object.keys(tflite.schema.BuiltinOperator)) {
@@ -127,10 +127,10 @@ tflite.Model = class {
                                 this._description = this._description ? [ this._description, modelMetadata.description].join(' ') : modelMetadata.description;
                                 this._description = this._description ? [ this._description, modelMetadata.description].join(' ') : modelMetadata.description;
                             }
                             }
                             if (modelMetadata.author) {
                             if (modelMetadata.author) {
-                                this._metadata.push({ name: 'author', value: modelMetadata.author });
+                                this._metadata.set('author', modelMetadata.author);
                             }
                             }
                             if (modelMetadata.license) {
                             if (modelMetadata.license) {
-                                this._metadata.push({ name: 'license', value: modelMetadata.license });
+                                this._metadata.set('license', modelMetadata.license);
                             }
                             }
                         }
                         }
                         break;
                         break;

+ 2 - 2
source/view.js

@@ -2959,8 +2959,8 @@ view.ModelSidebar = class extends view.ObjectSidebar {
             this.addProperty('runtime', model.runtime);
             this.addProperty('runtime', model.runtime);
         }
         }
         if (model.metadata) {
         if (model.metadata) {
-            for (const entry of model.metadata) {
-                this.addProperty(entry.name, entry.value);
+            for (const [name, value] of Array.from(model.metadata)) {
+                this.addProperty(name, value);
             }
             }
         }
         }
         const graphs = Array.isArray(model.graphs) ? model.graphs : [];
         const graphs = Array.isArray(model.graphs) ? model.graphs : [];

+ 3 - 0
test/worker.js

@@ -515,6 +515,9 @@ export class Target {
         if (this.runtime && this.model.runtime != this.runtime) {
         if (this.runtime && this.model.runtime != this.runtime) {
             throw new Error("Invalid runtime '" + this.model.runtime + "'.");
             throw new Error("Invalid runtime '" + this.model.runtime + "'.");
         }
         }
+        if (this.model.metadata && !(this.model.metadata instanceof Map)) {
+            throw new Error("Invalid metadata.'");
+        }
         if (this.assert) {
         if (this.assert) {
             for (const assert of this.assert) {
             for (const assert of this.assert) {
                 const parts = assert.split('==').map((item) => item.trim());
                 const parts = assert.split('==').map((item) => item.trim());