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/data_loader.h> 12 #include <executorch/runtime/core/error.h> 13 #include <executorch/runtime/core/result.h> 14 #include <executorch/runtime/platform/log.h> 15 #include <cstring> 16 17 namespace executorch { 18 namespace extension { 19 20 /** 21 * A DataLoader that wraps a pre-allocated buffer. The FreeableBuffers 22 * that it returns do not actually free any data. 23 * 24 * This can be used to wrap data that is directly embedded into the firmware 25 * image, or to wrap data that was allocated elsewhere. 26 */ 27 class BufferDataLoader final : public executorch::runtime::DataLoader { 28 public: BufferDataLoader(const void * data,size_t size)29 BufferDataLoader(const void* data, size_t size) 30 : data_(reinterpret_cast<const uint8_t*>(data)), size_(size) {} 31 32 ET_NODISCARD load(size_t offset,size_t size,ET_UNUSED const DataLoader::SegmentInfo & segment_info)33 executorch::runtime::Result<executorch::runtime::FreeableBuffer> load( 34 size_t offset, 35 size_t size, 36 ET_UNUSED const DataLoader::SegmentInfo& segment_info) const override { 37 ET_CHECK_OR_RETURN_ERROR( 38 offset + size <= size_, 39 InvalidArgument, 40 "offset %zu + size %zu > size_ %zu", 41 offset, 42 size, 43 size_); 44 return executorch::runtime::FreeableBuffer( 45 data_ + offset, size, /*free_fn=*/nullptr); 46 } 47 size()48 ET_NODISCARD executorch::runtime::Result<size_t> size() const override { 49 return size_; 50 } 51 load_into(size_t offset,size_t size,ET_UNUSED const SegmentInfo & segment_info,void * buffer)52 ET_NODISCARD executorch::runtime::Error load_into( 53 size_t offset, 54 size_t size, 55 ET_UNUSED const SegmentInfo& segment_info, 56 void* buffer) const override { 57 ET_CHECK_OR_RETURN_ERROR( 58 buffer != nullptr, 59 InvalidArgument, 60 "Destination buffer cannot be null"); 61 62 auto result = load(offset, size, segment_info); 63 if (!result.ok()) { 64 return result.error(); 65 } 66 std::memcpy(buffer, result->data(), size); 67 return executorch::runtime::Error::Ok; 68 } 69 70 private: 71 const uint8_t* const data_; // uint8 is easier to index into. 72 const size_t size_; 73 }; 74 75 } // namespace extension 76 } // namespace executorch 77 78 namespace torch { 79 namespace executor { 80 namespace util { 81 // TODO(T197294990): Remove these deprecated aliases once all users have moved 82 // to the new `::executorch` namespaces. 83 using ::executorch::extension::BufferDataLoader; 84 } // namespace util 85 } // namespace executor 86 } // namespace torch 87