Skip to content

Commit 0bef8b3

Browse files
committed
Add support for tuning spec path via C API
Signed-off-by: Bangtian Liu <liubangtian@gmail.com>
1 parent 925f9a9 commit 0bef8b3

3 files changed

Lines changed: 92 additions & 37 deletions

File tree

README.md

Lines changed: 21 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -177,72 +177,60 @@ The wrapper automatically:
177177

178178
#### Custom Compiler Flags
179179

180-
You can pass custom IREE compiler flags using the `FUSILLI_EXTRA_COMPILER_FLAGS`
181-
environment variable or the `--Xiree-compile` flag with the Python benchmark
182-
wrapper.
180+
Pass custom IREE compiler flags using:
181+
- **C++ driver**: `FUSILLI_EXTRA_COMPILER_FLAGS` environment variable
182+
- **Python wrapper**: `--Xiree-compile` flag (which sets the environment variable internally)
183183

184-
**Using the C++ benchmark driver with environment variable:**
184+
**Single flag examples:**
185+
186+
C++ driver:
185187
```shell
186188
FUSILLI_EXTRA_COMPILER_FLAGS="--iree-opt-level=O3" \
187189
build/bin/benchmarks/fusilli_benchmark_driver --iter 100 \
188-
matmul -M 8192 -N 2048 -K 4096 --transA \
189-
--a_type bf16 --b_type bf16 --out_type bf16
190+
matmul -M 8192 -N 2048 -K 4096 --transA --a_type bf16 --b_type bf16 --out_type bf16
190191
```
191192

192-
**Using the Python benchmark wrapper:**
193+
Python wrapper:
193194
```shell
194195
python benchmarks/run_benchmark.py \
195196
--Xiree-compile="--iree-opt-level=O3" \
196-
-o results.csv \
197-
-f commands.txt
197+
-f commands.txt -o results.csv
198198
```
199199

200-
**Passing multiple compiler flags:**
200+
**Multiple flags:**
201201

202-
Using environment variable:
202+
C++ driver (space-separated in one string):
203203
```shell
204204
FUSILLI_EXTRA_COMPILER_FLAGS="--iree-opt-level=O3 --iree-hal-dump-executable-files-to=/tmp/dump" \
205205
build/bin/benchmarks/fusilli_benchmark_driver ...
206206
```
207207

208-
Using Python wrapper:
208+
Python wrapper (repeat `--Xiree-compile`):
209209
```shell
210210
python benchmarks/run_benchmark.py \
211211
--Xiree-compile="--iree-opt-level=O3" \
212212
--Xiree-compile="--iree-hal-dump-executable-files-to=/tmp/dump" \
213213
-f commands.txt -o results.csv
214214
```
215215

216-
> [!NOTE]
217-
> If an extra compiler flag is exposed via CLI but not the C API, please select
218-
> the CLI backend (set `FUSILLI_COMPILE_BACKEND_USE_CLI=1`). Currently,
219-
> `--iree-codegen-tuning-spec-path` requires this since it is not exposed
220-
> through the C API. This limitation is being addressed and will be lifted
221-
> shortly.
222-
223216
#### Tuning Specs
224217

225-
IREE tuning specs (transform dialect libraries) specify optimal compiler code
226-
generation parameters such as workgroup sizes, tile sizes, MMA intrinsics, and
227-
shared memory allocation suited for specific workloads. You can pass tuning
228-
specs using the custom compiler flags feature described above.
218+
IREE tuning specs (transform dialect libraries) specify compiler code generation
219+
parameters like workgroup sizes, tile sizes, and MMA intrinsics for specific workloads.
220+
Pass tuning specs using the custom compiler flags shown above:
229221

230-
**Example with C++ benchmark driver:**
222+
C++ driver:
231223
```shell
232-
FUSILLI_COMPILE_BACKEND_USE_CLI=1 \
233224
FUSILLI_EXTRA_COMPILER_FLAGS="--iree-codegen-tuning-spec-path=/path/to/tuning_spec.mlir" \
234225
build/bin/benchmarks/fusilli_benchmark_driver --iter 100 \
235-
matmul -M 8192 -N 2048 -K 4096 --transA \
236-
--a_type bf16 --b_type bf16 --out_type bf16
226+
matmul -M 8192 -N 2048 -K 4096 --transA --a_type bf16 --b_type bf16 --out_type bf16
237227
```
238228

239-
**Example with Python benchmark wrapper:**
229+
Python wrapper:
240230
```shell
241-
FUSILLI_COMPILE_BACKEND_USE_CLI=1 \
242-
python benchmarks/run_benchmark.py \
231+
python benchmarks/run_benchmark.py \
243232
--Xiree-compile="--iree-codegen-tuning-spec-path=/path/to/tuning_spec.mlir" \
244-
-o results.csv \
245-
-f commands.txt
233+
-f commands.txt -o results.csv
246234
```
247235

248236
### Sanitizers
@@ -361,7 +349,7 @@ Alternatively, one may call the logging API directly as needed:
361349

