1 /* Copyright 2018 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 #include "tensorflow/c/env.h"
17
18 #include "tensorflow/c/c_api_internal.h"
19 #include "tensorflow/c/tf_status_helper.h"
20 #include "tensorflow/core/platform/env.h"
21 #include "tensorflow/core/platform/types.h"
22
23 struct TF_StringStream {
24 std::vector<::tensorflow::string>* list;
25 size_t position;
26 };
27
TF_CreateDir(const char * dirname,TF_Status * status)28 void TF_CreateDir(const char* dirname, TF_Status* status) {
29 TF_SetStatus(status, TF_OK, "");
30 ::tensorflow::Set_TF_Status_from_Status(
31 status, ::tensorflow::Env::Default()->CreateDir(dirname));
32 }
33
TF_DeleteDir(const char * dirname,TF_Status * status)34 void TF_DeleteDir(const char* dirname, TF_Status* status) {
35 TF_SetStatus(status, TF_OK, "");
36 ::tensorflow::Set_TF_Status_from_Status(
37 status, ::tensorflow::Env::Default()->DeleteDir(dirname));
38 }
39
TF_DeleteRecursively(const char * dirname,int64_t * undeleted_file_count,int64_t * undeleted_dir_count,TF_Status * status)40 void TF_DeleteRecursively(const char* dirname, int64_t* undeleted_file_count,
41 int64_t* undeleted_dir_count, TF_Status* status) {
42 ::tensorflow::int64 f, d;
43
44 TF_SetStatus(status, TF_OK, "");
45 ::tensorflow::Set_TF_Status_from_Status(
46 status, ::tensorflow::Env::Default()->DeleteRecursively(dirname, &f, &d));
47 *undeleted_file_count = f;
48 *undeleted_dir_count = d;
49 }
50
TF_FileStat(const char * filename,TF_FileStatistics * stats,TF_Status * status)51 void TF_FileStat(const char* filename, TF_FileStatistics* stats,
52 TF_Status* status) {
53 ::tensorflow::FileStatistics cc_stats;
54 TF_SetStatus(status, TF_OK, "");
55 ::tensorflow::Status s =
56 ::tensorflow::Env::Default()->Stat(filename, &cc_stats);
57 ::tensorflow::Set_TF_Status_from_Status(status, s);
58 if (s.ok()) {
59 stats->length = cc_stats.length;
60 stats->mtime_nsec = cc_stats.mtime_nsec;
61 stats->is_directory = cc_stats.is_directory;
62 }
63 }
64
TF_NewWritableFile(const char * filename,TF_WritableFileHandle ** handle,TF_Status * status)65 void TF_NewWritableFile(const char* filename, TF_WritableFileHandle** handle,
66 TF_Status* status) {
67 std::unique_ptr<::tensorflow::WritableFile> f;
68 TF_SetStatus(status, TF_OK, "");
69 ::tensorflow::Status s =
70 ::tensorflow::Env::Default()->NewWritableFile(filename, &f);
71 ::tensorflow::Set_TF_Status_from_Status(status, s);
72
73 if (s.ok()) {
74 *handle = reinterpret_cast<TF_WritableFileHandle*>(f.release());
75 }
76 }
77
TF_CloseWritableFile(TF_WritableFileHandle * handle,TF_Status * status)78 void TF_CloseWritableFile(TF_WritableFileHandle* handle, TF_Status* status) {
79 auto* cc_file = reinterpret_cast<::tensorflow::WritableFile*>(handle);
80 TF_SetStatus(status, TF_OK, "");
81 ::tensorflow::Set_TF_Status_from_Status(status, cc_file->Close());
82 delete cc_file;
83 }
84
TF_SyncWritableFile(TF_WritableFileHandle * handle,TF_Status * status)85 void TF_SyncWritableFile(TF_WritableFileHandle* handle, TF_Status* status) {
86 auto* cc_file = reinterpret_cast<::tensorflow::WritableFile*>(handle);
87 TF_SetStatus(status, TF_OK, "");
88 ::tensorflow::Set_TF_Status_from_Status(status, cc_file->Sync());
89 }
90
TF_FlushWritableFile(TF_WritableFileHandle * handle,TF_Status * status)91 void TF_FlushWritableFile(TF_WritableFileHandle* handle, TF_Status* status) {
92 auto* cc_file = reinterpret_cast<::tensorflow::WritableFile*>(handle);
93 TF_SetStatus(status, TF_OK, "");
94 ::tensorflow::Set_TF_Status_from_Status(status, cc_file->Flush());
95 }
96
TF_AppendWritableFile(TF_WritableFileHandle * handle,const char * data,size_t length,TF_Status * status)97 void TF_AppendWritableFile(TF_WritableFileHandle* handle, const char* data,
98 size_t length, TF_Status* status) {
99 auto* cc_file = reinterpret_cast<::tensorflow::WritableFile*>(handle);
100 TF_SetStatus(status, TF_OK, "");
101 ::tensorflow::Set_TF_Status_from_Status(
102 status, cc_file->Append(::tensorflow::StringPiece{data, length}));
103 }
104
TF_DeleteFile(const char * filename,TF_Status * status)105 void TF_DeleteFile(const char* filename, TF_Status* status) {
106 TF_SetStatus(status, TF_OK, "");
107 ::tensorflow::Set_TF_Status_from_Status(
108 status, ::tensorflow::Env::Default()->DeleteFile(filename));
109 }
110
TF_StringStreamNext(TF_StringStream * list,const char ** result)111 bool TF_StringStreamNext(TF_StringStream* list, const char** result) {
112 if (list->position >= list->list->size()) {
113 *result = nullptr;
114 return false;
115 }
116
117 *result = list->list->at(list->position++).c_str();
118 return true;
119 }
120
TF_StringStreamDone(TF_StringStream * list)121 void TF_StringStreamDone(TF_StringStream* list) {
122 delete list->list;
123 delete list;
124 }
TF_GetChildren(const char * dirname,TF_Status * status)125 TF_StringStream* TF_GetChildren(const char* dirname, TF_Status* status) {
126 auto* children = new std::vector<::tensorflow::string>;
127
128 TF_SetStatus(status, TF_OK, "");
129 ::tensorflow::Set_TF_Status_from_Status(
130 status, ::tensorflow::Env::Default()->GetChildren(dirname, children));
131
132 auto* list = new TF_StringStream;
133 list->list = children;
134 list->position = 0;
135 return list;
136 }
137
TF_GetLocalTempDirectories()138 TF_StringStream* TF_GetLocalTempDirectories() {
139 auto* tmpdirs = new std::vector<::tensorflow::string>;
140
141 ::tensorflow::Env::Default()->GetLocalTempDirectories(tmpdirs);
142
143 auto* list = new TF_StringStream;
144 list->list = tmpdirs;
145 list->position = 0;
146 return list;
147 }
148
TF_NowNanos(void)149 TF_CAPI_EXPORT extern uint64_t TF_NowNanos(void) {
150 return ::tensorflow::Env::Default()->NowNanos();
151 }
152
153 // Returns the number of microseconds since the Unix epoch.
TF_NowMicros(void)154 TF_CAPI_EXPORT extern uint64_t TF_NowMicros(void) {
155 return ::tensorflow::Env::Default()->NowMicros();
156 }
157
158 // Returns the number of seconds since the Unix epoch.
TF_NowSeconds(void)159 TF_CAPI_EXPORT extern uint64_t TF_NowSeconds(void) {
160 return ::tensorflow::Env::Default()->NowSeconds();
161 }
162
TF_DefaultThreadOptions(TF_ThreadOptions * options)163 void TF_DefaultThreadOptions(TF_ThreadOptions* options) {
164 options->stack_size = 0;
165 options->guard_size = 0;
166 options->numa_node = -1;
167 }
168
TF_StartThread(const TF_ThreadOptions * options,const char * thread_name,void (* work_func)(void *),void * param)169 TF_Thread* TF_StartThread(const TF_ThreadOptions* options,
170 const char* thread_name, void (*work_func)(void*),
171 void* param) {
172 ::tensorflow::ThreadOptions cc_options;
173 cc_options.stack_size = options->stack_size;
174 cc_options.guard_size = options->guard_size;
175 cc_options.numa_node = options->numa_node;
176 return reinterpret_cast<TF_Thread*>(::tensorflow::Env::Default()->StartThread(
177 cc_options, thread_name, [=]() { (*work_func)(param); }));
178 }
179
TF_JoinThread(TF_Thread * thread)180 void TF_JoinThread(TF_Thread* thread) {
181 // ::tensorflow::Thread joins on destruction
182 delete reinterpret_cast<::tensorflow::Thread*>(thread);
183 }
184