Explorar el Código

Add ExecuTorch test files (#1175)

Lutz Roeder hace 1 año
padre
commit
7177bfd009

+ 1 - 0
package.js

@@ -538,6 +538,7 @@ const update = async () => {
         'bigdl',
         'caffe', 'circle', 'cntk', 'coreml',
         'dlc', 'dnn',
+        'executorch',
         'gguf',
         'kann', 'keras',
         'mnn', 'mslite', 'megengine',

+ 435 - 0
source/executorch-schema.js

@@ -0,0 +1,435 @@
+
+export const executorch_flatbuffer = {};
+
+executorch_flatbuffer.ScalarType = {
+    BYTE: 0,
+    CHAR: 1,
+    SHORT: 2,
+    INT: 3,
+    LONG: 4,
+    HALF: 5,
+    FLOAT: 6,
+    DOUBLE: 7,
+    BOOL: 11,
+    QINT8: 12,
+    QUINT8: 13,
+    QINT32: 14,
+    QUINT4X2: 16,
+    QUINT2X4: 17,
+    BITS16: 22,
+    FLOAT8E5M2: 23,
+    FLOAT8E4M3FN: 24,
+    FLOAT8E5M2FNUZ: 25,
+    FLOAT8E4M3FNUZ: 26,
+    UINT16: 27,
+    UINT32: 28,
+    UINT64: 29
+};
+
+executorch_flatbuffer.ContainerMetadata = class ContainerMetadata {
+
+    static decode(reader, position) {
+        const $ = new executorch_flatbuffer.ContainerMetadata();
+        $.encoded_inp_str = reader.string_(position, 4, null);
+        $.encoded_out_str = reader.string_(position, 6, null);
+        return $;
+    }
+};
+
+executorch_flatbuffer.Null = class Null {
+
+    static decode(/* reader, position */) {
+        const $ = new executorch_flatbuffer.Null();
+        return $;
+    }
+};
+
+executorch_flatbuffer.AllocationDetails = class AllocationDetails {
+
+    static decode(reader, position) {
+        const $ = new executorch_flatbuffer.AllocationDetails();
+        $.memory_id = reader.uint32_(position, 4, 0);
+        $.memory_offset_low = reader.uint32_(position, 6, 0);
+        $.memory_offset_high = reader.uint32_(position, 8, 0);
+        return $;
+    }
+};
+
+executorch_flatbuffer.TensorShapeDynamism = {
+    STATIC: 0,
+    DYNAMIC_BOUND: 1,
+    DYNAMIC_UNBOUND: 2
+};
+
+executorch_flatbuffer.TensorDataLocation = {
+    SEGMENT: 0,
+    EXTERNAL: 1
+};
+
+executorch_flatbuffer.ExtraTensorInfo = class ExtraTensorInfo {
+
+    static decode(reader, position) {
+        const $ = new executorch_flatbuffer.ExtraTensorInfo();
+        $.mutable_data_segments_idx = reader.uint64_(position, 4, 0n);
+        $.fully_qualified_name = reader.string_(position, 6, null);
+        $.location = reader.int8_(position, 8, 0);
+        return $;
+    }
+};
+
+executorch_flatbuffer.Tensor = class Tensor {
+
+    static decode(reader, position) {
+        const $ = new executorch_flatbuffer.Tensor();
+        $.scalar_type = reader.int8_(position, 4, 0);
+        $.storage_offset = reader.int32_(position, 6, 0);
+        $.sizes = reader.array(position, 8, Int32Array);
+        $.dim_order = reader.array(position, 10, Uint8Array);
+        $.requires_grad = reader.bool_(position, 12, false);
+        $.data_buffer_idx = reader.uint32_(position, 14, 0);
+        $.allocation_info = reader.table(position, 16, executorch_flatbuffer.AllocationDetails);
+        $.layout = reader.int8_(position, 18, 0);
+        $.shape_dynamism = reader.int8_(position, 20, 0);
+        $.extra_tensor_info = reader.table(position, 22, executorch_flatbuffer.ExtraTensorInfo);
+        return $;
+    }
+};
+
+executorch_flatbuffer.Int = class Int {
+
+    static decode(reader, position) {
+        const $ = new executorch_flatbuffer.Int();
+        $.int_val = reader.int64_(position, 4, 0n);
+        return $;
+    }
+};
+
+executorch_flatbuffer.Bool = class Bool {
+
+    static decode(reader, position) {
+        const $ = new executorch_flatbuffer.Bool();
+        $.bool_val = reader.bool_(position, 4, false);
+        return $;
+    }
+};
+
+executorch_flatbuffer.Double = class Double {
+
+    static decode(reader, position) {
+        const $ = new executorch_flatbuffer.Double();
+        $.double_val = reader.float64_(position, 4, 0);
+        return $;
+    }
+};
+
+executorch_flatbuffer.String = class String {
+
+    static decode(reader, position) {
+        const $ = new executorch_flatbuffer.String();
+        $.string_val = reader.string_(position, 4, null);
+        return $;
+    }
+};
+
+executorch_flatbuffer.IntList = class IntList {
+
+    static decode(reader, position) {
+        const $ = new executorch_flatbuffer.IntList();
+        $.items = reader.int64s_(position, 4);
+        return $;
+    }
+};
+
+executorch_flatbuffer.DoubleList = class DoubleList {
+
+    static decode(reader, position) {
+        const $ = new executorch_flatbuffer.DoubleList();
+        $.items = reader.array(position, 4, Float64Array);
+        return $;
+    }
+};
+
+executorch_flatbuffer.BoolList = class BoolList {
+
+    static decode(reader, position) {
+        const $ = new executorch_flatbuffer.BoolList();
+        $.items = reader.bools_(position, 4);
+        return $;
+    }
+};
+
+executorch_flatbuffer.TensorList = class TensorList {
+
+    static decode(reader, position) {
+        const $ = new executorch_flatbuffer.TensorList();
+        $.items = reader.array(position, 4, Int32Array);
+        return $;
+    }
+};
+
+executorch_flatbuffer.OptionalTensorList = class OptionalTensorList {
+
+    static decode(reader, position) {
+        const $ = new executorch_flatbuffer.OptionalTensorList();
+        $.items = reader.array(position, 4, Int32Array);
+        return $;
+    }
+};
+
+executorch_flatbuffer.KernelTypes = class {
+
+    static decode(reader, position, type) {
+        switch (type) {
+            case 1: return executorch_flatbuffer.Null.decode(reader, position);
+            case 2: return executorch_flatbuffer.Int.decode(reader, position);
+            case 3: return executorch_flatbuffer.Bool.decode(reader, position);
+            case 4: return executorch_flatbuffer.Double.decode(reader, position);
+            case 5: return executorch_flatbuffer.Tensor.decode(reader, position);
+            case 6: return executorch_flatbuffer.String.decode(reader, position);
+            case 7: return executorch_flatbuffer.IntList.decode(reader, position);
+            case 8: return executorch_flatbuffer.DoubleList.decode(reader, position);
+            case 9: return executorch_flatbuffer.BoolList.decode(reader, position);
+            case 10: return executorch_flatbuffer.TensorList.decode(reader, position);
+            case 11: return executorch_flatbuffer.OptionalTensorList.decode(reader, position);
+            default: return undefined;
+        }
+    }
+};
+
+executorch_flatbuffer.EValue = class EValue {
+
+    static decode(reader, position) {
+        const $ = new executorch_flatbuffer.EValue();
+        $.val = reader.union(position, 4, executorch_flatbuffer.KernelTypes);
+        return $;
+    }
+};
+
+executorch_flatbuffer.Operator = class Operator {
+
+    static decode(reader, position) {
+        const $ = new executorch_flatbuffer.Operator();
+        $.name = reader.string_(position, 4, null);
+        $.overload = reader.string_(position, 6, null);
+        return $;
+    }
+};
+
+executorch_flatbuffer.KernelCall = class KernelCall {
+
+    static decode(reader, position) {
+        const $ = new executorch_flatbuffer.KernelCall();
+        $.op_index = reader.int32_(position, 4, 0);
+        $.args = reader.array(position, 6, Int32Array);
+        return $;
+    }
+};
+
+executorch_flatbuffer.DelegateCall = class DelegateCall {
+
+    static decode(reader, position) {
+        const $ = new executorch_flatbuffer.DelegateCall();
+        $.delegate_index = reader.int32_(position, 4, 0);
+        $.args = reader.array(position, 6, Int32Array);
+        return $;
+    }
+};
+
+executorch_flatbuffer.MoveCall = class MoveCall {
+
+    static decode(reader, position) {
+        const $ = new executorch_flatbuffer.MoveCall();
+        $.move_from = reader.int32_(position, 4, 0);
+        $.move_to = reader.int32_(position, 6, 0);
+        return $;
+    }
+};
+
+executorch_flatbuffer.JumpFalseCall = class JumpFalseCall {
+
+    static decode(reader, position) {
+        const $ = new executorch_flatbuffer.JumpFalseCall();
+        $.cond_value_index = reader.int32_(position, 4, 0);
+        $.destination_instruction = reader.int32_(position, 6, 0);
+        return $;
+    }
+};
+
+executorch_flatbuffer.FreeCall = class FreeCall {
+
+    static decode(reader, position) {
+        const $ = new executorch_flatbuffer.FreeCall();
+        $.value_index = reader.int32_(position, 4, 0);
+        return $;
+    }
+};
+
+executorch_flatbuffer.InstructionArguments = class {
+
+    static decode(reader, position, type) {
+        switch (type) {
+            case 1: return executorch_flatbuffer.KernelCall.decode(reader, position);
+            case 2: return executorch_flatbuffer.DelegateCall.decode(reader, position);
+            case 3: return executorch_flatbuffer.MoveCall.decode(reader, position);
+            case 4: return executorch_flatbuffer.JumpFalseCall.decode(reader, position);
+            case 5: return executorch_flatbuffer.FreeCall.decode(reader, position);
+            default: return undefined;
+        }
+    }
+};
+
+executorch_flatbuffer.Instruction = class Instruction {
+
+    static decode(reader, position) {
+        const $ = new executorch_flatbuffer.Instruction();
+        $.instr_args = reader.union(position, 4, executorch_flatbuffer.InstructionArguments);
+        return $;
+    }
+};
+
+executorch_flatbuffer.Frame = class Frame {
+
+    static decode(reader, position) {
+        const $ = new executorch_flatbuffer.Frame();
+        $.filename = reader.string_(position, 4, null);
+        $.lineno = reader.int32_(position, 6, 0);
+        $.name = reader.string_(position, 8, null);
+        $.context = reader.string_(position, 10, null);
+        return $;
+    }
+};
+
+executorch_flatbuffer.FrameList = class FrameList {
+
+    static decode(reader, position) {
+        const $ = new executorch_flatbuffer.FrameList();
+        $.items = reader.tables(position, 4, executorch_flatbuffer.Frame);
+        return $;
+    }
+};
+
+executorch_flatbuffer.DataLocation = {
+    INLINE: 0,
+    SEGMENT: 1
+};
+
+executorch_flatbuffer.BackendDelegateDataReference = class BackendDelegateDataReference {
+
+    static decode(reader, position) {
+        const $ = new executorch_flatbuffer.BackendDelegateDataReference();
+        $.location = reader.int8_(position, 4, 0);
+        $.index = reader.uint32_(position, 6, 0);
+        return $;
+    }
+};
+
+executorch_flatbuffer.CompileSpec = class CompileSpec {
+
+    static decode(reader, position) {
+        const $ = new executorch_flatbuffer.CompileSpec();
+        $.key = reader.string_(position, 4, null);
+        $.value = reader.array(position, 6, Uint8Array);
+        return $;
+    }
+};
+
+executorch_flatbuffer.BackendDelegate = class BackendDelegate {
+
+    static decode(reader, position) {
+        const $ = new executorch_flatbuffer.BackendDelegate();
+        $.id = reader.string_(position, 4, null);
+        $.processed = reader.table(position, 6, executorch_flatbuffer.BackendDelegateDataReference);
+        $.compile_specs = reader.tables(position, 8, executorch_flatbuffer.CompileSpec);
+        return $;
+    }
+};
+
+executorch_flatbuffer.Chain = class Chain {
+
+    static decode(reader, position) {
+        const $ = new executorch_flatbuffer.Chain();
+        $.inputs = reader.array(position, 4, Int32Array);
+        $.outputs = reader.array(position, 6, Int32Array);
+        $.instructions = reader.tables(position, 8, executorch_flatbuffer.Instruction);
+        $.stacktrace = reader.tables(position, 10, executorch_flatbuffer.FrameList);
+        return $;
+    }
+};
+
+executorch_flatbuffer.ExecutionPlan = class ExecutionPlan {
+
+    static decode(reader, position) {
+        const $ = new executorch_flatbuffer.ExecutionPlan();
+        $.name = reader.string_(position, 4, null);
+        $.container_meta_type = reader.table(position, 6, executorch_flatbuffer.ContainerMetadata);
+        $.values = reader.tables(position, 8, executorch_flatbuffer.EValue);
+        $.inputs = reader.array(position, 10, Int32Array);
+        $.outputs = reader.array(position, 12, Int32Array);
+        $.chains = reader.tables(position, 14, executorch_flatbuffer.Chain);
+        $.operators = reader.tables(position, 16, executorch_flatbuffer.Operator);
+        $.delegates = reader.tables(position, 18, executorch_flatbuffer.BackendDelegate);
+        $.non_const_buffer_sizes = reader.int64s_(position, 20);
+        return $;
+    }
+};
+
+executorch_flatbuffer.Buffer = class Buffer {
+
+    static decode(reader, position) {
+        const $ = new executorch_flatbuffer.Buffer();
+        $.storage = reader.array(position, 4, Uint8Array);
+        return $;
+    }
+};
+
+executorch_flatbuffer.BackendDelegateInlineData = class BackendDelegateInlineData {
+
+    static decode(reader, position) {
+        const $ = new executorch_flatbuffer.BackendDelegateInlineData();
+        $.data = reader.array(position, 4, Uint8Array);
+        return $;
+    }
+};
+
+executorch_flatbuffer.DataSegment = class DataSegment {
+
+    static decode(reader, position) {
+        const $ = new executorch_flatbuffer.DataSegment();
+        $.offset = reader.uint64_(position, 4, 0n);
+        $.size = reader.uint64_(position, 6, 0n);
+        return $;
+    }
+};
+
+executorch_flatbuffer.SubsegmentOffsets = class SubsegmentOffsets {
+
+    static decode(reader, position) {
+        const $ = new executorch_flatbuffer.SubsegmentOffsets();
+        $.segment_index = reader.uint32_(position, 4, 0);
+        $.offsets = reader.uint64s_(position, 6);
+        return $;
+    }
+};
+
+executorch_flatbuffer.Program = class Program {
+
+    static identifier(reader) {
+        return reader.identifier === 'ET12';
+    }
+
+    static create(reader) {
+        return executorch_flatbuffer.Program.decode(reader, reader.root);
+    }
+
+    static decode(reader, position) {
+        const $ = new executorch_flatbuffer.Program();
+        $.version = reader.uint32_(position, 4, 0);
+        $.execution_plan = reader.tables(position, 6, executorch_flatbuffer.ExecutionPlan);
+        $.constant_buffer = reader.tables(position, 8, executorch_flatbuffer.Buffer);
+        $.backend_delegate_data = reader.tables(position, 10, executorch_flatbuffer.BackendDelegateInlineData);
+        $.segments = reader.tables(position, 12, executorch_flatbuffer.DataSegment);
+        $.constant_segment = reader.table(position, 14, executorch_flatbuffer.SubsegmentOffsets);
+        $.mutable_data_segments = reader.tables(position, 16, executorch_flatbuffer.SubsegmentOffsets);
+        return $;
+    }
+};

+ 234 - 0
source/executorch.js

@@ -0,0 +1,234 @@
+
+// Experimental
+
+const executorch = {};
+
+import * as python from './python.js';
+import * as pytorch from './pytorch.js';
+
+executorch.ModelFactory = class {
+
+    match(context) {
+        const reader = context.peek('flatbuffers.binary');
+        if (reader && reader.identifier === 'ET12') {
+            context.type = 'executorch';
+            context.target = reader;
+        }
+    }
+
+    async open(context) {
+        executorch.schema = await context.require('./executorch-schema');
+        executorch.schema = executorch.schema.executorch_flatbuffer;
+        const metadata = await pytorch.Metadata.open(context);
+        const execution = new python.Execution();
+        metadata.register(execution);
+        const reader = context.target;
+        const program = executorch.schema.Program.create(reader);
+        return new executorch.Model(execution, program);
+    }
+};
+
+executorch.Model = class {
+
+    constructor(execution, program) {
+        this.format = `ExecuTorch v${program.version}`;
+        this.graphs = [];
+        for (const plan of program.execution_plan) {
+            for (const chain of plan.chains) {
+                const graph = new executorch.Graph(execution, chain, plan);
+                this.graphs.push(graph);
+            }
+        }
+    }
+};
+
+executorch.Graph = class {
+
+    constructor(execution, chain, plan) {
+        this.inputs = [];
+        this.outputs = [];
+        this.nodes = [];
+        const values = new Map();
+        values.map = (arg) => {
+            if (!values.has(arg)) {
+                const v = plan.values[arg].val;
+                if (v instanceof executorch.schema.Tensor || v instanceof executorch.schema.TensorList) {
+                    const tensors = v instanceof executorch.schema.Tensor ? [v] : Array.from(v.items).map((arg) => plan.values[arg].val);
+                    const list = [];
+                    for (let i = 0; i < tensors.length; i++) {
+                        const tensor = tensors[i];
+                        const type = new executorch.TensorType(tensor);
+                        let initializer = null;
+                        if (v.data_buffer_idx > 0) {
+                            initializer = new executorch.Tensor(tensor);
+                        }
+                        const identifier = tensors.length > 1 ? `${arg}.${i}` : arg.toString();
+                        list.push(new executorch.Value(identifier, type, initializer));
+                    }
+                    values.set(arg, { type: null, value: list });
+                } else if (v instanceof executorch.schema.Bool) {
+                    values.set(arg, { type: 'int64', value: v.bool_val });
+                } else if (v instanceof executorch.schema.Int) {
+                    values.set(arg, { type: 'int64', value: v.int_val });
+                } else if (v instanceof executorch.schema.IntList) {
+                    const list = v.items.map((index) => plan.values[index].val.int_val);
+                    values.set(arg, { type: 'int64[]', value: list });
+                } else if (v instanceof executorch.schema.Double) {
+                    values.set(arg, { type: 'float64', value: v.double_val });
+                } else if (v instanceof executorch.schema.Null) {
+                    values.set(arg, { type: 'attribute', value: null });
+                } else {
+                    throw new Error('Value type not implemented.');
+                }
+            }
+            return values.get(arg);
+        };
+        for (const input of plan.inputs) {
+            const value = values.map(input);
+            const argument = new executorch.Argument(input.toString(), value.value, value.type);
+            this.inputs.push(argument);
+        }
+        for (const output of plan.outputs) {
+            const value = values.map(output);
+            const argument = new executorch.Argument(output.toString(), value.value, value.type);
+            this.outputs.push(argument);
+        }
+        for (const instruction of chain.instructions) {
+            const node = new executorch.Node(execution, instruction, plan, values);
+            this.nodes.push(node);
+        }
+    }
+};
+
+executorch.Argument = class {
+
+    constructor(name, value, type, visible) {
+        this.name = name;
+        this.value = value;
+        this.type = type || null;
+        this.visible = visible !== false;
+    }
+};
+
+executorch.Value = class Value {
+
+    constructor(name, type, initializer) {
+        if (typeof name !== 'string') {
+            throw new executorch.Error(`Invalid value identifier '${JSON.stringify(name)}'.`);
+        }
+        this.name = name;
+        this.type = initializer && initializer.type ? initializer.type : type || null;
+        this.initializer = initializer || null;
+    }
+};
+
+executorch.Node = class {
+
+    constructor(execution, instruction, plan, values) {
+        this.name = '';
+        this.inputs = [];
+        this.outputs = [];
+        const instr_args = instruction.instr_args;
+        if (instr_args instanceof executorch.schema.KernelCall) {
+            const op = plan.operators[instr_args.op_index];
+            const name = op.name.split('::').pop();
+            const identifier = op.overload ? `${op.name}.${op.overload}` : op.name;
+            const schemas = execution.invoke('torch._C._jit_get_schemas_for_operator', [op.name]);
+            const schema = schemas.find((schema) => schema.name === op.name && schema.overload_name === op.overload);
+            const category = schema && schema.category ? schema.category : '';
+            const alias = (arg) => arg && arg.alias_info && arg.alias_info.before_set.length === 1 ? arg.alias_info.before_set[0] : null;
+            const outputs = new Set(schema && Array.isArray(schema.returns) ? schema.returns.map((arg) => alias(arg)).filter((alias) => alias !== null) : []);
+            const inputs = new Map();
+            this.type = { name, identifier, category };
+            let i = 0;
+            const args = instr_args.args;
+            for (; i < schema.arguments.length; i++) {
+                const v = args[i];
+                const arg = schema && i < schema.arguments.length ? schema.arguments[i] : null;
+                const output = arg ? alias(schema.arguments[i]) : null;
+                if (output && outputs.has(output)) {
+                    inputs.set(output, v);
+                    continue;
+                }
+                const name = arg ? arg.name : i.toString();
+                const value = values.map(v);
+                const argument = new executorch.Argument(name, value.value, value.type);
+                this.inputs.push(argument);
+            }
+            for (let j = 0; j < schema.returns.length; j++) {
+                const ret = schema.returns[j];
+                const output = alias(ret);
+                const v = output && inputs.has(output) ? inputs.get(output) : args[i++];
+                const name = ret.name;
+                const value = values.map(v);
+                const argument = new executorch.Argument(name || '', value.value, value.type);
+                this.outputs.push(argument);
+            }
+        } else if (instr_args instanceof executorch.schema.DelegateCall) {
+            const delegate = plan.delegates[instr_args.delegate_index];
+            const name = delegate.id;
+            this.type = { name };
+        } else {
+            throw new Error('Instruction argument not implemented.');
+        }
+    }
+};
+
+executorch.TensorType = class {
+
+    constructor(tensor) {
+        const ScalarType = executorch.schema.ScalarType;
+        switch (tensor.scalar_type) {
+
+            case ScalarType.BOOL: this.dataType = 'boolean'; break;
+            case ScalarType.BYTE: this.dataType = 'uint8'; break;
+            case ScalarType.CHAR: this.dataType = 'int8'; break;
+            case ScalarType.SHORT: this.dataType = 'int16'; break;
+            case ScalarType.INT: this.dataType = 'int32'; break;
+            case ScalarType.LONG: this.dataType = 'int64'; break;
+            case ScalarType.HALF: this.dataType = 'float16'; break;
+            case ScalarType.FLOAT: this.dataType = 'float32'; break;
+            case ScalarType.DOUBLE: this.dataType = 'float64'; break;
+            case ScalarType.UINT16: this.dataType = 'uint16'; break;
+            case ScalarType.UINT32: this.dataType = 'uint32'; break;
+            case ScalarType.UINT64: this.dataType = 'uint64'; break;
+            default: throw new executorch.Error(`Unknown tensor data type '${tensor.scalar_type}'.`);
+        }
+        this.shape = new executorch.TensorShape(Array.from(tensor.sizes));
+    }
+
+    toString() {
+        return this.dataType + this.shape.toString();
+    }
+};
+
+executorch.TensorShape = class {
+
+    constructor(dimensions) {
+        this.dimensions = dimensions || [];
+    }
+
+    toString() {
+        if (this.dimensions && this.dimensions.length > 0) {
+            return `[${this.dimensions.map((dimension) => dimension.toString()).join(',')}]`;
+        }
+        return '';
+    }
+};
+
+executorch.Tensor = class {
+
+    constructor(tensor) {
+        this.type = new executorch.TensorType(tensor);
+    }
+};
+
+executorch.Error = class extends Error {
+
+    constructor(message) {
+        super(message);
+        this.name = 'Error loading ExecuTorch model.';
+    }
+};
+
+export const ModelFactory = executorch.ModelFactory;

+ 9 - 0
source/pytorch-metadata.json

@@ -1196,6 +1196,12 @@
   {
     "name": "aten::select_copy.int_out(Tensor self, int dim, SymInt index, *, Tensor(a!) out) -> Tensor(a!)"
   },
+  {
+    "name": "aten::permute_copy(Tensor self, int[] dims) -> Tensor"
+  },
+  {
+    "name": "aten::permute_copy.out(Tensor self, int[] dims, *, Tensor(a!) out) -> Tensor(a!)"
+  },
   {
     "name": "aten::view_as_complex_copy(Tensor self) -> Tensor"
   },
@@ -7343,6 +7349,9 @@
   {
     "name": "torch_sparse::non_diag_mask(Tensor _0, Tensor _1, int _2, int _3, int _4) -> Tensor _0"
   },
+  {
+    "name": "executorch_prim::et_view.default(Tensor self, int[] size) -> (Tensor out)"
+  },
   {
     "name": "__torch__.torch.classes.rnn.CellParamsBase",
     "inputs": [

+ 0 - 435
source/pytorch-schema.js

@@ -1,8 +1,6 @@
 
 export const torch = {};
 
-export const executorch_flatbuffer = {};
-
 torch.jit = torch.jit || {};
 
 torch.jit.mobile = torch.jit.mobile || {};
@@ -350,436 +348,3 @@ torch.jit.mobile.serialization.Module = class Module {
         return $;
     }
 };
-
-executorch_flatbuffer.ScalarType = {
-    BYTE: 0,
-    CHAR: 1,
-    SHORT: 2,
-    INT: 3,
-    LONG: 4,
-    HALF: 5,
-    FLOAT: 6,
-    DOUBLE: 7,
-    BOOL: 11,
-    QINT8: 12,
-    QUINT8: 13,
-    QINT32: 14,
-    QUINT4X2: 16,
-    QUINT2X4: 17,
-    BITS16: 22,
-    FLOAT8E5M2: 23,
-    FLOAT8E4M3FN: 24,
-    FLOAT8E5M2FNUZ: 25,
-    FLOAT8E4M3FNUZ: 26,
-    UINT16: 27,
-    UINT32: 28,
-    UINT64: 29
-};
-
-executorch_flatbuffer.ContainerMetadata = class ContainerMetadata {
-
-    static decode(reader, position) {
-        const $ = new executorch_flatbuffer.ContainerMetadata();
-        $.encoded_inp_str = reader.string_(position, 4, null);
-        $.encoded_out_str = reader.string_(position, 6, null);
-        return $;
-    }
-};
-
-executorch_flatbuffer.Null = class Null {
-
-    static decode(/* reader, position */) {
-        const $ = new executorch_flatbuffer.Null();
-        return $;
-    }
-};
-
-executorch_flatbuffer.AllocationDetails = class AllocationDetails {
-
-    static decode(reader, position) {
-        const $ = new executorch_flatbuffer.AllocationDetails();
-        $.memory_id = reader.uint32_(position, 4, 0);
-        $.memory_offset_low = reader.uint32_(position, 6, 0);
-        $.memory_offset_high = reader.uint32_(position, 8, 0);
-        return $;
-    }
-};
-
-executorch_flatbuffer.TensorShapeDynamism = {
-    STATIC: 0,
-    DYNAMIC_BOUND: 1,
-    DYNAMIC_UNBOUND: 2
-};
-
-executorch_flatbuffer.TensorDataLocation = {
-    SEGMENT: 0,
-    EXTERNAL: 1
-};
-
-executorch_flatbuffer.ExtraTensorInfo = class ExtraTensorInfo {
-
-    static decode(reader, position) {
-        const $ = new executorch_flatbuffer.ExtraTensorInfo();
-        $.mutable_data_segments_idx = reader.uint64_(position, 4, 0n);
-        $.fully_qualified_name = reader.string_(position, 6, null);
-        $.location = reader.int8_(position, 8, 0);
-        return $;
-    }
-};
-
-executorch_flatbuffer.Tensor = class Tensor {
-
-    static decode(reader, position) {
-        const $ = new executorch_flatbuffer.Tensor();
-        $.scalar_type = reader.int8_(position, 4, 0);
-        $.storage_offset = reader.int32_(position, 6, 0);
-        $.sizes = reader.array(position, 8, Int32Array);
-        $.dim_order = reader.array(position, 10, Uint8Array);
-        $.requires_grad = reader.bool_(position, 12, false);
-        $.data_buffer_idx = reader.uint32_(position, 14, 0);
-        $.allocation_info = reader.table(position, 16, executorch_flatbuffer.AllocationDetails);
-        $.layout = reader.int8_(position, 18, 0);
-        $.shape_dynamism = reader.int8_(position, 20, 0);
-        $.extra_tensor_info = reader.table(position, 22, executorch_flatbuffer.ExtraTensorInfo);
-        return $;
-    }
-};
-
-executorch_flatbuffer.Int = class Int {
-
-    static decode(reader, position) {
-        const $ = new executorch_flatbuffer.Int();
-        $.int_val = reader.int64_(position, 4, 0n);
-        return $;
-    }
-};
-
-executorch_flatbuffer.Bool = class Bool {
-
-    static decode(reader, position) {
-        const $ = new executorch_flatbuffer.Bool();
-        $.bool_val = reader.bool_(position, 4, false);
-        return $;
-    }
-};
-
-executorch_flatbuffer.Double = class Double {
-
-    static decode(reader, position) {
-        const $ = new executorch_flatbuffer.Double();
-        $.double_val = reader.float64_(position, 4, 0);
-        return $;
-    }
-};
-
-executorch_flatbuffer.String = class String {
-
-    static decode(reader, position) {
-        const $ = new executorch_flatbuffer.String();
-        $.string_val = reader.string_(position, 4, null);
-        return $;
-    }
-};
-
-executorch_flatbuffer.IntList = class IntList {
-
-    static decode(reader, position) {
-        const $ = new executorch_flatbuffer.IntList();
-        $.items = reader.int64s_(position, 4);
-        return $;
-    }
-};
-
-executorch_flatbuffer.DoubleList = class DoubleList {
-
-    static decode(reader, position) {
-        const $ = new executorch_flatbuffer.DoubleList();
-        $.items = reader.array(position, 4, Float64Array);
-        return $;
-    }
-};
-
-executorch_flatbuffer.BoolList = class BoolList {
-
-    static decode(reader, position) {
-        const $ = new executorch_flatbuffer.BoolList();
-        $.items = reader.bools_(position, 4);
-        return $;
-    }
-};
-
-executorch_flatbuffer.TensorList = class TensorList {
-
-    static decode(reader, position) {
-        const $ = new executorch_flatbuffer.TensorList();
-        $.items = reader.array(position, 4, Int32Array);
-        return $;
-    }
-};
-
-executorch_flatbuffer.OptionalTensorList = class OptionalTensorList {
-
-    static decode(reader, position) {
-        const $ = new executorch_flatbuffer.OptionalTensorList();
-        $.items = reader.array(position, 4, Int32Array);
-        return $;
-    }
-};
-
-executorch_flatbuffer.KernelTypes = class {
-
-    static decode(reader, position, type) {
-        switch (type) {
-            case 1: return executorch_flatbuffer.Null.decode(reader, position);
-            case 2: return executorch_flatbuffer.Int.decode(reader, position);
-            case 3: return executorch_flatbuffer.Bool.decode(reader, position);
-            case 4: return executorch_flatbuffer.Double.decode(reader, position);
-            case 5: return executorch_flatbuffer.Tensor.decode(reader, position);
-            case 6: return executorch_flatbuffer.String.decode(reader, position);
-            case 7: return executorch_flatbuffer.IntList.decode(reader, position);
-            case 8: return executorch_flatbuffer.DoubleList.decode(reader, position);
-            case 9: return executorch_flatbuffer.BoolList.decode(reader, position);
-            case 10: return executorch_flatbuffer.TensorList.decode(reader, position);
-            case 11: return executorch_flatbuffer.OptionalTensorList.decode(reader, position);
-            default: return undefined;
-        }
-    }
-};
-
-executorch_flatbuffer.EValue = class EValue {
-
-    static decode(reader, position) {
-        const $ = new executorch_flatbuffer.EValue();
-        $.val = reader.union(position, 4, executorch_flatbuffer.KernelTypes);
-        return $;
-    }
-};
-
-executorch_flatbuffer.Operator = class Operator {
-
-    static decode(reader, position) {
-        const $ = new executorch_flatbuffer.Operator();
-        $.name = reader.string_(position, 4, null);
-        $.overload = reader.string_(position, 6, null);
-        return $;
-    }
-};
-
-executorch_flatbuffer.KernelCall = class KernelCall {
-
-    static decode(reader, position) {
-        const $ = new executorch_flatbuffer.KernelCall();
-        $.op_index = reader.int32_(position, 4, 0);
-        $.args = reader.array(position, 6, Int32Array);
-        return $;
-    }
-};
-
-executorch_flatbuffer.DelegateCall = class DelegateCall {
-
-    static decode(reader, position) {
-        const $ = new executorch_flatbuffer.DelegateCall();
-        $.delegate_index = reader.int32_(position, 4, 0);
-        $.args = reader.array(position, 6, Int32Array);
-        return $;
-    }
-};
-
-executorch_flatbuffer.MoveCall = class MoveCall {
-
-    static decode(reader, position) {
-        const $ = new executorch_flatbuffer.MoveCall();
-        $.move_from = reader.int32_(position, 4, 0);
-        $.move_to = reader.int32_(position, 6, 0);
-        return $;
-    }
-};
-
-executorch_flatbuffer.JumpFalseCall = class JumpFalseCall {
-
-    static decode(reader, position) {
-        const $ = new executorch_flatbuffer.JumpFalseCall();
-        $.cond_value_index = reader.int32_(position, 4, 0);
-        $.destination_instruction = reader.int32_(position, 6, 0);
-        return $;
-    }
-};
-
-executorch_flatbuffer.FreeCall = class FreeCall {
-
-    static decode(reader, position) {
-        const $ = new executorch_flatbuffer.FreeCall();
-        $.value_index = reader.int32_(position, 4, 0);
-        return $;
-    }
-};
-
-executorch_flatbuffer.InstructionArguments = class {
-
-    static decode(reader, position, type) {
-        switch (type) {
-            case 1: return executorch_flatbuffer.KernelCall.decode(reader, position);
-            case 2: return executorch_flatbuffer.DelegateCall.decode(reader, position);
-            case 3: return executorch_flatbuffer.MoveCall.decode(reader, position);
-            case 4: return executorch_flatbuffer.JumpFalseCall.decode(reader, position);
-            case 5: return executorch_flatbuffer.FreeCall.decode(reader, position);
-            default: return undefined;
-        }
-    }
-};
-
-executorch_flatbuffer.Instruction = class Instruction {
-
-    static decode(reader, position) {
-        const $ = new executorch_flatbuffer.Instruction();
-        $.instr_args = reader.union(position, 4, executorch_flatbuffer.InstructionArguments);
-        return $;
-    }
-};
-
-executorch_flatbuffer.Frame = class Frame {
-
-    static decode(reader, position) {
-        const $ = new executorch_flatbuffer.Frame();
-        $.filename = reader.string_(position, 4, null);
-        $.lineno = reader.int32_(position, 6, 0);
-        $.name = reader.string_(position, 8, null);
-        $.context = reader.string_(position, 10, null);
-        return $;
-    }
-};
-
-executorch_flatbuffer.FrameList = class FrameList {
-
-    static decode(reader, position) {
-        const $ = new executorch_flatbuffer.FrameList();
-        $.items = reader.tables(position, 4, executorch_flatbuffer.Frame);
-        return $;
-    }
-};
-
-executorch_flatbuffer.DataLocation = {
-    INLINE: 0,
-    SEGMENT: 1
-};
-
-executorch_flatbuffer.BackendDelegateDataReference = class BackendDelegateDataReference {
-
-    static decode(reader, position) {
-        const $ = new executorch_flatbuffer.BackendDelegateDataReference();
-        $.location = reader.int8_(position, 4, 0);
-        $.index = reader.uint32_(position, 6, 0);
-        return $;
-    }
-};
-
-executorch_flatbuffer.CompileSpec = class CompileSpec {
-
-    static decode(reader, position) {
-        const $ = new executorch_flatbuffer.CompileSpec();
-        $.key = reader.string_(position, 4, null);
-        $.value = reader.array(position, 6, Uint8Array);
-        return $;
-    }
-};
-
-executorch_flatbuffer.BackendDelegate = class BackendDelegate {
-
-    static decode(reader, position) {
-        const $ = new executorch_flatbuffer.BackendDelegate();
-        $.id = reader.string_(position, 4, null);
-        $.processed = reader.table(position, 6, executorch_flatbuffer.BackendDelegateDataReference);
-        $.compile_specs = reader.tables(position, 8, executorch_flatbuffer.CompileSpec);
-        return $;
-    }
-};
-
-executorch_flatbuffer.Chain = class Chain {
-
-    static decode(reader, position) {
-        const $ = new executorch_flatbuffer.Chain();
-        $.inputs = reader.array(position, 4, Int32Array);
-        $.outputs = reader.array(position, 6, Int32Array);
-        $.instructions = reader.tables(position, 8, executorch_flatbuffer.Instruction);
-        $.stacktrace = reader.tables(position, 10, executorch_flatbuffer.FrameList);
-        return $;
-    }
-};
-
-executorch_flatbuffer.ExecutionPlan = class ExecutionPlan {
-
-    static decode(reader, position) {
-        const $ = new executorch_flatbuffer.ExecutionPlan();
-        $.name = reader.string_(position, 4, null);
-        $.container_meta_type = reader.table(position, 6, executorch_flatbuffer.ContainerMetadata);
-        $.values = reader.tables(position, 8, executorch_flatbuffer.EValue);
-        $.inputs = reader.array(position, 10, Int32Array);
-        $.outputs = reader.array(position, 12, Int32Array);
-        $.chains = reader.tables(position, 14, executorch_flatbuffer.Chain);
-        $.operators = reader.tables(position, 16, executorch_flatbuffer.Operator);
-        $.delegates = reader.tables(position, 18, executorch_flatbuffer.BackendDelegate);
-        $.non_const_buffer_sizes = reader.int64s_(position, 20);
-        return $;
-    }
-};
-
-executorch_flatbuffer.Buffer = class Buffer {
-
-    static decode(reader, position) {
-        const $ = new executorch_flatbuffer.Buffer();
-        $.storage = reader.array(position, 4, Uint8Array);
-        return $;
-    }
-};
-
-executorch_flatbuffer.BackendDelegateInlineData = class BackendDelegateInlineData {
-
-    static decode(reader, position) {
-        const $ = new executorch_flatbuffer.BackendDelegateInlineData();
-        $.data = reader.array(position, 4, Uint8Array);
-        return $;
-    }
-};
-
-executorch_flatbuffer.DataSegment = class DataSegment {
-
-    static decode(reader, position) {
-        const $ = new executorch_flatbuffer.DataSegment();
-        $.offset = reader.uint64_(position, 4, 0n);
-        $.size = reader.uint64_(position, 6, 0n);
-        return $;
-    }
-};
-
-executorch_flatbuffer.SubsegmentOffsets = class SubsegmentOffsets {
-
-    static decode(reader, position) {
-        const $ = new executorch_flatbuffer.SubsegmentOffsets();
-        $.segment_index = reader.uint32_(position, 4, 0);
-        $.offsets = reader.uint64s_(position, 6);
-        return $;
-    }
-};
-
-executorch_flatbuffer.Program = class Program {
-
-    static identifier(reader) {
-        return reader.identifier === 'ET12';
-    }
-
-    static create(reader) {
-        return executorch_flatbuffer.Program.decode(reader, reader.root);
-    }
-
-    static decode(reader, position) {
-        const $ = new executorch_flatbuffer.Program();
-        $.version = reader.uint32_(position, 4, 0);
-        $.execution_plan = reader.tables(position, 6, executorch_flatbuffer.ExecutionPlan);
-        $.constant_buffer = reader.tables(position, 8, executorch_flatbuffer.Buffer);
-        $.backend_delegate_data = reader.tables(position, 10, executorch_flatbuffer.BackendDelegateInlineData);
-        $.segments = reader.tables(position, 12, executorch_flatbuffer.DataSegment);
-        $.constant_segment = reader.table(position, 14, executorch_flatbuffer.SubsegmentOffsets);
-        $.mutable_data_segments = reader.tables(position, 16, executorch_flatbuffer.SubsegmentOffsets);
-        return $;
-    }
-};

+ 1 - 28
source/pytorch.js

@@ -966,8 +966,7 @@ pytorch.Container = class {
             pytorch.Container.ModelJson,
             pytorch.Container.IR,
             pytorch.Container.Index,
-            pytorch.Container.ExportedProgram,
-            pytorch.Container.ExecuTorch,
+            pytorch.Container.ExportedProgram
         ];
         for (const type of types) {
             const container = type.open(context);
@@ -1183,31 +1182,6 @@ pytorch.Container.Mobile = class extends pytorch.Container {
     }
 };
 
-pytorch.Container.ExecuTorch = class extends pytorch.Container {
-
-    static open(context) {
-        const reader = context.peek('flatbuffers.binary');
-        if (reader && reader.identifier === 'ET12') {
-            return new pytorch.Container.ExecuTorch(context);
-        }
-        return null;
-    }
-
-    constructor(context) {
-        super();
-        this.type = 'pytorch.executorch';
-        this.context = context;
-    }
-
-    async read() {
-        pytorch.executorch = await this.context.require('./pytorch-schema');
-        pytorch.executorch = pytorch.executorch.executorch_flatbuffer;
-        const reader = this.context.read('flatbuffers.binary');
-        /* const program = */ pytorch.executorch.Program.create(reader);
-        throw new pytorch.Error('Invalid file content. File contains executorch.Program data.');
-    }
-};
-
 pytorch.Container.Zip = class extends pytorch.Container {
 
     static open(context) {
@@ -1631,7 +1605,6 @@ pytorch.Execution = class extends python.Execution {
                 [this.weight, this.bias, this.stride, this.padding, this.output_padding, this.dilation, this.groups, this.output_min, this.output_max] = state;
             }
         });
-        this._metadata = metadata;
     }
 
     call(target, name, args, keywords, context) {

+ 2 - 1
source/view.js

@@ -5764,7 +5764,7 @@ view.ModelFactoryService = class {
         this._factories = [];
         /* eslint-disable no-control-regex */
         this.register('./message', ['.message', '.netron', '.maxviz']);
-        this.register('./pytorch', ['.pt', '.pth', '.ptl', '.pt1', '.pyt', '.pyth', '.pkl', '.pickle', '.h5', '.t7', '.model', '.dms', '.tar', '.ckpt', '.chkpt', '.tckpt', '.bin', '.pb', '.zip', '.nn', '.torchmodel', '.torchscript', '.pytorch', '.ot', '.params', '.trt', '.ff', '.ptmf', '.jit', '.pte', '.bin.index.json', 'model.json', '.ir', 'serialized_exported_program.json', 'serialized_state_dict.json'], ['.model', '.pt2']);
+        this.register('./pytorch', ['.pt', '.pth', '.ptl', '.pt1', '.pyt', '.pyth', '.pkl', '.pickle', '.h5', '.t7', '.model', '.dms', '.tar', '.ckpt', '.chkpt', '.tckpt', '.bin', '.pb', '.zip', '.nn', '.torchmodel', '.torchscript', '.pytorch', '.ot', '.params', '.trt', '.ff', '.ptmf', '.jit', '.bin.index.json', 'model.json', '.ir', 'serialized_exported_program.json', 'serialized_state_dict.json'], ['.model', '.pt2']);
         this.register('./onnx', ['.onnx', '.onnx.data', '.onn', '.pb', '.onnxtxt', '.pbtxt', '.prototxt', '.txt', '.model', '.pt', '.pth', '.pkl', '.ort', '.ort.onnx', '.ngf', '.json', '.bin', 'onnxmodel'], [], [/^....ORTM/]);
         this.register('./tflite', ['.tflite', '.lite', '.tfl', '.bin', '.pb', '.tmfile', '.h5', '.model', '.json', '.txt', '.dat', '.nb', '.ckpt', '.onnx'], [], [/^....TFL3/]);
         this.register('./mxnet', ['.json', '.params'], ['.mar']);
@@ -5787,6 +5787,7 @@ view.ModelFactoryService = class {
         this.register('./bigdl', ['.model', '.bigdl']);
         this.register('./darknet', ['.cfg', '.model', '.txt', '.weights']);
         this.register('./mediapipe', ['.pbtxt']);
+        this.register('./executorch', ['.pte']);
         this.register('./rknn', ['.rknn', '.nb', '.onnx', '.json', '.bin', /^model$/]);
         this.register('./dlc', ['.dlc', /^model$/, '.params']);
         this.register('./armnn', ['.armnn', '.json']);

+ 22 - 8
test/models.json

@@ -5299,7 +5299,7 @@
     "type":     "pytorch",
     "target":   "add.pte",
     "source":   "https://github.com/lutzroeder/netron/files/13156981/add.pte.zip[add.pte]",
-    "error":    "Invalid file content. File contains executorch.Program data.",
+    "format":   "ExecuTorch v0",
     "link":     "https://github.com/lutzroeder/netron/issues/1175"
   },
   
@@ -5920,6 +5920,13 @@
     "format":   "PyTorch Export v5.3",
     "link":     "https://github.com/lutzroeder/netron/issues/1211"
   },
+  {
+    "type":     "pytorch",
+    "target":   "mobilenet_v2.pte",
+    "source":   "https://github.com/user-attachments/files/18462557/mobilenet_v2.pte.zip[mobilenet_v2.pte]",
+    "format":   "ExecuTorch v0",
+    "link":     "https://github.com/lutzroeder/netron/issues/1211"
+  },
   {
     "type":     "pytorch",
     "target":   "mobilenet_v2_traced.pt",
@@ -6025,6 +6032,13 @@
     "source":   "https://github.com/lutzroeder/netron/files/9075631/module_000007.pt.zip[module_000007.pt]",
     "link":     "https://github.com/lutzroeder/netron/issues/842"
   },
+  {
+    "type":     "pytorch",
+    "target":   "model_scripted.pt",
+    "source":   "https://github.com/user-attachments/files/16401554/model_scripted.pt.zip[model_scripted.pt]",
+    "format":   "PyTorch v1.6",
+    "link":     "https://github.com/lutzroeder/netron/issues/543"
+  },
   {
     "type":     "pytorch",
     "target":   "mtcnn.pt",
@@ -6033,13 +6047,6 @@
     "assert":   "model.graphs[0].nodes[0].inputs.length == 3",
     "link":     "https://github.com/deepware/dface/tree/master/dface"
   },
-  {
-    "type":     "pytorch",
-    "target":   "model_scripted.pt",
-    "source":   "https://github.com/user-attachments/files/16401554/model_scripted.pt.zip[model_scripted.pt]",
-    "format":   "PyTorch v1.6",
-    "link":     "https://github.com/lutzroeder/netron/issues/543"
-  },
   {
     "type":     "pytorch",
     "target":   "muzero_models.pb",
@@ -6054,6 +6061,13 @@
     "format":   "PyTorch Package v1.9",
     "link":     "https://github.com/lutzroeder/netron/issues/928"
   },
+  {
+    "type":     "pytorch",
+    "target":   "mv2_xnnpack.pte",
+    "source":   "https://github.com/user-attachments/files/18462560/mv2_xnnpack.pte.zip[mv2_xnnpack.pte]",
+    "format":   "ExecuTorch v0",
+    "link":     "https://github.com/lutzroeder/netron/issues/1175"
+  },
   {
     "type":     "pytorch",
     "target":   "netron_issue_313_v1.pt",

+ 39 - 0
tools/executorch

@@ -0,0 +1,39 @@
+#!/bin/bash
+
+set -e
+pushd $(cd $(dirname ${0})/..; pwd) > /dev/null
+
+case "${OSTYPE}" in
+    msys*) python="winpty python";;
+    *) python="python";;
+esac
+
+clean() {
+    echo "executorch clean"
+    rm -rf "./third_party/source/executorch"
+}
+
+sync() {
+    echo "executorch sync"
+    mkdir -p "./third_party/source/executorch/schema"
+    curl --silent --location --output "./third_party/source/executorch/schema/scalar_type.fbs" "https://github.com/pytorch/executorch/raw/main/schema/scalar_type.fbs"
+    curl --silent --location --output "./third_party/source/executorch/schema/program.fbs" "https://github.com/pytorch/executorch/raw/main/schema/program.fbs"
+}
+
+schema() {
+    echo "executorch schema"
+    [[ $(grep -U $'\x0D' ./source/executorch-schema.js) ]] && crlf=1
+    node ./tools/flatc.js --root torch --out ./source/executorch-schema.js ./third_party/source/executorch/schema/program.fbs
+    if [[ -n ${crlf} ]]; then
+        unix2dos --quiet --newfile ./source/executorch-schema.js ./source/executorch-schema.js
+    fi
+}
+
+while [ "$#" != 0 ]; do
+    command="$1" && shift
+    case "${command}" in
+        "clean") clean;;
+        "sync") sync;;
+        "schema") schema;;
+    esac
+done

