xref: /aosp_15_r20/external/executorch/extension/data_loader/file_descriptor_data_loader.h (revision 523fa7a60841cd1ecfb9cc4201f1ca8b03ed023a)
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 descriptor, allocating the
22  * memory with `malloc()`. This data loader is used when ET is running in a
23  * process that does not have access to the filesystem, and the caller is able
24  * to open the file and pass the file descriptor.
25  *
26  * Note that this will keep the file open for the duration of its lifetime, to
27  * avoid the overhead of opening it again for every load() call.
28  */
29 class FileDescriptorDataLoader final : public executorch::runtime::DataLoader {
30  public:
31   /**
32    * Creates a new FileDescriptorDataLoader that wraps the named file
33    * descriptor, and the ownership of the file descriptor is passed.
34    *
35    * @param[in] file_descriptor_uri File descriptor with the prefix "fd:///",
36    *     followed by the file descriptor number.
37    * @param[in] alignment Alignment in bytes of pointers returned by this
38    *     instance. Must be a power of two.
39    *
40    * @returns A new FileDescriptorDataLoader on success.
41    * @retval Error::InvalidArgument `alignment` is not a power of two.
42    * @retval Error::AccessFailed `file_descriptor_uri` is incorrectly formatted,
43    * or its size could not be found.
44    * @retval Error::MemoryAllocationFailed Internal memory allocation failure.
45    */
46   static executorch::runtime::Result<FileDescriptorDataLoader>
47   fromFileDescriptorUri(
48       const char* file_descriptor_uri,
49       size_t alignment = alignof(std::max_align_t));
50 
51   // Movable to be compatible with Result.
FileDescriptorDataLoader(FileDescriptorDataLoader && rhs)52   FileDescriptorDataLoader(FileDescriptorDataLoader&& rhs) noexcept
53       : file_descriptor_uri_(rhs.file_descriptor_uri_),
54         file_size_(rhs.file_size_),
55         alignment_(rhs.alignment_),
56         fd_(rhs.fd_) {
57     const_cast<const char*&>(rhs.file_descriptor_uri_) = nullptr;
58     const_cast<size_t&>(rhs.file_size_) = 0;
59     const_cast<size_t&>(rhs.alignment_) = 0;
60     const_cast<int&>(rhs.fd_) = -1;
61   }
62 
63   ~FileDescriptorDataLoader() override;
64 
65   ET_NODISCARD
66   executorch::runtime::Result<executorch::runtime::FreeableBuffer> load(
67       size_t offset,
68       size_t size,
69       const DataLoader::SegmentInfo& segment_info) const override;
70 
71   ET_NODISCARD executorch::runtime::Result<size_t> size() const override;
72 
73   ET_NODISCARD executorch::runtime::Error load_into(
74       size_t offset,
75       size_t size,
76       ET_UNUSED const SegmentInfo& segment_info,
77       void* buffer) const override;
78 
79  private:
FileDescriptorDataLoader(int fd,size_t file_size,size_t alignment,const char * file_descriptor_uri)80   FileDescriptorDataLoader(
81       int fd,
82       size_t file_size,
83       size_t alignment,
84       const char* file_descriptor_uri)
85       : file_descriptor_uri_(file_descriptor_uri),
86         file_size_(file_size),
87         alignment_(alignment),
88         fd_(fd) {}
89 
90   // Not safely copyable.
91   FileDescriptorDataLoader(const FileDescriptorDataLoader&) = delete;
92   FileDescriptorDataLoader& operator=(const FileDescriptorDataLoader&) = delete;
93   FileDescriptorDataLoader& operator=(FileDescriptorDataLoader&&) = delete;
94 
95   const char* const file_descriptor_uri_; // Owned by the instance.
96   const size_t file_size_;
97   const size_t alignment_;
98   const int fd_; // Owned by the instance.
99 };
100 
101 } // namespace extension
102 } // namespace executorch
103 
104 namespace torch {
105 namespace executor {
106 namespace util {
107 // TODO(T197294990): Remove these deprecated aliases once all users have moved
108 // to the new `::executorch` namespaces.
109 using ::executorch::extension::FileDescriptorDataLoader;
110 } // namespace util
111 } // namespace executor
112 } // namespace torch
113