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