+ 6 - 2
tools/pytorch

@@ -60,11 +60,15 @@ schema() {
         unix2dos --quiet --newfile ./source/pytorch-proto.js ./source/pytorch-proto.js
     fi
     [[ $(grep -U $'\x0D' ./source/pytorch-schema.js) ]] && crlf=1
-    node ./tools/flatc.js --root torch --out ./source/pytorch-schema.js ./third_party/source/pytorch/torch/csrc/jit/serialization/mobile_bytecode.fbs ./third_party/source/executorch/schema/program.fbs
+    node ./tools/flatc.js --root torch --out ./source/pytorch-schema.js ./third_party/source/pytorch/torch/csrc/jit/serialization/mobile_bytecode.fbs
     if [[ -n ${crlf} ]]; then
         unix2dos --quiet --newfile ./source/pytorch-schema.js ./source/pytorch-schema.js
     fi
-
+    [[ $(grep -U $'\x0D' ./source/executorch-schema.js) ]] && crlf=1
+    node ./tools/flatc.js --root torch --out ./source/executorch-schema.js ./third_party/source/executorch/schema/program.fbs
+    if [[ -n ${crlf} ]]; then
+        unix2dos --quiet --newfile ./source/executorch-schema.js ./source/executorch-schema.js
+    fi
 }
 
 metadata() {

+ 1 - 0
tools/pytorch_script.py

@@ -58,6 +58,7 @@ known_legacy_schema_definitions = [
     'aten::arange.start_out_(Scalar start, Scalar end) -> Tensor',
     'aten::fft(Tensor self, int signal_ndim, bool normalized=False) -> Tensor',
     'aten::grid_sampler.legacy(Tensor input, Tensor grid, int interpolation_mode, int padding_mode) -> Tensor',
+    'executorch_prim::et_view.default(Tensor self, int[] size) -> (Tensor out)',
     'neuron::_execute_neuron(__torch__.torch.classes.neuron.Model _0, Tensor[] _1) -> Tensor[] _0',
     'neuron::_from_neuron(Tensor _0) -> Tensor _0',
     'neuron::_init_neuron() -> ()',