Public Member Functions | Static Public Member Functions | Public Attributes | Private Member Functions | Private Attributes | List of all members
tf::Graph Class Reference

#include <tf_graph.h>

Public Member Functions

 ~Graph ()
 
std::vector< float > run (const std::vector< std::vector< float > > &x)
 
std::vector< std::vector< std::vector< float > > > run (const std::vector< std::vector< std::vector< std::vector< float > > > > &x, long long int samples=-1)
 
std::vector< std::vector< std::vector< float > > > run (const std::vector< tensorflow::Tensor > &x)
 
 ~Graph ()
 
std::vector< float > run (const std::vector< std::vector< float > > &x)
 
std::vector< std::vector< float > > run (const std::vector< std::vector< std::vector< std::vector< float > > > > &x, long long int samples=-1)
 
std::vector< std::vector< float > > run (const tensorflow::Tensor &x)
 

Static Public Member Functions

static std::unique_ptr< Graphcreate (const char *graph_file_name, const std::vector< std::string > &outputs={}, int ninputs=1, int noutputs=1)
 
static std::unique_ptr< Graphcreate (const char *graph_file_name, const std::vector< std::string > &outputs={})
 

Public Attributes

int n_inputs = 1
 
int n_outputs = 1
 

Private Member Functions

 Graph (const char *graph_file_name, const std::vector< std::string > &outputs, bool &success, int ninputs, int noutputs)
 Not-throwing constructor. More...
 
 Graph (const char *graph_file_name, const std::vector< std::string > &outputs, bool &success)
 Not-throwing constructor. More...
 

Private Attributes

tensorflow::Session * fSession
 
std::vector< std::stringfInputNames
 
std::vector< std::stringfOutputNames
 
std::string fInputName
 

Detailed Description

Definition at line 26 of file tf_graph.h.

Constructor & Destructor Documentation

tf::Graph::~Graph ( )

Definition at line 118 of file tf_graph.cc.

119 {
120  if ( ! fSession->Close().ok() ) {
121  std::cout << "tf::Graph::dtor: " << "Close failed." << std::endl;
122  }
123  //fSession->Close();
124  delete fSession;
125 }
tensorflow::Session * fSession
Definition: tf_graph.h:55
QTextStream & endl(QTextStream &s)
tf::Graph::Graph ( const char *  graph_file_name,
const std::vector< std::string > &  outputs,
bool success,
int  ninputs,
int  noutputs 
)
private

Not-throwing constructor.

Definition at line 18 of file tf_graph.cc.

