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 <cstddef> 12 13 #include <executorch/runtime/core/data_loader.h> 14 #include <executorch/runtime/core/result.h> 15 #include <executorch/runtime/platform/compiler.h> 16 17 namespace executorch { 18 namespace extension { 19 20 /** 21 * A DataLoader that loads segments from a file, allocating the memory 22 * with `malloc()`. 23 * 24 * Note that this will keep the file open for the duration of its lifetime, to 25 * avoid the overhead of opening it again for every load() call. 26 */ 27 class FileDataLoader final : public executorch::runtime::DataLoader { 28 public: 29 /** 30 * Creates a new FileDataLoader that wraps the named file. 31 * 32 * @param[in] file_name Path to the file to read from. 33 * @param[in] alignment Alignment in bytes of pointers returned by this 34 * instance. Must be a power of two. 35 * 36 * @returns A new FileDataLoader on success. 37 * @retval Error::InvalidArgument `alignment` is not a power of two. 38 * @retval Error::AccessFailed `file_name` could not be opened, or its size 39 * could not be found. 40 * @retval Error::MemoryAllocationFailed Internal memory allocation failure. 41 */ 42 static executorch::runtime::Result<FileDataLoader> from( 43 const char* file_name, 44 size_t alignment = alignof(std::max_align_t)); 45 46 /// DEPRECATED: Use the lowercase `from()` instead. 47 ET_DEPRECATED static executorch::runtime::Result<FileDataLoader> From( 48 const char* file_name, 49 size_t alignment = alignof(std::max_align_t)) { 50 return from(file_name, alignment); 51 } 52 53 // Movable to be compatible with Result. FileDataLoader(FileDataLoader && rhs)54 FileDataLoader(FileDataLoader&& rhs) noexcept 55 : file_name_(rhs.file_name_), 56 file_size_(rhs.file_size_), 57 alignment_(rhs.alignment_), 58 fd_(rhs.fd_) { 59 const_cast<const char*&>(rhs.file_name_) = nullptr; 60 const_cast<size_t&>(rhs.file_size_) = 0; 61 const_cast<size_t&>(rhs.alignment_) = 0; 62 const_cast<int&>(rhs.fd_) = -1; 63 } 64 65 ~FileDataLoader() override; 66 67 ET_NODISCARD 68 executorch::runtime::Result<executorch::runtime::FreeableBuffer> load( 69 size_t offset, 70 size_t size, 71 const DataLoader::SegmentInfo& segment_info) const override; 72 73 ET_NODISCARD executorch::runtime::Result<size_t> size() const override; 74 75 ET_NODISCARD executorch::runtime::Error load_into( 76 size_t offset, 77 size_t size, 78 ET_UNUSED const SegmentInfo& segment_info, 79 void* buffer) const override; 80 81 private: FileDataLoader(int fd,size_t file_size,size_t alignment,const char * file_name)82 FileDataLoader( 83 int fd, 84 size_t file_size, 85 size_t alignment, 86 const char* file_name) 87 : file_name_(file_name), 88 file_size_(file_size), 89 alignment_(alignment), 90 fd_(fd) {} 91 92 // Not safely copyable. 93 FileDataLoader(const FileDataLoader&) = delete; 94 FileDataLoader& operator=(const FileDataLoader&) = delete; 95 FileDataLoader& operator=(FileDataLoader&&) = delete; 96 97 const char* const file_name_; // Owned by the instance. 98 const size_t file_size_; 99 const size_t alignment_; 100 const int fd_; // Owned by the instance. 101 }; 102 103 } // namespace extension 104 } // namespace executorch 105 106 namespace torch { 107 namespace executor { 108 namespace util { 109 // TODO(T197294990): Remove these deprecated aliases once all users have moved 110 // to the new `::executorch` namespaces. 111 using ::executorch::extension::FileDataLoader; 112 } // namespace util 113 } // namespace executor 114 } // namespace torch 115