@@ -1036,14 +1036,27 @@ def fp8_scaled_vecmat_path_c_direct(
10361036 f"{ type (exc ).__name__ } : { exc } "
10371037 ) from exc
10381038 try :
1039- return kernel (
1039+ # Owner-output reuse contract: write in place into ``out`` and
1040+ # return that exact object (see the note at the primary dispatch
1041+ # site below). Dropping ``_tilelang_mlx_async_owner_outputs`` is
1042+ # behavior-preserving against the non-native (slow) tvm-ffi route
1043+ # -- which always ran synchronously and returned the caller object
1044+ # -- and restores ``returned is out`` under the now-live native
1045+ # bridge, whose async path returned a fresh aliasing wrapper.
1046+ returned = kernel (
10401047 x_fp8 ,
10411048 scale_x ,
10421049 W_fp8 ,
10431050 scale_w ,
10441051 out ,
1045- _tilelang_mlx_async_owner_outputs = True ,
10461052 )
1053+ if returned is not out :
1054+ raise FP8VecmatPathCDirectError (
1055+ "direct tvm-ffi FP8 vecmat did not return the caller-owned output"
1056+ )
1057+ return out
1058+ except FP8VecmatPathCDirectError :
1059+ raise
10471060 except Exception as exc :
10481061 try :
10491062 from tilelang .contrib .mlx_interop import DLPackInteropError
@@ -1079,13 +1092,22 @@ def fp8_scaled_vecmat_path_c_direct(
10791092 ) from exc
10801093
10811094 try :
1095+ # Owner-output reuse contract: the kernel writes in place into the
1096+ # caller-owned ``C`` (== ``out``) and the route returns that exact
1097+ # object, matching the sibling matmul direct route and the non-native
1098+ # (slow) tvm-ffi route, which always returns the caller object. The
1099+ # earlier ``_tilelang_mlx_async_owner_outputs=True`` request made the
1100+ # now-live native bridge return a fresh MLX wrapper that merely *aliases*
1101+ # ``out`` (correct data, but ``returned is out`` was False). The slow
1102+ # route ignored the async flag and ran synchronously, so dropping it is
1103+ # behavior-preserving against the committed baseline while restoring the
1104+ # documented ``returned is out`` contract under the native route.
10821105 returned = kernel (
10831106 A ,
10841107 A_scale ,
10851108 B ,
10861109 B_scale ,
10871110 C ,
1088- _tilelang_mlx_async_owner_outputs = True ,
10891111 )
10901112 except Exception as exc :
10911113 try :
@@ -1097,7 +1119,11 @@ def fp8_scaled_vecmat_path_c_direct(
10971119 raise FP8VecmatPathCDirectError (
10981120 f"direct tvm-ffi FP8 vecmat dispatch failed: { type (exc ).__name__ } : { exc } "
10991121 ) from exc
1100- return returned
1122+ if returned is not C :
1123+ raise FP8VecmatPathCDirectError (
1124+ "direct tvm-ffi FP8 vecmat did not return the caller-owned output"
1125+ )
1126+ return C
11011127
11021128
11031129def fp8_scaled_vecmat_path_c (
@@ -1116,10 +1142,10 @@ def fp8_scaled_vecmat_path_c(
11161142 ``x_fp8`` is ``(K,)`` uint8 e4m3 storage and ``W_fp8`` is transposed
11171143 ``(N, K)`` storage, matching Path B. ``scale_x`` is scalar; ``scale_w`` may
11181144 be scalar or per-output ``(N,)``. When ``out`` is provided, dispatches via
1119- tvm-ffi into that caller-owned output and returns the MLX graph output that
1120- aliases ``out``. Evaluating the returned value schedules the write; reading
1121- ``out`` after that observes the same storage . Without ``out``, this function
1122- fails explicitly: there is no non-owner-output Path C dispatch surface.
1145+ tvm-ffi into that caller-owned output and returns that same ``out`` object
1146+ (owner-output reuse contract, matching the sibling matmul direct route and
1147+ the non-native tvm-ffi route) . Without ``out``, this function fails
1148+ explicitly: there is no non-owner-output Path C dispatch surface.
11231149 """
11241150
11251151 if out is not None :
0 commit comments