362350
| Environment Variable | Description
363351
| ---------------------------------------- | -----------
364-
| `FUSILLI_COMPILE_BACKEND_USE_CLI` | Enables the use of the CLI tool to invoke compilation, otherwise uses CAPI
352+
| `FUSILLI_COMPILE_BACKEND_USE_CLI` | Enables the use of the CLI tool to invoke compilation instead of C API (for debugging purposes; default: use C API)
365353
| `FUSILLI_EXTERNAL_IREE_COMPILE` | Path to `iree-compile` binary
366354
| `FUSILLI_EXTERNAL_IREE_COMPILER_LIB` | Path to the IREE compiler dynamic library
367355
| `FUSILLI_EXTERNAL_ROCM_AGENT_ENUMERATOR` | Path to `rocm_agent_enumerator` binary

benchmarks/test_benchmark_runner.sh

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -6,10 +6,6 @@ set -x
66
BENCHMARK_RUNNER="$1"
77
BENCHMARK_DRIVER="$2"
88

9-
# Use CLI backend for tests (--iree-codegen-tuning-spec-path not available via C API)
10-
# TODO(iree-org/iree#23314): Remove this when tuning spec path support is added to C API
11-
export FUSILLI_COMPILE_BACKEND_USE_CLI=1
12-
139
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
1410
TEST_COMMANDS="${SCRIPT_DIR}/test_commands.txt"
1511
OUTPUT_CSV=$(mktemp)

tests/test_compile_session.cpp

Lines changed: 71 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -519,3 +519,74 @@ TEST_CASE("CompileSession::getArgs", "[CompileSession]") {
519519
}
520520
std::filesystem::remove_all(input.path.parent_path());
521521
}
522+
523+
TEST_CASE("CompileSession::addFlag with tuning spec path",
524+
"[CompileSession][tuning_spec]") {
525+
// Verify tuning spec path flag is accepted by C API.
526+
FUSILLI_REQUIRE_ASSIGN(auto *context, CompileContext::create());
527+
REQUIRE(context != nullptr);
528+
FUSILLI_REQUIRE_ASSIGN(Handle handle, Handle::create(kDefaultBackend));
529+
FUSILLI_REQUIRE_ASSIGN(auto session, context->createSession(handle));
530+
531+
std::string tuningSpecPath = "/tmp/test_tuning_spec.mlir";
532+
533+
auto result =
534+
session.addFlag("--iree-codegen-tuning-spec-path=" + tuningSpecPath);
535+
FUSILLI_REQUIRE_OK(result);
536+
537+
// Verify the flag was stored.
538+
const auto &args = session.getArgs();
539+
bool hasTuningSpecFlag = false;
540+
for (const auto &arg : args) {
541+
if (arg.find("--iree-codegen-tuning-spec-path") != std::string::npos) {
542+
hasTuningSpecFlag = true;
543+
break;
544+
}
545+
}
546+
REQUIRE(hasTuningSpecFlag);
547+
}
548+
549+
TEST_CASE("CompileSession::compile with tuning spec",
550+
"[CompileSession][integration][tuning_spec]") {
551+
// End-to-end compilation with tuning spec via C API.
552+
FUSILLI_REQUIRE_ASSIGN(auto *context, CompileContext::create());
553+
REQUIRE(context != nullptr);
554+
FUSILLI_REQUIRE_ASSIGN(Handle handle, Handle::create(kDefaultBackend));
555+
FUSILLI_REQUIRE_ASSIGN(auto session, context->createSession(handle));
556+
557+
// Create a minimal no-op tuning spec.
558+
FUSILLI_REQUIRE_ASSIGN(
559+
CacheFile tuningSpec,
560+
CacheFile::create(kGraphName, "test_tuning_spec.mlir", /*remove=*/true));
561+
562+
std::string tuningSpecContent = R"(
563+
// Minimal no-op tuning spec for testing.
564+
module attributes {transform.with_named_sequence} {
565+
transform.named_sequence @__kernel_config(%arg0: !transform.any_op {transform.consumed})
566+
-> !transform.any_op attributes {iree_codegen.tuning_spec_entrypoint} {
567+
transform.yield %arg0 : !transform.any_op
568+
}
569+
}
570+
)";
571+
FUSILLI_REQUIRE_OK(tuningSpec.write(tuningSpecContent));
572+
573+
FUSILLI_REQUIRE_OK(session.addFlag("--iree-codegen-tuning-spec-path=" +
574+
tuningSpec.path.string()));
575+
FUSILLI_REQUIRE_ASSIGN(
576+
CacheFile input,
577+
CacheFile::create(kGraphName, "input_with_spec.mlir", /*remove=*/true));
578+
FUSILLI_REQUIRE_ASSIGN(
579+
CacheFile output,
580+
CacheFile::create(kGraphName, "output_with_spec.vmfb", /*remove=*/true));
581+
582+
std::string mlirContent = getSimpleMLIRModule();
583+
FUSILLI_REQUIRE_OK(input.write(mlirContent));
584+
585+
auto compileResult =
586+
session.compile(input.path.string(), output.path.string());
587+
FUSILLI_REQUIRE_OK(compileResult);
588+
REQUIRE(std::filesystem::exists(output.path));
589+
REQUIRE(std::filesystem::file_size(output.path) > 0);
590+
591+
std::filesystem::remove_all(input.path.parent_path());
592+
}

0 commit comments

Comments
 (0)