19 {
20  success = false; // until all is done correctly
21 
22  n_inputs = ninputs;
23  n_outputs = noutputs;
24 
25  // Force tf to only use a single core so it doesn't eat batch farms
26  tensorflow::SessionOptions options;
27  tensorflow::ConfigProto &config = options.config;
28  config.set_inter_op_parallelism_threads(1);
29  config.set_intra_op_parallelism_threads(1);
30  config.set_use_per_session_threads(false);
31 
32  auto status = tensorflow::NewSession(options, &fSession);
33  if (!status.ok())
34  {
35  std::cout << status.ToString() << std::endl;
36  return;
37  }
38 
39  tensorflow::GraphDef graph_def;
40  status = tensorflow::ReadBinaryProto(tensorflow::Env::Default(), graph_file_name, &graph_def);
41  if (!status.ok())
42  {
43  std::cout << status.ToString() << std::endl;
44  return;
45  }
46 
47  size_t ng = graph_def.node().size();
48 
49  // fill input names (TODO: generic)
50  for(int i=0; i<n_inputs; ++i)
51  {
52  fInputNames.push_back(graph_def.node()[i].name());
53  }
54 
55  /*
56  std::cout << "Input names: " << std::endl;
57  for(int i=0; i<n_inputs; ++i)
58  std::cout << fInputNames[i] << std::endl;
59  */
60 
61  // last node as output if no specific name provided
62  if (outputs.empty())
63  {
64  for(int i=n_outputs; i>0; --i)
65  {
66  fOutputNames.push_back(graph_def.node()[ng - i].name());
67  }
68 
69  /*
70  std::cout << "Output names: " << std::endl;
71  for(int i=0; i<n_outputs; ++i)
72  std::cout << fOutputNames[i] << std::endl;
73  */
74  }
75  else // or last nodes with names containing provided strings
76  {
78  for (size_t n = 0; n < ng; ++n)
79  {
80  name = graph_def.node()[n].name();
81  auto pos = name.find("/");
82  if (pos != std::string::npos) { basename = name.substr(0, pos); }
83  else { continue; }
84 
85  bool found = false;
86  for (const auto & s : outputs)
87  {
88  if (name.find(s) != std::string::npos) { found = true; break; }
89  }
90  if (found)
91  {
92  if (!last.empty() && (basename != current))
93  {
94  fOutputNames.push_back(last);
95  }
96  current = basename;
97  last = name;
98  }
99  }
100  if (!last.empty()) { fOutputNames.push_back(last); }
101  }
102  if (fOutputNames.empty())
103  {
104  std::cout << "Output nodes not found in the graph." << std::endl;
105  return;
106  }
107 
108  status = fSession->Create(graph_def);
109  if (!status.ok())
110  {
111  std::cout << status.ToString() << std::endl;
112  return;
113  }
114 
115  success = true; // ok, graph loaded from the file
116 }
static QCString name
Definition: declinfo.cpp:673
std::string string
Definition: nybbler.cc:12
tensorflow::Session * fSession
Definition: tf_graph.h:55
int n_outputs
Definition: tf_graph.h:30
static Config * config
Definition: config.cpp:1054
std::void_t< T > n
static Entry * current
std::vector< std::string > fOutputNames
Definition: tf_graph.h:58
int n_inputs
Definition: tf_graph.h:29
std::vector< std::string > fInputNames
Definition: tf_graph.h:57
static QCString * s
Definition: config.cpp:1042
QTextStream & endl(QTextStream &s)
tf::Graph::~Graph ( )
tf::Graph::Graph ( const char *  graph_file_name,
const std::vector< std::string > &  outputs,
bool success 
)
private

Not-throwing constructor.

Definition at line 18 of file tf_graph.cc.

19 {
20  success = false; // until all is done correctly
21 
22  // Force tf to only use a single core so it doesn't eat batch farms
23  tensorflow::SessionOptions options;
24  tensorflow::ConfigProto &config = options.config;
25  config.set_inter_op_parallelism_threads(1);
26  config.set_intra_op_parallelism_threads(1);
27  config.set_use_per_session_threads(false);
28 
29  auto status = tensorflow::NewSession(options, &fSession);
30  if (!status.ok())
31  {
32  std::cout << status.ToString() << std::endl;
33  return;
34  }
35 
36  tensorflow::GraphDef graph_def;
37  status = tensorflow::ReadBinaryProto(tensorflow::Env::Default(), graph_file_name, &graph_def);
38  if (!status.ok())
39  {
40  std::cout << status.ToString() << std::endl;
41  return;
42  }
43 
44  size_t ng = graph_def.node().size();
45  fInputName = graph_def.node()[0].name();
46 
47  // last node as output if no specific name provided
48  if (outputs.empty()) { fOutputNames.push_back(graph_def.node()[ng - 1].name()); }
49  else // or last nodes with names containing provided strings
50  {
52  for (size_t n = 0; n < ng; ++n)
53  {
54  name = graph_def.node()[n].name();
55  auto pos = name.find("/");
56  if (pos != std::string::npos) { basename = name.substr(0, pos); }
57  else { continue; }
58 
59  bool found = false;
60  for (const auto & s : outputs)
61  {
62  if (name.find(s) != std::string::npos) { found = true; break; }
63  }
64  if (found)
65  {
66  if (!last.empty() && (basename != current))
67  {
68  fOutputNames.push_back(last);
69  }
70  current = basename;
71  last = name;
72  }
73  }
74  if (!last.empty()) { fOutputNames.push_back(last); }
75  }
76  if (fOutputNames.empty())
77  {
78  std::cout << "Output nodes not found in the graph." << std::endl;
79  return;
80  }
81 
82  status = fSession->Create(graph_def);
83  if (!status.ok())
84  {
85  std::cout << status.ToString() << std::endl;
86  return;
87  }
88 
89  success = true; // ok, graph loaded from the file
90 }
static QCString name
Definition: declinfo.cpp:673
std::string string
Definition: nybbler.cc:12
std::string fInputName
Definition: tf_graph.h:53
tensorflow::Session * fSession
Definition: tf_graph.h:55
static Config * config
Definition: config.cpp:1054
std::void_t< T > n
static Entry * current
std::vector< std::string > fOutputNames
Definition: tf_graph.h:58
static QCString * s
Definition: config.cpp:1042
QTextStream & endl(QTextStream &s)

