Compute Library
 21.11
GemmTuner Namespace Reference

Data Structures

class  BenchmarkResult
 
class  GEMMBenchmarkResultRecorder
 
class  GEMMConfigDistribution
 
class  GEMMParam
 
class  Measurement
 
class  NativeGEMMConfig
 
class  ReshapedGEMMConfig
 
class  ReshapedOnlyRHSGEMMConfig
 

Functions

def parse_benchmark_commandline
 Functions. More...
 
def extract_benchmark_results
 
def parse_json (dir_name)
 
def check_out_path (out_path)
 
def dump_json (out_path, dict)
 
def main (args)
 Main. More...
 

Variables

 Strategy = Enum("Strategy", ["Native", "ReshapedOnlyRHS", "Reshaped"])
 Types. More...
 
 GEMMConfigT
 
dictionary GEMM_CONFIG_FACTORY
 
dictionary EXAMPLE_FILE_2_STRATEGY
 
dictionary GEMM_EXAMPLE_ARGS_FACTORY
 
string BENCHMARK_RESULT_JSON_EXTENSION = "gemmtuner_benchmark"
 
 parser = argparse.ArgumentParser(description="CL GEMM Tuner")
 
 dest
 
 metavar
 
 action
 
 type
 
 help
 
 required
 
 default
 
 args = parser.parse_args()
 
 logging_level = logging.DEBUG if args.debug else logging.INFO
 
 level
 

Function Documentation

◆ check_out_path()

def GemmTuner.check_out_path (   out_path)

Definition at line 566 of file GemmTuner.py.

References arm_compute::test::validation.input.

Referenced by GEMMBenchmarkResultRecorder.save_to_jsons().

566 def check_out_path(out_path):
567  if os.path.exists(out_path):
568  overwrite = (
569  input(
570  "Output JSON {} already exists. Overwrite? [Y/N]: ".format(
571  out_path)
572  ).lower()
573  == "y"
574  )
575  if not overwrite:
576  logging.info("Skipping {}".format(out_path))
577  return False
578  logging.info("Saving JSON file to {}".format(out_path))
579  return True
580 
581 
def check_out_path(out_path)
Definition: GemmTuner.py:566

◆ dump_json()

def GemmTuner.dump_json (   out_path,
  dict 
)

Definition at line 582 of file GemmTuner.py.

Referenced by GEMMBenchmarkResultRecorder.save_to_jsons().

582 def dump_json(out_path, dict):
583  with open(out_path, "w") as f:
584  json.dump(dict, f)
585  logging.info("Saved")
586 
587 
def dump_json(out_path, dict)
Definition: GemmTuner.py:582

◆ extract_benchmark_results()

def GemmTuner.extract_benchmark_results (   json_results)

Definition at line 489 of file GemmTuner.py.

References parse_benchmark_commandline().

Referenced by main(), and parse_benchmark_commandline().

489  json_results: Dict, measurement_method="avg"
490 ) -> Generator[BenchmarkResult, None, None]:
491  """ Parse the benchmark result and extract relevant information, namely:
492  GEMM param,
493  Strategy,
494  GEMM config,
495  Measurements
496  """
497  for json_res in json_results:
498  # Get example test and test data.
499  # There should only be 1 test per run
500  example_tests = list(json_res["tests"].items())
501  assert len(example_tests) == 1
502  example_fn, example_test_data = example_tests[0]
503 
504  # Process example file name
505  example_fn = example_fn.split(os.path.sep)[-1]
506 
507  # Get strategy
508  strategy = EXAMPLE_FILE_2_STRATEGY[example_fn]
509 
510  # Get gemm params + gemm configs from example args
511  benchmark_args = parse_benchmark_commandline(json_res["CommandLine"])
512  Gemm_Example_Args_T = GEMM_EXAMPLE_ARGS_FACTORY[strategy]
513  example_args = Gemm_Example_Args_T(
514  *(benchmark_args["example_args"].split(",")))
515  # Gemm_Example_Arg consists of GEMMParam first and then GEMMConfig (in that order)
516  # However data type option is parsed separately from end of options, hence -1 is applied to fields length
517  gemm_param_fields_len = len(GEMMParam._fields) - 1
518  gemm_param = GEMMParam.parse_from_strs(
519  *example_args[:gemm_param_fields_len],
520  data_type = benchmark_args["type"])
521  GEMMConfig = GEMM_CONFIG_FACTORY[strategy]
522  gemm_config = GEMMConfig.parse_from_strs(
523  *example_args[gemm_param_fields_len:])
524 
525  # Get OpenCL_Time_Ms stats
526  measurements = list(example_test_data["measurements"].items())
527  # For reshaped RHS only we have two measurements (one also for the reshape kernel)
528  # Hence we must parse and sum them
529  measurement_ms_reshape = 0
530  measurement_ms_kernel = 0
531  for single_measurement in measurements:
532  measurement_instrument, data = single_measurement
533  # Get instrument name and assert that it is the one we expect
534  measurement_instrument_name = measurement_instrument.split("/")[0]
535  assert measurement_instrument_name == "OpenCLTimer"
536  # Take either the minimum or the average of the raw data as the measurement value
537  if measurement_method == "min":
538  measurement_val = min(data["raw"])
539  elif measurement_method == "avg":
540  measurement_val = sum(data["raw"]) / len(data["raw"])
541  else:
542  raise ValueError(
543  "Invalid measurement method: {}".format(measurement_method)
544  )
545 
546  measurement_type = measurement_instrument.split("/")[1]
547  if "reshape" in measurement_type.split("_"):
548  measurement_ms_reshape = measurement_val
549  else:
550  measurement_ms_kernel = measurement_val
551 
552  measurement = Measurement(
553  measurement_ms_reshape, measurement_ms_kernel)
554 
555  yield BenchmarkResult(gemm_param, strategy, gemm_config, measurement)
556 
557 
def parse_benchmark_commandline
Functions.
Definition: GemmTuner.py:468

