def run_benchmark(func_config: FunctionConfig, input_configs):
    """
    Runs the benchmark for the provided function configuration with the given input configurations.
    """
    # print new line to seperate benchmark runs
    print()
    if DEBUG:
        print("func_config:", func_config)

    # extract function configuration parameters
    fn_name = func_config.fn_name
    mode = func_config.mode
    dtype = func_config.dtype
    backend = func_config.backend

    # load flash attention module
    flash_attn_module = load_flash_attn_module(backend, func_config.env_configs, verbose=True)
 
    # start timing the benchmark
    start_time = time.time()

    # print bench fn
    print(f"Benchmarking {func_config} ...")

    # Setup benchmark configurations
    bench_configs = [
        triton.testing.Benchmark(
            x_names=["BATCH", "HQ", "HK", "N_CTX_Q", "N_CTX_K", "D_HEAD", "CAUSAL", "DROPOUT"],
            x_vals=list(input_configs.keys()),
            line_arg="provider",
            line_vals=["triton"],
            line_names=["Time (ms)"],
            styles=[("red", "-")],
            ylabel="ms",
            plot_name=f"benchmark-{func_config}",
            args={
            },
        )
    ]

    @triton.testing.perf_report(bench_configs)
    def bench_function(
        BATCH, HQ, HK, N_CTX_Q, N_CTX_K, D_HEAD, CAUSAL, DROPOUT, provider, device="cuda"
    ):
        if DEBUG:
            print("BATCH:", BATCH)
            print("HQ:", HQ)
            print("HK:", HK)
            print("N_CTX_Q:", N_CTX_Q)
            print("N_CTX_Q:", N_CTX_Q)
            print("D_HEAD:", D_HEAD)
            print("CAUSAL:", CAUSAL)
            print("DROPOUT:", DROPOUT)
            print("mode:", mode)
            print("provider:", provider)
            print("device:", device)
        fn_input = input_configs[(BATCH, HQ, HK, N_CTX_Q, N_CTX_K, D_HEAD, CAUSAL, DROPOUT)]
        benchmark_fn = create_benchmark_fn(flash_attn_module, fn_name, fn_input, mode)

        # run the benchmark
        ms = triton.testing.do_bench(benchmark_fn, warmup=25, rep=100)
        return ms

    df = bench_function.run(save_path=".", print_data=True, return_df=True)[0]
    
    # set the column name to reflect the function configuration
    df = df.rename(columns={"Time (ms)": func_config.column_name()})
    
    # calculate and print elapsed time
    elapsed_time = time.time() - start_time
    print(f"Total time for benchmarking {fn_name} in {mode} mode with {dtype}: {elapsed_time:.2f} seconds")

    return df

    Runs the benchmark for the provided function configuration with the given input configurations.
    
flash_attn/flash_attn_triton_amd/bench.py