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