Files
wehub-resource-sync 7254f7b4d1
Build / Build (macos-latest) (push) Has been cancelled
Build / Build (ubuntu-latest) (push) Has been cancelled
Build / Build (windows-latest) (push) Has been cancelled
Build / Analyze (javascript) (push) Has been cancelled
Build / Analyze (python) (push) Has been cancelled
chore: import upstream snapshot with attribution
2026-07-13 12:37:45 +08:00

868 lines
40 KiB
JavaScript

const openvino = {};
openvino.ModelFactory = class {
async match(context) {
const identifier = context.identifier.toLowerCase();
const extension = identifier.split('.').pop();
if (/^.*\.ncnn\.bin$/.test(identifier) ||
/^.*\.pnnx\.bin$/.test(identifier) ||
/^.*pytorch_model.*\.bin$/.test(identifier) ||
/^.*group.+-shard.+of.+\.bin$/.test(identifier) ||
/^.*param\.bin$/.test(identifier)) {
return null;
}
if (extension === 'bin') {
const stream = context.stream;
const length = Math.min(0x10000, stream.length);
if (length >= 4) {
let buffer = stream.peek(length);
const view = new DataView(buffer.buffer, buffer.byteOffset, buffer.length);
const signature = view.getUint32(0, true);
for (let i = 0; i < buffer.length - 4; i++) {
const signature = view.getUint32(i, true);
if (signature === 0xdeadbeef || // Core ML
signature === 0x01306b47 || signature === 0x000d4b38 || signature === 0x0002c056) { // ncnn
return null;
}
}
const match = (pattern, identifier, buffer) => {
if (pattern.identifier && typeof pattern.identifier === 'string' && identifier !== pattern.identifier) {
return false;
} else if (pattern.identifier && pattern.identifier instanceof RegExp && !pattern.identifier.test(identifier)) {
return false;
} else if (pattern.signature && !pattern.signature.every((value, index) => value === buffer[index])) {
return false;
}
return true;
};
const include = [
{ identifier: 'googlenet-v1.bin', signature: [0x80, 0xD6, 0x50, 0xD7, 0xB0, 0xD7, 0xA5, 0x2D, 0xCA, 0x28, 0x49, 0x2A, 0x35, 0x31, 0x0A, 0x31] },
{ identifier: 'text-recognition-0012.bin', signature: [0x0B, 0x21, 0xC6, 0xBC, 0xD0, 0xBB, 0xC1, 0x3B] },
];
if (include.some((pattern) => match(pattern, identifier, buffer))) {
return context.set('openvino.bin');
}
const exclude = [
{ identifier: '__model__.bin' },
{ identifier: 'config.bin' },
{ identifier: 'model.bin' },
{ identifier: 'ncnn.bin' },
{ identifier: 'programs.bin' },
{ identifier: 'weights.bin' },
{ identifier: /stories\d+(m|k)\.bin$/ },
{ signature: [0x21, 0xA8, 0xEF, 0xBE, 0xAD, 0xDE] }
];
if (exclude.some((pattern) => match(pattern, identifier, buffer))) {
return null;
}
if (signature === 0x00000001) {
return null;
}
const size = Math.min(buffer.length & 0xfffffffc, 128);
buffer = buffer.subarray(0, size);
if (Array.from(buffer).every((value) => value === 0)) {
return context.set('openvino.bin');
}
const f32 = new Array(buffer.length >> 2);
for (let i = 0; i < f32.length; i++) {
f32[i] = view.getFloat32(i << 2, true);
}
const f16 = new Array(buffer.length >> 1);
for (let i = 0; i < f16.length; i++) {
f16[i] = view.getFloat16(i << 1, true);
}
const i32 = new Array(buffer.length >> 2);
for (let i = 0; i < f32.length; i++) {
i32[i] = view.getInt32(i << 2, true);
}
const validateFloat = (array) => array[0] !== 0 && array.every((x) => !Number.isNaN(x) && Number.isFinite(x)) &&
(array.every((x) => x > -20.0 && x < 20.0 && (x >= 0 || x < -0.0000001) && (x <= 0 || x > 0.0000001)) ||
array.every((x) => x > -100.0 && x < 100.0 && (x * 10) % 1 === 0));
const validateInt = (array) => array.length > 32 &&
array.slice(0, 32).every((x) => x === 0 || x === 1 || x === 2 || x === 0x7fffffff);
if (validateFloat(f32) || validateFloat(f16) || validateInt(i32)) {
return context.set('openvino.bin');
}
}
return null;
}
const tags = await context.tags('xml');
if (tags.has('net')) {
return context.set('openvino.xml');
}
return null;
}
filter(context, match) {
return context.type !== 'openvino.xml' || match.type !== 'openvino.bin';
}
async open(context) {
const identifier = context.identifier;
const base = identifier.substring(0, identifier.length - 4);
let bin = null;
switch (context.type) {
case 'openvino.xml': {
try {
const file = `${base}.bin`;
const content = await context.fetch(file);
bin = content.stream.peek();
} catch {
// continue regardless of error
}
break;
}
case 'openvino.bin': {
try {
const file = `${base}.xml`;
bin = context.stream.peek();
context = await context.fetch(file, null);
} catch (error) {
const message = error && error.message ? error.message : error.toString();
throw new openvino.Error(`Required OpenVINO model definition not found (${message.replace(/\.$/, '')}).`);
}
break;
}
default: {
throw new openvino.Error(`Unsupported OpenVINO format '${context.type}'.`);
}
}
let document = null;
try {
document = await context.read('xml');
} catch (error) {
const message = error && error.message ? error.message : error.toString();
throw new openvino.Error(`File format is not OpenVINO XML (${message.replace(/\.$/, '')}).`);
}
if (!document.documentElement || document.documentElement.localName !== 'net') {
throw new openvino.Error('File format is not OpenVINO IR.');
}
const element = document.documentElement;
const metadata = await context.metadata('openvino-metadata.json');
const object = (element) => {
const obj = {};
for (const attribute of element.attributes) {
obj[attribute.localName] = attribute.value;
}
return obj;
};
const child = (parent, name) => {
const elements = parent.getElementsByTagName(name);
if (elements.length > 1) {
throw new openvino.Error(`Element '${parent.localName}' has multiple '${name}' elements.`);
}
return elements.length > 0 ? elements[0] : null;
};
const children = (parent, name, element) => {
const list = child(parent, name);
return list ? list.getElementsByTagName(element) : [];
};
const edges = (parent, name) => {
const map = {};
for (const element of children(parent, name || 'edges', 'edge')) {
const fromLayer = element.getAttribute('from-layer');
const fromPort = element.getAttribute('from-port');
const toLayer = element.getAttribute('to-layer');
const toPort = element.getAttribute('to-port');
map[`${toLayer}:${toPort}`] = `${fromLayer}:${fromPort}`;
}
return map;
};
const layers = (parent) => {
const ports = (parent, name) => {
return children(parent, name, 'port').map((element) => {
const port = object(element);
port.dims = element.getElementsByTagName('dim').map((dim) => parseInt(dim.textContent.trim(), 10));
return port;
});
};
return children(parent, 'layers', 'layer').map((element) => {
const layer = object(element);
layer.input = ports(element, 'input');
layer.output = ports(element, 'output');
const data = child(element, 'data');
const blobs = child(element, 'blobs');
layer.data = data ? object(data) : {};
layer.blobs = blobs ? blobs.getElementsByTagName('*').map((blob) => {
const obj = object(blob);
obj.name = blob.localName;
obj.offset = parseInt(obj.offset, 10);
obj.size = parseInt(obj.size, 10);
return obj;
}) : [];
if (layer.type === 'TensorIterator') {
layer.back_edges = edges(element, 'back_edges');
const body = child(element, 'body');
if (body) {
layer.body = {
layers: layers(body),
edges: edges(body)
};
}
const port_map = child(element, 'port_map');
if (port_map) {
layer.port_map = { input: [], output: [] };
for (const port of port_map.getElementsByTagName('*')) {
const item = object(port);
switch (port.localName) {
case 'input': layer.port_map.input.push(item); break;
case 'output': layer.port_map.output.push(item); break;
default: throw new openvino.Error(`Unsupported port local name '${port.localName}'.`);
}
}
}
}
return layer;
});
};
const net = object(element);
net.body = {
layers: layers(element),
edges: edges(element)
};
return new openvino.Model(metadata, net, bin);
}
};
openvino.Model = class {
constructor(metadata, net, bin) {
this.name = net.name || '';
this.modules = [new openvino.Graph(metadata, net, bin)];
this.format = 'OpenVINO IR';
}
};
openvino.Graph = class {
constructor(metadata, net, bin) {
this.name = net.name || '';
this.nodes = [];
this.inputs = [];
this.outputs = [];
const tensors = new Map();
const values = new Map();
values.map = (layer, precision, port, map) => {
const id = `${layer}:${port.id}`;
const name = map && map[id] ? map[id] : id;
if (name === '') {
throw new openvino.Error('Empty value name.');
}
const shape = port.dims.length === 0 ? null : new openvino.TensorShape(port.dims);
if (!precision && values.has(name)) {
const value = values.get(name);
if (value.type && value.type.shape && value.type.shape.equals(shape)) {
return value;
}
}
const type = new openvino.TensorType(precision, shape);
let tensor = null;
if (tensors.has(id)) {
const blob = tensors.get(id);
const offset = blob.offset;
const size = blob.size;
const shape = new openvino.TensorShape(blob.shape);
const type = new openvino.TensorType(blob.precision || precision, shape);
const data = (bin && (offset + size) <= bin.length) ? bin.slice(offset, offset + size) : null;
tensor = new openvino.Tensor(type, data, 'Const');
}
if (!values.has(name)) {
values.set(name, new openvino.Value(name, type, tensor));
} else if (name === id && type && !type.equals(values.get(name).type)) {
throw new openvino.Error(`Duplicate value '${name}'.`);
}
return values.get(name);
};
const nodes = new Map();
const constant = (layers, edges, back_edges) => {
back_edges = back_edges || {};
for (const layer of layers) {
if (layer.type === 'Const' &&
layer.input.length === 0 && layer.output.length === 1 && layer.blobs.length === 0 &&
layer.data && layer.data.element_type !== undefined && layer.data.offset !== undefined && layer.data.size !== undefined) {
let precision = null;
switch (layer.data.element_type) {
case 'f16': precision = 'FP16'; break;
case 'f32': precision = 'FP32'; break;
case 'f64': precision = 'FP64'; break;
default: precision = layer.data.element_type.toUpperCase();
}
const shape = layer.data.shape;
layer.blobs.push({
name: 'value',
precision,
offset: parseInt(layer.data.offset, 10),
size: parseInt(layer.data.size, 10),
shape: shape ? shape.split(',').map((dim) => parseInt(dim.trim(), 10)) : null
});
layer.data = {};
}
if (layer.type === 'Const' && layer.blobs.length === 1 && !layer.blobs[0].shape &&
layer.input.length === 0 && layer.output.length === 1 && layer.output[0].dims) {
layer.blobs[0].shape = layer.output[0].dims;
}
}
const constants = new Map();
for (const layer of layers) {
if (layer.type === 'Const' && layer.input.length === 0 && layer.output.length === 1) {
const from = `${layer.id}:${layer.output[0].id}`;
constants.set(from, { layer, counter: 0 });
}
}
for (const from of Object.values(edges)) {
if (constants.has(from)) {
constants.get(from).counter++;
}
}
if (back_edges) {
for (const from of Object.values(back_edges)) {
if (constants.has(from)) {
constants.get(from).counter++;
}
}
}
for (const [name, value] of constants) {
if (value.counter !== 1) {
constants.delete(name);
}
}
for (const layer of layers) {
if (layer.blobs.length === 0) {
for (let i = layer.input.length - 1; i >= 0; i--) {
const input = layer.input[i];
const to = `${layer.id}:${input.id}`;
const from = edges[to] || back_edges[to];
if (!constants.has(from)) {
break;
}
const constLayer = constants.get(from).layer;
if (constLayer && Array.isArray(constLayer.blobs) && constLayer.blobs.length > 0) {
const [blob] = constLayer.blobs;
if (blob) {
blob.id = constLayer.name || constLayer.id;
layer.input[i].blob = blob;
constants.get(from).layer = null;
constants.get(from).delete = true;
}
}
}
}
}
return layers.filter((layer) => {
if (layer.type === 'Const' && layer.input.length === 0 && layer.output.length === 1) {
const from = `${layer.id}:${layer.output[0].id}`;
if (constants.has(from) && constants.get(from).delete) {
return false;
}
}
return true;
});
};
const body = net.body;
const body_layers = body && Array.isArray(body.layers) ? body.layers : [];
const body_edges = body && body.edges ? body.edges : {};
const layers = new Map(body_layers.map((entry) => [entry.id, entry]));
const ports = new Map();
if (Array.isArray(net.input)) {
for (const input of net.input) {
const value = values.map('', input.precision || null, input);
const argument = new openvino.Argument(input.id, [value]);
this.inputs.push(argument);
ports.set(input.id, value);
}
}
if (Array.isArray(net.output)) {
for (const output of net.output) {
const value = values.map('', output.precision || null, output);
const argument = new openvino.Argument(output.id, [value]);
this.outputs.push(argument);
ports.set(output.id, value);
}
}
for (const layer of body_layers) {
for (const output of layer.output) {
if (!output.precision) {
output.precision = layer.precision;
}
}
}
if (net.port_map) {
for (const input of net.port_map.input) {
const external_port = net.input.find((v) => v.id === input.external_port_id);
const layer = layers.get(input.internal_layer_id);
if (input.internal_port_id === undefined) {
input.internal_port_id = '';
layer.input.push({
id: input.internal_port_id,
precision: layer.data.element_type,
dims: layer.data.shape.split(',')
});
}
const internal_port = layer.input.find((v) => v.id === input.internal_port_id);
internal_port.precision = external_port.precision;
}
for (const output of net.port_map.output) {
const external_port = net.output.find((v) => v.id === output.external_port_id);
const layer = layers.get(output.internal_layer_id);
if (output.internal_port_id === undefined) {
output.internal_port_id = '';
layer.output.push({
id: output.internal_port_id,
precision: external_port.precision,
dims: external_port.dims
});
}
}
}
const layer_list = constant(body_layers, body_edges);
for (const layer of layer_list) {
for (const input of layer.input) {
if (input.blob) {
tensors.set(`${layer.id}:${input.id}`, input.blob);
}
}
}
for (const layer of layer_list) {
for (const output of layer.output) {
values.map(layer.id, output.precision, output, null);
}
}
for (const layer of layer_list) {
const inputs = layer.input.map((input) => {
const to = `${layer.id}:${input.id}`;
if (body.edges[to]) {
const output = body.edges[to] ? body.edges[to].split(':') : [];
const [outputLayerId, outputId] = output;
const outputLayer = layers.get(outputLayerId);
if (outputLayer && outputId) {
const output = outputLayer.output.find((output) => output.id === outputId);
if (input && output) {
input.precision = output.precision;
}
}
}
return values.map(layer.id, input.precision || layer.precision || null, input, body.edges);
});
const outputs = layer.output.map((output) => {
let precision = null;
if (output && output.precision) {
precision = output.precision;
} else if (layer && layer.precision) {
precision = layer.precision;
}
return values.map(layer.id, precision, output, null);
});
const subgraph = Array.isArray(net.input) || Array.isArray(net.output);
if (!subgraph && (layer.type === 'Input' || layer.type === 'Parameter')) {
const name = layer.name || '';
// precision is a part of OpenVINO IR layers of IR v6 and earlier
// in IR v7 and newer the port is no longer an attribute of the layer but of each output port
// IR input is not just a placeholder, it is conceptually the legitimate layer
// in order not to break compatibility with the overall approach
// with openvino.Argument for inputs and openvino.Node for outputs
// input openvino.Node would be stored as an optional attribute of openvino.Parameter
this.inputs.push(new openvino.Argument(name, outputs));
} else {
const node = new openvino.Node(metadata, layer, inputs, outputs, bin);
nodes.set(layer.id, node);
}
}
this.nodes = Array.from(nodes.values());
if (net.port_map) {
const createMapLayer = (obj) => {
const data = {};
for (const [name, value] of Object.entries(obj)) {
if (name !== 'external_port_id' && name !== 'internal_layer_id' && name !== 'internal_port_id') {
data[name] = value;
}
}
return { type: '-', data };
};
for (const input of net.port_map.input) {
const internal_port = layers.get(input.internal_layer_id).input.find((v) => v.id === input.internal_port_id);
const inputs = [ports.get(input.external_port_id)];
const outputs = [values.map(input.internal_layer_id, internal_port.precision, internal_port)];
const layer = createMapLayer(input);
this.nodes.push(new openvino.Node(metadata, layer, inputs, outputs));
}
for (const output of net.port_map.output) {
const internal_port = layers.get(output.internal_layer_id).output.find((v) => v.id === output.internal_port_id);
const inputs = [values.map(output.internal_layer_id, internal_port.precision, internal_port)];
const outputs = [ports.get(output.external_port_id)];
const layer = createMapLayer(output);
this.nodes.push(new openvino.Node(metadata, layer, inputs, outputs));
}
}
}
};
openvino.Node = class {
constructor(metadata, layer, inputs, outputs, bin) {
this.name = layer.name || '';
this.inputs = [];
this.outputs = [];
this.attributes = [];
const type = layer.type;
this.type = metadata.type(type) || { name: type };
for (let i = 0; i < inputs.length;) {
let input = null;
if (this.type && Array.isArray(this.type.inputs) && i < this.type.inputs.length) {
input = this.type.inputs[i];
} else if (inputs.length === 1) {
input = { name: 'input' };
} else {
input = { name: i.toString() };
}
const count = input.type === 'Tensor[]' ? inputs.length - i : 1;
const values = inputs.slice(i, i + count);
const argument = new openvino.Argument(input.name, values);
this.inputs.push(argument);
i += count;
}
for (let i = 0; i < outputs.length;) {
let output = null;
if (this.type && Array.isArray(this.type.outputs) && i < this.type.outputs.length) {
output = this.type.outputs[i];
} else if (outputs.length === 1) {
output = { name: 'output' };
} else {
output = { name: i.toString() };
}
const count = output.type === 'Tensor[]' ? outputs.length - i : 1;
const values = outputs.slice(i, i + count);
const argument = new openvino.Argument(output.name, values);
this.outputs.push(argument);
i += count;
}
const op = type;
for (const [name, obj] of Object.entries(layer.data)) {
const schema = metadata.attribute(op, name);
let value = obj;
let type = null;
let visible = true;
if (schema && schema.type !== undefined) {
type = schema.type;
switch (schema.type) {
case '':
case 'graph':
case 'string':
break;
case 'boolean':
if (obj === '1' || obj === 'true' || obj === 'True') {
value = true;
} else if (obj === '0' || obj === 'false' || obj === 'False') {
value = false;
} else {
throw new openvino.Error(`Unsupported attribute boolean value '${obj}'.`);
}
break;
case 'int32':
case 'int64': {
const intValue = Number.parseInt(obj, 10);
value = Number.isNaN(obj - intValue) ? obj : intValue;
break;
}
case 'float32':
case 'float64': {
const floatValue = Number.parseFloat(obj);
value = Number.isNaN(obj - floatValue) ? obj : floatValue;
break;
}
case 'int32[]':
if (obj.length > 2) {
let ints = [];
for (const entry of obj.split(',')) {
const item = entry.trim();
const intValue = Number.parseInt(item, 10);
if (Number.isNaN(item - intValue)) {
ints = null;
} else if (ints !== null) {
ints.push(intValue);
}
}
if (ints !== null) {
value = ints;
}
}
break;
case 'float32[]':
if (obj.length > 2) {
let floats = [];
for (const entry of obj.split(',')) {
const item = entry.trim();
const floatValue = Number.parseFloat(item);
if (Number.isNaN(item - floatValue)) {
floats = null;
} else if (floats !== null) {
floats.push(floatValue);
}
}
if (floats !== null) {
value = floats;
}
}
break;
default:
throw new openvino.Error(`Unsupported attribute type '${schema.type}'.`);
}
}
if (schema && schema.visible === false) {
visible = false;
} else if (schema && schema.default !== undefined) {
const defaultValue = schema.default;
if (value === defaultValue) {
visible = false;
} else if (Array.isArray(value) && Array.isArray(defaultValue)) {
const repeat = defaultValue.length > 1 && defaultValue[defaultValue.length - 1] === null;
if (value.every((item, index) => item === (repeat && index >= defaultValue.length - 1 ? defaultValue[defaultValue.length - 2] : defaultValue[index]))) {
visible = false;
}
}
}
const attribute = new openvino.Argument(name, value, type, visible);
this.attributes.push(attribute);
}
if (layer.type === 'TensorIterator') {
const graph = new openvino.Graph(metadata, layer, null);
const attribute = new openvino.Argument('body', graph, 'graph');
this.attributes.push(attribute);
}
for (const blob of layer.blobs || []) {
const name = blob.name;
const offset = blob.offset;
let data = (bin && (offset + blob.size) <= bin.length) ? bin.slice(offset, offset + blob.size) : null;
let dimensions = blob.shape || null;
const category = blob.kind || 'Blob';
const id = blob.id || '';
const precision = blob.precision || layer.precision || null;
let itemSize = -1;
switch (precision) {
case 'BOOL': case 'BOOLEAN': itemSize = 1; break;
case 'I1': case 'U1': itemSize = 0.125; break;
case 'I2': case 'U2': itemSize = 0.25; break;
case 'I4': case 'U4': itemSize = 0.5; break;
case 'I8': case 'U8': itemSize = 1; break;
case 'I16': case 'U16': case 'FP16': itemSize = 2; break;
case 'I32': case 'U32': case 'FP32': itemSize = 4; break;
case 'I64': case 'U64': case 'FP64': itemSize = 8; break;
case 'F8E4M3': itemSize = 1; break;
case 'BF16': itemSize = 2; break;
case 'DYNAMIC': itemSize = 0; break;
default: throw new openvino.Error(`Unsupported data type size '${precision}'.`);
}
const weight = (name, precision, dimensions, data) => {
const shape = dimensions ? new openvino.TensorShape(dimensions) : null;
const type = new openvino.TensorType(precision, shape);
const tensor = new openvino.Tensor(type, data, category);
const value = new openvino.Value(id, null, tensor);
this.inputs.push(new openvino.Argument(name, [value]));
const size = Math.ceil(dimensions.reduce((a, b) => a * b, 1) * itemSize);
if (data && data.length !== size) {
return data.slice(size, data.length);
}
return null;
};
if (itemSize !== -1) {
switch (`${type}:${name}`) {
case 'FullyConnected:weights': {
const outSize = parseInt(layer.data['out-size'], 10);
dimensions = [layer.input[0].dims[1], outSize];
break;
}
case 'FullyConnected:biases': {
dimensions = [parseInt(layer.data['out-size'], 10)];
break;
}
case 'Convolution:weights':
case 'Deconvolution:weights': {
const c = this.inputs[0].value[0].type.shape.dimensions[1];
const group = parseInt(layer.data.group || '1', 10);
const kernel = layer.data['kernel-x'] !== undefined && layer.data['kernel-y'] !== undefined ?
[parseInt(layer.data['kernel-x'], 10), parseInt(layer.data['kernel-y'], 10)] :
layer.data.kernel.split(',').map((v) => parseInt(v.trim(), 10));
const n = parseInt(layer.data.output, 10);
dimensions = [Math.floor(c / group), n].concat(kernel);
break;
}
case 'LSTMCell:weights': {
const input_size = inputs[0].type.shape.dimensions[1];
const hidden_size = parseInt(layer.data.hidden_size, 10);
data = weight('W', precision, [4 * hidden_size, input_size], data);
data = weight('R', precision, [4 * hidden_size, hidden_size], data);
break;
}
case 'LSTMCell:biases': {
const hidden_size = parseInt(layer.data.hidden_size, 10);
data = weight('B', precision, [4 * hidden_size], data);
break;
}
case 'GRUCell:weights': {
const input_size = inputs[0].type.shape.dimensions[1];
const hidden_size = parseInt(layer.data.hidden_size, 10);
data = weight('W', precision, [3 * hidden_size, input_size], data);
data = weight('R', precision, [3 * hidden_size, hidden_size], data);
break;
}
case 'GRUCell:biases': {
const linear_before_reset = parseInt(layer.data.linear_before_reset, 10);
const hidden_size = parseInt(layer.data.hidden_size, 10);
dimensions = linear_before_reset ? [4 * hidden_size] : [3 * hidden_size];
data = weight('B', precision, dimensions, data);
break;
}
case 'Convolution:biases': {
dimensions = [parseInt(layer.data.output, 10)];
break;
}
case 'ScaleShift:weights':
case 'ScaleShift:biases':
case 'Normalize:weights': {
dimensions = [layer.input[0].dims[1]];
break;
}
case 'PReLU:weights': {
dimensions = layer.data.channel_shared === '1' ? [1] : [layer.input[0].dims[1]];
break;
}
case 'Const:custom': {
if (this.outputs.length > 0 &&
this.outputs[0].value.length > 0 &&
this.outputs[0].value[0].type &&
this.outputs[0].value[0].type.shape &&
this.outputs[0].value[0].type.shape.dimensions) {
dimensions = this.outputs[0].value[0].type.shape.dimensions;
}
break;
}
default: {
break;
}
}
}
if (data) {
weight(name, precision, dimensions, data);
}
}
}
};
openvino.Argument = class {
constructor(name, value, type = null, visible = true) {
this.name = name;
this.value = value;
this.type = type;
this.visible = visible;
}
};
openvino.Value = class {
constructor(name, type, initializer = null) {
if (typeof name !== 'string') {
throw new openvino.Error(`Invalid value identifier '${JSON.stringify(name)}'.`);
}
this.name = name;
this.type = initializer ? initializer.type : type;
this.initializer = initializer;
}
};
openvino.Tensor = class {
constructor(type, data, category) {
this.type = type;
this.values = data;
this.category = category;
}
};
openvino.TensorType = class {
constructor(precision, shape) {
precision = precision ? precision.toLowerCase() : precision;
switch (precision) {
case 'f4e2m1': this.dataType = 'float4e2m1'; break;
case 'f8e4m3': this.dataType = 'float8e4m3'; break;
case 'f8e5m2': this.dataType = 'float8e5m2'; break;
case 'f8e8m0': this.dataType = 'float8e8m0'; break;
case 'f16': this.dataType = 'float16'; break;
case 'f32': this.dataType = 'float32'; break;
case 'f64': this.dataType = 'float64'; break;
case 'fp16': this.dataType = 'float16'; break;
case 'fp32': this.dataType = 'float32'; break;
case 'fp64': this.dataType = 'float64'; break;
case 'bf16': this.dataType = 'bfloat16'; break;
case 'nf4': this.dataType = 'nfloat4'; break;
case 'i2': this.dataType = 'int2'; break;
case 'i4': this.dataType = 'int4'; break;
case 'i8': this.dataType = 'int8'; break;
case 'i16': this.dataType = 'int16'; break;
case 'i32': this.dataType = 'int32'; break;
case 'i64': this.dataType = 'int64'; break;
case 'u1': this.dataType = 'boolean'; break;
case 'u2': this.dataType = 'uint2'; break;
case 'u4': this.dataType = 'uint4'; break;
case 'u8': this.dataType = 'uint8'; break;
case 'u16': this.dataType = 'uint16'; break;
case 'u32': this.dataType = 'uint32'; break;
case 'u64': this.dataType = 'uint64'; break;
case 'bool': this.dataType = 'boolean'; break;
case 'boolean': this.dataType = 'boolean'; break;
case 'bin': this.dataType = 'bit'; break;
case 'string': this.dataType = 'string'; break;
case 'dynamic': this.dataType = 'dynamic'; break;
case 'unspecified': this.dataType = 'unspecified'; break;
case '': this.dataType = '?'; break;
case null: this.dataType = '?'; break;
default: throw new openvino.Error(`Unsupported precision '${JSON.stringify(precision)}'.`);
}
this.shape = shape;
}
equals(obj) {
return obj && this.dataType === obj.dataType &&
((this.shape === null && obj.shape === null) || this.shape && this.shape.equals(obj.shape));
}
toString() {
if (this.shape === null) {
return `${this.dataType}[?]`;
}
return this.dataType + this.shape.toString();
}
};
openvino.TensorShape = class {
constructor(dimensions) {
this.dimensions = dimensions;
}
equals(obj) {
return obj && Array.isArray(obj.dimensions) &&
Array.isArray(this.dimensions) && this.dimensions.length === obj.dimensions.length
&& obj.dimensions.every((value, index) => this.dimensions[index] === value);
}
toString() {
if (!this.dimensions || this.dimensions.length === 0) {
return '';
}
return `[${this.dimensions.join(',')}]`;
}
};
openvino.Error = class extends Error {
constructor(message) {
super(message);
this.name = 'Error loading OpenVINO model.';
}
};
export const ModelFactory = openvino.ModelFactory;