Member Function Documentation

static std::unique_ptr<Graph> tf::Graph::create ( const char *  graph_file_name,
const std::vector< std::string > &  outputs = {} 
)
inlinestatic

Definition at line 29 of file tf_graph.h.

29  {})
30  {
31  bool success;
32  std::unique_ptr<Graph> ptr(new Graph(graph_file_name, outputs, success));
33  if (success) { return ptr; }
34  else { return nullptr; }
35  }
Graph(const char *graph_file_name, const std::vector< std::string > &outputs, bool &success, int ninputs, int noutputs)
Not-throwing constructor.
Definition: tf_graph.cc:18
static std::unique_ptr<Graph> tf::Graph::create ( const char *  graph_file_name,
const std::vector< std::string > &  outputs = {},
int  ninputs = 1,
int  noutputs = 1 
)
inlinestatic

Definition at line 32 of file tf_graph.h.

32  {}, int ninputs = 1, int noutputs = 1)
33  {
34  bool success;
35  std::unique_ptr<Graph> ptr(new Graph(graph_file_name, outputs, success, ninputs, noutputs));
36  if (success) { return ptr; }
37  else { return nullptr; }
38  }
Graph(const char *graph_file_name, const std::vector< std::string > &outputs, bool &success, int ninputs, int noutputs)
Not-throwing constructor.
Definition: tf_graph.cc:18
std::vector<float> tf::Graph::run ( const std::vector< std::vector< float > > &  x)
std::vector< float > tf::Graph::run ( const std::vector< std::vector< float > > &  x)

Definition at line 99 of file tf_graph.cc.

100 {
101  if (x.empty() || x.front().empty()) { return std::vector<float>(); }
102 
103  long long int rows = x.size(), cols = x.front().size();
104 
105  tensorflow::Tensor _x(tensorflow::DT_FLOAT, tensorflow::TensorShape({ 1, rows, cols, 1 }));
106  auto input_map = _x.tensor<float, 4>();
107 
108  for (long long int r = 0; r < rows; ++r) {
109  const auto & row = x[r];
110  for (long long int c = 0; c < cols; ++c) {
111  input_map(0, r, c, 0) = row[c];
112  }
113  }
114 
115  auto result = run(_x);
116  if (!result.empty()) { return result.front(); }
117  else { return std::vector<float>(); }
118 }
static QCString result
std::vector< float > run(const std::vector< std::vector< float > > &x)
Definition: tf_graph.cc:99
std::vector< std::vector<float> > tf::Graph::run ( const std::vector< std::vector< std::vector< std::vector< float > > > > &  x,
long long int  samples = -1 
)
std::vector< std::vector< float > > tf::Graph::run ( const tensorflow::Tensor &  x)

Definition at line 154 of file tf_graph.cc.

