const onednn = {}; onednn.ModelFactory = class { async match(context) { const obj = await context.peek('json'); if (obj && obj.version && obj.engine_kind && obj.fpmath_mode && obj.graph) { return context.set('onednn', obj); } return null; } async open(context) { const metadata = await context.metadata('onednn-metadata.json'); return new onednn.Model(metadata, context.value); } }; onednn.Model = class { constructor(metadata, symbol) { const version = symbol.version; this.format = `oneDNN${version ? ` v${version}` : ''}`; this.runtime = `${symbol.engine_kind} ${symbol.fpmath_mode}`; this.modules = [new onednn.Graph(metadata, symbol)]; } }; onednn.Graph = class { constructor(metadata, symbol) { this.nodes = []; this.inputs = []; this.outputs = []; const layers = []; const tensors = new Set(); for (const layer of symbol.graph) { if (layer.kind === 'Wildcard' && layer.inputs.length === 0) { for (const output of layer.outputs) { tensors.add(output.id); } } else { layers.push(layer); } } const values = new Map(); const value = (obj) => { const id = obj.id; const shape = !obj.shape || (obj.shape.length === 1 && obj.shape[0] === -1) ? null : new onednn.TensorShape(obj.shape); const type = new onednn.TensorType(obj.dtype, shape); const tensor = tensors.has(id) ? new onednn.Tensor(type, obj.property_type) : null; if (!values.has(id)) { values.set(id, new onednn.Value(id.toString(), type, tensor)); } else if ((type && !type.equals(values.get(id).type)) || (tensor && !tensor.equals(values.get(id).initializer))) { throw new onednn.Error(`Duplicate value '${id}'.`); } return values.get(id); }; for (const layer of layers) { for (const input of layer.inputs) { value(input); } for (const output of layer.outputs) { value(output); } } const engine = symbol.engine_kind; for (const layer of layers) { const node = new onednn.Node(metadata, layer, engine, value, tensors); this.nodes.push(node); } const inputs = symbol.input_ports || []; for (const input of inputs) { const value = values.get(input); if (value) { const argument = new onednn.Argument(input.toString(), [value]); this.inputs.push(argument); } } const outputs = symbol.output_ports || []; for (const output of outputs) { const value = values.get(output); if (value) { const argument = new onednn.Argument(output.toString(), [value]); this.outputs.push(argument); } } } }; onednn.Node = class { constructor(metadata, node, device, value) { this.name = node.name; this.attributes = []; this.inputs = []; this.outputs = []; this.type = metadata.type(node.kind) || { name: node.kind }; this.device = device; this.identifier = node.id; const attrs = node.attrs; if (attrs) { for (const [name, obj] of Object.entries(attrs)) { let type = obj.type; let value = obj.value; switch (type) { case 'bool': type = 'boolean'; switch (value) { case 1: value = true; break; case 0: value = false; break; default: throw new onednn.Error(`Unsupported attribute boolean value '${value}'.`); } break; case 's64': { type = 'int64'; const number = Number.parseInt(value, 10); value = Number.isNaN(value - number) ? value : number; break; } case 's64[]': type = 'int64[]'; if (value.length > 2 && value.toString().startsWith('[') && value.toString().endsWith(']')) { let array = []; const items = value.substring(1, value.length - 1).split(',') .map((item) => item.trim()) .map((item) => item.endsWith('L') ? item.substring(0, item.length - 1) : item); for (const item of items) { const value = Number.parseInt(item, 10); if (Number.isNaN(item - value)) { array = null; } else if (array !== null) { array.push(value); } } if (array !== null) { value = array; } } break; case 'f32': { type = 'float32'; const number = Number.parseFloat(value); value = Number.isNaN(value - number) ? value : number; break; } case 'f32[]': type = 'float32[]'; if (value.length > 2 && value.toString().startsWith('[') && value.toString().endsWith(']')) { let array = []; const items = value.substring(1, value.length - 1).split(',') .map((item) => item.trim()) .map((item) => item.endsWith('L') ? item.substring(0, item.length - 1) : item); for (const item of items) { const value = Number.parseFloat(item); if (Number.isNaN(item - value)) { array = null; } else if (array !== null) { array.push(value); } } if (array !== null) { value = array; } } break; case 'string': type = 'string'; break; default: { throw new onednn.Error(`Unsupported attribute array data type '${type}'.`); } } const attribute = new onednn.Argument(name, value, type); this.attributes.push(attribute); } } const inputs = node.inputs || []; for (let i = 0; i < inputs.length; i++) { let name = inputs.length === 1 ? 'input' : i.toString(); if (this.type && this.type.inputs && this.type.inputs.length > 0) { name = this.type.inputs[i].name; } const argument = new onednn.Argument(name, [value(inputs[i])]); this.inputs.push(argument); } const outputs = node.outputs || []; for (let i = 0; i < outputs.length; i++) { let name = outputs.length === 1 ? 'output' : i.toString(); if (this.type && this.type.outputs && this.type.outputs.length > 0) { name = this.type.outputs[i].name; } const argument = new onednn.Argument(name, [value(outputs[i])]); this.outputs.push(argument); } } }; onednn.Argument = class { constructor(name, value, type = null) { this.name = name; this.value = value; this.type = type; } }; onednn.Value = class { constructor(name, type = null, initializer = null) { if (typeof name !== 'string') { throw new onednn.Error(`Invalid value identifier '${JSON.stringify(name)}'.`); } this.name = name; this.type = type; this.initializer = initializer; } }; onednn.TensorType = class { constructor(dataType, shape) { switch (dataType) { case 'f8_e4m3': this.dataType = 'float8e4m3'; break; case 'f8_e5m2': this.dataType = 'float8e5m2'; break; case 'f16': this.dataType = 'float16'; break; case 'f32': this.dataType = 'float32'; break; case 's4': this.dataType = 'int4'; break; case 's8': this.dataType = 'int8'; break; case 's32': this.dataType = 'int32'; break; case 's64': this.dataType = 'int64'; break; case 'u4': this.dataType = 'uint4'; break; case 'u8': this.dataType = 'uint8'; break; case 'bf16': this.dataType = 'bfloat16'; break; case 'boolean': this.dataType = 'boolean'; break; case 'undef': this.dataType = '?'; break; default: throw new onednn.Error(`Unsupported tensor data type '${dataType}'.`); } this.shape = shape; } equals(obj) { return obj && this.dataType === obj.dataType && ((this.shape && this.shape.equals(obj.shape)) || (this.shape === null && obj.shape === null)); } toString() { return this.dataType + (this.shape ? this.shape.toString() : '[?]'); } }; onednn.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() { return this.dimensions ? (`[${this.dimensions.map((dimension) => dimension ? dimension.toString() : '?').join(',')}]`) : ''; } }; onednn.Tensor = class { constructor(type, property_type) { this.type = type; this.category = property_type; } equals(obj) { return obj && this.type.equals(obj.type) && this.category === obj.category; } }; onednn.Error = class extends Error { constructor(message) { super(message); this.name = 'Error loading oneDNN Graph model.'; } }; export const ModelFactory = onednn.ModelFactory;