| from __future__ import absolute_import |
| from __future__ import division |
| from __future__ import print_function |
| from __future__ import unicode_literals |
| |
| from caffe2.python import core, workspace |
| from operator_benchmark import benchmark_core, benchmark_utils |
| |
| """Caffe2 performance microbenchmarks. |
| |
| This module contains Caffe2-specific functionalities for performance |
| microbenchmarks. |
| """ |
| |
| |
| def Caffe2OperatorTestCase(test_name, op_type, input_shapes, op_args, run_mode): |
| """Benchmark Tester function for Caffe2 framework. |
| """ |
| idx = 0 |
| input_blobs = [] |
| for input in input_shapes: |
| blob_name = 'input_' + test_name + str(input_shapes) + str(op_args) + str(idx) |
| input_blobs.append(blob_name) |
| # TODO: figure out the data type from operator schema/ |
| # or accept custom data type for more comprehensive coverage. |
| # Also, consider a more complex range/distribution of numerical inputs. |
| workspace.FeedBlob(blob_name, benchmark_utils.numpy_random_fp32(*input)) |
| idx += 1 |
| |
| # TODO: consider reuse logic in Caffe2's Functional utility to get |
| # these benefits |
| # - Read operator schema to figure out if inplace enforcement is needed |
| # for the operator and name the output blob appropriately. |
| # - Also figure out the number of outputs from operator schema. |
| op = core.CreateOperator( |
| op_type, input_blobs, ['out'], **op_args |
| ) |
| |
| def benchmark_func(num_runs): |
| if not workspace.RunOperatorMultiple(op, num_runs): |
| raise RuntimeError('Unable to run operator test case ' % test_name) |
| |
| benchmark_core.add_benchmark_tester("Caffe2", test_name, input_shapes, op_args, run_mode, benchmark_func) |