155 {
156  std::vector< std::pair<std::string, tensorflow::Tensor> > inputs = {
157  { fInputName, x }
158  };
159 
160  //std::cout << "run session" << std::endl;
161 
162  std::vector<tensorflow::Tensor> outputs;
163  auto status = fSession->Run(inputs, fOutputNames, {}, &outputs);
164 
165  //std::cout << "out size " << outputs.size() << std::endl;
166 
167  if (status.ok())
168  {
169  size_t samples = 0, nouts = 0;
170  for (size_t o = 0; o < outputs.size(); ++o)
171  {
172  if (o == 0) { samples = outputs[o].dim_size(0); }
173  else if ((int)samples != outputs[o].dim_size(0))
174  {
175  throw std::string("TF outputs size inconsistent.");
176  }
177  nouts += outputs[o].dim_size(1);
178  }
179  //std::cout << "samples " << samples << " nouts " << nouts << std::endl;
180 
181  std::vector< std::vector< float > > result;
182  result.resize(samples, std::vector< float >(nouts));
183 
184  size_t idx0 = 0;
185  for (size_t o = 0; o < outputs.size(); ++o)
186  {
187  auto output_map = outputs[o].tensor<float, 2>();
188 
189  size_t n = outputs[o].dim_size(1);
190  for (size_t s = 0; s < samples; ++s) {
191  std::vector< float > & vs = result[s];
192  for (size_t i = 0; i < n; ++i) {
193  vs[idx0 + i] = output_map(s, i);
194  }
195  }
196  idx0 += n;
197  }
198  return result;
199  }
200  else
201  {
202  std::cout << status.ToString() << std::endl;
203  return std::vector< std::vector< float > >();
204  }
205 }
static QCString result
std::string string
Definition: nybbler.cc:12
std::string fInputName
Definition: tf_graph.h:53
tensorflow::Session * fSession
Definition: tf_graph.h:55
std::void_t< T > n
std::vector< std::string > fOutputNames
Definition: tf_graph.h:58
list x
Definition: train.py:276
static QCString * s
Definition: config.cpp:1042
QTextStream & endl(QTextStream &s)
std::vector< std::vector< float > > tf::Graph::run ( const std::vector< std::vector< std::vector< std::vector< float > > > > &  x,
long long int  samples = -1 
)

Definition at line 129 of file tf_graph.cc.

132 {
133  if ((samples == 0) || x.empty() || x.front().empty() || x.front().front().empty() || x.front().front().front().empty())
134  return std::vector< std::vector< std::vector<float> > >();
135 
136  if ((samples == -1) || (samples > (long long int)x.size())) { samples = x.size(); }
137 
138  long long int
139  rows = x.front().size(),
140  cols = x.front().front().size(),
141  depth = x.front().front().front().size();
142 
143  std::vector< tensorflow::Tensor > _x;
144 
145  // Single-input network
146  if (n_inputs == 1)
147  {
148  _x.push_back(tensorflow::Tensor(tensorflow::DT_FLOAT, tensorflow::TensorShape({ samples, rows, cols, depth })));
149  auto input_map = _x[0].tensor<float, 4>();
150  for (long long int s = 0; s < samples; ++s) {
151  const auto & sample = x[s];
152  for (long long int r = 0; r < rows; ++r) {
153  const auto & row = sample[r];
154  for (long long int c = 0; c < cols; ++c) {
155  const auto & col = row[c];
156  for (long long int d = 0; d < depth; ++d) {
157  input_map(s, r, c, d) = col[d];
158  }
159  }
160  }
161  }
162  }
163  // Multi-input network
164  else
165  {
166  for(int i=0; i<depth; ++i){
167  _x.push_back(tensorflow::Tensor(tensorflow::DT_FLOAT, tensorflow::TensorShape({ samples, rows, cols, 1 })));
168  }
169 
170  //tensorflow::Tensor _x(tensorflow::DT_FLOAT, tensorflow::TensorShape({ samples, rows, cols, depth }));
171 
172  for(int view=0; view<depth; ++view){
173  auto input_map = _x[view].tensor<float, 4>();
174  for (long long int s = 0; s < samples; ++s) {
175  const auto & sample = x[s];
176  for (long long int r = 0; r < rows; ++r) {
177  const auto & row = sample[r];
178  for (long long int c = 0; c < cols; ++c) {
179  const auto & col = row[c];
180  long long int d = view;
181  input_map(s, r, c, 0) = col[d];
182  }
183  }
184  }
185  }
186  }
187 
188  return run(_x);
189 }
struct vector vector
std::vector< float > run(const std::vector< std::vector< float > > &x)
Definition: tf_graph.cc:99
int n_inputs
Definition: tf_graph.h:29
static QCString * s
Definition: config.cpp:1042
std::vector< std::vector< std::vector< float > > > tf::Graph::run ( const std::vector< tensorflow::Tensor > &  x)

