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" 26 CAFFE2_DEFINE_string(net,
"",
"The given net to benchmark.");
30 "The given net to initialize any parameters.");
34 "Input that is needed for running the network. If " 35 "multiple input needed, use comma separated string.");
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 " 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 " 53 "",
"Input type (uint8_t/float)");
57 "Output that should be dumped after the execution " 58 "finishes. If multiple outputs are needed, use comma " 59 "separated string. If you want to dump everything, pass " 60 "'*' as the output value.");
64 "The folder that the output should be written to. This " 65 "folder must already exist in the file system.");
66 CAFFE2_DEFINE_int(warmup, 0,
"The number of iterations to warm up.");
67 CAFFE2_DEFINE_int(iter, 10,
"The number of iterations to run.");
71 "Whether to benchmark individual operators.");
73 CAFFE2_DEFINE_bool(force_engine,
false,
"Force engine field for all operators");
74 CAFFE2_DEFINE_string(engine,
"",
"Forced engine field value");
75 CAFFE2_DEFINE_bool(force_algo,
false,
"Force algo arg for all operators");
76 CAFFE2_DEFINE_string(algo,
"",
"Forced algo arg value");
79 using std::unique_ptr;
82 int main(
int argc,
char** argv) {
87 caffe2::NetDef net_def;
88 CAFFE_ENFORCE(ReadProtoFromFile(caffe2::FLAGS_init_net, &net_def));
89 CAFFE_ENFORCE(workspace->RunNetOnce(net_def));
92 if (caffe2::FLAGS_input.size()) {
93 vector<string> input_names = caffe2::split(
',', caffe2::FLAGS_input);
94 if (caffe2::FLAGS_input_file.size()) {
95 vector<string> input_files = caffe2::split(
',', caffe2::FLAGS_input_file);
99 "Input name and file should have the same number.");
100 for (
int i = 0; i < input_names.size(); ++i) {
101 caffe2::BlobProto blob_proto;
102 CAFFE_ENFORCE(caffe2::ReadProtoFromFile(input_files[i], &blob_proto));
103 workspace->CreateBlob(input_names[i])->Deserialize(blob_proto);
105 }
else if (caffe2::FLAGS_input_dims.size() || caffe2::FLAGS_input_type.size()) {
106 CAFFE_ENFORCE_NE(0, caffe2::FLAGS_input_dims.size(),
107 "Input dims must be specified when input tensors are used.");
108 CAFFE_ENFORCE_NE(0, caffe2::FLAGS_input_type.size(),
109 "Input type must be specified when input tensors are used.");
111 vector<string> input_dims_list =
112 caffe2::split(
';', caffe2::FLAGS_input_dims);
115 input_dims_list.size(),
116 "Input name and dims should have the same number of items.");
117 vector<string> input_type_list =
118 caffe2::split(
';', caffe2::FLAGS_input_type);
121 input_type_list.size(),
122 "Input name and type should have the same number of items.");
123 for (
size_t i = 0; i < input_names.size(); ++i) {
124 vector<string> input_dims_str = caffe2::split(
',', input_dims_list[i]);
125 vector<int> input_dims;
126 for (
const string& s : input_dims_str) {
127 input_dims.push_back(caffe2::stoi(s));
129 caffe2::Blob* blob = workspace->GetBlob(input_names[i]);
130 if (blob ==
nullptr) {
131 blob = workspace->CreateBlob(input_names[i]);
134 CHECK_NOTNULL(tensor);
135 tensor->
Resize(input_dims);
136 if (input_type_list[i] ==
"uint8_t") {
138 }
else if (input_type_list[i] ==
"float") {
141 CAFFE_THROW(
"Unsupported input type: ", input_type_list[i]);
146 "You requested input tensors, but neither input_file nor " 147 "input_dims is set.");
152 CAFFE_ENFORCE(ReadProtoFromFile(caffe2::FLAGS_net, &net_def));
154 if (caffe2::FLAGS_force_engine) {
155 LOG(INFO) <<
"force engine be: " << caffe2::FLAGS_engine;
156 for (
const auto& op : net_def.op()) {
157 const_cast<caffe2::OperatorDef*
>(&op)->set_engine(caffe2::FLAGS_engine);
160 if (caffe2::FLAGS_force_algo) {
161 LOG(INFO) <<
"force algo be: " << caffe2::FLAGS_algo;
162 for (
const auto& op : net_def.op()) {
163 caffe2::GetMutableArgument(
164 "algo",
true, const_cast<caffe2::OperatorDef*>(&op))
165 ->set_s(caffe2::FLAGS_algo);
171 caffe2::FLAGS_warmup, caffe2::FLAGS_iter, caffe2::FLAGS_run_individual);
173 string output_prefix = caffe2::FLAGS_output_folder.size()
174 ? caffe2::FLAGS_output_folder +
"/" 176 if (caffe2::FLAGS_output.size()) {
177 vector<string> output_names = caffe2::split(
',', caffe2::FLAGS_output);
178 if (caffe2::FLAGS_output ==
"*") {
179 output_names = workspace->Blobs();
181 for (
const string& name : output_names) {
183 workspace->HasBlob(name),
184 "You requested a non-existing blob: ",
186 string serialized = workspace->GetBlob(name)->Serialize(name);
187 string output_filename = output_prefix + name;
188 caffe2::WriteStringToFile(serialized, output_filename.c_str());
Blob is a general container that hosts a typed pointer.
bool GlobalInit(int *pargc, char ***pargv)
Initialize the global environment of caffe2.
T * mutable_data()
Returns a typed pointer of the underlying storage.
Workspace is a class that holds all the related objects created during runtime: (1) all blobs...
void Resize(Ts...dim_source)
Resizes a tensor.
T * GetMutable(bool *is_new_object=nullptr)
Gets a mutable pointer to the stored object.
virtual vector< float > TEST_Benchmark(const int, const int, const bool)
Benchmarks a network.