12

I am not able to find any examples about how to load a graph with tensorflow.so and c_api.h in C++. I read the c_api.h, however the ReadBinaryProto function was not in it. How can I load a graph without the ReadBinaryProto function?

wolfcastle
  • 5,850
  • 3
  • 33
  • 46
Misaya.Z
  • 165
  • 1
  • 1
  • 9
  • Why are you trying to use C API in C++ instead of the native C++ [library](https://www.tensorflow.org/api_docs/cc/namespace/tensorflow#readbinaryproto)? – Grisha Levit Jan 17 '17 at 03:07
  • 3
    In fact, I want to use c++ api of tensorflow to load graph outside tensorflow project – Misaya.Z Jan 17 '17 at 07:07
  • 4
    @GrishaLevit maybe because the horrible release pipeline of Tensorflow, making it nearly impossible to deploy in a product without some safety compromises (pip install) – Mehdi Sep 18 '18 at 14:49

2 Answers2

23

If you're using C++, you might want to use the C++ API instead. The label image example would probably be a good sample to help you start.

If you really want to use just the C API, use TF_GraphImportGraphDef to load a graph. Note that the C API isn't particularly convenient to use (it is intended to build bindings in other languages such as Go, Java, Rust, Haskell etc.) For example:

#include <stdio.h>                                                                        
#include <stdlib.h>                                                                       
#include <tensorflow/c/c_api.h>                                                           

TF_Buffer* read_file(const char* file);                                                   

void free_buffer(void* data, size_t length) {                                             
        free(data);                                                                       
}                                                                                         

int main() {                                                                              
  // Graph definition from unzipped https://storage.googleapis.com/download.tensorflow.org/models/inception5h.zip
  // which is used in the Go, Java and Android examples                                   
  TF_Buffer* graph_def = read_file("tensorflow_inception_graph.pb");                      
  TF_Graph* graph = TF_NewGraph();

  // Import graph_def into graph                                                          
  TF_Status* status = TF_NewStatus();                                                     
  TF_ImportGraphDefOptions* opts = TF_NewImportGraphDefOptions();                         
  TF_GraphImportGraphDef(graph, graph_def, opts, status);
  TF_DeleteImportGraphDefOptions(opts);
  if (TF_GetCode(status) != TF_OK) {
          fprintf(stderr, "ERROR: Unable to import graph %s", TF_Message(status));        
          return 1;
  }       
  fprintf(stdout, "Successfully imported graph");                                         
  TF_DeleteStatus(status);
  TF_DeleteBuffer(graph_def);                                                             

  // Use the graph                                                                        
  TF_DeleteGraph(graph);                                                                  
  return 0;
} 

TF_Buffer* read_file(const char* file) {                                                  
  FILE *f = fopen(file, "rb");
  fseek(f, 0, SEEK_END);
  long fsize = ftell(f);                                                                  
  fseek(f, 0, SEEK_SET);  //same as rewind(f);                                            

  void* data = malloc(fsize);                                                             
  fread(data, fsize, 1, f);
  fclose(f);

  TF_Buffer* buf = TF_NewBuffer();                                                        
  buf->data = data;
  buf->length = fsize;                                                                    
  buf->data_deallocator = free_buffer;                                                    
  return buf;
} 
ash
  • 6,681
  • 3
  • 18
  • 30
  • 3
    Thank you for your answer. I want to use C++ API outside tensorflow project. The "label image example" is build inside tensorflow project. How can I use C++ API outside tensorflow? what are the header files should I include? – Misaya.Z Jan 17 '17 at 07:11
  • 3
    @ash using the C Api might be bad, but it is unfortunately the only way to run inference on target systems without having to install the full tensorflow and having to use pip. ahead of time compilation is also another way but it still doesn't support a lot of modules and the documentation is nearly inexistent. – Mehdi Sep 18 '18 at 14:52
  • If you have to use the C API I recommend you to use [cppflow](https://github.com/serizba/cppflow), a C++ wrapper of the TensorFlow C API. By using it you can avoid the headache of using mallocs and free. – Sergio Izquierdo May 16 '19 at 11:30
  • You can checkout this example on Github. https://github.com/AmirulOm/tensorflow_capi_sample – shioko Jan 12 '21 at 07:13
1

The previous answer is your main option if you are wanting to use it outside of the TensorFlow project (and consequently not build with Bazel). You need to load it from the c_api.h with TF_GraphImportDef, I recommend training and doing testing in Python and then exporting the model/graph for use with C++/C Api when you have finished.

Luke Greenwood
  • 451
  • 3
  • 5
  • [Related](https://stackoverflow.com/questions/55558207/exporting-a-network-with-python-and-importing-in-c-without-bazel) – BlueMoon93 Apr 07 '19 at 10:57