Files
TheRock/rocm-libraries/projects/hipblaslt/utilities/geko/README.md
T
derek.holloway 7502bf64a4
CodeQL / Analyze (actions) (push) Canceled after 0s
CodeQL / Analyze (python) (push) Canceled after 0s
pre-commit / pre-commit (push) Canceled after 0s
Multi-Arch CI / setup (push) Canceled after 0s
Publish build_manylinux_x86_64 images / publish_build_manylinux_x86_64 (push) Canceled after 0s
Setup (Multi-Arch) / setup (push) Canceled after 0s
Multi-Arch CI / Linux::${{ fromJSON(needs.setup.outputs.linux_build_config || '{}').build_variant_label || 'skip' }} (push) Canceled after 0s
Publish TheRock Docker image / build-and-push-image (push) Canceled after 0s
Publish no_rocm_image_ubi10 image / publish_no_rocm_image_ubi10 (push) Canceled after 0s
Multi-Arch CI / Windows::${{ fromJSON(needs.setup.outputs.windows_build_config || '{}').build_variant_label || 'skip' }} (push) Canceled after 0s
Publish TheRock Docker image / build-and-push-image (push) Canceled after 0s
Multi-Arch CI / Manifest Diff (push) Canceled after 0s
TheRock Manifest Diff Report / Generate Manifest Diff Report (push) Canceled after 0s
Multi-Arch CI / CI Summary (push) Canceled after 0s
Publish no_rocm_image_ubuntu24_04 images / publish_no_rocm_image_ubuntu24_04 (push) Canceled after 0s
Publish no_rocm_image_ubuntu24_04_ocl_rt images / publish_no_rocm_image_ubuntu24_04_ocl_rt (push) Canceled after 0s
Publish TheRock Docker image / build-and-push-image (push) Canceled after 0s
Publish TheRock Docker image / build-and-push-image (push) Canceled after 0s
Publish no_rocm_image_ubuntu24_04 images / publish_no_rocm_image_ubuntu24_04_rocgdb (push) Canceled after 0s
Publish no_rocm_image_ubuntu24_04_rocgdb images / publish_no_rocm_image_ubuntu24_04_rocgdb (push) Canceled after 0s
Publish no_rocm_image_ubuntu24_04 images / publish_no_rocm_image_ubuntu24_04_ocl_rt (push) Canceled after 0s
Publish TheRock Docker image / build-and-push-image (push) Canceled after 0s
Unit Tests / Unit Tests :: ubuntu-24.04 (push) Canceled after 0s
Unit Tests / Unit Tests :: windows-2022 (push) Canceled after 0s
Publish no_rocm_image_ubuntu24_04 images / publish_no_rocm_image_ubuntu24_04_media (push) Canceled after 0s
Unit Tests / Unit Tests Summary (push) Canceled after 0s
Publish no_rocm_image_ubuntu24_04 images / publish_no_rocm_image_ubuntu24_04_openmpi (push) Canceled after 0s
Flatten subprojects into a single base monorepo
2026-09-02 16:34:47 -07:00

