xref: /aosp_15_r20/external/executorch/backends/xnnpack/runtime/XNNHeader.h (revision 523fa7a60841cd1ecfb9cc4201f1ca8b03ed023a)
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