Time: benchmark the execution time of a model.
| 332 | |
| 333 | // Time: benchmark the execution time of a model. |
| 334 | int time() { |
| 335 | CHECK_GT(FLAGS_model.size(), 0) << "Need a model definition to time."; |
| 336 | caffe::Phase phase = get_phase_from_flags(caffe::TRAIN); |
| 337 | vector<string> stages = get_stages_from_flags(); |
| 338 | |
| 339 | // Set device id and mode |
| 340 | vector<int> gpus; |
| 341 | get_gpus(&gpus); |
| 342 | if (gpus.size() != 0) { |
| 343 | LOG(INFO) << "Use GPU with device ID " << gpus[0]; |
| 344 | Caffe::SetDevice(gpus[0]); |
| 345 | Caffe::set_mode(Caffe::GPU); |
| 346 | } else { |
| 347 | LOG(INFO) << "Use CPU."; |
| 348 | Caffe::set_mode(Caffe::CPU); |
| 349 | } |
| 350 | // Instantiate the caffe net. |
| 351 | Net<float> caffe_net(FLAGS_model, phase, FLAGS_level, &stages); |
| 352 | |
| 353 | // Do a clean forward and backward pass, so that memory allocation are done |
| 354 | // and future iterations will be more stable. |
| 355 | LOG(INFO) << "Performing Forward"; |
| 356 | // Note that for the speed benchmark, we will assume that the network does |
| 357 | // not take any input blobs. |
| 358 | float initial_loss; |
| 359 | caffe_net.Forward(&initial_loss); |
| 360 | LOG(INFO) << "Initial loss: " << initial_loss; |
| 361 | LOG(INFO) << "Performing Backward"; |
| 362 | caffe_net.Backward(); |
| 363 | |
| 364 | const vector<shared_ptr<Layer<float> > >& layers = caffe_net.layers(); |
| 365 | const vector<vector<Blob<float>*> >& bottom_vecs = caffe_net.bottom_vecs(); |
| 366 | const vector<vector<Blob<float>*> >& top_vecs = caffe_net.top_vecs(); |
| 367 | const vector<vector<bool> >& bottom_need_backward = |
| 368 | caffe_net.bottom_need_backward(); |
| 369 | LOG(INFO) << "*** Benchmark begins ***"; |
| 370 | LOG(INFO) << "Testing for " << FLAGS_iterations << " iterations."; |
| 371 | Timer total_timer; |
| 372 | total_timer.Start(); |
| 373 | Timer forward_timer; |
| 374 | Timer backward_timer; |
| 375 | Timer timer; |
| 376 | std::vector<double> forward_time_per_layer(layers.size(), 0.0); |
| 377 | std::vector<double> backward_time_per_layer(layers.size(), 0.0); |
| 378 | double forward_time = 0.0; |
| 379 | double backward_time = 0.0; |
| 380 | for (int j = 0; j < FLAGS_iterations; ++j) { |
| 381 | Timer iter_timer; |
| 382 | iter_timer.Start(); |
| 383 | forward_timer.Start(); |
| 384 | for (int i = 0; i < layers.size(); ++i) { |
| 385 | timer.Start(); |
| 386 | layers[i]->Forward(bottom_vecs[i], top_vecs[i]); |
| 387 | forward_time_per_layer[i] += timer.MicroSeconds(); |
| 388 | } |
| 389 | forward_time += forward_timer.MicroSeconds(); |
| 390 | backward_timer.Start(); |
| 391 | for (int i = layers.size() - 1; i >= 0; --i) { |