Definition at line 193 of file tf_graph.cc.

194 {
195  std::vector< std::pair<std::string, tensorflow::Tensor> > inputs;
196  for(int i=0; i<n_inputs; ++i){
197  inputs.push_back({fInputNames[i], x[i]});
198  }
199 
200  /*
201  // print input/outputs
202  for(int i = 0; i<n_inputs; ++i)
203  std::cout << inputs[i].first << std::endl;
204  for(int i = 0; i<n_outputs; ++i)
205  std::cout << fOutputNames[i] << std::endl;
206  */
207  //std::cout << "run session" << std::endl;
208 
209  std::vector<tensorflow::Tensor> outputs;
210  auto status = fSession->Run(inputs, fOutputNames, {}, &outputs);
211 
212  //std::cout << "out size " << outputs.size() << std::endl;
213 
214  if (status.ok())
215  {
216  size_t samples = 0;
217 
218  for (size_t o = 0; o < outputs.size(); ++o)
219  {
220  if (o == 0) { samples = outputs[o].dim_size(0); }
221  else if ((int)samples != outputs[o].dim_size(0))
222  {
223  throw std::string("TF outputs size inconsistent.");
224  }
225  }
226 
227  std::vector< std::vector< std::vector< float > > > result;
228  result.resize(samples, std::vector< std::vector< float > >(outputs.size()));
229 
230  for (size_t s = 0; s < samples; ++s)
231  {
232  for (size_t o = 0; o < outputs.size(); ++o)
233  {
234  size_t n = outputs[o].dim_size(1);
235  auto output_map = outputs[o].tensor<float, 2>();
236 
237  result[s][o].resize(outputs[o].dim_size(1));
238 
239  std::vector< float > & vs = result[s][o];
240  for (size_t i = 0; i < n; ++i)
241  {
242  vs[i] = output_map(s, i);
243  }
244  }
245  }
246 
247  return result;
248  }
249  else
250  {
251  std::cout << status.ToString() << std::endl;
252  return std::vector< std::vector< std::vector< float > > >();
253  }
254 }
static QCString result
std::string string
Definition: nybbler.cc:12
struct vector vector
tensorflow::Session * fSession
Definition: tf_graph.h:55
std::void_t< T > n
std::vector< std::string > fOutputNames
Definition: tf_graph.h:58
int n_inputs
Definition: tf_graph.h:29
std::vector< std::string > fInputNames
Definition: tf_graph.h:57
static QCString * s
Definition: config.cpp:1042
QTextStream & endl(QTextStream &s)

Member Data Documentation

std::string tf::Graph::fInputName
private

Definition at line 53 of file tf_graph.h.

std::vector< std::string > tf::Graph::fInputNames
private

Definition at line 57 of file tf_graph.h.

std::vector< std::string > tf::Graph::fOutputNames
private

Definition at line 58 of file tf_graph.h.

tensorflow::Session * tf::Graph::fSession
private

Definition at line 55 of file tf_graph.h.

int tf::Graph::n_inputs = 1

Definition at line 29 of file tf_graph.h.

int tf::Graph::n_outputs = 1

Definition at line 30 of file tf_graph.h.


The documentation for this class was generated from the following files: