You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
[FEA]: Support a MetaTensor that does not hold data for debug purposes. #56
Is this a new feature, an improvement, or a change to existing functionality?
New Feature
How would you describe the priority of this feature request?
High
Please provide a clear description of problem this feature solves
Is it possible to support a MetaTensor that does not hold data for debug purposes?
Feature Description
We can utilize this to run the frontmost part of cuTile (python->hir->ir->TileIR) and either dump IR from each level for inspection or build tools like transpiler without having to create real data on GPU and even calling tileiras.
This comes from my personal experiments; (1) I have to develop on machines without Blackwell GPUs; (2) I have tried to implement a LSP server and cuTile -> numpy transpiler for debug purposes, but found it hard to catch up to the rapid development of cuTile mainstream.
Describe your ideal solution
If possible, I would like to discuss what the interface looks like and/or implement this.
Describe any alternatives you have considered
No response
Additional context
No response
Contributing Guidelines
I agree to follow cuTile Python's contributing guidelines
I have searched the open feature requests and have found no duplicates for this feature request
import cuda.tile as ct
from cuda.tile._cext import default_tile_context
from cuda.tile._compile import _get_final_ir
class FakeTensor:
@property
def __cuda_array_interface__(self):
return dict(
typestr="f4", # float32
shape=(100, 200),
strides=None, # C-contiguous format
data=(0, False),
)
@ct.kernel
def kernel(x):
t = ct.gather(x, (0, 0))
ct.scatter(x, (1, 1), t)
x = FakeTensor()
print(_get_final_ir(kernel._pyfunc, (x,), default_tile_context))
This still requires building the C++ extension, unfortunately. Please let us know if there are any gaps that we could address.
As for the rapid development, we hope the big disruptive changes will slow down soon, once we land certain features like lambdas etc.
import cuda.tile as ct
from cuda.tile._cext import default_tile_context
from cuda.tile._compile import _get_final_ir
class FakeTensor:
@property
def __cuda_array_interface__(self):
return dict(
typestr="f4", # float32
shape=(100, 200),
strides=None, # C-contiguous format
data=(0, False),
)
@ct.kernel
def kernel(x):
t = ct.gather(x, (0, 0))
ct.scatter(x, (1, 1), t)
x = FakeTensor()
print(_get_final_ir(kernel._pyfunc, (x,), default_tile_context))
This still requires building the C++ extension, unfortunately. Please let us know if there are any gaps that we could address. As for the rapid development, we hope the big disruptive changes will slow down soon, once we land certain features like lambdas etc.
I have already tried __cuda_array_interface__, but it comes with limitations (as of my knowledge), the primary one is it does not seem to support bfloat16 or lower precision
Personally I would desire a solution without any C++ code... I have tried to workaround this in my personal repos, and would like to know if it is possible for the cuTile mainstream to include something like this. (line number may be wrong because this diff is based on a legacy commit)
(Added: _cext.py to mock the missing lib, this part is vibe coded)
fromcuda.tile._contextimportTileContextConfigdeflaunch(stream, grid, kernel, kernel_args, /):
"""Mock launch function - does not actually launch kernel"""raiseRuntimeError(
"Cannot launch kernel: CUDA driver not available. This mock module only supports IR generation."
)
classTileDispatcher:
"""Mock TileDispatcher class"""def__new__(cls, *args, **kwargs):
# 正确处理 __new__ 方法instance=object.__new__(cls)
returninstancedef__init__(self, arg_constant_flags, compile_func):
self._arg_constant_flags=arg_constant_flagsself._compile_func=compile_funcclassTileContext:
"""Mock TileContext class"""def__init__(self, config=None):
ifconfigisNone:
fromcuda.tile._contextimportinit_context_config_from_envconfig=init_context_config_from_env()
self._config=config@propertydefconfig(self):
returnself._config# Create default tile contextdefault_tile_context=TileContext()
defget_compute_capability():
"""Mock get_compute_capability - returns a default value"""# Return Hopper (9.0) as default# Users can modify this if neededreturn (9, 0)
classArraySpecialization:
"""Mock ArraySpecialization class for array type analysis"""def__init__(self, base_ptr, dtype_bitwidth, shape, strides):
self.base_ptr=base_ptrself.dtype_bitwidth=dtype_bitwidthself.shape=shapeself.strides=strides# 简单的启发式规则:假设所有 stride 都是静态的self.stride_is_static=tuple(Truefor_instrides)
# 假设元素不重叠self.elements_disjoint=True# 对齐信息:假设基本对齐self.base_ptr_div_by=dtype_bitwidth//8# 按字节对齐self.stride_div_by=tuple(1for_instrides)
self.shape_div_by=tuple(1for_inshape)
Currently get_final_ir depend on TileContext (defined in C++ code?) which seems not referenced based on a simple code search. Is it possible to get rid of it, or does it serve some undocumented purposes? Could you please explain? Thanks a lot. If the _get_final_ir function can be independent on C++ code, can we split the _get_final_ir function into 2 halves (first pure python half, then python + C++ half) and expose a public interface for the first half?
Sorry for my bad English, if there is anything not clear please ask for my clarification.
Since we only need tensor metadata to compile the cuTile kernel (without tensor data), is it possible to first construct such metadata into a dedicated dataclass, compile the kernel, and launch the kernel with real data? This could make the FakeTensor workflow not an exception, but a "part of the main compiler workflow".
Since we only need tensor metadata to compile the cuTile kernel (without tensor data), is it possible to first construct such metadata into a dedicated dataclass, compile the kernel, and launch the kernel with real data? This could make the FakeTensor workflow not an exception, but a "part of the main compiler workflow".
Yes, something along those lines is on our TODO list. Right now there is duplicated logic between the C++ dispatcher code (classify_arg() and friends) and the Python side (typeof_pyval etc.), which is very fragile. It would be great if the C++ dispatcher decided what the types are and passed them to the compilation pipeline. This would also be very useful for supporting ahead-of-time compilation. However, I don't know when we can get to it. I'll try to prioritize this when I have some time free from scheduled feature work.
I have already tried cuda_array_interface, but it comes with limitations (as of my knowledge), the primary one is it does not seem to support bfloat16
I believe bfloat16 is supported (typestring V2, see parse_typestr() in tile_kernel.cpp), but yes, I agree it is a limited interface, e.g. it is not possible to express float8 types.
Currently get_final_ir depend on TileContext (defined in C++ code?) which seems not referenced based on a simple code search. Is it possible to get rid of it, or does it serve some undocumented purposes? Could you please explain? Thanks a lot. If the _get_final_ir function can be independent on C++ code, can we split the _get_final_ir function into 2 halves (first pure python half, then python + C++ half) and expose a public interface for the first half?
The goal of TileContext is to store all global state, like the flags set by environment variables etc. This is still work in progress, but it is already used in hir2ir in order to check the debug printing settings (via ir_ctx.tile_ctx). The idea is that if another library needs to depend on cutile, it can create an isolated context that is unaffected by environment variables etc. We need to access the TileContext object in the C++ dispatcher, so we can't move it to Python for performance reasons. Is there a specific reason you want to avoid building the C++ extension? It has very minimal dependencies and should be relatively simple to build. If you need to build it on a Mac, or don't want to install the CUDA toolkit, we could in theory add some conditional compilation to build a "dummy" extension with stubbed out functionality (this is also on my personal TODO list).
As an alternative , I think maybe we could change _get_final_ir to accept a TileContextConfig instead of the full TileContext object, which is a pure python class.
I have tried to workaround this in my personal repos, and would like to know if it is possible for the cuTile mainstream to include something like this.
I'd be in favor of adding a more explicit compilation API, e.g. going the "part of the main compiler workflow" route. Also, once your LSP server reaches a usable state, would you be interested in upstreaming it? This could help us deal with the internal API breakages, as we could test it in the CI. It doesn't have to be part of the main package, as we can put it into the experimental package or similar.
It is already usable in my sense, and it is here, but it is based on commit 7a8625 (before the introduction of hir), and it is probably buggy. Its type information comes from the ir after typecheck but before any optimization. There is also a to-numpy transpiler in transpile branch, which is also based on a legacy commit.
going the "part of the main compiler workflow" route
My naive idea can be illustrated in this flowchart
Is there a specific reason you want to avoid building the C++ extension?
The main reason is to avoid building a C++ extension just for a debug tool where we actually don't need to use anything inside it, to Make it possible to do this level of debugging on computers without NVIDIA hardware or even Mac.
As an alternative , I think maybe we could change _get_final_ir to accept a TileContextConfig instead of the full TileContext object, which is a pure python class.
This would be great! As far as I know, syntax checking and type checking is done inside _get_final_ir, which means this approach makes it possible to raise any possible errors when converting a python program into a valid cuTile-python program without C++ libraries. I think this is pretty much everything needed to develop debug tools.
The main reason is to avoid building a C++ extension just for a debug tool where we actually don't need to use anything inside it, to Make it possible to do this level of debugging on computers without NVIDIA hardware or even Mac.
You shouldn't need NVIDIA hardware to compile the C++ extension, a normal C++ compiler should be sufficient (we support GCC and MSVC, hopefully clang should work as well). I agree that it would be nice to drive the compilation pipeline with pure Python, but I'm afraid this may not be viable in the long term. The C++ extension needs to have the logic similar to typeof_pyval() to be able to quickly classify the arguments, and thus we'd need to duplicate the logic in Python (which we currently do, but ideally we need to get rid of this duplication).
In any case, I have staged a change to _get_final_ir that should hopefully address your use case:
Now we take a TileContextConfig instead of TileContext. It can be obtained by calling init_context_config_from_env().
Instead of args, we take a sequence of KernelArgument structs, which is a renamed ir.Argument:
@dataclass
class KernelArgument:
type: Type
is_const: bool = False
const_value: Any = None
I hope this should allow you to drive the compilation pipeline without creating concrete array objects. The KernelArgument class should work similarly to a "meta tensor", with the downside of having to also call get_constant_annotations() etc. yourself.
The change is stacked on top of a couple other in-progress PRs, so it should hopefully get into public main sometime next week.
I have synced the cutile to numpy transpiler to newest main branch (it's here, and it's definitely buggy), as a proof of concept that everything it need is the output of _get_final_ir
You shouldn't need NVIDIA hardware to compile the C++ extension, a normal C++ compiler should be sufficient (we support GCC and MSVC, hopefully clang should work as well).
@gbonik May I ask if there are any instructions to compile the C++ extension without an NVIDIA GPU? When I run pip install -e . currently, it still requires CTK to be installed:
error: subprocess-exited-with-error
× Building editable for cuda-tile (pyproject.toml) did not run successfully.
│ exit code: 1
╰─> [40 lines of output]
running editable_wheel
creating /tmp/pip-wheel-tt5sdcxh/.tmp-g4l145e6/cuda_tile.egg-info
writing /tmp/pip-wheel-tt5sdcxh/.tmp-g4l145e6/cuda_tile.egg-info/PKG-INFO
writing dependency_links to /tmp/pip-wheel-tt5sdcxh/.tmp-g4l145e6/cuda_tile.egg-info/dependency_links.txt
writing requirements to /tmp/pip-wheel-tt5sdcxh/.tmp-g4l145e6/cuda_tile.egg-info/requires.txt
writing top-level names to /tmp/pip-wheel-tt5sdcxh/.tmp-g4l145e6/cuda_tile.egg-info/top_level.txt
writing manifest file '/tmp/pip-wheel-tt5sdcxh/.tmp-g4l145e6/cuda_tile.egg-info/SOURCES.txt'
reading manifest file '/tmp/pip-wheel-tt5sdcxh/.tmp-g4l145e6/cuda_tile.egg-info/SOURCES.txt'
adding license file 'LICENSES/Apache-2.0.txt'
writing manifest file '/tmp/pip-wheel-tt5sdcxh/.tmp-g4l145e6/cuda_tile.egg-info/SOURCES.txt'
creating '/tmp/pip-wheel-tt5sdcxh/.tmp-g4l145e6/cuda_tile-9.9.99.dist-info'
creating /tmp/pip-wheel-tt5sdcxh/.tmp-g4l145e6/cuda_tile-9.9.99.dist-info/WHEEL
running build_py
running build_ext
cmake -B /root/dev/cutile-dev/build /root/dev/cutile-dev -DDLPACK_PATH= -DCMAKE_BUILD_TYPE=Release -DCMAKE_POLICY_VERSION_MINIMUM=3.5
-- The C compiler identification is GNU 12.3.1
-- The CXX compiler identification is GNU 12.3.1
-- Detecting C compiler ABI info
-- Detecting C compiler ABI info - done
-- Check for working C compiler: /usr/bin/cc - skipped
-- Detecting C compile features
-- Detecting C compile features - done
-- Detecting CXX compiler ABI info
-- Detecting CXX compiler ABI info - done
-- Check for working CXX compiler: /usr/bin/c++ - skipped
-- Detecting CXX compile features
-- Detecting CXX compile features - done
-- Found Python: /root/miniconda3/bin/python3.1 (found version "3.13.5") found components: Interpreter Development Development.Module Development.Embed
-- Looking for CUDA Toolkit
-- No cuda.h found in /usr/local/cuda/include
CMake Error at /usr/share/cmake/Modules/FindPackageHandleStandardArgs.cmake:230 (message):
Could NOT find CUDAToolkit (missing: CUDAToolkit_INCLUDE_DIR)
Call Stack (most recent call first):
/usr/share/cmake/Modules/FindPackageHandleStandardArgs.cmake:600 (_FPHSA_FAILURE_MESSAGE)
cmake/FindCUDAToolkit.cmake:32 (find_package_handle_standard_args)
CMakeLists.txt:69 (find_package)
-- Configuring incomplete, errors occurred!
error: command '/usr/bin/cmake' failed with exit code 1
[end of output]
note: This error originates from a subprocess, and is likely not a problem with pip.
ERROR: Failed building editable for cuda-tile
Failed to build cuda-tile
ERROR: Failed to build installable wheels for some pyproject.toml based projects (cuda-tile)
There is currently no way to build without CUDA SDK, but we can add an option to CMake and some #ifdefs to the code. I can try to sneak in the necessary change within the next couple of weeks.
Also, once your LSP server reaches a usable state, would you be interested in upstreaming it? This could help us deal with the internal API breakages, as we could test it in the CI. It doesn't have to be part of the main package, as we can put it into the experimental package or similar.
@gbonik The LSP server I implemented is here. It now works with cuda-tile v1.1.0 (or the current main branch) and I deem it usable though it is still buggy:
Activity
gbonik commentedon Jan 13, 2026
Hi @Da1sypetals, thanks for you question. I believe it should be possible to implement a fake
__cuda_array_interface__to make this work (see https://numba.readthedocs.io/en/stable/cuda/cuda_array_interface.html ).Here is an example that Works On My Machine (TM):
This still requires building the C++ extension, unfortunately. Please let us know if there are any gaps that we could address.
As for the rapid development, we hope the big disruptive changes will slow down soon, once we land certain features like lambdas etc.
Da1sypetals commentedon Jan 14, 2026
__cuda_array_interface__, but it comes with limitations (as of my knowledge), the primary one is it does not seem to support bfloat16 or lower precision(Added:
_cext.pyto mock the missing lib, this part is vibe coded)get_final_irdepend on TileContext (defined in C++ code?) which seems not referenced based on a simple code search. Is it possible to get rid of it, or does it serve some undocumented purposes? Could you please explain? Thanks a lot. If the_get_final_irfunction can be independent on C++ code, can we split the_get_final_irfunction into 2 halves (first pure python half, then python + C++ half) and expose a public interface for the first half?Da1sypetals commentedon Jan 14, 2026
Since we only need tensor metadata to compile the cuTile kernel (without tensor data), is it possible to first construct such metadata into a dedicated dataclass, compile the kernel, and launch the kernel with real data? This could make the FakeTensor workflow not an exception, but a "part of the main compiler workflow".
gbonik commentedon Jan 14, 2026
Yes, something along those lines is on our TODO list. Right now there is duplicated logic between the C++ dispatcher code (
classify_arg()and friends) and the Python side (typeof_pyvaletc.), which is very fragile. It would be great if the C++ dispatcher decided what the types are and passed them to the compilation pipeline. This would also be very useful for supporting ahead-of-time compilation. However, I don't know when we can get to it. I'll try to prioritize this when I have some time free from scheduled feature work.I believe bfloat16 is supported (typestring
V2, seeparse_typestr()intile_kernel.cpp), but yes, I agree it is a limited interface, e.g. it is not possible to express float8 types.The goal of TileContext is to store all global state, like the flags set by environment variables etc. This is still work in progress, but it is already used in hir2ir in order to check the debug printing settings (via ir_ctx.tile_ctx). The idea is that if another library needs to depend on cutile, it can create an isolated context that is unaffected by environment variables etc. We need to access the TileContext object in the C++ dispatcher, so we can't move it to Python for performance reasons. Is there a specific reason you want to avoid building the C++ extension? It has very minimal dependencies and should be relatively simple to build. If you need to build it on a Mac, or don't want to install the CUDA toolkit, we could in theory add some conditional compilation to build a "dummy" extension with stubbed out functionality (this is also on my personal TODO list).
As an alternative , I think maybe we could change
_get_final_irto accept a TileContextConfig instead of the full TileContext object, which is a pure python class.I'd be in favor of adding a more explicit compilation API, e.g. going the "part of the main compiler workflow" route. Also, once your LSP server reaches a usable state, would you be interested in upstreaming it? This could help us deal with the internal API breakages, as we could test it in the CI. It doesn't have to be part of the main package, as we can put it into the
experimentalpackage or similar.Da1sypetals commentedon Jan 15, 2026
It is already usable in my sense, and it is here, but it is based on commit 7a8625 (before the introduction of hir), and it is probably buggy. Its type information comes from the ir after typecheck but before any optimization. There is also a to-numpy transpiler in
transpilebranch, which is also based on a legacy commit.My naive idea can be illustrated in this flowchart

The main reason is to avoid building a C++ extension just for a debug tool where we actually don't need to use anything inside it, to Make it possible to do this level of debugging on computers without NVIDIA hardware or even Mac.
This would be great! As far as I know, syntax checking and type checking is done inside
_get_final_ir, which means this approach makes it possible to raise any possible errors when converting a python program into a valid cuTile-python program without C++ libraries. I think this is pretty much everything needed to develop debug tools.gbonik commentedon Jan 15, 2026
You shouldn't need NVIDIA hardware to compile the C++ extension, a normal C++ compiler should be sufficient (we support GCC and MSVC, hopefully clang should work as well). I agree that it would be nice to drive the compilation pipeline with pure Python, but I'm afraid this may not be viable in the long term. The C++ extension needs to have the logic similar to typeof_pyval() to be able to quickly classify the arguments, and thus we'd need to duplicate the logic in Python (which we currently do, but ideally we need to get rid of this duplication).
In any case, I have staged a change to
_get_final_irthat should hopefully address your use case:init_context_config_from_env().args, we take a sequence of KernelArgument structs, which is a renamed ir.Argument:I hope this should allow you to drive the compilation pipeline without creating concrete array objects. The KernelArgument class should work similarly to a "meta tensor", with the downside of having to also call
get_constant_annotations()etc. yourself.The change is stacked on top of a couple other in-progress PRs, so it should hopefully get into public
mainsometime next week.Da1sypetals commentedon Jan 16, 2026
I have synced the cutile to numpy transpiler to newest main branch (it's here, and it's definitely buggy), as a proof of concept that everything it need is the output of
_get_final_irgbonik commentedon Jan 30, 2026
The _get_final_ir() change has been pushed to public main: 48ab3e3 . I hope this is sufficient to unblock you for now.
Da1sypetals commentedon Feb 3, 2026
@gbonik May I ask if there are any instructions to compile the C++ extension without an NVIDIA GPU? When I run
pip install -e .currently, it still requires CTK to be installed:gbonik commentedon Feb 4, 2026
There is currently no way to build without CUDA SDK, but we can add an option to CMake and some #ifdefs to the code. I can try to sneak in the necessary change within the next couple of weeks.
Da1sypetals commentedon Feb 6, 2026
@gbonik The LSP server I implemented is here. It now works with
cuda-tilev1.1.0 (or the currentmainbranch) and I deem it usable though it is still buggy: