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 Workeruint64_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 Workeruint32_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 WorkerResult<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