1*523fa7a6SAndroid Build Coastguard Worker /* 2*523fa7a6SAndroid Build Coastguard Worker * Copyright (c) Meta Platforms, Inc. and affiliates. 3*523fa7a6SAndroid Build Coastguard Worker * All rights reserved. 4*523fa7a6SAndroid Build Coastguard Worker * 5*523fa7a6SAndroid Build Coastguard Worker * This source code is licensed under the BSD-style license found in the 6*523fa7a6SAndroid Build Coastguard Worker * LICENSE file in the root directory of this source tree. 7*523fa7a6SAndroid Build Coastguard Worker */ 8*523fa7a6SAndroid Build Coastguard Worker 9*523fa7a6SAndroid Build Coastguard Worker #pragma once 10*523fa7a6SAndroid Build Coastguard Worker 11*523fa7a6SAndroid Build Coastguard Worker #include <executorch/runtime/core/result.h> 12*523fa7a6SAndroid Build Coastguard Worker 13*523fa7a6SAndroid Build Coastguard Worker namespace executorch { 14*523fa7a6SAndroid Build Coastguard Worker namespace backends { 15*523fa7a6SAndroid Build Coastguard Worker namespace xnnpack { 16*523fa7a6SAndroid Build Coastguard Worker namespace delegate { 17*523fa7a6SAndroid Build Coastguard Worker 18*523fa7a6SAndroid Build Coastguard Worker /** 19*523fa7a6SAndroid Build Coastguard Worker * An extended XNNPACK-header that is embeded before the flatbuffer payload 20*523fa7a6SAndroid Build Coastguard Worker * 21*523fa7a6SAndroid Build Coastguard Worker */ 22*523fa7a6SAndroid Build Coastguard Worker struct XNNHeader { 23*523fa7a6SAndroid Build Coastguard Worker /** 24*523fa7a6SAndroid Build Coastguard Worker * The minimum size of the XNNHeader. The caller should provide at least this 25*523fa7a6SAndroid Build Coastguard Worker * many bytes of the head of the serialized XNNPACK Data 26*523fa7a6SAndroid Build Coastguard Worker */ 27*523fa7a6SAndroid Build Coastguard Worker static constexpr size_t kMinSize = 30; 28*523fa7a6SAndroid Build Coastguard Worker 29*523fa7a6SAndroid Build Coastguard Worker /** 30*523fa7a6SAndroid Build Coastguard Worker * The magic offset. This offset is the same as the offset for flatbuffer 31*523fa7a6SAndroid Build Coastguard Worker * header so we will be able to check if the header is is either the 32*523fa7a6SAndroid Build Coastguard Worker * flatbuffer head or the wrapper header we introduce here 33*523fa7a6SAndroid Build Coastguard Worker */ 34*523fa7a6SAndroid Build Coastguard Worker static constexpr size_t kMagicOffset = 4; 35*523fa7a6SAndroid Build Coastguard Worker 36*523fa7a6SAndroid Build Coastguard Worker /** 37*523fa7a6SAndroid Build Coastguard Worker * The magic bytes that identify the header. 38*523fa7a6SAndroid Build Coastguard Worker * 39*523fa7a6SAndroid Build Coastguard Worker * This is the canonical definition of the expected value. If the header 40*523fa7a6SAndroid Build Coastguard Worker * layout ever changes in a compatibility-breaking way, increment the digits 41*523fa7a6SAndroid Build Coastguard Worker * in the magic. But, doing so will prevent older binaries from recognizing 42*523fa7a6SAndroid Build Coastguard Worker * the presence of the header. The compatibility-preserving way to make 43*523fa7a6SAndroid Build Coastguard Worker * changes is to increase the header's length field and add new fields at the 44*523fa7a6SAndroid Build Coastguard Worker * end. 45*523fa7a6SAndroid Build Coastguard Worker */ 46*523fa7a6SAndroid Build Coastguard Worker static constexpr size_t kMagicSize = 4; 47*523fa7a6SAndroid Build Coastguard Worker static constexpr char kMagic[kMagicSize] = {'X', 'H', '0', '0'}; 48*523fa7a6SAndroid Build Coastguard Worker 49*523fa7a6SAndroid Build Coastguard Worker /** 50*523fa7a6SAndroid Build Coastguard Worker * The size in bytes of the header length. We store 2 bytes for the header 51*523fa7a6SAndroid Build Coastguard Worker * length 52*523fa7a6SAndroid Build Coastguard Worker */ 53*523fa7a6SAndroid Build Coastguard Worker static constexpr size_t kHeaderLengthSize = 2; 54*523fa7a6SAndroid Build Coastguard Worker 55*523fa7a6SAndroid Build Coastguard Worker /** 56*523fa7a6SAndroid Build Coastguard Worker * The expected location of the header length field relative to the beginning 57*523fa7a6SAndroid Build Coastguard Worker * of the header. 58*523fa7a6SAndroid Build Coastguard Worker */ 59*523fa7a6SAndroid Build Coastguard Worker static constexpr size_t kHeaderLengthOffset = 60*523fa7a6SAndroid Build Coastguard Worker XNNHeader::kMagicOffset + XNNHeader::kMagicSize; 61*523fa7a6SAndroid Build Coastguard Worker 62*523fa7a6SAndroid Build Coastguard Worker /** 63*523fa7a6SAndroid Build Coastguard Worker * The expected location of the flatbuffer data offset field relative to the 64*523fa7a6SAndroid Build Coastguard Worker * beginning of the header. 65*523fa7a6SAndroid Build Coastguard Worker */ 66*523fa7a6SAndroid Build Coastguard Worker static constexpr size_t kFlatbufferDataOffsetOffset = 67*523fa7a6SAndroid Build Coastguard Worker kHeaderLengthOffset + sizeof(uint16_t); 68*523fa7a6SAndroid Build Coastguard Worker 69*523fa7a6SAndroid Build Coastguard Worker /** 70*523fa7a6SAndroid Build Coastguard Worker * The expected location of the flatbuffer data size field relative to the 71*523fa7a6SAndroid Build Coastguard Worker * beginning of the header. 72*523fa7a6SAndroid Build Coastguard Worker */ 73*523fa7a6SAndroid Build Coastguard Worker static constexpr size_t kFlatbufferDataSizeOffset = 74*523fa7a6SAndroid Build Coastguard Worker kFlatbufferDataOffsetOffset + sizeof(uint32_t); 75*523fa7a6SAndroid Build Coastguard Worker 76*523fa7a6SAndroid Build Coastguard Worker /* 77*523fa7a6SAndroid Build Coastguard Worker * The expected location of the constant data offset field relative to the 78*523fa7a6SAndroid Build Coastguard Worker * beginning of the header. 79*523fa7a6SAndroid Build Coastguard Worker */ 80*523fa7a6SAndroid Build Coastguard Worker static constexpr size_t kConstantDataOffsetOffset = 81*523fa7a6SAndroid Build Coastguard Worker kFlatbufferDataSizeOffset + sizeof(uint32_t); 82*523fa7a6SAndroid Build Coastguard Worker 83*523fa7a6SAndroid Build Coastguard Worker /* 84*523fa7a6SAndroid Build Coastguard Worker * The expected location of the constant data size field relative to the 85*523fa7a6SAndroid Build Coastguard Worker * beginning of the header. 86*523fa7a6SAndroid Build Coastguard Worker */ 87*523fa7a6SAndroid Build Coastguard Worker static constexpr size_t kConstantDataSizeOffset = 88*523fa7a6SAndroid Build Coastguard Worker kConstantDataOffsetOffset + sizeof(uint32_t); 89*523fa7a6SAndroid Build Coastguard Worker 90*523fa7a6SAndroid Build Coastguard Worker /** 91*523fa7a6SAndroid Build Coastguard Worker * Look for and parse an ExtendedHeader in the provided data. 92*523fa7a6SAndroid Build Coastguard Worker * 93*523fa7a6SAndroid Build Coastguard Worker * @param[in] data The contents of the beginning of the serialized binary 94*523fa7a6SAndroid Build Coastguard Worker * Program data, starting at offset 0 (i.e., the head of the file). 95*523fa7a6SAndroid Build Coastguard Worker * @param[in] size Length of `data` in bytes. 96*523fa7a6SAndroid Build Coastguard Worker * 97*523fa7a6SAndroid Build Coastguard Worker * @returns an XNNHeader if the header was found and is valid. Returns an 98*523fa7a6SAndroid Build Coastguard Worker * error if size was too short, if the header was not found, or if the 99*523fa7a6SAndroid Build Coastguard Worker * header appeared to be corrupt. 100*523fa7a6SAndroid Build Coastguard Worker */ 101*523fa7a6SAndroid Build Coastguard Worker static executorch::runtime::Result<XNNHeader> Parse( 102*523fa7a6SAndroid Build Coastguard Worker const void* data, 103*523fa7a6SAndroid Build Coastguard Worker size_t size); 104*523fa7a6SAndroid Build Coastguard Worker 105*523fa7a6SAndroid Build Coastguard Worker /** 106*523fa7a6SAndroid Build Coastguard Worker * The offset in bytes to the beginning of the flatbuffer data. 107*523fa7a6SAndroid Build Coastguard Worker */ 108*523fa7a6SAndroid Build Coastguard Worker uint32_t flatbuffer_offset; 109*523fa7a6SAndroid Build Coastguard Worker /** 110*523fa7a6SAndroid Build Coastguard Worker * The size in bytes of the flatbuffer data. 111*523fa7a6SAndroid Build Coastguard Worker */ 112*523fa7a6SAndroid Build Coastguard Worker uint32_t flatbuffer_size; 113*523fa7a6SAndroid Build Coastguard Worker 114*523fa7a6SAndroid Build Coastguard Worker /** 115*523fa7a6SAndroid Build Coastguard Worker * The offset in bytes to the beginning of the constant data. 116*523fa7a6SAndroid Build Coastguard Worker */ 117*523fa7a6SAndroid Build Coastguard Worker uint32_t constant_data_offset; 118*523fa7a6SAndroid Build Coastguard Worker /** 119*523fa7a6SAndroid Build Coastguard Worker * The size in bytes of the constant data. 120*523fa7a6SAndroid Build Coastguard Worker */ 121*523fa7a6SAndroid Build Coastguard Worker uint64_t constant_data_size; 122*523fa7a6SAndroid Build Coastguard Worker }; 123*523fa7a6SAndroid Build Coastguard Worker 124*523fa7a6SAndroid Build Coastguard Worker } // namespace delegate 125*523fa7a6SAndroid Build Coastguard Worker } // namespace xnnpack 126*523fa7a6SAndroid Build Coastguard Worker } // namespace backends 127*523fa7a6SAndroid Build Coastguard Worker } // namespace executorch 128