1313 lines
46 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# GEKO - GEMM Kernel Optimizer
A comprehensive Python framework for optimizing General Matrix Multiply (GEMM) kernels in hipBLASLt. GEKO automates the complete workflow from workload analysis to the final optimized library, providing significant GEMM performance improvements for AMD GPUs.
## Table of Contents
- [Overview](#overview)
- [GEKO Package Architecture](#geko-package-architecture)
- [Requirements](#requirements)
- [Installation](#installation)
- [CLI Reference](#cli-reference)
- [Usage Guide](#usage-guide)
- [GA-based Optimization](#1-ga-based-optimization)
- [Dense Search (Offline Tuning)](#2-dense-search-offline-tuning)
- [Benchmark](#3-benchmark)
- [Module Reference](#module-reference)
- [Common Usage Patterns](#common-usage-patterns)
- [Troubleshooting](#troubleshooting)
- [Contributing](#contributing)
- [License](#license)
## Overview
GEKO provides an end-to-end solution for optimizing GEMM kernels in hipBLASLt through two alternative tuning workflows and a standalone benchmark mode:
### Optimization Workflow
Generates the most optimized kernels for individual sizes and datatypes. There are three main steps:
1. **Configuration Phase** (`scripts/configure.py`): Analyze hipblaslt logs (actual workload) → Generate tensilelite configuration yamls for tuning. There are different options to create one config file per size for the best performance, or cluster similar sizes in the same config file for more efficient tuning.
2. **Optimization Phase** (`scripts/optimize.py`): Run GEMM kernel optimization → Benchmark → Filter → Create final library. There are different options to use (Genetic Algorithm for the best performance, or exhaustive kernel search across all possible kernel based on the yaml configuration file parameters for experiments).
3. **Integration Phase**: Merge the optimized libraries into hipBLASLt → Install
Note that the CLI merges steps 1 and 2 in one command. While we recommend the two-step approach (to review configurations before running optimization), you can use the CLI for a faster method. The instruction is in the following sections.
Optimization Workflow:
```
hipBLASLt Logs → Configure → Optimize → Benchmark → Filter → Merge
↓ ↓ ↓ ↓ ↓ ↓
YAML logs Tensile Tuning Performance Final hipBLASLt
Configs (Ductile or full) Analysis Library Integration
```
### Search Workflow (Dense Benchmarking - Offline Tuning)
Performs exhaustive search across existing solutions:
1. **Search Phase (AKA offline tuning)** (`scripts/search.py` or `./bin/geko --search`): Parse logs → Dense benchmark across all solutions → Extract winners → Filter → Create final library
Here is the sample command for gfx950:
`./bin/geko --search --workload-log hipblaslt-log-mask64.yaml --devices=0,1,2,3,4,5,6,7`
This is the workflow:
```
hipBLASLt Logs → Search → Extract → Benchmark → Filter → Merge
↓ ↓ ↓ ↓ ↓ ↓
YAML logs Dense Winning Performance Final hipBLASLt
Benchmark Kernels Analysis Library Integration
```
2. **Integration Phase**: Merge the optimized libraries into hipBLASLt → Install
### Benchmark Mode
Runs hipblaslt-bench on a workload log without any tuning. Useful for measuring baseline performance or verifying results after integration.
`./bin/geko --bench --workload-log hipblaslt-log-mask64.yaml --devices=0`
### Workload Input Options
All three modes above accept exactly one of the following workload sources:
| Option | Description |
|--------|-------------|
| `--workload-log PATH` | hipBLASLt GEMM log YAML captured with `HIPBLASLT_LOG_MASK=64`. Contains real workload sizes from an application run. |
| `--list PATH` | Generator tuning YAML (see `geko/config_generator/config.yaml` for an example). Supports two size modes: an explicit list (`SIZE_OPTION=0`) or an internally generated M×N grid filtered by CU boundary constraints (`SIZE_OPTION=1`). |
| `--inline M N batch K DataType DestDataType ComputeDataType transA transB` | Single GEMM specified directly on the command line (e.g. `--inline 1024 1024 1 1024 B B S N T`). |
## GEKO Package Architecture
The `geko` package is organized into specialized modules for different optimization workflow stages:
```
geko/
├── bench/ # Benchmarking and performance analysis
│ ├── bench.py # Core benchmark execution
│ ├── log.py # hipBLASLt log file parsing
│ └── utils.py # Benchmark parsing utilities
├── optim/ # GA-based tensilelite configuration and execution
│ ├── optim.py # Optimization and result analysis
│ └── utils.py # Progress tracking and device management
├── search.py # Dense search workflow (offline tuning)
├── library/ # Kernel library management
│ ├── library.py # Library and LibraryCollection classes
│ ├── operations.py # Library loading, merging, creation, etc.
│ └── _bank.py # Solution bank utilities
├── config_generator/ # Tensile configuration generation utilities
│ ├── config.yaml # Example configuration template
│ ├── config_generator.py
│ ├── config_merger.py
│ ├── config_sections_generator.py
│ ├── load_input_config.py
│ ├── mi_designer.py
│ ├── sizes.py
│ ├── cluster_sizes.py
│ ├── fork_param_generator.py
│ ├── output_writer.py
│ ├── shared_utils.py
│ ├── utils.py
│ ├── constants.py
│ └── fork_params/ # Per-architecture tuning parameter profiles
│ ├── optimization_param.py
│ ├── post_processor.py
│ ├── param_meta.py
│ └── hw_profiles/
│ ├── gfx942/ # gfx942 optimization params and post-processing
│ └── gfx950/ # gfx950 optimization params and post-processing
├── concurrency/ # Multi-GPU concurrency management
│ ├── runner.py # Concurrent job execution
│ └── utils.py # Concurrency utilities
├── cli.py # Command-line interface entry point
├── pipeline.py # Workflow orchestration pipeline
├── schemas.py # Data structures (GemmType, GemmConfig, etc.)
├── constants.py # Data type mappings and field definitions
└── utils.py # Common utilities (e.g. device management)
```
### Workflow Output Structure
**Optimization Workflow Output:**
```
workdir/
├── run_state.json # Workflow state tracking
├── hipblaslt-log-mask64.yaml # Updated benchmark file
├── hipblaslt-log-mask64.out # hipblaslt-bench output
├── summary.csv # GEMM contribution analysis
├── gemms.csv # Extracted unique GEMMs
├── optimizations/ # Phase 1: Configuration output
│ ├── BBS_TN_0.yaml # Tensile config for GEMM type
│ ├── BBS_TN_0.sh # Execution script
│ ├── F8BS_TN_1.yaml # Another GEMM configuration
│ ├── ...
│ └── build_*/ # Phase 2: Optimization results
│ ├── ...
│ ├── 3_LibraryLogic/ # Optimized kernel libraries
│ │ └── *.yaml # Individual library files
│ ├── *-tensilelite.log # Detailed tuning logs
│ └── *-optimization.log # Optimization logs
├── libs/ # Merged optimized libraries
│ └── *.yaml # Individual library per GEMM type
├── tensile/library/*.dat # Compiled Tensile libraries
├── benchmarks/ # Benchmark configurations
│ ├── *_bench.yaml # Generated benchmark inputs
│ └── *_verify.yaml # Verification inputs
├── results/ # Performance analysis
│ ├── raw_results.csv # All benchmark data
│ └── final_results.csv # Filtered results
└── final_libs/ # Filtered optimized libraries
└── *.yaml # Individual libraries for integration
```
**Search Workflow Output:**
```
workdir/
├── run_state.json # Workflow state tracking
├── hipblaslt-log-mask64.yaml # Updated benchmark file
├── hipblaslt-log-mask64.out # hipblaslt-bench output
├── summary.csv # GEMM contribution analysis
├── gemms.csv # Extracted unique GEMMs
├── winners.csv # Best kernel per GEMM
├── search/ # Dense search results
│ ├── BBS_TN_M1024_N32...yaml # Individual GEMM configs
│ ├── BBS_TN_M1024_N32...out # Benchmark outputs
│ └── failed_jobs.log # Failed benchmark log
├── libs/ # Extracted winning kernels
│ └── *.yaml # Individual library per GEMM type
├── tensile/library/*.dat # Compiled Tensile libraries
├── benchmarks/ # Benchmark configurations
│ └── *_bench.yaml # Generated benchmark inputs
├── results/ # Performance analysis
│ ├── raw_results.csv # All benchmark data
│ └── final_results.csv # Filtered results
└── final_libs/ # Filtered optimized libraries
└── *.yaml # Individual libraries for integration
```
---
## Requirements
### System Dependencies
#### ROCm Installation
ROCm 6.0+ is required. Follow the [Quick start installation guide](https://rocm.docs.amd.com/projects/install-on-linux/en/latest/install/quick-start.html).
**Verify ROCm Installation:**
```bash
/opt/rocm/bin/hipconfig --full
```
Expected output:
```
HIP version: 6.5.50421-9e0f69f3c
HIP_PATH :/opt/rocm-7.0.0
ROCM_PATH :/opt/rocm-7.0.0
HIP_PLATFORM :amd
...
```
Paths and version strings vary with your installation; the listing above is illustrative.
> **Troubleshooting ROCm**
> If you encounter ROCm issues, try a [clean removal](https://rocm.docs.amd.com/projects/install-on-linux/en/docs-7.1.0/install/install-methods/package-manager/package-manager-ubuntu.html#uninstalling) and reinstall. Refer to the [Installation Troubleshooting Guide](https://rocm.docs.amd.com/projects/install-on-linux/en/docs-7.1.0/reference/install-faq.html) for additional help.
> For Runtime errors, refer to the [Runtime Error Triage Checklist](https://github.com/ROCm/rocm-libraries/blob/users/davidd-amd/hipblaslt-triage-checklist.md/docs/hipblaslt-runtime-triage-checklist.md).
#### System Packages
> [!NOTE]
> One may want to fix any broken dependencies first by executing: ```sudo apt update && sudo apt --fix-broken install```
Run the following commands to install required packages:
```
sudo apt update
sudo apt install python3 python3-yaml
sudo apt install clang lldb lld
sudo apt install libomp-dev
sudo apt install libboost-all-dev libboost-program-options-dev libboost-filesystem-dev
sudo apt install libtinfo-dev libzstd-dev libmsgpack-dev libgtest-dev libgmock-dev
```
---
## Installation
### 1. Clone hipBLASLt (Sparse Checkout)
```bash
git clone --no-checkout --filter=blob:none https://github.com/ROCm/rocm-libraries.git
cd rocm-libraries
git sparse-checkout init --cone
git sparse-checkout set projects/hipblaslt shared/origami shared/stinkytofu shared/mxdatagenerator cmake
git checkout develop
```
If you already have hipblaslt, make sure you have the latest commit/version.
### 2. Build hipBLASLt
```bash
cd rocm-libraries/projects/hipblaslt
pip install -r requirements.txt
invoke build --install-deps --clients --install-pkg --architecture gfx950 --skip-rocroller # Replace gfx950 with your GPU architecture - If you need to work with MX datatypes, remove the rocroller flag - Remove the --install-pkg to build locally and to not sytem wide.
```
> See the [hipBLASLt README](../../README.md) for full build prerequisites, supported architectures, and `install.sh` / `invoke build` options.
### 3. Install tensilelite dependencies
```bash
cd rocm-libraries/projects/hipblaslt/tensilelite
pip install -r requirements-dev.txt
```
### 4. Install GEKO Framework
GEKO ships inside the hipBLASLt checkout at `projects/hipblaslt/utilities/geko`
(no separate clone needed — the sparse-checkout above already includes it). It
uses a `pyproject.toml` build, `tox.ini` for test environments, and a
`tasks.py` `invoke` runner. The `invoke` tasks require `invoke` (install it via
`pip install invoke` or `pip install --group dev` if not already present).
```bash
cd rocm-libraries/projects/hipblaslt/utilities/geko
pip install . # installs the geko console script + runtime deps (from requirements.txt)
```
`pip install .` (non-editable) is recommended; developers who want live source edits can use `pip install -e .` (see developer setup below).
> **hipBLASLt path** is auto-detected by the in-tree launchers (`./bin/geko`, `scripts/*.py`). To target a different build, pass `--hipblaslt PATH` on any entry point (see its `--help`) or set `GEKO_HIPBLASLT_PATH`; the installed `geko` command needs one of these.
To set up a development environment (test runner, linters, `invoke`):
```bash
pip install -e . # runtime deps + geko console script
pip install --group dev # dev tools: pytest, invoke, flake8, black, isort
```
Common developer tasks are exposed via `invoke` (run `invoke --list` to see all):
```bash
invoke install # editable install (pip install -e .)
invoke test # run the test suite
invoke test --skip-slow # quick run
invoke lint # flake8 over geko/
invoke format # black + isort
invoke build # build sdist + wheel into dist/
```
From the GEKO package root you can also run the driver without installing (same code path as the installed CLI; adds the package root to ``PYTHONPATH``):
```bash
./bin/geko --help
```
For the full flag list with descriptions and defaults, see [CLI Reference](#cli-reference).
Required packages (see `requirements.txt` for pinned versions):
- `pyyaml` - YAML parsing
- `pandas` - Data manipulation and tabular data operations
- `numpy` - Numerical array operations
- `tqdm` - Progress bars
- `joblib` - Parallel execution
- `pytest` - Test runner (used by the test suite under `tests/`)
### 5. Testing GEKO Framework
From the GEKO root (with dev dependencies installed):
```bash
python3 -m pytest tests/ # direct pytest
invoke test # via the invoke task runner
tox # in an isolated tox environment
```
`tox` and `invoke test` forward extra arguments straight to pytest, e.g.
`tox -- --skip-slow --skip-geko-bin` or `invoke test --skip-slow`.
The plain `python3 -m pytest` / `invoke test` / `tox` paths assume you have already
provisioned the environment by hand (steps 2–4, i.e. `tensilelite/requirements-dev.txt`
which builds `rocisa`). To provision that environment automatically and run the suite
inside it, use the `integration` tox env, which installs the tensilelite dependencies
(`rocisa`) from the hipBLASLt checkout pointed at by `HIPBLASLT_PATH` before running pytest:
```bash
HIPBLASLT_PATH=~/rocm-libraries/projects/hipblaslt tox -e integration
HIPBLASLT_PATH=~/rocm-libraries/projects/hipblaslt tox -e integration -- --skip-slow
```
Tests that require Tensile/`rocisa` are skipped (not errored) when `rocisa` is not
importable, so the hermetic subset still runs in a bare environment.
Integration tests need a hipBLASLt repo and (in some cases) a tuning config and/or a workload log. Pass these via custom pytest options:
```bash
python3 -m pytest tests/ \
--hipblaslt-path ~/rocm-libraries/projects/hipblaslt \
--config tests/config_generator/fixtures/minimal_config.yaml \
--workload tests/test_data/workload.yaml
```
Optional `--hw gfx942` (etc.) overrides the architecture used by configure / optimize integration tests; the default is `gfx950`.
Test markers and skip flags (registered in `tests/conftest.py`):
- `@pytest.mark.slow` — long-running subprocess / GPU integration tests. Skip with `--skip-slow`.
- `@pytest.mark.geko_bin` — subprocess smoke tests for `bin/geko`. Skip with `--skip-geko-bin`.
```bash
# Skip slow and bin/geko subprocess tests for a quick run
python3 -m pytest tests/ --skip-slow --skip-geko-bin
```
See [`tests/README.md`](tests/README.md) for further details on the test layout.
---
## CLI Reference
`./bin/geko` is the single entry point for tuning and benchmarking. The flags below match `./bin/geko --help`. Per-script flags for `scripts/configure.py`, `scripts/optimize.py`, and `scripts/search.py` are documented under [Usage Guide](#usage-guide).
### Mode (exactly one required)
| Flag | Description |
|------|-------------|
| `--tune` | GA workflow: configure then optimize. |
| `--search` | Dense-search tuning workflow. |
| `--bench` | Benchmark GEMMs from the workload only (no tuning). |
### Workload source (exactly one required)
| Flag | Description |
|------|-------------|
| `--workload-log PATH` | hipBLASLt GEMM log YAML (typically captured with `HIPBLASLT_LOG_MASK=64`). |
| `--list PATH` | Generator tuning YAML. See [Specifying GEMMs via a Tuning List (`--list`)](#specifying-gemms-via-a-tuning-list---list) and [`geko/config_generator/config.yaml`](geko/config_generator/config.yaml). |
| `--inline M N batch K DataType DestDataType ComputeDataType transA transB` | Single GEMM on the command line, e.g. `--inline 1024 1024 1 1024 B B S N T`. `transA`/`transB` must each be `N` or `T`. |
### Common options (apply to all modes)
| Flag | Default | Description |
|------|---------|-------------|
| `-d, --devices LIST` | _required_ | Comma-separated GPU device IDs (e.g. `0,1,2,3`). |
| `--workdir PATH` | autogenerated `geko_<timestamp>/` | Output directory for all artifacts of this run. |
| `--keep_thr FLOAT` | `0.0` (`0.1` for `--search`) | Drop GEMMs that contribute less than this fraction of total runtime. |
| `-v, --verbose {0,1,2}` | `1` | Logging verbosity: 0=WARNING, 1=INFO, 2=DEBUG. |
| `--bench-freq` | off | Set `HIPBLASLT_BENCH_FREQ` during `hipblaslt-bench` runs to capture clock-frequency telemetry. Off by default to avoid the small collection overhead. |
### `--tune` options
| Flag | Default | Description |
|------|---------|-------------|
| `--arch ARCH` | _none_ | Target gfx architecture. Can also come from `ARCH:` inside a `--list` YAML. Choices: `gfx950`, `gfx950_128cu`, `gfx942`, `gfx942_80cu`, `gfx942_38cu`, `gfx942_20cu`, `gfx942_228cu`. |
| `--backend {ductile,tensile}` | `ductile` | Tuning backend used in the configure step. Only used with `--tune`. |
| `-n, --n_slots INT` | `4` | Max concurrent optimization jobs per device during the optimize step. |
| `--up_thr FLOAT` | `1.03` | Performance uplift threshold (e.g. `1.03` keeps kernels with ≥3% uplift). |
| `--no_retry` | off | Disable retry of failed optimization jobs. |
### `--search` options
| Flag | Default | Description |
|------|---------|-------------|
| `--duration SEC` | `0.04` | Target dense-search benchmark duration per GEMM. |
### `--bench` options
| Flag | Default | Description |
|------|---------|-------------|
| `--benchmark-duration SEC` | `0.5` | Target seconds per cold and per timed phase of `hipblaslt-bench`. |
### Validation rules (enforced by the parser)
- `--workload-log` and `--list` paths must exist.
- `--inline` requires integer M, N, batch, K and `transA`/`transB` ∈ {`N`, `T`}.
- `--arch` is required with `--tune`.
---
## Usage Guide
| Feature | Best for | Speed |
|---------|----------|-------|
| [GA Optimization](#1-ga-based-optimization) | Maximum performance, custom kernel parameters | Slow (hours) |
| [Dense Search](#2-dense-search-offline-tuning) | Fast results, finding best existing kernels | Faster (minutes) |
| [Benchmark](#3-benchmark) | Baseline measurement, result verification | Fast |
### Capturing a hipBLASLt Workload Log
All tuning and benchmark workflows require a workload input. The most common source is a hipBLASLt log captured from a real application run:
```bash
HIPBLASLT_LOG_MASK=64 HIPBLASLT_LOG_FILE=hipblaslt-log-mask64.yaml python my_application.py
```
Each entry in the log looks like:
```yaml
- {function: matmul, M: 16032, N: 109, K: 16384, lda: 16384, ldb: 16384, ldc: 16032, ldd: 16032, stride_a: 0, stride_b: 0, stride_c: 0, stride_d: 0, alpha: 1.0, beta: 0.0, transA: T, transB: N, batch_count: 1, scaleA: 0, scaleB: 0, scaleAlpha_vector: false, gradient: false, use_e: false, bias_vector: false, bias_source: d, a_type: bf16_r, b_type: bf16_r, c_type: bf16_r, d_type: bf16_r, scale_type: f32_r, bias_type: f32_r, compute_type: c_f32_r, activation_type: none, flush: false, rotating: 512, cold_iters: 0, iters: 0, call_count: 1}
```
Pass it to any mode with `--workload-log`, e.g. `--workload-log hipblaslt-log-mask64.yaml`.
### Specifying GEMMs via a Tuning List (`--list`)
When you do not have (or do not need) a captured log, you can describe the workload directly with a small generator-style YAML and pass it via `--list`. This is convenient for tuning a curated set of sizes (e.g. a fixed benchmark suite) without running an application.
The minimum content is the GEMM type, the architecture, and a list of `[M, N, batch, K]` sizes. A short example:
```yaml
TRANSA: 'N'
TRANSB: 'T'
DataType: "B" # bf16 inputs
DestDataType: "B" # bf16 outputs
ComputeDataType: "S" # fp32 accumulate
ARCH: "gfx950"
Sizes:
- [1024, 1024, 1, 1024]
- [2048, 2048, 1, 2048]
- [4096, 4096, 1, 4096]
```
Save it as e.g. `my_gemm_list.yaml` and pass it to any mode:
```bash
./bin/geko --bench --list my_gemm_list.yaml --devices=0
```
The full template (StreamK, GA, MI filtering, `SIZE_OPTION=1` grid mode, etc.) lives at `geko/config_generator/config.yaml`. Multiple sizes per GEMM type and multiple GEMM problems per file are supported. See [Workload Input Options](#workload-input-options) for the complete set of input flags.
---
### 1. GA-based Optimization
Tunes new kernel parameters using a Genetic Algorithm (via Ductile) or exhaustive Tensile grid search. Produces the highest performance gains but takes hours.
#### Option A: Single CLI command
```bash
./bin/geko --tune --workload-log hipblaslt-log-mask64.yaml --arch gfx950 --devices=0,1,2,3
```
#### Option B: Two-step script control (recommended — lets you review configs before tuning)
**Step 1 — Configure** (`scripts/configure.py`): parse the log, group GEMMs by type, generate tensilelite configs.
**Options:**
| Option | Description | Default |
|--------|-------------|---------|
| `-d, --device` | GPU device for baseline benchmarking | 0 |
| `--keep_thr` | Filter threshold (% of total time) | 0 |
| `-a, --architecture` | Target GPU architecture | gfx950 |
| `-b, --backend` | Tuning backend: `ductile` (GA) or `tensile` (grid) | ductile |
| `-w, --workdir` | Working directory | workdir |
| `-v, --verbose` | Logging verbosity (0=WARNING, 1=INFO, 2=DEBUG) | 1 |
| `--bench-freq` | Enable `HIPBLASLT_BENCH_FREQ` during benchmark runs (only when `--keep_thr > 0`) | False |
```bash
python scripts/configure.py hipblaslt-log-mask64.yaml \
-a gfx950 --workdir my_optimization --keep_thr 0.05 --device 0
```
Output:
```
my_optimization/
├── run_state.json
├── hipblaslt-log-mask64.yaml / hipblaslt-log-mask64.out # Baseline benchmark
├── summary.csv / gemms.csv # GEMM contribution analysis
└── optimizations/
├── BBS_TN_0.yaml # Tensile config per GEMM type
├── BBS_TN_0.sh
└── ...
```
Log:
```
GEKO:INFO [configure:main] Starting configuration phase...
GEKO:INFO [configure:main] Found 2 unique GEMMs after filtering
GEKO:INFO [optim:configure] GemmType(transA='T', transB='N', a_type='bf16_r', ...) with 2 sizes
GEKO:INFO [configure:main] Generated 1 configuration files in 'my_optimization/optimizations'
GEKO:INFO [configure:main] Configuration phase completed successfully!
```
**Step 2 — Optimize** (`scripts/optimize.py`): run GA tuning across GPUs, merge, benchmark, and filter results.
**Options:**
| Option | Description | Default |
|--------|-------------|---------|
| `-w, --workdir` | Working directory with configs | workdir |
| `-d, --devices` | Comma-separated GPU device IDs | 0,1,2,3,4,5,6,7 |
| `-n, --n_slots` | Max concurrent optimization jobs per device | 4 |
| `--up_thr` | Performance uplift threshold | 1.03 (3%) |
| `--err_thr` | Error threshold for filtering | 0.03 |
| `--client_build_dir` | Directory path for tensilelite client build | build_tmp |
| `--no_retry` | Do not retry failed optimizations | False |
| `-v, --verbose` | Logging verbosity (0=WARNING, 1=INFO, 2=DEBUG) | 1 |
| `--bench-freq` | Enable `HIPBLASLT_BENCH_FREQ` during benchmark runs | False |
```bash
python scripts/optimize.py --workdir my_optimization --devices=0,1,2,3 --up_thr 1.03
```
Log:
```
Optimization in progress: 100%|████████| 2/2 [04:33<00:00, 136.5s/it, n_completed: 2, n_failed: 0]
GEKO:INFO [optim:analyze] Average GEMM uplift of 3.1002% for a total of 1 GEMMs
GEKO:INFO [optimize:main] Final optimized library available in: 'my_optimization/final_libs'
GEKO:INFO [optimize:main] Optimization workflow completed successfully!
```
Output:
```
my_optimization/
├── optimizations/build_*/ # Per-GEMM tuning results and logs
├── libs/ # Merged libraries
├── tensile/library/*.dat # Compiled Tensile libraries
├── benchmarks/ # Benchmark inputs
├── results/raw_results.csv / final_results.csv
└── final_libs/ # Ready for integration
└── gfx950_*.yaml
```
#### Step 3 — Integrate
```bash
HIPBLASLT_PATH="/path/to/rocm-libraries/projects/hipblaslt"
LIBRARY_DIR="${HIPBLASLT_PATH}/library/src/amd_detail/rocblaslt/src/Tensile/Logic/asm_full/gfx950/Equality/"
${HIPBLASLT_PATH}/tensilelite/Tensile/bin/TensileMergeLibrary \
--no_eff --force_merge True \
"${LIBRARY_DIR}" my_optimization/final_libs "${LIBRARY_DIR}"
cd "${HIPBLASLT_PATH}"
invoke build --install-deps --clients --architecture gfx950 --skip-rocroller
```
`TensileMergeLibrary` arguments: `--no_eff` skips efficiency calculations; `--force_merge True` forces merge on conflicts; the three positional args are original dir, new libs dir, output dir (same as original to update in place).
**Verify:**
```bash
"${HIPBLASLT_PATH}/build/release/clients/staging/hipblaslt-bench" \
--yaml my_optimization/hipblaslt-log-mask64.yaml --device 0
```
**Install system-wide (optional):**
```bash
cd "${HIPBLASLT_PATH}/build/release"
sudo make -j 64 install && sudo make package
sudo dpkg -i hipblaslt[-\_]*.deb
```
---
### 2. Dense Search (Offline Tuning)
Benchmarks all existing hipBLASLt solutions exhaustively and picks the winner per GEMM — no new kernel parameters are tuned. Much faster than GA optimization.
Both entry points below run the same `run_search` pipeline and produce the same `my_search/` layout.
#### Option A: Single CLI command
```bash
./bin/geko --search --workload-log hipblaslt-log-mask64.yaml \
--devices=0,1,2,3,4,5,6,7 --workdir my_search --keep_thr 0.1 --up_thr 1.03
```
#### Option B: Script entry point (`scripts/search.py`)
Equivalent to Option A but takes the workload log as a positional argument and uses the script-style defaults shared with `configure.py` / `optimize.py`. Only a hipBLASLt workload log (YAML or CSV with the same fields) is accepted as input; for `--list` (generator YAML) or `--inline` GEMM specs, use Option A.
**Options:**
| Option | Description | Default |
|--------|-------------|---------|
| `-d, --devices` | Comma-separated GPU device IDs | 0,1,2,3,4,5,6,7 |
| `--keep_thr` | Filter threshold (% of total time) | 0.1 |
| `--up_thr` | Performance uplift threshold | 1.03 (3%) |
| `-w, --workdir` | Working directory | workdir |
| `--duration` | Target benchmark duration per GEMM (seconds) | 0.04 |
| `-v, --verbose` | Logging verbosity (0=WARNING, 1=INFO, 2=DEBUG) | 1 |
| `--bench-freq` | Enable `HIPBLASLT_BENCH_FREQ` during benchmark runs | False |
```bash
python scripts/search.py hipblaslt-log-mask64.yaml \
--devices=0,1,2,3,4,5,6,7 --workdir my_search --keep_thr 0.1 --up_thr 1.03
```
Log:
```
Search in progress: 100%|████████| 2/2 [10:25<00:00, 20.85s/it, n_completed: 2, n_failed: 0]
GEKO:INFO [optim:analyze] Average GEMM uplift of 10.4697% for a total of 2 GEMMs
GEKO:INFO [search:main] Final remapped library available in: 'my_search/final_libs'
GEKO:INFO [search:main] Search workflow completed successfully!
```
Output:
```
my_search/
├── hipblaslt-log-mask64.yaml / hipblaslt-log-mask64.out # Baseline benchmark
├── summary.csv / gemms.csv / winners.csv
├── search/ # Per-GEMM benchmark files and outputs
├── libs/ # Extracted winning kernels
├── tensile/library/*.dat
├── benchmarks/
├── results/raw_results.csv / final_results.csv
└── final_libs/ # Ready for integration
└── gfx950_*.yaml
```
#### Integrate
Same steps as GA Optimization — run `TensileMergeLibrary` then rebuild hipBLASLt with the contents of `my_search/final_libs`.
---
### 3. Benchmark
Runs hipblaslt-bench on a workload without any tuning. Useful for measuring baseline performance or verifying results after integration.
```bash
# From a workload log
./bin/geko --bench --workload-log hipblaslt-log-mask64.yaml --devices=0
# From a single inline GEMM
./bin/geko --bench --inline 1024 1024 1 1024 B B S N T --devices=0
# From a generator tuning YAML
./bin/geko --bench --list my_gemm_config.yaml --devices=0
```
---
## Module Reference
### `geko.bench` - Benchmarking Module
Handles benchmark execution and performance analysis.
**Key Functions:**
- `bench.run()` - Execute hipblaslt-bench with configuration
- `bench.compare()` - Compare reference vs tuned library performance
- `bench.log.parse()` - Parse hipBLASLt log files
- `bench.log.update()` - Update benchmark configuration (e.g. duration, flush, etc.)
- `bench.log.summarize()` - Analyze and filter GEMMs by contribution
- `bench.utils.parse_benchmark_output()` - Parse benchmark results
**Example Usage:**
```python
from geko import bench
# Parse hipBLASLt logs
df = bench.log.parse("hipblaslt-log-mask64.yaml", as_df=True)
# Summarize GEMM contributions
summary_df, unique_df = bench.log.summarize(
hipblaslt_path="/path/to/rocm-libraries/projects/hipblaslt",
log_file="hipblaslt-log-mask64.yaml",
output_dir="workdir",
keep_thr=0.1,
device=0
)
# Compare libraries
results = bench.compare(
hipblaslt_path="/path/to/rocm-libraries/projects/hipblaslt",
lib_dir="optimized_libs",
custom_lib_dir="build",
benchmark_dir="benchmarks",
device=0
)
```
---
### `geko.optim` - Optimization Module
Orchestrates multi-GPU kernel optimization.
**Key Functions:**
- `optim.configure()` - Generate Tensile configurations
- `optim.run()` - Execute multi-GPU optimization
- `optim.analyze()` - Benchmark and filter optimized kernels
**Example Usage:**
```python
from geko import optim
from geko.schemas import GemmType, GemmConfig
# Create GEMM configuration
gemm_type = GemmType(
transA="T", transB="N",
a_type="bf16_r", b_type="bf16_r",
c_type="bf16_r", compute_type="f32_r"
)
gemm_config = GemmConfig(
gemm_type=gemm_type,
sizes=[[16032, 109, 1, 16384], [16032, 113, 1, 16384]]
)
# Generate configuration
config = optim.configure(
hipblaslt_path="/path/to/rocm-libraries/projects/hipblaslt",
gemm_configs=gemm_config,
output_dir="workdir/optimizations",
arch="gfx950"
)
# Run optimization
optim.run(
hipblaslt_path="/path/to/rocm-libraries/projects/hipblaslt",
tuning_dir="workdir/optimizations",
devices=[0, 1, 2, 3],
retry=True
)
# Analyze results
results = optim.analyze(
hipblaslt_path="/path/to/rocm-libraries/projects/hipblaslt",
lib_dir="workdir/optimizations",
output_dir="workdir/results",
up_thr=1.03,
error_thr=0.03
)
```
---
### `geko.search` - Dense Search Module
Implements exhaustive kernel search workflow (offline tuning) with multi-GPU support.
**Key Functions:**
- `search.configure()` - Generate benchmark configurations from GEMM DataFrame
- `search.run()` - Execute dense search across multiple GPUs
**Example Usage:**
```python
from geko import search
import pandas as pd
# Create benchmark configurations from GEMMs
df = pd.DataFrame([
{'M': 1024, 'N': 1024, 'K': 1024, 'batch_count': 1,
'transA': 'N', 'transB': 'N',
'a_type': 'f16_r', 'b_type': 'f16_r',
'c_type': 'f16_r', 'd_type': 'f16_r',
'compute_type': 'f32_r', 'us': 125.5}
])
configs = search.configure(
df=df,
duration=0.04, # Target 40ms benchmark duration
iters=100,
cold_iters=20,
rotating=512
)
# Run dense search across GPUs
winners = search.run(
hipblaslt_path="/path/to/rocm-libraries/projects/hipblaslt",
configs=configs,
output_dir="search_results",
devices=[0, 1, 2, 3, 4, 5, 6, 7],
)
```
**Features:**
- **Multi-GPU Load Balancing**: Distributes benchmarks across devices
- **Progress Tracking**: Real-time tqdm progress bar with completion/failure counts
- **Cache Support**: Skips re-running completed benchmarks
- **Detailed Logging**: Creates `failed_jobs.log` for troubleshooting
**Workflow Integration:**
```python
from pathlib import Path
from geko import bench, search, optim, library
# 1. Parse and filter GEMMs
summary_df, uniq_df = bench.log.summarize(
hipblaslt_path="/path/to/hipblaslt",
log_file="hipblaslt-log-mask64.yaml",
output_dir="workdir",
keep_thr=0.1,
device=0
)
# 2. Configure and run search
configs = search.configure(summary_df, duration=0.04)
winners = search.run(
hipblaslt_path="/path/to/hipblaslt",
configs=configs,
output_dir="workdir/search",
devices=[0, 1, 2, 3, 4, 5, 6, 7],
)
# 3. Extract winning solutions
match_table = Path("/path/to/hipblaslt/build/release/device-library/MatchTable.yaml")
libs = library.operations.extract_solutions(winners, match_table)
libs.dump("workdir/libs")
# 4. Analyze and filter
results = optim.analyze(
hipblaslt_path="/path/to/hipblaslt",
lib_dir="workdir/libs",
output_dir="workdir/results",
device=0,
up_thr=1.03
)
# 5. Create final library
library.from_dataframe(results, "workdir/libs").dump("workdir/final_libs")
```
---
### `geko.library` - Library Management Module
Manages Tensile library loading, merging, and manipulation.
**Key Classes:**
- `Library` - Represents a single kernel library
- `LibraryCollection` - Collection of multiple libraries
**Key Functions:**
- `library.operations.load_library()` - Load YAML library file
- `library.operations.load_collection()` - Load directory of libraries
- `library.operations.merge_solutions()` - Merge optimized solutions
- `library.operations.extract_solutions()` - Extract solutions by solution index from a DataFrame
- `library.operations.create()` - Call TensileCreateLibrary
- `library.operations.from_dataframe()` - Create libraries from filtered results
- `library.operations.prune_library()` - Trim a library to its minimum required solutions, without losing performance
**Example Usage:**
```python
from geko import library
# Load single library
lib = library.operations.load_library("gfx950_Cijk_Alik_Bljk_BBS_TN.yaml")
# Load collection
collection = library.operations.load_collection("optimized_libs/")
# Remove duplicate sizes/solutions
collection.trim()
# Add epilogue support
collection.add_epilogues()
# Create benchmark inputs
collection.create_bench_input(
output_dir="benchmarks",
verify=True,
duration=1.0,
beta=True
)
# Merge solutions
merged = library.operations.merge_solutions(
input_dir="workdir/optimizations",
epilogues=True
)
# Filter and save
filtered = library.operations.from_dataframe(
df=results_df,
lib_dir="optimized_libs"
)
filtered.dump("final/")
```
---
### `geko.schemas` - Data Structures
Defines typed data structures with validation.
**Classes:**
- `GemmType` - GEMM operation specification
- `GemmConfig` - GEMM type with problem sizes
- `RunState` - Workflow state tracking
**Example Usage:**
```python
from geko.schemas import GemmType, GemmConfig
# Prefer factory constructors (they keep Tensile + hipBLASLt fields consistent).
gemm_type = GemmType.from_hipblaslt(
"T", "N", "f16_r", "f16_r", "f16_r", "f32_r"
)
# Or from Tensile YAML codes only:
# gemm_type = GemmType.from_tensile("N", "T", "H", "H", "S")
gemm_config = GemmConfig(
gemm_type=gemm_type,
sizes=[[1024, 1024, 1, 1024], [2048, 2048, 1, 2048]],
)
rows = gemm_config.workload_log_rows() # hipBLASLt log-shaped dicts (GEMM_LOG_FIELDS)
```
---
### `geko.utils` - Utility Functions
Common utilities for the framework.
**Key Functions:**
- `run_silent_command()` - Execute shell commands silently
- `build_tensilelite_client()` - Build the tensilelite client (cached by hipBLASLt git hash)
- `parse_devices()` - Parse a comma-separated device string into a list of device IDs
**Example Usage:**
```python
from geko.utils import (
build_tensilelite_client,
run_silent_command,
)
# Run command silently
run_silent_command(["ls", "-la", "/tmp"])
# Build tensilelite client
hipblaslt_path = "/path/to/rocm-libraries/projects/hipblaslt"
build_dir = "build_tmp"
build_tensilelite_client(hipblaslt_path, build_dir)
```
---
## Common Usage Patterns
### Pattern 1: Full GA-based Optimization Workflow
```python
from pathlib import Path
from geko import bench, optim, library
from geko.constants import GEMM_TYPE_FIELDS
from geko.schemas import GemmType, GemmConfig
# Paths
hipblaslt_path = "/path/to/rocm-libraries/projects/hipblaslt"
workdir = Path("workdir")
log_file = "hipblaslt-log-mask64.yaml"
# Phase 1: Configure
summary_df, unique_df = bench.log.summarize(
hipblaslt_path,
log_file,
output_dir=workdir,
keep_thr=0.1,
device=0
)
# Generate configurations for each GEMM type
for gemm_type, gby in unique_df.groupby(list(GEMM_TYPE_FIELDS)):
sizes = gby[["m", "n", "batch_count", "k"]].values.tolist()
gemm_type = GemmType(**dict(zip(GEMM_TYPE_FIELDS, gemm_type)))
optim.configure(
hipblaslt_path,
GemmConfig(gemm_type, sizes),
workdir / "optimizations",
arch="gfx950",
)
# Phase 2: Optimize
optim.run(
hipblaslt_path,
tuning_dir=workdir / "optimizations",
devices=[0, 1, 2, 3],
retry=True
)
# Phase 3: Merge and benchmark
merged = library.operations.merge_solutions(
workdir / "optimizations",
epilogues=True
)
merged.dump(workdir / "merged_libs")
results_df = optim.analyze(
hipblaslt_path,
lib_dir=workdir / "merged_libs",
output_dir=workdir / "results",
up_thr=1.03,
error_thr=0.03
)
# Phase 4: Create final library
final = library.operations.from_dataframe(
results_df,
lib_dir=workdir / "merged_libs"
)
final.dump("final/")
```
### Pattern 2: Full Dense Search Workflow
```python
from pathlib import Path
from geko import bench, search, optim, library
# Paths
hipblaslt_path = "/path/to/rocm-libraries/projects/hipblaslt"
workdir = Path("workdir")
log_file = "hipblaslt-log-mask64.yaml"
# Phase 1: Parse and filter GEMMs
summary_df, uniq_df = bench.log.summarize(
hipblaslt_path,
log_file,
output_dir=workdir,
keep_thr=0.1,
device=0
)
# Phase 2: Configure and run search
configs = search.configure(summary_df, duration=0.04)
winners = search.run(
hipblaslt_path,
configs=configs,
output_dir=workdir / "search",
devices=[0, 1, 2, 3, 4, 5, 6, 7],
)
# Phase 3: Extract winning solutions
match_table = Path(hipblaslt_path) / "build/release/device-library/MatchTable.yaml"
libs = library.operations.extract_solutions(winners, match_table)
libs.dump(workdir / "libs")
# Phase 4: Analyze and filter
results = optim.analyze(
hipblaslt_path,
lib_dir=workdir / "libs",
output_dir=workdir / "results",
device=0,
up_thr=1.03
)
# Phase 5: Create final library
library.from_dataframe(results, workdir / "libs").dump(workdir / "final_libs")
```
### Pattern 3: Custom Library Manipulation
```python
from geko import library
# Load and modify library
lib = library.operations.load_library("my_library.yaml")
# Add epilogue support
lib.add_epilogues()
# Create benchmark configurations
bench_file, verify_file = lib.create_bench_input(
output_dir="benchmarks",
verify=True,
duration=2.0,
beta=True,
initialization="trig_float"
)
# Filter sizes based on custom logic
filtered_sizes = [size for size in lib.sizes if size[0][3] < 2048] # Keep small K
lib.sizes = filtered_sizes
lib.trim() # Remove duplicate sizes, unused solutions
# Save modified library
lib.dump("modified_libs")
```
### Pattern 4: Custom Benchmarking
```python
from geko import bench
# Parse existing benchmark results
results = bench.utils.parse_benchmark_output_dir(
"benchmarks",
suffix="_bench"
)
# Run custom benchmark
hipblaslt_path = "/path/to/rocm-libraries/projects/hipblaslt"
# Build custom library (third arg is the output directory; pass version= for code-object version)
library.operations.create(hipblaslt_path, "modified_libs", "build")
benchmark_df = bench.run(
hipblaslt_path="/path/to/rocm-libraries/projects/hipblaslt",
bench_file="custom_bench.yaml",
output_file="results/custom_bench.out",
custom_lib_dir="build",
device=0,
cache=True
)
# Compare libraries
comparison = bench.compare(
hipblaslt_path="/path/to/rocm-libraries/projects/hipblaslt",
lib_dir="optimized_libs",
custom_lib_dir="build",
benchmark_dir="benchmarks",
duration=1.0,
device=0
)
```
---
## Troubleshooting
### Common Issues
#### 1. Configuration Failures
Common causes:
- Failure to benchmark a hipBLASLt log file.
- Invalid GEMM types.
- No solutions found for a given GEMM type and size.
- No tensilelite configurations are generated.
**Solutions:**
**Failure to Benchmark a hipBLASLt Log File:**
Ensure the log file has the correct format and required fields:
```bash
# Verify log file format
head -5 hipblaslt-log-mask64.yaml
```
The log must be a YAML file with GEMM entries containing required fields. Check `geko/constants.py` for `LOG_FIELDS` to see all allowed fields. Required fields include:
- `function`: Must be "matmul"
- `M`, `N`, `K`, `batch_count`: Matrix dimensions and batch size (positive integers)
- `transA`, `transB`: Transpose flags ("T" or "N")
- `a_type`, `b_type`, `c_type`, `d_type`: Data types
- `compute_type`: Computation type
**Example valid log entry:**
```yaml
- {function: matmul, M: 1024, N: 1024, K: 1024, transA: N, transB: N,
a_type: f16_r, b_type: f16_r, c_type: f16_r, d_type: f16_r,
compute_type: c_f32_r, batch_count: 1, alpha: 1.0, beta: 0.0}
```
If the benchmark fails, check for:
- Missing required fields
- Incorrect field names (case-sensitive)
- Invalid data types
- Malformed YAML syntax
**Invalid GEMM Types:**
Check the supported data types in hipBLASLt:
- Visit the [tensilelite DataType definitions](https://github.com/ROCm/rocm-libraries/blob/develop/projects/hipblaslt/tensilelite/Tensile/Common/DataType.py)
- Verify your log file contains valid `a_type`, `b_type`, `c_type`, and `compute_type` combinations
- Example valid types: `f16_r`, `bf16_r`, `f32_r`, `f8_r`, `bf8_r`
**Invalid GEMM Sizes:**
Ensure all GEMM dimensions are positive integers:
```bash
# Check your log file for invalid sizes
grep -E "M: [^0-9]|N: [^0-9]|K: [^0-9]" hipblaslt-log-mask64.yaml
# Valid example: M: 1024, N: 1024, K: 1024
# Invalid example: M: 0, N: -1, K: 1024.5
```
**No Solutions Found for GEMM Type/Size:**
If you encounter errors like "No solutions found":
- **Important GEMMs**: Contact the GEMM Optimization team for support
- **Non-critical GEMMs**: Remove the problematic GEMM from your hipBLASLt log file
**No tensilelite Configurations Generated:**
If `scripts/configure.py` produces no configuration files:
```bash
# Lower the keep threshold to include more GEMMs
python scripts/configure.py hipblaslt-log-mask64.yaml \
--keep_thr 0.01 # Include GEMMs contributing >= 0.01% of total time
# Or set to 0 to include all GEMMs
python scripts/configure.py hipblaslt-log-mask64.yaml --keep_thr 0
```
#### 2. Optimization Failures
Check `workdir/optimizations/failed_jobs.log` for details.
Common causes:
- Unstable rocm-libraries version, leading to assembly compile errors.
- No available AMD GPU devices.
- No valid kernels could be generated. Re-visit the configuration step.
**Solutions:**
```bash
# To not retry failed optimizations
python scripts/optimize.py --workdir workdir --no_retry
# Use the appropriate devices or check if your GPUs are available (amd-smi command)
python scripts/optimize.py --devices=0,1
# Check individual logs for detailed errors
cat workdir/optimizations/build_*/BBS_TN_0-tensilelite.log
```
#### 3. Import Errors
```bash
# Ensure GEKO is in Python path
export PYTHONPATH=/path/to/geko:$PYTHONPATH
# Or install the package
pip install .
# Or install in development mode
pip install -e .
```
### Debug Mode
Enable verbose logging:
```bash
# Maximum verbosity
python scripts/configure.py log.yaml -v 2
python scripts/optimize.py -v 2
python scripts/search.py log.yaml -v 2
# Python script
import logging
logging.getLogger("GEKO").setLevel(logging.DEBUG)
```
### Performance Tips
1. **Use appropriate keep_thr**: Higher threshold = fewer GEMMs = faster optimization
```bash
python scripts/configure.py ... --keep_thr 1.0 # Only with 1% contribution or higher
```
2. **Optimize GPU allocation**: Match device count to available GPUs
```bash
python scripts/optimize.py ... --devices=0,1 # Use only 2 GPUs
```
3. **Enable caching**: Reuse benchmark results
```python
bench.compare(..., cache=True)
```
4. **Parallel library dumps**: Automatically parallelized in `LibraryCollection.dump()`
---
## Contributing
To contribute to our repository, you can create a GitHub pull request. Please follow these guidelines:
1. Follow Google-style docstrings
2. Add type hints to all functions
3. Use descriptive variable names
4. Include examples in module docstrings
5. Test on multiple GPU architectures
If you want to submit an issue, you can do so on
[GitHub](https://github.com/ROCm/rocm-libraries/issues).
---
## License
MIT License. Copyright (C) Advanced Micro Devices, Inc.