Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions .ci/scripts/tests/test_filter_cuda_matrix.py
Original file line number Diff line number Diff line change
Expand Up @@ -327,6 +327,8 @@ def test_supported_toolkits_select_the_matching_torch_index(self):
INSTALL_UTILS.platform, "system", return_value="Linux"
), mock.patch.object(
INSTALL_UTILS.subprocess, "run", return_value=detected
), mock.patch.dict(
os.environ, {"CMAKE_ARGS": "-DEXECUTORCH_BUILD_CUDA=ON"}
):
self.assertEqual(
INSTALL_UTILS.determine_torch_url(base_url),
Expand Down
1 change: 1 addition & 0 deletions .ci/scripts/wheel/test_shared_libraries.py
Original file line number Diff line number Diff line change
Expand Up @@ -92,6 +92,7 @@
_AOTI_SHIM_SYMBOLS = (
"aoti_torch_empty_strided",
"aoti_torch_delete_tensor_object",
"aoti_torch_dtype_element_size",
"executorch::backends::cuda::CUDAStreamGuard::create",
# From the CUDA sources rather than the C++ ones. The build drops every .cu file when no working
# compiler is found, and the library is still produced from its .cpp sources, so a check that
Expand Down
8 changes: 7 additions & 1 deletion .github/workflows/pull.yml
Original file line number Diff line number Diff line change
Expand Up @@ -213,7 +213,13 @@ jobs:
EXECUTORCH_PYBIND_TEST_BFLOAT16_CHANNELS_LAST_PTE=cmake-out-no-aten/add_bfloat16_channels_last.pte \
PYTHONPATH=cmake-out-no-aten:.. \
python extension/pybindings/test/test_pybindings_no_aten.py
if ldd cmake-out-no-aten/_C*.so | grep -Eiq 'torch|aten|c10'; then
NO_ATEN_LINKS="$(ldd cmake-out-no-aten/_C*.so)"
printf '%s\n' "$NO_ATEN_LINKS"
if grep -q 'not found' <<<"$NO_ATEN_LINKS"; then
echo "torch-free pybindings have a missing runtime dependency"
exit 1
fi
if grep -Eiq '^[[:space:]]*(lib(torch|aten|c10)[^[:space:]/]*\.so|[^[:space:]]*/lib(torch|aten|c10)[^[:space:]/]*\.so)' <<<"$NO_ATEN_LINKS"; then
echo "torch-free pybindings unexpectedly link against ATen"
exit 1
fi
Expand Down
14 changes: 13 additions & 1 deletion .github/workflows/release-runner-groups-refresh.yml
Original file line number Diff line number Diff line change
Expand Up @@ -23,8 +23,20 @@ concurrency:
cancel-in-progress: true

jobs:
dispatch:
if: github.repository_owner == 'pytorch' && github.event_name == 'push'
runs-on: ubuntu-latest
permissions:
actions: write
steps:
- name: Refresh runner groups from protected main
env:
GH_TOKEN: ${{ github.token }}
GH_REPO: ${{ github.repository }}
run: gh workflow run release-runner-groups-refresh.yml --ref main -f apply=true

reconcile:
if: github.repository_owner == 'pytorch'
if: github.repository_owner == 'pytorch' && github.event_name != 'push'
runs-on: ubuntu-latest
environment: ${{ github.event_name != 'pull_request' && 'runner-group' || '' }}
steps:
Expand Down
5 changes: 5 additions & 0 deletions backends/aoti/common_shims_slim.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -164,6 +164,11 @@ int32_t aoti_torch_dtype_bool() {
return 11; // ScalarType::Bool
}

size_t aoti_torch_dtype_element_size(int32_t dtype) {
using namespace executorch::backends::aoti::slim::c10;
return elementSize(static_cast<ScalarType>(dtype));
}

// ============================================================
// Device Type Constants - Implementations
// ============================================================
Expand Down
2 changes: 2 additions & 0 deletions backends/aoti/common_shims_slim.h
Original file line number Diff line number Diff line change
Expand Up @@ -87,6 +87,8 @@ AOTI_SHIM_EXPORT int32_t aoti_torch_dtype_int8();
AOTI_SHIM_EXPORT int32_t aoti_torch_dtype_uint8();
AOTI_SHIM_EXPORT int32_t aoti_torch_dtype_bool();

AOTI_SHIM_EXPORT size_t aoti_torch_dtype_element_size(int32_t dtype);

// ============================================================
// Device Type Constants - Declarations
// ============================================================
Expand Down
Binary file modified backends/cuda/runtime/aoti_cuda_shims.lib
Binary file not shown.
7 changes: 5 additions & 2 deletions backends/cuda/runtime/aoti_cuda_shims.lib.md
Original file line number Diff line number Diff line change
Expand Up @@ -10,12 +10,12 @@ pin moves and the generated wrapper starts calling something new:

```
nm --defined-only aoti_cuda_shims.lib \
| sed -n 's/.* T _\?\(aoti_torch_[a-z_0-9]*\)$/\1/p' \
| sed -n 's/.* T _\?\(aoti_torch_[A-Za-z_0-9]*\)$/\1/p' \
| sort -u > exports.txt
# add the new names to exports.txt, then
{ echo 'LIBRARY aoti_cuda_shims.dll'; echo 'EXPORTS'; sed 's/^/ /' exports.txt; } \
> aoti_cuda_shims.def
x86_64-w64-mingw32-dlltool -d aoti_cuda_shims.def -l aoti_cuda_shims.lib \
x86_64-w64-mingw32-dlltool -m i386:x86-64 -d aoti_cuda_shims.def -l aoti_cuda_shims.lib \
--dllname aoti_cuda_shims.dll
# zero the archive metadata so the file is reproducible
mkdir extract && cd extract && x86_64-w64-mingw32-ar x ../aoti_cuda_shims.lib \
Expand All @@ -27,6 +27,9 @@ The archive has to be built at a fresh path. Updating it in place keeps the reve
member order the generator produced, so the same export list would not give the same
bytes twice.

Use the relative output name shown above in each build directory. The generator embeds
the output name in its object names, so absolute temporary paths change the bytes.

Then check the result is a superset of what it replaced and that no member carries a
timestamp, since this file ships in the wheel and a stamped one makes two builds of
the same source differ.
Expand Down
5 changes: 3 additions & 2 deletions backends/cuda/tests/test_int6_large_quantized_gemm.py
Original file line number Diff line number Diff line change
Expand Up @@ -76,8 +76,9 @@ def test_buckets_and_generic_candidate_counts(self):
for bucket, expected in expected_counts.items():
configs = tile_autotune_configs(bucket)
self.assertEqual(len(configs), expected)
self.assertEqual(len(legal_configs(bucket, 256)), expected // 3)
self.assertEqual(len(legal_configs(bucket, 5376)), expected)
legal_expected = 18 if torch.version.hip is not None else expected
self.assertEqual(len(legal_configs(bucket, 256)), legal_expected // 3)
self.assertEqual(len(legal_configs(bucket, 5376)), legal_expected)
self.assertTrue(hasattr(torch.ops.triton, f"int6_quantized_gemm_m{bucket}"))

@unittest.skipUnless(torch.cuda.is_available(), "CUDA required")
Expand Down
4 changes: 4 additions & 0 deletions backends/cuda/triton/kernels/int6_quantized_gemm.py
Original file line number Diff line number Diff line change
Expand Up @@ -1239,6 +1239,10 @@ def _tile_main_loop_trips(args) -> int:


def _prune_tiles(configs, named_args, **kwargs):
if torch.version.hip is not None:
# Larger M tiles can access invalid memory on masked tails with ROCm
# 7.14. Keep the eight-row path for the release.
configs = [config for config in configs if config.kwargs["BLOCK_M"] == 8]
return prune_by_main_loop_trips(
_tile_main_loop_trips, configs, named_args, **kwargs
)
Expand Down
25 changes: 21 additions & 4 deletions examples/cuda/scripts/export_amd_pointwise.py
Original file line number Diff line number Diff line change
Expand Up @@ -66,7 +66,11 @@ def main() -> None:
CompileSpec("target_device", f"cuda:{device_index}".encode()),
CompileSpec("triton_kernel_mode", b"ON"),
CompileSpec("max_autotune", b"OFF"),
CompileSpec("autotune_at_compile_time", b"OFF"),
# Compile the Triton kernels during AOTI lowering: with
# autotune_at_compile_time OFF, AOTInductor also generates JIT code
# and the JIT code fails to run on gfx950 with the pinned
# ROCm 7.14 toolchain, so lowering never completes.
CompileSpec("autotune_at_compile_time", b"ON"),
]
edge_program = to_edge_transform_and_lower(
exported_program,
Expand Down Expand Up @@ -106,10 +110,20 @@ def main() -> None:
if not ptd_path.is_file():
raise RuntimeError(f"expected AOTI data file was not created: {ptd_path}")

# Verify the embedded code object matches the active device.
triple = f"amdgcn-amd-amdhsa--{arch}".encode()
if triple not in pte_path.read_bytes():
# Verify the generated code object targets the active device. The
# toolchain embeds the bare architecture name, not the full amdgcn
# triple, in the program and in the hsaco files, so check for that
# and require a compiled hsaco for the device.
arch_marker = arch.encode()
if arch_marker not in pte_path.read_bytes():
raise RuntimeError(f"{pte_path} embeds no code object for {arch}")
hsaco_paths = [
hsaco_path
for hsaco_path in cache_dir.rglob("*.hsaco")
if arch_marker in hsaco_path.read_bytes()
]
if not hsaco_paths:
raise RuntimeError(f"no hsaco code object for {arch} under {cache_dir}")

print(f"ROCm: {torch.version.hip}")
print(f"Compile GPU: cuda:{device_index} {device.name} ({device.gcnArchName})")
Expand All @@ -119,6 +133,9 @@ def main() -> None:
print("Triton sources:")
for source_path in triton_sources:
print(f" {source_path}")
print("Code objects:")
for hsaco_path in hsaco_paths:
print(f" {hsaco_path}")


if __name__ == "__main__":
Expand Down