◆ main()

def GemmTuner.main (   args)

Main.

Definition at line 593 of file GemmTuner.py.

References extract_benchmark_results(), and parse_json().

593 def main(args):
594  logging.info(
595  "Searching best gemm configurations from {}".format(
596  args.benchmark_results_dir)
597  )
598 
599  benchmark_results = extract_benchmark_results(
600  parse_json(args.benchmark_results_dir)
601  )
602 
603  # Add all benchmark results to the recorder
604  benchmark_result_recorder = GEMMBenchmarkResultRecorder(tol=args.tolerance)
605  for benchmark_result in benchmark_results:
606  benchmark_result_recorder.add(benchmark_result)
607 
608  if args.debug:
609  recorder_sum_level = GEMMBenchmarkResultRecorder.SummaryLevel.Detailed
610  else:
611  recorder_sum_level = GEMMBenchmarkResultRecorder.SummaryLevel.Short
612 
613  # Print overall summary of the recorded results
614  logging.info(benchmark_result_recorder.summary(
615  sum_level=recorder_sum_level))
616 
617  # Get GEMM configuration distributions for each strategy
618  all_config_dists = benchmark_result_recorder.get_config_distributions()
619 
620  logging.info("=== Result ===")
621  for strategy, config_dist in all_config_dists.items():
622  logging.info("Strategy: {}".format(strategy.name))
623  logging.debug("GEMM Config, Votes")
624  for config, freq in config_dist.frequency():
625  logging.debug("{}, {}".format(config, freq))
626  logging.info(
627  "Best GEMM Config: {} with std: {}".format(
628  config_dist.best_config(), config_dist.std()
629  )
630  )
631 
632  # Save the recorded results to JSON files in output directory
633  if args.output_dir is not None:
634  benchmark_result_recorder.save_to_jsons(
635  args.output_dir, only_best_config=(not args.debug)
636  )
637 
638 
def extract_benchmark_results
Definition: GemmTuner.py:489
def parse_json(dir_name)
Definition: GemmTuner.py:558
def main(args)
Main.
Definition: GemmTuner.py:593

◆ parse_benchmark_commandline()

def GemmTuner.parse_benchmark_commandline (   commandline)

Functions.

Definition at line 468 of file GemmTuner.py.

References extract_benchmark_results(), and arm_compute::utils.map().

Referenced by extract_benchmark_results().

468 def parse_benchmark_commandline(commandline: str) -> Dict[str, str]:
469  """ Parse the benchmark example command-line string into a dictionary of command-line arguments
470  """
471  # Separate the data type option from the example_args portion of the string
472  commandline = commandline.replace(",--type=", " --type=")
473 
474  args = commandline.split()
475  # Discard program name
476  args = args[1:]
477  # Split into a list of (argument name, argument value)
478  args = map(lambda arg: arg.split("="), args)
479 
480  def transform(_name):
481  # Strip '-'/"--" if it exists
482  _name = _name.lstrip("-")
483  return _name
484 
485  return {transform(name): val for name, val in args}
486 
487 
void map(T &tensor, bool blocking)
Maps a tensor if needed.
Definition: Utils.h:212
def parse_benchmark_commandline
Functions.
Definition: GemmTuner.py:468

◆ parse_json()

def GemmTuner.parse_json (   dir_name)
Glob all benchmark result json files and parse them into json objects (dicts).

Definition at line 558 of file GemmTuner.py.

Referenced by main().

558 def parse_json(dir_name):
559  """ Glob all benchmark result json files and parse them into json objects (dicts).
560  """
561  for res_fn in Path(dir_name).rglob("*.{}".format(BENCHMARK_RESULT_JSON_EXTENSION)):
562  with open(res_fn) as res_fp:
563  yield json.load(res_fp)
564 
565 
def parse_json(dir_name)
Definition: GemmTuner.py:558

Variable Documentation

◆ action

action

Definition at line 646 of file GemmTuner.py.

