Files
wehub-resource-sync 26446540fa
Lint / lint (push) Waiting to run
CI / MacOS (push) Waiting to run
CI / Windows (push) Waiting to run
chore: import upstream snapshot with attribution
2026-07-13 13:36:25 +08:00

78 lines
2.5 KiB
Python

# Licensed to the Apache Software Foundation (ASF) under one
# or more contributor license agreements. See the NOTICE file
# distributed with this work for additional information
# regarding copyright ownership. The ASF licenses this file
# to you under the Apache License, Version 2.0 (the
# "License"); you may not use this file except in compliance
# with the License. You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing,
# software distributed under the License is distributed on an
# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
# KIND, either express or implied. See the License for the
# specific language governing permissions and limitations
# under the License.
"""Codegen registry for CUDA HW ops.
User-facing Python wrappers are hand-written in :mod:`tvm.tirx.op` so that
editors / static analyzers (Cursor, Pyright) can see their signatures. This
module only handles the backend codegen side.
"""
import functools
import tvm_ffi
CODEGEN_REGISTRY = {}
def _canonical_device_intrin_name(op_name: str) -> str:
if not op_name.startswith("tirx."):
return op_name
basename = op_name[len("tirx.") :]
if "." in basename:
return op_name
for prefix, namespace in (
("cuda_", "cuda"),
("ptx_", "ptx"),
("nvshmem_", "nvshmem"),
("nki_", "nki"),
):
if basename.startswith(prefix):
return f"tirx.{namespace}.{basename[len(prefix) :]}"
return op_name
@tvm_ffi.register_global_func("tirx.intrinsics.cuda.get_codegen")
def get_codegen(op):
"""get the codegen function for a given op"""
return CODEGEN_REGISTRY.get(op, None)
def register_codegen(op, backend="cuda"):
"""Register a codegen function for a given op.
The codegen function should return a ``cuda_func_call`` statement, and
optionally a list of tags that the codegen function needs.
"""
def decorator(func):
full_op_name = "tirx." + op
canonical_op_name = _canonical_device_intrin_name(full_op_name)
op_names = {full_op_name, canonical_op_name}
@functools.wraps(func)
def wrapper(arg_list):
res = func(*arg_list) # pylint: disable=not-callable
if isinstance(res, tuple):
return res[0], res[1]
return res, list()
for op_name in op_names:
CODEGEN_REGISTRY[op_name] = wrapper
return wrapper
return decorator