Caffe2 - C++ API
A deep learning, cross platform ML framework
speed_benchmark.cc
1 
17 #include <string>
18 
19 #include "caffe2/core/init.h"
20 #include "caffe2/core/logging.h"
21 #include "caffe2/core/operator.h"
22 #include "caffe2/proto/caffe2.pb.h"
23 #include "caffe2/utils/proto_utils.h"
24 #include "caffe2/utils/string_utils.h"
25 
26 CAFFE2_DEFINE_string(net, "", "The given net to benchmark.");
27 CAFFE2_DEFINE_string(
28  init_net,
29  "",
30  "The given net to initialize any parameters.");
31 CAFFE2_DEFINE_string(
32  input,
33  "",
34  "Input that is needed for running the network. If "
35  "multiple input needed, use comma separated string.");
36 CAFFE2_DEFINE_string(
37  input_file,
38  "",
39  "Input file that contain the serialized protobuf for "
40  "the input blobs. If multiple input needed, use comma "
41  "separated string. Must have the same number of items "
42  "as input does.");
43 CAFFE2_DEFINE_string(
44  input_dims,
45  "",
46  "Alternate to input_files, if all inputs are simple "
47  "float TensorCPUs, specify the dimension using comma "
48  "separated numbers. If multiple input needed, use "
49  "semicolon to separate the dimension of different "
50  "tensors.");
51 CAFFE2_DEFINE_string(
52  output,
53  "",
54  "Output that should be dumped after the execution "
55  "finishes. If multiple outputs are needed, use comma "
56  "separated string. If you want to dump everything, pass "
57  "'*' as the output value.");
58 CAFFE2_DEFINE_string(
59  output_folder,
60  "",
61  "The folder that the output should be written to. This "
62  "folder must already exist in the file system.");
63 CAFFE2_DEFINE_int(warmup, 0, "The number of iterations to warm up.");
64 CAFFE2_DEFINE_int(iter, 10, "The number of iterations to run.");
65 CAFFE2_DEFINE_bool(
66  run_individual,
67  false,
68  "Whether to benchmark individual operators.");
69 
70 CAFFE2_DEFINE_bool(force_engine, false, "Force engine field for all operators");
71 CAFFE2_DEFINE_string(engine, "", "Forced engine field value");
72 CAFFE2_DEFINE_bool(force_algo, false, "Force algo arg for all operators");
73 CAFFE2_DEFINE_string(algo, "", "Forced algo arg value");
74 
75 using std::string;
76 using std::unique_ptr;
77 using std::vector;
78 
79 int main(int argc, char** argv) {
80  caffe2::GlobalInit(&argc, &argv);
81  unique_ptr<caffe2::Workspace> workspace(new caffe2::Workspace());
82 
83  // Run initialization network.
84  caffe2::NetDef net_def;
85  CAFFE_ENFORCE(ReadProtoFromFile(caffe2::FLAGS_init_net, &net_def));
86  CAFFE_ENFORCE(workspace->RunNetOnce(net_def));
87 
88  // Load input.
89  if (caffe2::FLAGS_input.size()) {
90  vector<string> input_names = caffe2::split(',', caffe2::FLAGS_input);
91  if (caffe2::FLAGS_input_file.size()) {
92  vector<string> input_files = caffe2::split(',', caffe2::FLAGS_input_file);
93  CAFFE_ENFORCE_EQ(
94  input_names.size(),
95  input_files.size(),
96  "Input name and file should have the same number.");
97  for (int i = 0; i < input_names.size(); ++i) {
98  caffe2::BlobProto blob_proto;
99  CAFFE_ENFORCE(caffe2::ReadProtoFromFile(input_files[i], &blob_proto));
100  workspace->CreateBlob(input_names[i])->Deserialize(blob_proto);
101  }
102  } else if (caffe2::FLAGS_input_dims.size()) {
103  vector<string> input_dims_list =
104  caffe2::split(';', caffe2::FLAGS_input_dims);
105  CAFFE_ENFORCE_EQ(
106  input_names.size(),
107  input_dims_list.size(),
108  "Input name and dims should have the same number of items.");
109  for (int i = 0; i < input_names.size(); ++i) {
110  vector<string> input_dims_str = caffe2::split(',', input_dims_list[i]);
111  vector<int> input_dims;
112  for (const string& s : input_dims_str) {
113  input_dims.push_back(caffe2::stoi(s));
114  }
115  caffe2::TensorCPU* tensor =
116  workspace->GetBlob(input_names[i])->GetMutable<caffe2::TensorCPU>();
117  tensor->Resize(input_dims);
118  tensor->mutable_data<float>();
119  }
120  } else {
121  CAFFE_THROW(
122  "You requested input tensors, but neither input_file nor "
123  "input_dims is set.");
124  }
125  }
126 
127  // Run main network.
128  CAFFE_ENFORCE(ReadProtoFromFile(caffe2::FLAGS_net, &net_def));
129  // force changing engine and algo
130  if (caffe2::FLAGS_force_engine) {
131  LOG(INFO) << "force engine be: " << caffe2::FLAGS_engine;
132  for (const auto& op : net_def.op()) {
133  const_cast<caffe2::OperatorDef*>(&op)->set_engine(caffe2::FLAGS_engine);
134  }
135  }
136  if (caffe2::FLAGS_force_algo) {
137  LOG(INFO) << "force algo be: " << caffe2::FLAGS_algo;
138  for (const auto& op : net_def.op()) {
139  caffe2::GetMutableArgument(
140  "algo", true, const_cast<caffe2::OperatorDef*>(&op))
141  ->set_s(caffe2::FLAGS_algo);
142  }
143  }
144  caffe2::NetBase* net = workspace->CreateNet(net_def);
145  CHECK_NOTNULL(net);
146  net->TEST_Benchmark(
147  caffe2::FLAGS_warmup, caffe2::FLAGS_iter, caffe2::FLAGS_run_individual);
148 
149  string output_prefix = caffe2::FLAGS_output_folder.size()
150  ? caffe2::FLAGS_output_folder + "/"
151  : "";
152  if (caffe2::FLAGS_output.size()) {
153  vector<string> output_names = caffe2::split(',', caffe2::FLAGS_output);
154  if (caffe2::FLAGS_output == "*") {
155  output_names = workspace->Blobs();
156  }
157  for (const string& name : output_names) {
158  CAFFE_ENFORCE(
159  workspace->HasBlob(name),
160  "You requested a non-existing blob: ",
161  name);
162  string serialized = workspace->GetBlob(name)->Serialize(name);
163  string output_filename = output_prefix + name;
164  caffe2::WriteStringToFile(serialized, output_filename.c_str());
165  }
166  }
167 
168  return 0;
169 }
bool GlobalInit(int *pargc, char ***pargv)
Initialize the global environment of caffe2.
Definition: init.cc:34
T * mutable_data()
Returns a typed pointer of the underlying storage.
Definition: tensor.h:594
Workspace is a class that holds all the related objects created during runtime: (1) all blobs...
Definition: workspace.h:63
void Resize(Ts...dim_source)
Resizes a tensor.
Definition: tensor.h:304
virtual vector< float > TEST_Benchmark(const int, const int, const bool)
Benchmarks a network.
Definition: net.h:93