This is an automated email from the ASF dual-hosted git repository.
tqchen pushed a commit to branch main
in repository https://gitbox.apache.org/repos/asf/tvm-ffi.git
The following commit(s) were added to refs/heads/main by this push:
new 6742be0a [DLPACK] Bump DLPack to 1.4 (#919)
6742be0a is described below
commit 6742be0ab9a0ed3cedea80a23842cb2f3cb0150c
Author: Tianqi Chen <[email protected]>
AuthorDate: Wed Nov 4 11:05:54 2026 -0500
[DLPACK] Bump DLPack to 1.4 (#919)
Bump DLPack to the latest release, 1.4.
---
3rdparty/dlpack | 2 +-
include/tvm/ffi/device.h | 3 +++
include/tvm/ffi/dtype.h | 10 +++++++++-
python/tvm_ffi/__init__.py | 1 +
python/tvm_ffi/_dtype.py | 4 ++++
python/tvm_ffi/core.pyi | 6 +++++-
python/tvm_ffi/cython/base.pxi | 3 +++
python/tvm_ffi/cython/device.pxi | 9 +++++++++
python/tvm_ffi/cython/dtype.pxi | 2 ++
rust/tvm-ffi-sys/src/dlpack.rs | 4 ++++
rust/tvm-ffi/tests/test_device.rs | 19 +++++++++++++------
rust/tvm-ffi/tests/test_dtype.rs | 9 +++++++++
src/ffi/dtype.cc | 10 +++++++++-
src/ffi/extra/dataclass.cc | 6 ++++++
tests/cpp/test_device.cc | 11 +++++++----
tests/cpp/test_dtype.cc | 8 ++++++++
tests/python/test_device.py | 5 +++++
tests/python/test_dlpack_exchange_api.py | 6 ++----
tests/python/test_dtype.py | 18 ++++++++++++++++++
19 files changed, 118 insertions(+), 18 deletions(-)
diff --git a/3rdparty/dlpack b/3rdparty/dlpack
index 84d107bf..6eca9e64 160000
--- a/3rdparty/dlpack
+++ b/3rdparty/dlpack
@@ -1 +1 @@
-Subproject commit 84d107bf416c6bab9ae68ad285876600d230490d
+Subproject commit 6eca9e643fcf7e870b7a1c99ee7fb166c5c2c459
diff --git a/include/tvm/ffi/device.h b/include/tvm/ffi/device.h
index 3a34006c..64e355a4 100644
--- a/include/tvm/ffi/device.h
+++ b/include/tvm/ffi/device.h
@@ -52,6 +52,9 @@ TVM_FFI_INLINE static std::optional<DLDeviceType>
TryParseDLDeviceType(std::stri
if (name == "wgpu" || name == "webgpu") return kDLWebGPU;
if (name == "maia") return kDLMAIA;
if (name == "trn") return kDLTrn;
+ if (name == "tpu") return kDLTPU;
+ if (name == "tpu_host") return kDLTPUHost;
+ if (name == "ascend") return kDLAscend;
return std::nullopt;
}
diff --git a/include/tvm/ffi/dtype.h b/include/tvm/ffi/dtype.h
index b627692d..338025b1 100644
--- a/include/tvm/ffi/dtype.h
+++ b/include/tvm/ffi/dtype.h
@@ -66,6 +66,9 @@ inline const char* DLDataTypeCodeAsCStr(DLDataTypeCode
type_code) { // NOLINT(*
case kDLBfloat: {
return "bfloat";
}
+ case kDLBcomplex: {
+ return "bcomplex";
+ }
case kDLBool: {
return "bool";
}
@@ -214,6 +217,10 @@ inline std::string DTypeAbbrev(DLDataType dtype) {
result = "bf";
break;
}
+ case kDLBcomplex: {
+ result = "bcomplex";
+ break;
+ }
case kDLBool: {
result = "bool";
break;
@@ -273,7 +280,8 @@ inline std::string DTypeAbbrev(DLDataType dtype) {
}
int16_t lanes = static_cast<int16_t>(dtype.lanes);
- if (dtype.code < kDLFloat8_e3m4 && (dtype.code != kDLBool || dtype.bits !=
8)) {
+ if ((dtype.code < kDLFloat8_e3m4 || dtype.code == kDLBcomplex) &&
+ (dtype.code != kDLBool || dtype.bits != 8)) {
result += std::to_string(static_cast<int>(dtype.bits));
}
if (lanes > 1) {
diff --git a/python/tvm_ffi/__init__.py b/python/tvm_ffi/__init__.py
index 7eafc132..d3d723c5 100644
--- a/python/tvm_ffi/__init__.py
+++ b/python/tvm_ffi/__init__.py
@@ -115,6 +115,7 @@ if TYPE_CHECKING or not _is_config_mode():
float64,
float32,
float16,
+ bcomplex32,
bfloat16,
float8_e3m4,
float8_e4m3,
diff --git a/python/tvm_ffi/_dtype.py b/python/tvm_ffi/_dtype.py
index 6477c935..e75afaa8 100644
--- a/python/tvm_ffi/_dtype.py
+++ b/python/tvm_ffi/_dtype.py
@@ -46,6 +46,7 @@ class DataTypeCode(IntEnum):
Float6E2M3FN = 15
Float6E3M2FN = 16
Float4E2M1FN = 17
+ BCOMPLEX = 18
class dtype(str):
@@ -386,6 +387,8 @@ try:
dtype._NUMPY_DTYPE_TO_STR[np.dtype(ml_dtypes.bfloat16)] = "bfloat16"
dtype._NUMPY_DTYPE_TO_STR[np.dtype(ml_dtypes.float8_e4m3fn)] =
"float8_e4m3fn"
dtype._NUMPY_DTYPE_TO_STR[np.dtype(ml_dtypes.float8_e5m2)] = "float8_e5m2"
+ if hasattr(ml_dtypes, "bcomplex32"): # ml_dtypes >= 0.6.0
+ dtype._NUMPY_DTYPE_TO_STR[np.dtype(ml_dtypes.bcomplex32)] =
"bcomplex32"
if hasattr(ml_dtypes, "float4_e2m1fn"): # ml_dtypes >= 0.5.0
dtype._NUMPY_DTYPE_TO_STR[np.dtype(ml_dtypes.float4_e2m1fn)] =
"float4_e2m1fn"
except ImportError:
@@ -410,6 +413,7 @@ float64 = dtype("float64")
float32 = dtype("float32")
float16 = dtype("float16")
bfloat16 = dtype("bfloat16")
+bcomplex32 = dtype("bcomplex32")
# float8 dtypes
float8_e3m4 = dtype("float8_e3m4")
float8_e4m3 = dtype("float8_e4m3")
diff --git a/python/tvm_ffi/core.pyi b/python/tvm_ffi/core.pyi
index 237eb39b..6c7374e8 100644
--- a/python/tvm_ffi/core.pyi
+++ b/python/tvm_ffi/core.pyi
@@ -141,7 +141,11 @@ class DLDeviceType(IntEnum):
kDLOneAPI = 14
kDLWebGPU = 15
kDLHexagon = 16
- kDLTrn = 17
+ kDLMAIA = 17
+ kDLTrn = 18
+ kDLTPU = 19
+ kDLTPUHost = 20
+ kDLAscend = 21
class Device:
def __init__(self, device_type: str | int, index: int | None = None) ->
None: ...
diff --git a/python/tvm_ffi/cython/base.pxi b/python/tvm_ffi/cython/base.pxi
index 2fd957b3..cff5422b 100644
--- a/python/tvm_ffi/cython/base.pxi
+++ b/python/tvm_ffi/cython/base.pxi
@@ -45,6 +45,9 @@ cdef extern from "dlpack/dlpack.h":
kDLHexagon = 16,
kDLMAIA = 17
kDLTrn = 18
+ kDLTPU = 19
+ kDLTPUHost = 20
+ kDLAscend = 21
ctypedef struct DLDataType:
uint8_t code
diff --git a/python/tvm_ffi/cython/device.pxi b/python/tvm_ffi/cython/device.pxi
index 642bac68..c60a0bd9 100644
--- a/python/tvm_ffi/cython/device.pxi
+++ b/python/tvm_ffi/cython/device.pxi
@@ -63,6 +63,9 @@ class DLDeviceType(IntEnum):
kDLHexagon = 16
kDLMAIA = 17
kDLTrn = 18
+ kDLTPU = 19
+ kDLTPUHost = 20
+ kDLAscend = 21
cdef class Device:
@@ -112,6 +115,9 @@ cdef class Device:
DLDeviceType.kDLHexagon: "hexagon",
DLDeviceType.kDLMAIA: "maia",
DLDeviceType.kDLTrn: "trn",
+ DLDeviceType.kDLTPU: "tpu",
+ DLDeviceType.kDLTPUHost: "tpu_host",
+ DLDeviceType.kDLAscend: "ascend",
}
_DEVICE_NAME_TO_TYPE = {
@@ -131,6 +137,9 @@ cdef class Device:
"webgpu": DLDeviceType.kDLWebGPU,
"maia": DLDeviceType.kDLMAIA,
"trn": DLDeviceType.kDLTrn,
+ "tpu": DLDeviceType.kDLTPU,
+ "tpu_host": DLDeviceType.kDLTPUHost,
+ "ascend": DLDeviceType.kDLAscend,
}
def __init__(self, device_type: str | int, index: Optional[Integral] =
None) -> None:
diff --git a/python/tvm_ffi/cython/dtype.pxi b/python/tvm_ffi/cython/dtype.pxi
index 6838be6b..96adf845 100644
--- a/python/tvm_ffi/cython/dtype.pxi
+++ b/python/tvm_ffi/cython/dtype.pxi
@@ -235,6 +235,8 @@ if ml_dtypes is not None:
MLDTYPES_DTYPE_TO_DL_DATA_TYPE[numpy.dtype(ml_dtypes.float6_e2m3fn)] =
DLDataType(15, 6, 1)
MLDTYPES_DTYPE_TO_DL_DATA_TYPE[numpy.dtype(ml_dtypes.float6_e3m2fn)] =
DLDataType(16, 6, 1)
MLDTYPES_DTYPE_TO_DL_DATA_TYPE[numpy.dtype(ml_dtypes.float4_e2m1fn)] =
DLDataType(17, 4, 1)
+ if hasattr(ml_dtypes, "bcomplex32"):
+ MLDTYPES_DTYPE_TO_DL_DATA_TYPE[numpy.dtype(ml_dtypes.bcomplex32)] =
DLDataType(18, 32, 1)
if numpy is not None:
diff --git a/rust/tvm-ffi-sys/src/dlpack.rs b/rust/tvm-ffi-sys/src/dlpack.rs
index e069ea8e..dcbdd31b 100644
--- a/rust/tvm-ffi-sys/src/dlpack.rs
+++ b/rust/tvm-ffi-sys/src/dlpack.rs
@@ -41,6 +41,9 @@ pub enum DLDeviceType {
kDLHexagon = 16,
kDLMAIA = 17,
kDLTrn = 18,
+ kDLTPU = 19,
+ kDLTPUHost = 20,
+ kDLAscend = 21,
}
#[repr(C)]
@@ -72,6 +75,7 @@ pub enum DLDataTypeCode {
kDLFloat6_e2m3fn = 15,
kDLFloat6_e3m2fn = 16,
kDLFloat4_e2m1fn = 17,
+ kDLBcomplex = 18,
}
/// DLPack data type struct
diff --git a/rust/tvm-ffi/tests/test_device.rs
b/rust/tvm-ffi/tests/test_device.rs
index 31b8c42b..fc530cff 100644
--- a/rust/tvm-ffi/tests/test_device.rs
+++ b/rust/tvm-ffi/tests/test_device.rs
@@ -65,10 +65,17 @@ fn test_device_stream_restored_after_panic() {
#[test]
fn test_device_any_conversion() {
- let device = DLDevice::new(DLDeviceType::kDLCPU, 0);
- let any_device: Any = device.into();
- assert_eq!(any_device.type_index(), TypeIndex::kTVMFFIDevice as i32);
- let converted_device: DLDevice = any_device.try_into().unwrap();
- assert_eq!(converted_device.device_type, device.device_type);
- assert_eq!(converted_device.device_id, device.device_id);
+ for device_type in [
+ DLDeviceType::kDLCPU,
+ DLDeviceType::kDLTPU,
+ DLDeviceType::kDLTPUHost,
+ DLDeviceType::kDLAscend,
+ ] {
+ let device = DLDevice::new(device_type, 3);
+ let any_device: Any = device.into();
+ assert_eq!(any_device.type_index(), TypeIndex::kTVMFFIDevice as i32);
+ let converted_device: DLDevice = any_device.try_into().unwrap();
+ assert_eq!(converted_device.device_type, device.device_type);
+ assert_eq!(converted_device.device_id, device.device_id);
+ }
}
diff --git a/rust/tvm-ffi/tests/test_dtype.rs b/rust/tvm-ffi/tests/test_dtype.rs
index c0a28fb5..506413e6 100644
--- a/rust/tvm-ffi/tests/test_dtype.rs
+++ b/rust/tvm-ffi/tests/test_dtype.rs
@@ -22,6 +22,14 @@ use tvm_ffi::*;
fn test_dl_datatype_from_string() {
// Test valid dtype strings
let test_cases = vec![
+ (
+ "bcomplex32",
+ DLDataType::new(DLDataTypeCode::kDLBcomplex, 32, 1),
+ ),
+ (
+ "bcomplex32x4",
+ DLDataType::new(DLDataTypeCode::kDLBcomplex, 32, 4),
+ ),
(
"int32",
DLDataType {
@@ -67,6 +75,7 @@ fn test_dl_datatype_from_string() {
for item in test_cases {
let dtype = DLDataType::try_from_str(item.0).unwrap();
assert_eq!(dtype, item.1);
+ assert_eq!(dtype.to_string(), item.0);
}
}
diff --git a/src/ffi/dtype.cc b/src/ffi/dtype.cc
index 0780910a..b86d561a 100644
--- a/src/ffi/dtype.cc
+++ b/src/ffi/dtype.cc
@@ -97,6 +97,10 @@ inline void PrintDLDataTypeCodeAsStr(std::ostream& os,
DLDataTypeCode type_code)
os << "bfloat";
break;
}
+ case kDLBcomplex: {
+ os << "bcomplex";
+ break;
+ }
case kDLFloat8_e3m4: {
os << "float8_e3m4";
break;
@@ -178,7 +182,8 @@ inline std::string DLDataTypeToString_(DLDataType dtype) {
// NOLINT(*)
}
if (dtype.code == kDLOpaqueHandle) return os.str();
int16_t lanes = static_cast<int16_t>(dtype.lanes);
- if ((dtype.code < kDLFloat8_e3m4 || dtype.code >= kDLExtCustomBegin) &&
+ if ((dtype.code < kDLFloat8_e3m4 || dtype.code == kDLBcomplex ||
+ dtype.code >= kDLExtCustomBegin) &&
(dtype.code != kDLBool || dtype.bits != 8)) {
os << static_cast<int>(dtype.bits);
}
@@ -399,6 +404,9 @@ inline DLDataType StringViewToDLDataType_(std::string_view
str) {
dtype.code = kDLOpaqueHandle;
dtype.bits = 64; // handle uses 64 bit by default.
scan = str.data() + 6;
+ } else if (str.compare(0, 8, "bcomplex") == 0) {
+ dtype.code = kDLBcomplex;
+ scan = str.data() + 8;
} else if (str.compare(0, 6, "bfloat") == 0) {
dtype.code = kDLBfloat;
dtype.bits = 16;
diff --git a/src/ffi/extra/dataclass.cc b/src/ffi/extra/dataclass.cc
index 8acc6803..55ffd8ce 100644
--- a/src/ffi/extra/dataclass.cc
+++ b/src/ffi/extra/dataclass.cc
@@ -596,6 +596,12 @@ const char* DeviceTypeName(int device_type) {
return "maia";
case kDLTrn:
return "trn";
+ case kDLTPU:
+ return "tpu";
+ case kDLTPUHost:
+ return "tpu_host";
+ case kDLAscend:
+ return "ascend";
default:
return "unknown";
}
diff --git a/tests/cpp/test_device.cc b/tests/cpp/test_device.cc
index a4051eb3..996318da 100644
--- a/tests/cpp/test_device.cc
+++ b/tests/cpp/test_device.cc
@@ -39,10 +39,13 @@ TEST(Device, AnyConversionWithString) {
DLDeviceType device_type;
};
const TestCase test_cases[] = {
- {"cpu", kDLCPU}, {"cuda", kDLCUDA}, {"opencl", kDLOpenCL},
{"vulkan", kDLVulkan},
- {"metal", kDLMetal}, {"mps", kDLMetal}, {"vpi", kDLVPI},
{"rocm", kDLROCM},
- {"ext_dev", kDLExtDev}, {"hexagon", kDLHexagon}, {"wgpu", kDLWebGPU},
{"webgpu", kDLWebGPU},
- {"maia", kDLMAIA}, {"trn", kDLTrn}, {"oneapi", kDLOneAPI},
{"xpu", kDLOneAPI},
+ {"cpu", kDLCPU}, {"cuda", kDLCUDA}, {"opencl", kDLOpenCL},
+ {"vulkan", kDLVulkan}, {"metal", kDLMetal}, {"mps", kDLMetal},
+ {"vpi", kDLVPI}, {"rocm", kDLROCM}, {"ext_dev", kDLExtDev},
+ {"hexagon", kDLHexagon}, {"wgpu", kDLWebGPU}, {"webgpu", kDLWebGPU},
+ {"maia", kDLMAIA}, {"trn", kDLTrn}, {"tpu", kDLTPU},
+ {"tpu_host", kDLTPUHost}, {"ascend", kDLAscend}, {"oneapi", kDLOneAPI},
+ {"xpu", kDLOneAPI},
};
for (const TestCase& test_case : test_cases) {
SCOPED_TRACE(test_case.name);
diff --git a/tests/cpp/test_dtype.cc b/tests/cpp/test_dtype.cc
index ebe56d57..2cb46f30 100644
--- a/tests/cpp/test_dtype.cc
+++ b/tests/cpp/test_dtype.cc
@@ -56,6 +56,8 @@ TEST(DType, StringConversionAllDLPackTypes) {
{DLDataType{kDLInt, 16, 1}, "int16"},
{DLDataType{kDLUInt, 16, 1}, "uint16"},
{DLDataType{kDLBfloat, 16, 1}, "bfloat16"},
+ {DLDataType{kDLBcomplex, 32, 1}, "bcomplex32"},
+ {DLDataType{kDLBcomplex, 32, 4}, "bcomplex32x4"},
{DLDataType{kDLFloat8_e3m4, 8, 1}, "float8_e3m4"},
{DLDataType{kDLFloat8_e4m3, 8, 1}, "float8_e4m3"},
{DLDataType{kDLFloat8_e4m3b11fnuz, 8, 1}, "float8_e4m3b11fnuz"},
@@ -75,6 +77,12 @@ TEST(DType, StringConversionAllDLPackTypes) {
}
}
+TEST(DType, BcomplexAbbrev) {
+ for (const char* str : {"bcomplex32", "bcomplex32x4",
"bcomplex32xvscalex4"}) {
+ EXPECT_EQ(DTypeAbbrev(StringToDLDataType(str)), str);
+ }
+}
+
TEST(DType, StringConversionAliases) {
std::vector<std::pair<std::string, std::string>> test_cases = {
{"i32", "int32"},
diff --git a/tests/python/test_device.py b/tests/python/test_device.py
index c770245c..bbcaab32 100644
--- a/tests/python/test_device.py
+++ b/tests/python/test_device.py
@@ -54,6 +54,9 @@ def test_device_from_str() -> None:
("oneapi:1", DLDeviceType.kDLOneAPI, 1),
("xpu", DLDeviceType.kDLOneAPI, 0),
("xpu:2", DLDeviceType.kDLOneAPI, 2),
+ ("tpu:1", DLDeviceType.kDLTPU, 1),
+ ("tpu_host:2", DLDeviceType.kDLTPUHost, 2),
+ ("ascend:3", DLDeviceType.kDLAscend, 3),
],
)
def test_device_dlpack_device_type(
@@ -62,6 +65,8 @@ def test_device_dlpack_device_type(
expect_device_id: int,
) -> None:
dev = tvm_ffi.device(dev_str)
+ expected_name = "oneapi" if dev_str.startswith("xpu") else
dev_str.split(":")[0]
+ assert str(dev) == f"{expected_name}:{expect_device_id}"
assert dev.dlpack_device_type() == expected_device_type
assert dev.index == expect_device_id
diff --git a/tests/python/test_dlpack_exchange_api.py
b/tests/python/test_dlpack_exchange_api.py
index 4d837ba5..f97d2f19 100644
--- a/tests/python/test_dlpack_exchange_api.py
+++ b/tests/python/test_dlpack_exchange_api.py
@@ -74,8 +74,7 @@ def test_dlpack_exchange_api(tmp_path: Path) -> None:
TORCH_CHECK(api != nullptr, "API pointer is NULL");
TORCH_CHECK(api->header.version.major == DLPACK_MAJOR_VERSION,
"Expected major version ", DLPACK_MAJOR_VERSION, ",
got ", api->header.version.major);
- TORCH_CHECK(api->header.version.minor == DLPACK_MINOR_VERSION,
- "Expected minor version ", DLPACK_MINOR_VERSION, ",
got ", api->header.version.minor);
+ // Minor versions may differ when the fields used here are
supported.
TORCH_CHECK(api->managed_tensor_allocator != nullptr,
"managed_tensor_allocator is NULL");
TORCH_CHECK(api->managed_tensor_from_py_object_no_sync != nullptr,
@@ -133,8 +132,7 @@ def test_dlpack_exchange_api(tmp_path: Path) -> None:
TORCH_CHECK(out_tensor != nullptr, "from_py_object_no_sync
returned NULL");
TORCH_CHECK(out_tensor->version.major == DLPACK_MAJOR_VERSION,
"Expected major version ", DLPACK_MAJOR_VERSION, ",
got ", out_tensor->version.major);
- TORCH_CHECK(out_tensor->version.minor == DLPACK_MINOR_VERSION,
- "Expected minor version ", DLPACK_MINOR_VERSION, ",
got ", out_tensor->version.minor);
+ // A producer using an older minor version can export these fields.
TORCH_CHECK(out_tensor->dl_tensor.ndim == 3, "Expected ndim 3, got
", out_tensor->dl_tensor.ndim);
TORCH_CHECK(out_tensor->dl_tensor.shape[0] == 2, "Expected
shape[0] = 2, got ", out_tensor->dl_tensor.shape[0]);
TORCH_CHECK(out_tensor->dl_tensor.shape[1] == 3, "Expected
shape[1] = 3, got ", out_tensor->dl_tensor.shape[1]);
diff --git a/tests/python/test_dtype.py b/tests/python/test_dtype.py
index a01d2c7c..163f9be5 100644
--- a/tests/python/test_dtype.py
+++ b/tests/python/test_dtype.py
@@ -226,6 +226,23 @@ def test_ml_dtypes_dtype_conversion() -> None:
_check_dtype(np.dtype(ml_dtypes.float4_e2m1fn), 17, 4, 1)
[email protected]("lanes", [1, 4])
+def test_bcomplex_dtype_roundtrip(lanes: int) -> None:
+ dtype = tvm_ffi.dtype.from_dlpack_data_type((18, 32, lanes))
+ assert str(dtype) == "bcomplex32" + (f"x{lanes}" if lanes != 1 else "")
+ assert dtype.itemsize == 4 * lanes
+ _check_dtype(dtype, 18, 32, lanes)
+ _check_dtype(tvm_ffi.dtype(str(dtype)), 18, 32, lanes)
+
+
+def test_ml_dtypes_bcomplex_conversion() -> None:
+ ml_dtypes = pytest.importorskip("ml_dtypes")
+ if not hasattr(ml_dtypes, "bcomplex32"):
+ pytest.skip("ml_dtypes does not expose bcomplex32")
+ _check_dtype(np.dtype(ml_dtypes.bcomplex32), 18, 32, 1)
+ assert np.dtype(tvm_ffi.bcomplex32) == np.dtype(ml_dtypes.bcomplex32)
+
+
def test_builtin_dtype_conversion() -> None:
_check_dtype(tvm_ffi.bool, 6, 8, 1)
_check_dtype(tvm_ffi.int8, 0, 8, 1)
@@ -240,6 +257,7 @@ def test_builtin_dtype_conversion() -> None:
_check_dtype(tvm_ffi.float32, 2, 32, 1)
_check_dtype(tvm_ffi.float64, 2, 64, 1)
_check_dtype(tvm_ffi.bfloat16, 4, 16, 1)
+ _check_dtype(tvm_ffi.bcomplex32, 18, 32, 1)
_check_dtype(tvm_ffi.float8_e3m4, 7, 8, 1)
_check_dtype(tvm_ffi.float8_e4m3, 8, 8, 1)
_check_dtype(tvm_ffi.float8_e4m3b11fnuz, 9, 8, 1)