xref: /aosp_15_r20/external/executorch/backends/xnnpack/runtime/XNNHeader.cpp (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 #include <executorch/backends/xnnpack/runtime/XNNHeader.h>
10*523fa7a6SAndroid Build Coastguard Worker 
11*523fa7a6SAndroid Build Coastguard Worker #include <cstring>
12*523fa7a6SAndroid Build Coastguard Worker 
13*523fa7a6SAndroid Build Coastguard Worker #include <executorch/runtime/core/error.h>
14*523fa7a6SAndroid Build Coastguard Worker #include <executorch/runtime/core/result.h>
15*523fa7a6SAndroid Build Coastguard Worker 
16*523fa7a6SAndroid Build Coastguard Worker #pragma clang diagnostic ignored "-Wdeprecated"
17*523fa7a6SAndroid Build Coastguard Worker 
18*523fa7a6SAndroid Build Coastguard Worker namespace executorch {
19*523fa7a6SAndroid Build Coastguard Worker namespace backends {
20*523fa7a6SAndroid Build Coastguard Worker namespace xnnpack {
21*523fa7a6SAndroid Build Coastguard Worker namespace delegate {
22*523fa7a6SAndroid Build Coastguard Worker 
23*523fa7a6SAndroid Build Coastguard Worker using executorch::runtime::Error;
24*523fa7a6SAndroid Build Coastguard Worker using executorch::runtime::Result;
25*523fa7a6SAndroid Build Coastguard Worker 
26*523fa7a6SAndroid Build Coastguard Worker namespace {
27*523fa7a6SAndroid Build Coastguard Worker /// Interprets the 8 bytes at `data` as a little-endian uint64_t.
GetUInt64LE(const uint8_t * data)28*523fa7a6SAndroid Build Coastguard Worker uint64_t GetUInt64LE(const uint8_t* data) {
29*523fa7a6SAndroid Build Coastguard Worker   return (uint64_t)data[0] | ((uint64_t)data[1] << 8) |
30*523fa7a6SAndroid Build Coastguard Worker       ((uint64_t)data[2] << 16) | ((uint64_t)data[3] << 24) |
31*523fa7a6SAndroid Build Coastguard Worker       ((uint64_t)data[4] << 32) | ((uint64_t)data[5] << 40) |
32*523fa7a6SAndroid Build Coastguard Worker       ((uint64_t)data[6] << 48) | ((uint64_t)data[7] << 56);
33*523fa7a6SAndroid Build Coastguard Worker }
34*523fa7a6SAndroid Build Coastguard Worker 
35*523fa7a6SAndroid Build Coastguard Worker /// Interprets the 4 bytes at `data` as a little-endian uint32_t.
GetUInt32LE(const uint8_t * data)36*523fa7a6SAndroid Build Coastguard Worker uint32_t GetUInt32LE(const uint8_t* data) {
37*523fa7a6SAndroid Build Coastguard Worker   return (uint32_t)data[0] | ((uint32_t)data[1] << 8) |
38*523fa7a6SAndroid Build Coastguard Worker       ((uint32_t)data[2] << 16) | ((uint32_t)data[3] << 24);
39*523fa7a6SAndroid Build Coastguard Worker }
40*523fa7a6SAndroid Build Coastguard Worker 
41*523fa7a6SAndroid Build Coastguard Worker } // namespace
42*523fa7a6SAndroid Build Coastguard Worker 
Parse(const void * data,size_t size)43*523fa7a6SAndroid Build Coastguard Worker Result<XNNHeader> XNNHeader::Parse(const void* data, size_t size) {
44*523fa7a6SAndroid Build Coastguard Worker   const uint8_t* header_data = (const uint8_t*)data;
45*523fa7a6SAndroid Build Coastguard Worker 
46*523fa7a6SAndroid Build Coastguard Worker   if (size < XNNHeader::kMinSize) {
47*523fa7a6SAndroid Build Coastguard Worker     return Error::InvalidArgument;
48*523fa7a6SAndroid Build Coastguard Worker   }
49*523fa7a6SAndroid Build Coastguard Worker 
50*523fa7a6SAndroid Build Coastguard Worker   const uint8_t* magic_start = header_data + XNNHeader::kMagicOffset;
51*523fa7a6SAndroid Build Coastguard Worker   if (std::memcmp(magic_start, XNNHeader::kMagic, XNNHeader::kMagicSize) != 0) {
52*523fa7a6SAndroid Build Coastguard Worker     return Error::NotFound;
53*523fa7a6SAndroid Build Coastguard Worker   }
54*523fa7a6SAndroid Build Coastguard Worker 
55*523fa7a6SAndroid Build Coastguard Worker   uint32_t flatbuffer_offset =
56*523fa7a6SAndroid Build Coastguard Worker       GetUInt32LE(header_data + XNNHeader::kFlatbufferDataOffsetOffset);
57*523fa7a6SAndroid Build Coastguard Worker 
58*523fa7a6SAndroid Build Coastguard Worker   uint32_t flatbuffer_size =
59*523fa7a6SAndroid Build Coastguard Worker       GetUInt32LE(header_data + XNNHeader::kFlatbufferDataSizeOffset);
60*523fa7a6SAndroid Build Coastguard Worker 
61*523fa7a6SAndroid Build Coastguard Worker   uint32_t constant_data_offset =
62*523fa7a6SAndroid Build Coastguard Worker       GetUInt32LE(header_data + XNNHeader::kConstantDataOffsetOffset);
63*523fa7a6SAndroid Build Coastguard Worker 
64*523fa7a6SAndroid Build Coastguard Worker   uint64_t constant_data_size =
65*523fa7a6SAndroid Build Coastguard Worker       GetUInt64LE(header_data + XNNHeader::kConstantDataSizeOffset);
66*523fa7a6SAndroid Build Coastguard Worker 
67*523fa7a6SAndroid Build Coastguard Worker   return XNNHeader{
68*523fa7a6SAndroid Build Coastguard Worker       flatbuffer_offset,
69*523fa7a6SAndroid Build Coastguard Worker       flatbuffer_size,
70*523fa7a6SAndroid Build Coastguard Worker       constant_data_offset,
71*523fa7a6SAndroid Build Coastguard Worker       constant_data_size};
72*523fa7a6SAndroid Build Coastguard Worker }
73*523fa7a6SAndroid Build Coastguard Worker 
74*523fa7a6SAndroid Build Coastguard Worker // Define storage for the static.
75*523fa7a6SAndroid Build Coastguard Worker constexpr char XNNHeader::kMagic[kMagicSize];
76*523fa7a6SAndroid Build Coastguard Worker 
77*523fa7a6SAndroid Build Coastguard Worker } // namespace delegate
78*523fa7a6SAndroid Build Coastguard Worker } // namespace xnnpack
79*523fa7a6SAndroid Build Coastguard Worker } // namespace backends
80*523fa7a6SAndroid Build Coastguard Worker } // namespace executorch
81