| /* Copyright 2018 The TensorFlow Authors. All Rights Reserved. |
| |
| Licensed under the Apache License, Version 2.0 (the "License"); |
| you may not use this file except in compliance with the License. |
| You may obtain a copy of the License at |
| |
| http://www.apache.org/licenses/LICENSE-2.0 |
| |
| Unless required by applicable law or agreed to in writing, software |
| distributed under the License is distributed on an "AS IS" BASIS, |
| WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
| See the License for the specific language governing permissions and |
| limitations under the License. |
| ==============================================================================*/ |
| |
| #include "tensorflow/c/env.h" |
| |
| #include "tensorflow/c/c_api_macros.h" |
| #include "tensorflow/c/tf_status.h" |
| #include "tensorflow/c/tf_status_helper.h" |
| #include "tensorflow/core/platform/env.h" |
| #include "tensorflow/core/platform/path.h" |
| #include "tensorflow/core/platform/types.h" |
| |
| struct TF_StringStream { |
| std::vector<::tensorflow::string>* list; |
| size_t position; |
| }; |
| |
| void TF_CreateDir(const char* dirname, TF_Status* status) { |
| TF_SetStatus(status, TF_OK, ""); |
| ::tensorflow::Set_TF_Status_from_Status( |
| status, ::tensorflow::Env::Default()->CreateDir(dirname)); |
| } |
| |
| void TF_DeleteDir(const char* dirname, TF_Status* status) { |
| TF_SetStatus(status, TF_OK, ""); |
| ::tensorflow::Set_TF_Status_from_Status( |
| status, ::tensorflow::Env::Default()->DeleteDir(dirname)); |
| } |
| |
| void TF_DeleteRecursively(const char* dirname, int64_t* undeleted_file_count, |
| int64_t* undeleted_dir_count, TF_Status* status) { |
| ::int64_t f, d; |
| |
| TF_SetStatus(status, TF_OK, ""); |
| ::tensorflow::Set_TF_Status_from_Status( |
| status, ::tensorflow::Env::Default()->DeleteRecursively(dirname, &f, &d)); |
| *undeleted_file_count = f; |
| *undeleted_dir_count = d; |
| } |
| |
| void TF_FileStat(const char* filename, TF_FileStatistics* stats, |
| TF_Status* status) { |
| ::tensorflow::FileStatistics cc_stats; |
| TF_SetStatus(status, TF_OK, ""); |
| ::tensorflow::Status s = |
| ::tensorflow::Env::Default()->Stat(filename, &cc_stats); |
| ::tensorflow::Set_TF_Status_from_Status(status, s); |
| if (s.ok()) { |
| stats->length = cc_stats.length; |
| stats->mtime_nsec = cc_stats.mtime_nsec; |
| stats->is_directory = cc_stats.is_directory; |
| } |
| } |
| |
| void TF_NewWritableFile(const char* filename, TF_WritableFileHandle** handle, |
| TF_Status* status) { |
| std::unique_ptr<::tensorflow::WritableFile> f; |
| TF_SetStatus(status, TF_OK, ""); |
| ::tensorflow::Status s = |
| ::tensorflow::Env::Default()->NewWritableFile(filename, &f); |
| ::tensorflow::Set_TF_Status_from_Status(status, s); |
| |
| if (s.ok()) { |
| *handle = reinterpret_cast<TF_WritableFileHandle*>(f.release()); |
| } |
| } |
| |
| void TF_CloseWritableFile(TF_WritableFileHandle* handle, TF_Status* status) { |
| auto* cc_file = reinterpret_cast<::tensorflow::WritableFile*>(handle); |
| TF_SetStatus(status, TF_OK, ""); |
| ::tensorflow::Set_TF_Status_from_Status(status, cc_file->Close()); |
| delete cc_file; |
| } |
| |
| void TF_SyncWritableFile(TF_WritableFileHandle* handle, TF_Status* status) { |
| auto* cc_file = reinterpret_cast<::tensorflow::WritableFile*>(handle); |
| TF_SetStatus(status, TF_OK, ""); |
| ::tensorflow::Set_TF_Status_from_Status(status, cc_file->Sync()); |
| } |
| |
| void TF_FlushWritableFile(TF_WritableFileHandle* handle, TF_Status* status) { |
| auto* cc_file = reinterpret_cast<::tensorflow::WritableFile*>(handle); |
| TF_SetStatus(status, TF_OK, ""); |
| ::tensorflow::Set_TF_Status_from_Status(status, cc_file->Flush()); |
| } |
| |
| void TF_AppendWritableFile(TF_WritableFileHandle* handle, const char* data, |
| size_t length, TF_Status* status) { |
| auto* cc_file = reinterpret_cast<::tensorflow::WritableFile*>(handle); |
| TF_SetStatus(status, TF_OK, ""); |
| ::tensorflow::Set_TF_Status_from_Status( |
| status, cc_file->Append(::tensorflow::StringPiece{data, length})); |
| } |
| |
| void TF_DeleteFile(const char* filename, TF_Status* status) { |
| TF_SetStatus(status, TF_OK, ""); |
| ::tensorflow::Set_TF_Status_from_Status( |
| status, ::tensorflow::Env::Default()->DeleteFile(filename)); |
| } |
| |
| bool TF_StringStreamNext(TF_StringStream* list, const char** result) { |
| if (list->position >= list->list->size()) { |
| *result = nullptr; |
| return false; |
| } |
| |
| *result = list->list->at(list->position++).c_str(); |
| return true; |
| } |
| |
| void TF_StringStreamDone(TF_StringStream* list) { |
| delete list->list; |
| delete list; |
| } |
| TF_StringStream* TF_GetChildren(const char* dirname, TF_Status* status) { |
| auto* children = new std::vector<::tensorflow::string>; |
| |
| TF_SetStatus(status, TF_OK, ""); |
| ::tensorflow::Set_TF_Status_from_Status( |
| status, ::tensorflow::Env::Default()->GetChildren(dirname, children)); |
| |
| auto* list = new TF_StringStream; |
| list->list = children; |
| list->position = 0; |
| return list; |
| } |
| |
| TF_StringStream* TF_GetLocalTempDirectories() { |
| auto* tmpdirs = new std::vector<::tensorflow::string>; |
| |
| ::tensorflow::Env::Default()->GetLocalTempDirectories(tmpdirs); |
| |
| auto* list = new TF_StringStream; |
| list->list = tmpdirs; |
| list->position = 0; |
| return list; |
| } |
| |
| char* TF_GetTempFileName(const char* extension) { |
| return strdup(::tensorflow::io::GetTempFilename(extension).c_str()); |
| } |
| |
| TF_CAPI_EXPORT extern uint64_t TF_NowNanos(void) { |
| return ::tensorflow::Env::Default()->NowNanos(); |
| } |
| |
| // Returns the number of microseconds since the Unix epoch. |
| TF_CAPI_EXPORT extern uint64_t TF_NowMicros(void) { |
| return ::tensorflow::Env::Default()->NowMicros(); |
| } |
| |
| // Returns the number of seconds since the Unix epoch. |
| TF_CAPI_EXPORT extern uint64_t TF_NowSeconds(void) { |
| return ::tensorflow::Env::Default()->NowSeconds(); |
| } |
| |
| void TF_DefaultThreadOptions(TF_ThreadOptions* options) { |
| options->stack_size = 0; |
| options->guard_size = 0; |
| options->numa_node = -1; |
| } |
| |
| TF_Thread* TF_StartThread(const TF_ThreadOptions* options, |
| const char* thread_name, void (*work_func)(void*), |
| void* param) { |
| ::tensorflow::ThreadOptions cc_options; |
| cc_options.stack_size = options->stack_size; |
| cc_options.guard_size = options->guard_size; |
| cc_options.numa_node = options->numa_node; |
| return reinterpret_cast<TF_Thread*>(::tensorflow::Env::Default()->StartThread( |
| cc_options, thread_name, [=]() { (*work_func)(param); })); |
| } |
| |
| void TF_JoinThread(TF_Thread* thread) { |
| // ::tensorflow::Thread joins on destruction |
| delete reinterpret_cast<::tensorflow::Thread*>(thread); |
| } |
| |
| void* TF_LoadSharedLibrary(const char* library_filename, TF_Status* status) { |
| void* handle = nullptr; |
| TF_SetStatus(status, TF_OK, ""); |
| ::tensorflow::Set_TF_Status_from_Status( |
| status, ::tensorflow::Env::Default()->LoadDynamicLibrary(library_filename, |
| &handle)); |
| return handle; |
| } |
| |
| void* TF_GetSymbolFromLibrary(void* handle, const char* symbol_name, |
| TF_Status* status) { |
| void* symbol = nullptr; |
| TF_SetStatus(status, TF_OK, ""); |
| ::tensorflow::Set_TF_Status_from_Status( |
| status, ::tensorflow::Env::Default()->GetSymbolFromLibrary( |
| handle, symbol_name, &symbol)); |
| return symbol; |
| } |