◆ args

args = parser.parse_args()

Definition at line 679 of file GemmTuner.py.

Referenced by Graph.add_node(), CommandLineParser.add_option(), CommandLineParser.add_positional_option(), CLSynthetizeOperator< ClGemmMatrixMultiplyReshapedOnlyRhsKernel >.configure(), NESynthetizeFunction< K >.configure(), NESynthetizeFunctionWithZeroConstantBorder< K, bordersize >.configure(), CLSynthetizeOperatorInitOutputWithZeroAndWithZeroConstantBorder< K, bordersize >.configure(), NESynthetizeFunctionWithZeroConstantKernelBorder< K >.configure(), CLSynthetizeFunction< K >.configure(), CLSynthetizeFunctionWithZeroConstantBorder< K, bordersize >.configure(), CLSynthetizeFunctionInitOutputWithZeroAndWithZeroConstantBorder< K, bordersize >.configure(), ClSynthetizeOperatorWithBorder< K >.configure(), arm_compute::graph::backends.create_named_function(), arm_compute::graph::backends.create_named_memory_managed_function(), arm_conv::depthwise.depthwise(), arm_compute::utility.for_each(), arm_compute::detail.for_each_error(), arm_gemm.gemm_implementation_list< bfloat16, float >(), arm_gemm.gemm_implementation_list< float, float >(), GemmImplementation< Top, Tret, OutputStage >.GemmImplementation(), GemmImplementation< Top, Tret, Nothing >.GemmImplementation(), GemvBatched< To, Tr >.GemvBatched(), arm_conv::depthwise.get_compatible_kernels(), CpuPool2dAssemblyWrapperKernel.is_configured(), Logger.log(), arm_compute.operator<<(), arm_conv::pooling.pooling(), PostOpList< arm_compute::ITensorInfo *>.push_back_op(), arm_compute::support::cpp11.snprintf(), arm_compute::support::cpp11.stof(), arm_compute::logging.string_with_format(), arm_compute.to_string(), NESynthetizeFunction< K >.validate(), CLSynthetizeOperator< ClGemmMatrixMultiplyReshapedOnlyRhsKernel >.validate(), and CLSynthetizeFunction< K >.validate().

◆ BENCHMARK_RESULT_JSON_EXTENSION

string BENCHMARK_RESULT_JSON_EXTENSION = "gemmtuner_benchmark"

Definition at line 461 of file GemmTuner.py.

◆ default

default

Definition at line 668 of file GemmTuner.py.

◆ dest

dest

Definition at line 644 of file GemmTuner.py.

◆ EXAMPLE_FILE_2_STRATEGY

dictionary EXAMPLE_FILE_2_STRATEGY
Initial value:
1 = {
2  "benchmark_cl_gemm_native": Strategy.Native,
3  "benchmark_cl_gemm_reshaped_rhs_only": Strategy.ReshapedOnlyRHS,
4  "benchmark_cl_gemm_reshaped": Strategy.Reshaped,
5 }

Definition at line 434 of file GemmTuner.py.

◆ GEMM_CONFIG_FACTORY

dictionary GEMM_CONFIG_FACTORY
Initial value:
1 = {
2  Strategy.Native: NativeGEMMConfig,
3  Strategy.ReshapedOnlyRHS: ReshapedOnlyRHSGEMMConfig,
4  Strategy.Reshaped: ReshapedGEMMConfig,
5 }

Definition at line 426 of file GemmTuner.py.

◆ GEMM_EXAMPLE_ARGS_FACTORY

dictionary GEMM_EXAMPLE_ARGS_FACTORY
Initial value:
1 = {
2  # We ignore the data type field from GEMMParam as that is extracted separately
3  strategy: namedtuple(
4  "{}_Gemm_Example_Args".format(strategy_name),
5  GEMMParam._fields[:-1] + GEMM_CONFIG_FACTORY[strategy]._fields,
6  )
7  for strategy_name, strategy in Strategy.__members__.items()
8  if strategy_name == strategy.name
9 }

Definition at line 450 of file GemmTuner.py.

◆ GEMMConfigT

GEMMConfigT
Initial value:
1 = Union[NativeGEMMConfig,
2  ReshapedOnlyRHSGEMMConfig, ReshapedGEMMConfig]

Definition at line 189 of file GemmTuner.py.

◆ help

◆ level

level

Definition at line 681 of file GemmTuner.py.

Referenced by arm_compute::test::framework.to_string().

◆ logging_level

logging_level = logging.DEBUG if args.debug else logging.INFO

Definition at line 680 of file GemmTuner.py.

◆ metavar

metavar

Definition at line 645 of file GemmTuner.py.

◆ parser

◆ required

required

Definition at line 652 of file GemmTuner.py.

◆ Strategy

Strategy = Enum("Strategy", ["Native", "ReshapedOnlyRHS", "Reshaped"])

◆ type

type

Definition at line 647 of file GemmTuner.py.