xref: /aosp_15_r20/external/tensorflow/tensorflow/core/platform/env.h (revision b6fb3261f9314811a0f4371741dbb8839866f948)
1 /* Copyright 2015 The TensorFlow Authors. All Rights Reserved.
2 
3 Licensed under the Apache License, Version 2.0 (the "License");
4 you may not use this file except in compliance with the License.
5 You may obtain a copy of the License at
6 
7     http://www.apache.org/licenses/LICENSE-2.0
8 
9 Unless required by applicable law or agreed to in writing, software
10 distributed under the License is distributed on an "AS IS" BASIS,
11 WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 See the License for the specific language governing permissions and
13 limitations under the License.
14 ==============================================================================*/
15 
16 #ifndef TENSORFLOW_CORE_PLATFORM_ENV_H_
17 #define TENSORFLOW_CORE_PLATFORM_ENV_H_
18 
19 #include <stdint.h>
20 
21 #include <memory>
22 #include <string>
23 #include <unordered_map>
24 #include <vector>
25 
26 #include "tensorflow/core/platform/env_time.h"
27 #include "tensorflow/core/platform/errors.h"
28 #include "tensorflow/core/platform/file_system.h"
29 #include "tensorflow/core/platform/macros.h"
30 #include "tensorflow/core/platform/mutex.h"
31 #include "tensorflow/core/platform/numa.h"
32 #include "tensorflow/core/platform/platform.h"
33 #include "tensorflow/core/platform/protobuf.h"
34 #include "tensorflow/core/platform/status.h"
35 #include "tensorflow/core/platform/stringpiece.h"
36 #include "tensorflow/core/platform/types.h"
37 
38 // Delete leaked Windows definitions.
39 #ifdef PLATFORM_WINDOWS
40 #undef CopyFile
41 #undef DeleteFile
42 #endif
43 
44 namespace tensorflow {
45 
46 class Thread;
47 struct ThreadOptions;
48 
49 /// \brief An interface used by the tensorflow implementation to
50 /// access operating system functionality like the filesystem etc.
51 ///
52 /// Callers may wish to provide a custom Env object to get fine grain
53 /// control.
54 ///
55 /// All Env implementations are safe for concurrent access from
56 /// multiple threads without any external synchronization.
57 class Env {
58  public:
59   Env();
60   virtual ~Env() = default;
61 
62   /// \brief Returns a default environment suitable for the current operating
63   /// system.
64   ///
65   /// Sophisticated users may wish to provide their own Env
66   /// implementation instead of relying on this default environment.
67   ///
68   /// The result of Default() belongs to this library and must never be deleted.
69   static Env* Default();
70 
71   /// \brief Returns the FileSystem object to handle operations on the file
72   /// specified by 'fname'. The FileSystem object is used as the implementation
73   /// for the file system related (non-virtual) functions that follow.
74   /// Returned FileSystem object is still owned by the Env object and will
75   // (might) be destroyed when the environment is destroyed.
76   virtual Status GetFileSystemForFile(const std::string& fname,
77                                       FileSystem** result);
78 
79   /// \brief Returns the file system schemes registered for this Env.
80   virtual Status GetRegisteredFileSystemSchemes(
81       std::vector<std::string>* schemes);
82 
83   /// \brief Register a file system for a scheme.
84   virtual Status RegisterFileSystem(const std::string& scheme,
85                                     FileSystemRegistry::Factory factory);
86 
87   /// \brief Register a modular file system for a scheme.
88   ///
89   /// Same as `RegisterFileSystem` but for filesystems provided by plugins.
90   ///
91   /// TODO(b/139060984): After all filesystems are converted, make this be the
92   /// canonical registration function.
93   virtual Status RegisterFileSystem(const std::string& scheme,
94                                     std::unique_ptr<FileSystem> filesystem);
95 
96   Status SetOption(const std::string& scheme, const std::string& key,
97                    const std::string& value);
98 
99   Status SetOption(const std::string& scheme, const std::string& key,
100                    const std::vector<string>& values);
101 
102   Status SetOption(const std::string& scheme, const std::string& key,
103                    const std::vector<int64_t>& values);
104 
105   Status SetOption(const std::string& scheme, const std::string& key,
106                    const std::vector<double>& values);
107 
108   /// \brief Flush filesystem caches for all registered filesystems.
109   Status FlushFileSystemCaches();
110 
111   /// \brief Creates a brand new random access read-only file with the
112   /// specified name.
113 
114   /// On success, stores a pointer to the new file in
115   /// *result and returns OK.  On failure stores NULL in *result and
116   /// returns non-OK.  If the file does not exist, returns a non-OK
117   /// status.
118   ///
119   /// The returned file may be concurrently accessed by multiple threads.
120   ///
121   /// The ownership of the returned RandomAccessFile is passed to the caller
122   /// and the object should be deleted when is not used. The file object
123   /// shouldn't live longer than the Env object.
124   Status NewRandomAccessFile(const std::string& fname,
125                              std::unique_ptr<RandomAccessFile>* result);
126 
NewRandomAccessFile(const std::string & fname,TransactionToken * token,std::unique_ptr<RandomAccessFile> * result)127   Status NewRandomAccessFile(const std::string& fname, TransactionToken* token,
128                              std::unique_ptr<RandomAccessFile>* result) {
129     // We duplicate these methods due to Google internal coding style prevents
130     // virtual functions with default arguments. See PR #41615.
131     return OkStatus();
132   }
133 
134   /// \brief Creates an object that writes to a new file with the specified
135   /// name.
136   ///
137   /// Deletes any existing file with the same name and creates a
138   /// new file.  On success, stores a pointer to the new file in
139   /// *result and returns OK.  On failure stores NULL in *result and
140   /// returns non-OK.
141   ///
142   /// The returned file will only be accessed by one thread at a time.
143   ///
144   /// The ownership of the returned WritableFile is passed to the caller
145   /// and the object should be deleted when is not used. The file object
146   /// shouldn't live longer than the Env object.
147   Status NewWritableFile(const std::string& fname,
148                          std::unique_ptr<WritableFile>* result);
149 
NewWritableFile(const std::string & fname,TransactionToken * token,std::unique_ptr<WritableFile> * result)150   Status NewWritableFile(const std::string& fname, TransactionToken* token,
151                          std::unique_ptr<WritableFile>* result) {
152     return OkStatus();
153   }
154 
155   /// \brief Creates an object that either appends to an existing file, or
156   /// writes to a new file (if the file does not exist to begin with).
157   ///
158   /// On success, stores a pointer to the new file in *result and
159   /// returns OK.  On failure stores NULL in *result and returns
160   /// non-OK.
161   ///
162   /// The returned file will only be accessed by one thread at a time.
163   ///
164   /// The ownership of the returned WritableFile is passed to the caller
165   /// and the object should be deleted when is not used. The file object
166   /// shouldn't live longer than the Env object.
167   Status NewAppendableFile(const std::string& fname,
168                            std::unique_ptr<WritableFile>* result);
169 
NewAppendableFile(const std::string & fname,TransactionToken * token,std::unique_ptr<WritableFile> * result)170   Status NewAppendableFile(const std::string& fname, TransactionToken* token,
171                            std::unique_ptr<WritableFile>* result) {
172     return OkStatus();
173   }
174   /// \brief Creates a readonly region of memory with the file context.
175   ///
176   /// On success, it returns a pointer to read-only memory region
177   /// from the content of file fname. The ownership of the region is passed to
178   /// the caller. On failure stores nullptr in *result and returns non-OK.
179   ///
180   /// The returned memory region can be accessed from many threads in parallel.
181   ///
182   /// The ownership of the returned ReadOnlyMemoryRegion is passed to the caller
183   /// and the object should be deleted when is not used. The memory region
184   /// object shouldn't live longer than the Env object.
185   Status NewReadOnlyMemoryRegionFromFile(
186       const std::string& fname, std::unique_ptr<ReadOnlyMemoryRegion>* result);
187 
NewReadOnlyMemoryRegionFromFile(const std::string & fname,TransactionToken * token,std::unique_ptr<ReadOnlyMemoryRegion> * result)188   Status NewReadOnlyMemoryRegionFromFile(
189       const std::string& fname, TransactionToken* token,
190       std::unique_ptr<ReadOnlyMemoryRegion>* result) {
191     return OkStatus();
192   }
193 
194   /// Returns OK if the named path exists and NOT_FOUND otherwise.
195   Status FileExists(const std::string& fname);
196 
FileExists(const std::string & fname,TransactionToken * token)197   Status FileExists(const std::string& fname, TransactionToken* token) {
198     return OkStatus();
199   }
200 
201   /// Returns true if all the listed files exist, false otherwise.
202   /// if status is not null, populate the vector with a detailed status
203   /// for each file.
204   bool FilesExist(const std::vector<string>& files,
205                   std::vector<Status>* status);
206 
FilesExist(const std::vector<string> & files,TransactionToken * token,std::vector<Status> * status)207   bool FilesExist(const std::vector<string>& files, TransactionToken* token,
208                   std::vector<Status>* status) {
209     return true;
210   }
211 
212   /// \brief Stores in *result the names of the children of the specified
213   /// directory. The names are relative to "dir".
214   ///
215   /// Original contents of *results are dropped.
216   Status GetChildren(const std::string& dir, std::vector<string>* result);
217 
GetChildren(const std::string & dir,TransactionToken * token,std::vector<string> * result)218   Status GetChildren(const std::string& dir, TransactionToken* token,
219                      std::vector<string>* result) {
220     return OkStatus();
221   }
222 
223   /// \brief Returns true if the path matches the given pattern. The wildcards
224   /// allowed in pattern are described in FileSystem::GetMatchingPaths.
225   virtual bool MatchPath(const std::string& path,
226                          const std::string& pattern) = 0;
227 
228   /// \brief Given a pattern, stores in *results the set of paths that matches
229   /// that pattern. *results is cleared.
230   ///
231   /// More details about `pattern` in FileSystem::GetMatchingPaths.
232   virtual Status GetMatchingPaths(const std::string& pattern,
233                                   std::vector<string>* results);
234 
GetMatchingPaths(const std::string & pattern,TransactionToken * token,std::vector<string> * results)235   Status GetMatchingPaths(const std::string& pattern, TransactionToken* token,
236                           std::vector<string>* results) {
237     return OkStatus();
238   }
239 
240   /// Deletes the named file.
241   Status DeleteFile(const std::string& fname);
242 
DeleteFile(const std::string & fname,TransactionToken * token)243   Status DeleteFile(const std::string& fname, TransactionToken* token) {
244     return OkStatus();
245   }
246 
247   /// \brief Deletes the specified directory and all subdirectories and files
248   /// underneath it. This is accomplished by traversing the directory tree
249   /// rooted at dirname and deleting entries as they are encountered.
250   ///
251   /// If dirname itself is not readable or does not exist, *undeleted_dir_count
252   /// is set to 1, *undeleted_file_count is set to 0 and an appropriate status
253   /// (e.g. NOT_FOUND) is returned.
254   ///
255   /// If dirname and all its descendants were successfully deleted, TF_OK is
256   /// returned and both error counters are set to zero.
257   ///
258   /// Otherwise, while traversing the tree, undeleted_file_count and
259   /// undeleted_dir_count are updated if an entry of the corresponding type
260   /// could not be deleted. The returned error status represents the reason that
261   /// any one of these entries could not be deleted.
262   ///
263   /// REQUIRES: undeleted_files, undeleted_dirs to be not null.
264   ///
265   /// Typical return codes:
266   ///  * OK - dirname exists and we were able to delete everything underneath.
267   ///  * NOT_FOUND - dirname doesn't exist
268   ///  * PERMISSION_DENIED - dirname or some descendant is not writable
269   ///  * UNIMPLEMENTED - Some underlying functions (like Delete) are not
270   ///                    implemented
271   Status DeleteRecursively(const std::string& dirname, int64_t* undeleted_files,
272                            int64_t* undeleted_dirs);
273 
DeleteRecursively(const std::string & dirname,TransactionToken * token,int64_t * undeleted_files,int64_t * undeleted_dirs)274   Status DeleteRecursively(const std::string& dirname, TransactionToken* token,
275                            int64_t* undeleted_files, int64_t* undeleted_dirs) {
276     return OkStatus();
277   }
278 
279   /// \brief Creates the specified directory and all the necessary
280   /// subdirectories. Typical return codes.
281   ///  * OK - successfully created the directory and sub directories, even if
282   ///         they were already created.
283   ///  * PERMISSION_DENIED - dirname or some subdirectory is not writable.
284   Status RecursivelyCreateDir(const std::string& dirname);
285 
RecursivelyCreateDir(const std::string & dirname,TransactionToken * token)286   Status RecursivelyCreateDir(const std::string& dirname,
287                               TransactionToken* token) {
288     return OkStatus();
289   }
290   /// \brief Creates the specified directory. Typical return codes
291   ///  * OK - successfully created the directory.
292   ///  * ALREADY_EXISTS - directory already exists.
293   ///  * PERMISSION_DENIED - dirname is not writable.
294   Status CreateDir(const std::string& dirname);
295 
CreateDir(const std::string & dirname,TransactionToken * token)296   Status CreateDir(const std::string& dirname, TransactionToken* token) {
297     return OkStatus();
298   }
299 
300   /// Deletes the specified directory.
301   Status DeleteDir(const std::string& dirname);
302 
DeleteDir(const std::string & dirname,TransactionToken * token)303   Status DeleteDir(const std::string& dirname, TransactionToken* token) {
304     return OkStatus();
305   }
306 
307   /// Obtains statistics for the given path.
308   Status Stat(const std::string& fname, FileStatistics* stat);
309 
Stat(const std::string & fname,TransactionToken * token,FileStatistics * stat)310   Status Stat(const std::string& fname, TransactionToken* token,
311               FileStatistics* stat) {
312     return OkStatus();
313   }
314 
315   /// \brief Returns whether the given path is a directory or not.
316   /// Typical return codes (not guaranteed exhaustive):
317   ///  * OK - The path exists and is a directory.
318   ///  * FAILED_PRECONDITION - The path exists and is not a directory.
319   ///  * NOT_FOUND - The path entry does not exist.
320   ///  * PERMISSION_DENIED - Insufficient permissions.
321   ///  * UNIMPLEMENTED - The file factory doesn't support directories.
322   Status IsDirectory(const std::string& fname);
323 
324   /// \brief Returns whether the given path is on a file system
325   /// that has atomic move capabilities. This can be used
326   /// to determine if there needs to be a temp location to safely write objects.
327   /// The second boolean argument has_atomic_move contains this information.
328   ///
329   /// Returns one of the following status codes (not guaranteed exhaustive):
330   ///  * OK - The path is on a recognized file system,
331   ///         so has_atomic_move holds the above information.
332   ///  * UNIMPLEMENTED - The file system of the path hasn't been implemented in
333   ///  TF
334   Status HasAtomicMove(const std::string& path, bool* has_atomic_move);
335 
336   /// Returns whether the give path is on a file system
337   /// that has ability to create a new temp file. This can be used
338   /// to determine if there needs to be a temp location to safely write objects.
339   /// If this returns false, TensorFlow will write directly to output files
340   /// instead of creating a temporary file and swapping it in. This may mean
341   /// that incomplete writes are visible to consumers.
342   Status CanCreateTempFile(const std::string& fname,
343                            bool* can_create_temp_file);
344 
345   /// Stores the size of `fname` in `*file_size`.
346   Status GetFileSize(const std::string& fname, uint64* file_size);
347 
GetFileSize(const std::string & fname,TransactionToken * token,uint64 * file_size)348   Status GetFileSize(const std::string& fname, TransactionToken* token,
349                      uint64* file_size) {
350     return OkStatus();
351   }
352 
353   /// \brief Renames file src to target. If target already exists, it will be
354   /// replaced.
355   Status RenameFile(const std::string& src, const std::string& target);
356 
RenameFile(const std::string & src,const std::string & target,TransactionToken * token)357   Status RenameFile(const std::string& src, const std::string& target,
358                     TransactionToken* token) {
359     return OkStatus();
360   }
361 
362   /// \brief Copy the src to target.
363   Status CopyFile(const std::string& src, const std::string& target);
364 
CopyFile(const std::string & src,const std::string & target,TransactionToken * token)365   Status CopyFile(const std::string& src, const std::string& target,
366                   TransactionToken* token) {
367     return OkStatus();
368   }
369 
370   /// \brief starts a new transaction on the filesystem that handles filename
StartTransaction(const std::string & filename,TransactionToken ** token)371   Status StartTransaction(const std::string& filename,
372                           TransactionToken** token) {
373     *token = nullptr;
374     return OkStatus();
375   }
376 
377   /// \brief Adds `path` to transaction in `token` if token belongs to
378   /// filesystem that handles the path.
AddToTransaction(const std::string & path,TransactionToken * token)379   Status AddToTransaction(const std::string& path, TransactionToken* token) {
380     return OkStatus();
381   }
382 
383   /// \brief Get token for `path` or start a new transaction and add `path` to
384   /// it.
GetTokenOrStartTransaction(const std::string & path,TransactionToken ** token)385   Status GetTokenOrStartTransaction(const std::string& path,
386                                     TransactionToken** token) {
387     *token = nullptr;
388     return OkStatus();
389   }
390 
391   /// \brief Returns the transaction for `path` or nullptr in `token`
GetTransactionForPath(const std::string & path,TransactionToken ** token)392   Status GetTransactionForPath(const std::string& path,
393                                TransactionToken** token) {
394     *token = nullptr;
395     return OkStatus();
396   }
397 
398   /// \brief Finalizes the transaction
EndTransaction(TransactionToken * token)399   Status EndTransaction(TransactionToken* token) { return OkStatus(); }
400 
401   /// \brief Returns the absolute path of the current executable. It resolves
402   /// symlinks if there is any.
403   std::string GetExecutablePath();
404 
405   /// Creates a local unique temporary file name. Returns true if success.
406   bool LocalTempFilename(std::string* filename);
407 
408   /// Creates a local unique file name that starts with |prefix| and ends with
409   /// |suffix|. Returns true if success.
410   bool CreateUniqueFileName(std::string* prefix, const std::string& suffix);
411 
412   /// \brief Return the runfiles directory if running under bazel. Returns
413   /// the directory the executable is located in if not running under bazel.
414   virtual std::string GetRunfilesDir() = 0;
415 
416   // TODO(jeff,sanjay): Add back thread/thread-pool support if needed.
417   // TODO(jeff,sanjay): if needed, tighten spec so relative to epoch, or
418   // provide a routine to get the absolute time.
419 
420   /// \brief Returns the number of nano-seconds since the Unix epoch.
NowNanos()421   virtual uint64 NowNanos() const { return EnvTime::NowNanos(); }
422 
423   /// \brief Returns the number of micro-seconds since the Unix epoch.
NowMicros()424   virtual uint64 NowMicros() const { return EnvTime::NowMicros(); }
425 
426   /// \brief Returns the number of seconds since the Unix epoch.
NowSeconds()427   virtual uint64 NowSeconds() const { return EnvTime::NowSeconds(); }
428 
429   /// Sleeps/delays the thread for the prescribed number of micro-seconds.
430   virtual void SleepForMicroseconds(int64_t micros) = 0;
431 
432   /// Returns the process ID of the calling process.
433   int32 GetProcessId();
434 
435   /// \brief Returns a new thread that is running fn() and is identified
436   /// (for debugging/performance-analysis) by "name".
437   ///
438   /// Caller takes ownership of the result and must delete it eventually
439   /// (the deletion will block until fn() stops running).
440   virtual Thread* StartThread(const ThreadOptions& thread_options,
441                               const std::string& name,
442                               std::function<void()> fn) TF_MUST_USE_RESULT = 0;
443 
444   // Returns the thread id of calling thread.
445   // Posix: Returns pthread id which is only guaranteed to be unique within a
446   //        process.
447   // Windows: Returns thread id which is unique.
448   virtual int32 GetCurrentThreadId() = 0;
449 
450   // Copies current thread name to "name". Returns true if success.
451   virtual bool GetCurrentThreadName(std::string* name) = 0;
452 
453   // \brief Schedules the given closure on a thread-pool.
454   //
455   // NOTE(mrry): This closure may block.
456   virtual void SchedClosure(std::function<void()> closure) = 0;
457 
458   // \brief Schedules the given closure on a thread-pool after the given number
459   // of microseconds.
460   //
461   // NOTE(mrry): This closure must not block.
462   virtual void SchedClosureAfter(int64_t micros,
463                                  std::function<void()> closure) = 0;
464 
465   // \brief Load a dynamic library.
466   //
467   // Pass "library_filename" to a platform-specific mechanism for dynamically
468   // loading a library.  The rules for determining the exact location of the
469   // library are platform-specific and are not documented here.
470   //
471   // On success, returns a handle to the library in "*handle" and returns
472   // OK from the function.
473   // Otherwise returns nullptr in "*handle" and an error status from the
474   // function.
475   virtual Status LoadDynamicLibrary(const char* library_filename,
476                                     void** handle) = 0;
477 
478   // \brief Get a pointer to a symbol from a dynamic library.
479   //
480   // "handle" should be a pointer returned from a previous call to LoadLibrary.
481   // On success, store a pointer to the located symbol in "*symbol" and return
482   // OK from the function. Otherwise, returns nullptr in "*symbol" and an error
483   // status from the function.
484   virtual Status GetSymbolFromLibrary(void* handle, const char* symbol_name,
485                                       void** symbol) = 0;
486 
487   // \brief build the name of dynamic library.
488   //
489   // "name" should be name of the library.
490   // "version" should be the version of the library or NULL
491   // returns the name that LoadLibrary() can use
492   virtual std::string FormatLibraryFileName(const std::string& name,
493                                             const std::string& version) = 0;
494 
495   // Returns a possible list of local temporary directories.
496   virtual void GetLocalTempDirectories(std::vector<string>* list) = 0;
497 
498  private:
499   std::unique_ptr<FileSystemRegistry> file_system_registry_;
500   TF_DISALLOW_COPY_AND_ASSIGN(Env);
501 };
502 
503 /// \brief An implementation of Env that forwards all calls to another Env.
504 ///
505 /// May be useful to clients who wish to override just part of the
506 /// functionality of another Env.
507 class EnvWrapper : public Env {
508  public:
509   /// Initializes an EnvWrapper that delegates all calls to *t
EnvWrapper(Env * t)510   explicit EnvWrapper(Env* t) : target_(t) {}
511   ~EnvWrapper() override;
512 
513   /// Returns the target to which this Env forwards all calls
target()514   Env* target() const { return target_; }
515 
GetFileSystemForFile(const std::string & fname,FileSystem ** result)516   Status GetFileSystemForFile(const std::string& fname,
517                               FileSystem** result) override {
518     return target_->GetFileSystemForFile(fname, result);
519   }
520 
GetRegisteredFileSystemSchemes(std::vector<string> * schemes)521   Status GetRegisteredFileSystemSchemes(std::vector<string>* schemes) override {
522     return target_->GetRegisteredFileSystemSchemes(schemes);
523   }
524 
RegisterFileSystem(const std::string & scheme,FileSystemRegistry::Factory factory)525   Status RegisterFileSystem(const std::string& scheme,
526                             FileSystemRegistry::Factory factory) override {
527     return target_->RegisterFileSystem(scheme, factory);
528   }
529 
MatchPath(const std::string & path,const std::string & pattern)530   bool MatchPath(const std::string& path, const std::string& pattern) override {
531     return target_->MatchPath(path, pattern);
532   }
533 
NowMicros()534   uint64 NowMicros() const override { return target_->NowMicros(); }
SleepForMicroseconds(int64_t micros)535   void SleepForMicroseconds(int64_t micros) override {
536     target_->SleepForMicroseconds(micros);
537   }
StartThread(const ThreadOptions & thread_options,const std::string & name,std::function<void ()> fn)538   Thread* StartThread(const ThreadOptions& thread_options,
539                       const std::string& name,
540                       std::function<void()> fn) override {
541     return target_->StartThread(thread_options, name, fn);
542   }
GetCurrentThreadId()543   int32 GetCurrentThreadId() override { return target_->GetCurrentThreadId(); }
GetCurrentThreadName(std::string * name)544   bool GetCurrentThreadName(std::string* name) override {
545     return target_->GetCurrentThreadName(name);
546   }
SchedClosure(std::function<void ()> closure)547   void SchedClosure(std::function<void()> closure) override {
548     target_->SchedClosure(closure);
549   }
SchedClosureAfter(int64_t micros,std::function<void ()> closure)550   void SchedClosureAfter(int64_t micros,
551                          std::function<void()> closure) override {
552     target_->SchedClosureAfter(micros, closure);
553   }
LoadDynamicLibrary(const char * library_filename,void ** handle)554   Status LoadDynamicLibrary(const char* library_filename,
555                             void** handle) override {
556     return target_->LoadDynamicLibrary(library_filename, handle);
557   }
GetSymbolFromLibrary(void * handle,const char * symbol_name,void ** symbol)558   Status GetSymbolFromLibrary(void* handle, const char* symbol_name,
559                               void** symbol) override {
560     return target_->GetSymbolFromLibrary(handle, symbol_name, symbol);
561   }
FormatLibraryFileName(const std::string & name,const std::string & version)562   std::string FormatLibraryFileName(const std::string& name,
563                                     const std::string& version) override {
564     return target_->FormatLibraryFileName(name, version);
565   }
566 
GetRunfilesDir()567   std::string GetRunfilesDir() override { return target_->GetRunfilesDir(); }
568 
569  private:
GetLocalTempDirectories(std::vector<string> * list)570   void GetLocalTempDirectories(std::vector<string>* list) override {
571     target_->GetLocalTempDirectories(list);
572   }
573 
574   Env* target_;
575 };
576 
577 /// Represents a thread used to run a TensorFlow function.
578 class Thread {
579  public:
Thread()580   Thread() {}
581 
582   /// Blocks until the thread of control stops running.
583   virtual ~Thread();
584 
585  private:
586   TF_DISALLOW_COPY_AND_ASSIGN(Thread);
587 };
588 
589 /// \brief Cross-platform setenv.
590 ///
591 /// Since setenv() is not available on windows, we provide an
592 /// alternative with platform specific implementations here.
593 int setenv(const char* name, const char* value, int overwrite);
594 
595 /// Cross-platform unsetenv.
596 int unsetenv(const char* name);
597 
598 /// \brief Options to configure a Thread.
599 ///
600 /// Note that the options are all hints, and the
601 /// underlying implementation may choose to ignore it.
602 struct ThreadOptions {
603   /// Thread stack size to use (in bytes).
604   size_t stack_size = 0;  // 0: use system default value
605   /// Guard area size to use near thread stacks to use (in bytes)
606   size_t guard_size = 0;  // 0: use system default value
607   int numa_node = port::kNUMANoAffinity;
608 };
609 
610 /// A utility routine: copy contents of `src` in file system `src_fs`
611 /// to `target` in file system `target_fs`.
612 Status FileSystemCopyFile(FileSystem* src_fs, const std::string& src,
613                           FileSystem* target_fs, const std::string& target);
614 
615 /// A utility routine: reads contents of named file into `*data`
616 Status ReadFileToString(Env* env, const std::string& fname, std::string* data);
617 
618 /// A utility routine: write contents of `data` to file named `fname`
619 /// (overwriting existing contents, if any).
620 Status WriteStringToFile(Env* env, const std::string& fname,
621                          const StringPiece& data);
622 
623 /// Write binary representation of "proto" to the named file.
624 Status WriteBinaryProto(Env* env, const std::string& fname,
625                         const protobuf::MessageLite& proto);
626 
627 /// Reads contents of named file and parse as binary encoded proto data
628 /// and store into `*proto`.
629 Status ReadBinaryProto(Env* env, const std::string& fname,
630                        protobuf::MessageLite* proto);
631 
632 /// Write the text representation of "proto" to the named file.
WriteTextProto(Env *,const std::string &,const protobuf::MessageLite &)633 inline Status WriteTextProto(Env* /* env */, const std::string& /* fname */,
634                              const protobuf::MessageLite& /* proto */) {
635   return errors::Unimplemented("Can't write text protos with protolite.");
636 }
637 Status WriteTextProto(Env* env, const std::string& fname,
638                       const protobuf::Message& proto);
639 
640 /// Read contents of named file and parse as text encoded proto data
641 /// and store into `*proto`.
ReadTextProto(Env *,const std::string &,protobuf::MessageLite *)642 inline Status ReadTextProto(Env* /* env */, const std::string& /* fname */,
643                             protobuf::MessageLite* /* proto */) {
644   return errors::Unimplemented("Can't parse text protos with protolite.");
645 }
646 Status ReadTextProto(Env* env, const std::string& fname,
647                      protobuf::Message* proto);
648 
649 /// Read contents of named file and parse as either text or binary encoded proto
650 /// data and store into `*proto`.
651 Status ReadTextOrBinaryProto(Env* env, const std::string& fname,
652                              protobuf::Message* proto);
653 Status ReadTextOrBinaryProto(Env* env, const std::string& fname,
654                              protobuf::MessageLite* proto);
655 
656 // START_SKIP_DOXYGEN
657 
658 // The following approach to register filesystems is deprecated and will be
659 // replaced with modular filesystem plugins registration.
660 // TODO(b/139060984): After all filesystems are converted, remove this.
661 namespace register_file_system {
662 
663 template <typename Factory>
664 struct Register {
RegisterRegister665   Register(Env* env, const std::string& scheme, bool try_modular_filesystems) {
666     // TODO(yongtang): Remove legacy file system registration for hdfs/s3/gcs
667     // after TF 2.6+.
668     if (try_modular_filesystems) {
669       const char* env_value = getenv("TF_USE_MODULAR_FILESYSTEM");
670       string load_plugin = env_value ? absl::AsciiStrToLower(env_value) : "";
671       if (load_plugin == "true" || load_plugin == "1") {
672         // We don't register the static filesystem and wait for SIG IO one
673         LOG(WARNING) << "Using modular file system for '" << scheme << "'."
674                      << " Please switch to tensorflow-io"
675                      << " (https://github.com/tensorflow/io) for file system"
676                      << " support of '" << scheme << "'.";
677         return;
678       }
679       // If the envvar is missing or not "true"/"1", then fall back to legacy
680       // implementation to be backwards compatible.
681     }
682     // TODO(b/32704451): Don't just ignore the ::tensorflow::Status object!
683     env->RegisterFileSystem(scheme, []() -> FileSystem* { return new Factory; })
684         .IgnoreError();
685   }
686 };
687 
688 }  // namespace register_file_system
689 
690 // END_SKIP_DOXYGEN
691 
692 }  // namespace tensorflow
693 
694 // Register a FileSystem implementation for a scheme. Files with names that have
695 // "scheme://" prefixes are routed to use this implementation.
696 #define REGISTER_FILE_SYSTEM_ENV(env, scheme, factory, modular) \
697   REGISTER_FILE_SYSTEM_UNIQ_HELPER(__COUNTER__, env, scheme, factory, modular)
698 #define REGISTER_FILE_SYSTEM_UNIQ_HELPER(ctr, env, scheme, factory, modular) \
699   REGISTER_FILE_SYSTEM_UNIQ(ctr, env, scheme, factory, modular)
700 #define REGISTER_FILE_SYSTEM_UNIQ(ctr, env, scheme, factory, modular)        \
701   static ::tensorflow::register_file_system::Register<factory>               \
702       register_ff##ctr TF_ATTRIBUTE_UNUSED =                                 \
703           ::tensorflow::register_file_system::Register<factory>(env, scheme, \
704                                                                 modular)
705 
706 #define REGISTER_FILE_SYSTEM(scheme, factory)                             \
707   REGISTER_FILE_SYSTEM_ENV(::tensorflow::Env::Default(), scheme, factory, \
708                            false);
709 
710 #define REGISTER_LEGACY_FILE_SYSTEM(scheme, factory) \
711   REGISTER_FILE_SYSTEM_ENV(::tensorflow::Env::Default(), scheme, factory, true);
712 
713 #endif  // TENSORFLOW_CORE_PLATFORM_ENV_H_
714