blob: cc258d5e13eccab0d8358ca393f39b08c83476a5 [file]
// Copyright 2021 The IREE Authors
//
// Licensed under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
#ifndef IREE_TESTING_BENCHMARK_H_
#define IREE_TESTING_BENCHMARK_H_
// This is a C API shim for a benchmark-like interface.
// The intent is that we can write benchmarks that are portable to bare-metal
// systems and use some simple tooling while also allowing them to run on
// the full benchmark library with all its useful reporting and statistics.
#include "iree/base/api.h"
#ifdef __cplusplus
extern "C" {
#endif // __cplusplus
//===----------------------------------------------------------------------===//
// iree_benchmark_state_t
//===----------------------------------------------------------------------===//
// Benchmark state manipulator.
// Passed to each benchmark during execution to control the benchmark state
// or append information beyond just timing.
typedef struct iree_benchmark_state_t {
// Internal implementation handle.
void* impl;
// Allocator that can be used for host allocations required during benchmark
// execution.
iree_allocator_t host_allocator;
} iree_benchmark_state_t;
// Returns a range argument with the given ordial.
int64_t iree_benchmark_get_range(iree_benchmark_state_t* state,
iree_host_size_t ordinal);
// Returns true while the benchmark should keep running its step loop.
//
// Usage:
// while (iree_benchmark_keep_running(state, 1000)) {
// // process 1000 elements
// }
bool iree_benchmark_keep_running(iree_benchmark_state_t* state,
uint64_t batch_count);
// Reports that the currently executing benchmark cannot be run.
// Callers should return after calling as further benchmark-related calls may
// fail.
void iree_benchmark_skip(iree_benchmark_state_t* state, const char* message);
// Suspends the benchmark timer until iree_benchmark_resume_timing is called.
// This can be used to guard per-step code that is required to initialze the
// work but not something that needs to be accounted for in the benchmark
// timing. Introduces non-trivial overhead: only use this ~once per step when
// then going on to perform large amounts of batch work in the step.
void iree_benchmark_pause_timing(iree_benchmark_state_t* state);
// Resumes the benchmark timer after a prior iree_benchmark_suspend_timing.
void iree_benchmark_resume_timing(iree_benchmark_state_t* state);
// Sets a label string that will be displayed alongside the report line from the
// currently executing benchmark.
void iree_benchmark_set_label(iree_benchmark_state_t* state, const char* label);
// Adds a 'bytes/s' label with the given value.
//
// REQUIRES: must only be called outside of the benchmark step loop.
void iree_benchmark_set_bytes_processed(iree_benchmark_state_t* state,
int64_t bytes);
// Adds an `items/s` label with the given value.
//
// REQUIRES: must only be called outside of the benchmark step loop.
void iree_benchmark_set_items_processed(iree_benchmark_state_t* state,
int64_t items);
//===----------------------------------------------------------------------===//
// iree_benchmark_def_t
//===----------------------------------------------------------------------===//
enum iree_benchmark_flag_bits_t {
IREE_BENCHMARK_FLAG_MEASURE_PROCESS_CPU_TIME = 1u << 0,
IREE_BENCHMARK_FLAG_USE_REAL_TIME = 1u << 1,
IREE_BENCHMARK_FLAG_USE_MANUAL_TIME = 1u << 2,
};
typedef uint32_t iree_benchmark_flags_t;
typedef enum iree_benchmark_unit_e {
IREE_BENCHMARK_UNIT_MILLISECOND = 0,
IREE_BENCHMARK_UNIT_MICROSECOND,
IREE_BENCHMARK_UNIT_NANOSECOND,
} iree_benchmark_unit_t;
typedef struct iree_benchmark_def_t iree_benchmark_def_t;
// A benchmark case definition.
struct iree_benchmark_def_t {
// IREE_BENCHMARK_FLAG_* bitmask controlling benchmark behavior and reporting.
iree_benchmark_flags_t flags;
// Time unit used in display.
iree_benchmark_unit_t time_unit; // MILLISECOND by default
// Optional minimum duration the benchmark should run for in nanoseconds.
iree_duration_t minimum_duration_ns; // 0 if unspecified to autodetect
// Optional iteration count the benchmark should run for.
uint64_t iteration_count; // 0 if unspecified to autodetect
// TODO(benvanik): add range arguments.
// Runs the benchmark to completion.
// Implementations must call iree_benchmark_keep_running in a loop until it
// returns false.
iree_status_t (*run)(const iree_benchmark_def_t* benchmark_def,
iree_benchmark_state_t* benchmark_state);
// User-defined data accessible in the run function.
const void* user_data;
};
// Registers a benchmark with the given definition.
void iree_benchmark_register(iree_string_view_t name,
const iree_benchmark_def_t* benchmark_def);
//===----------------------------------------------------------------------===//
// Benchmark infra management
//===----------------------------------------------------------------------===//
// Initializes the benchmark framework.
// Must be called before any other iree_benchmark_* functions.
void iree_benchmark_initialize(int* argc, char** argv);
// Runs all registered benchmarks specified by the command line flags.
// Must be called after iree_benchmark_initialize and zero or more benchmarks
// have been registered with iree_benchmark_register.
void iree_benchmark_run_specified(void);
#ifdef __cplusplus
} // extern "C"
#endif // __cplusplus
#endif // IREE_TESTING_BENCHMARK_H_