
Taichi C-API 核心功能实战指南Runtime 生命周期、显存管理与 AOT 模块调度【免费下载链接】taichiProductive, portable, and performant GPU programming in Python.项目地址: https://gitcode.com/GitHub_Trending/ta/taichiTaichi Coretaichi_core.h定义的核心 C-API为在 Python 之外的其他语言C/C、C# 等中运行 Taichi 预编译的 AOT 模块提供了全部必要接口。本指南基于 docs/lang/articles/c-api/taichi_core.md 展开覆盖 Runtime 实例的创建与销毁、设备内存/图像的分配与映射、AOT 模块的加载以及 Kernel 与 Compute Graph 的启动与同步读完你将能够在自己的宿主程序中用一段可移植的 C 代码把 Taichi 编译产物调度到 Vulkan、Metal、CUDA 或 CPU 上执行。仓库中的对应头文件 c_api/include/taichi/taichi_core.h 与实现 c_api/src/taichi_core_impl.cpp 可随时对照查阅。背景为什么需要 Taichi C-APITaichi 以 Python 为中心提供了便捷的编程体验但 AOTAhead-Of-Time场景需要把编译好的 Kernel 交付给非 Python 的宿主程序如游戏引擎、渲染器、嵌入式应用使用。Taichi Core 正是这条桥它以稳定的 C 接口对外暴露运行时能力让宿主程序跨语言调用。C-API 具有以下特点后端无关文档所列功能在任何后端上均可用不依赖特定图形 API 细节。仍在演进对应 API 仍在开发中行为可能变化本文以当前仓库为准。分层清晰宿主host只与TiRuntime、TiMemory、TiAotModule等句柄打交道底层设备细节被完全封装。可用后端与维护分级Taichi C-API 计划支持以下后端docs/lang/articles/c-api/taichi_core.md 中 Availability 一节后端卸载目标维护级别已稳定VulkanGPUTier 1是MetalGPUmacOS、iOSTier 2否CUDA (LLVM)GPUNVIDIATier 2否CPU (LLVM)CPUTier 2否OpenGLGPUTier 2否OpenGL ESGPUTier 2否DirectX 11GPUWindowsN/A否Tier 1 后端被开发与测试得最密集新特性通常会最先在 Vulkan 上可用因为它在一级后端中跨平台兼容性最好。Tier 2 后端的次要问题修复会有延迟。术语约定文档约定后文通用device设备指逻辑上的计算设备Taichi 运行时将计算任务卸载到它上面一个 device 未必是独立于 CPU 的物理处理器宿主也未必能访问分配在 device 上的内存。除非特别说明device、backend、offload target、GPU可互换host、user code、user procedure、CPU可互换。核心句柄与基础类型C-API 中所有资源都以不透明指针句柄形式存在生命周期由运行时管理。以下句柄自 Taichi 1.4.0 起稳定定义见 c_api/include/taichi/taichi_core.h句柄说明TiRuntime逻辑后端实例及其内部动态状态的表示用户负责同步其使用同一线程内不得操作多个TiRuntimeTiAotModule预编译的 AOT 模块包含一组 Kernel 与 Compute GraphTiMemory一段连续的设备内存分配TiImage一段连续的设备图像分配TiKernel可在卸载目标上启动执行的 Taichi KernelTiComputeGraph按预定顺序在卸载目标上启动的一组 Taichi Kernel基础标量类型包括TiBooluint32_t取值只能是TI_TRUE(1) 或TI_FALSE(0)赋其他值属未定义行为和TiFlagsuint32_t位域。TI_NULL_HANDLE定义为 0是无效句柄哨兵——合法的 C-API 调用永远不会产生它。另外各枚举都带一个TI_XXX_MAX_ENUM 0xffffffff成员仅用于保证枚举占 32 位内存宽度无语义影响可安全忽略。Runtime 实例的创建与销毁在使用 Taichi 之前必须先创建 Runtime 实例且每线程仅允许一个Runtime。当前并未正式承诺同一进程内多个 Runtime 可以共存。// 在 Vulkan 设备 0 上创建一个 Taichi Runtime。 TiRuntime runtime ti_create_runtime(TI_ARCH_VULKAN, 0);从源码看c_api/src/taichi_core_impl.cppti_create_runtime按TiArch分发到各后端实现Vulkan 后端会把device_index传入set_vulkan_visible_device选择物理设备CI 环境下还会额外开启验证层OpenGL / LLVMx64、arm64、CUDA/ Metal 后端目前仅支持设备索引 0否则直接返回TI_ERROR_NOT_SUPPORTED。因此使用TI_ARCH_VULKAN时device_index表示 Vulkan 物理设备序号可大于 0其余后端传非 0 索引会失败除非将来实现放开限制。程序结束前必须销毁 Runtime且所有关联资源都要先于TiRuntime本身销毁ti_destroy_runtime(runtime);实现中ti_destroy_runtime直接delete底层 Runtime 对象c_api/src/taichi_core_impl.cpp因此把依赖它的 Kernel、Memory 等对象留在后面释放将导致悬垂访问。设备内存分配、映射与释放分配设备私有内存分配一段仅对设备可见的内存GPU 后端上通常位于显存 GRAM 中TiMemoryAllocateInfo mai {}; mai.size 1024; // 单位字节 mai.usage TI_MEMORY_USAGE_STORAGE_BIT; TiMemory memory ti_allocate_memory(runtime, mai);TiMemoryAllocateInfo结构字段如下字段类型含义sizeuint64_t分配大小字节host_writeTiBool宿主是否需要写入该内存host_readTiBool宿主是否需要读取该内存export_sharingTiBool是否需要导出给其他后端如 Vulkan→CUDAusageTiMemoryUsageFlags内存所有可能用途多数场景TI_MEMORY_USAGE_STORAGE_BIT已足够TiMemoryUsageFlags位域包含TI_MEMORY_USAGE_STORAGE_BIT可被任意 Kernel 读写、TI_MEMORY_USAGE_UNIFORM_BIT图形管线 uniform buffer、TI_MEMORY_USAGE_VERTEX_BIT顶点缓冲、TI_MEMORY_USAGE_INDEX_BIT索引缓冲。注意Taichi 要求 Kernel 参数内存必须以TI_MEMORY_USAGE_STORAGE_BIT分配。分配的内存会在TiRuntime销毁时自动释放也可以手动释放ti_free_memory(runtime, memory);分配宿主可访问内存零拷贝写入与回读默认情况下内存分配出于性能考虑物理或概念上位于卸载目标本地。若需要宿主访问可通过TiMemoryAllocateInfo配置。但请注意宿主可访问分配可能因宿主内存与设备间总线带宽有限而拖慢 GPU 计算。零拷贝写入必须设置host_write TI_TRUETiMemoryAllocateInfo mai {}; mai.size 1024; // 单位字节 mai.host_write TI_TRUE; mai.usage TI_MEMORY_USAGE_STORAGE_BIT; TiMemory steaming_memory ti_allocate_memory(runtime, mai); // ... std::vectoruint8_t src some_random_data_source(); void* dst ti_map_memory(runtime, steaming_memory); std::memcpy(dst, src.data(), src.size()); ti_unmap_memory(runtime, streaming_memory);回读数据到宿主则必须设置host_read TI_TRUETiMemoryAllocateInfo mai {}; mai.size 1024; // 单位字节 mai.host_read TI_TRUE; mai.usage TI_MEMORY_USAGE_STORAGE_BIT; TiMemory read_back_memory ti_allocate_memory(runtime, mai); // ... std::vectoruint8_t dst(1024); void* src ti_map_memory(runtime, read_back_memory); std::memcpy(dst.data(), src, dst.size()); ti_unmap_memory(runtime, read_back_memory); ti_free_memory(runtime, read_back_memory);要点与约束host_read与host_write可同时设置得到双向可访问的映射内存。ti_map_memory返回宿主可寻址空间指针映射前必须确保设备没有任何正在使用该内存的设备命令应先 flush/wait见下文同步一节。ti_unmap_memory解除映射并把宿主的修改对设备可见解除映射后不得再访问之前的宿主地址空间。内存切片通过TiMemorySlice表达包含memory、offset、size且offset size不得超过所属分配的大小设备命令ti_copy_memory_device_to_device用它完成设备内两个不重叠子区间的拷贝。加载与销毁 AOT 模块AOT 模块是 Taichi Python 侧编译产物的集合。Python 侧通过ti.aot.Module(arch)构建调用save(filepath)写出目录内部生成metadata.json与各 Kernel 二进制或调用archive(filepath)打包为.tcm归档见 python/taichi/aot/module.py。C 侧加载方式如下TiAotModule aot_module ti_load_aot_module(runtime, /path/to/aot/module);/path/to/aot/module必须指向一个包含metadata.json的目录Python 侧save输出即是该布局。若加载失败ti_load_aot_module返回TI_NULL_HANDLE实现中会以TI_ERROR_CORRUPTED_DATA记录错误c_api/src/taichi_core_impl.cpp。也可用ti_create_aot_module(runtime, tcm, size)直接从.tcm内存数据创建模块实现内部把 TCM 数据当作 zip 虚拟目录解包见 taichi/common/virtual_dir.cpp。销毁不用的 AOT 模块时务必确保没有与其关联的 Kernel 或 Compute Graph 正处于待ti_flush的挂起状态ti_destroy_aot_module(aot_module);提取并启动 Kernel 与 Compute GraphKernel 和 Compute Graph 是模块的组成部分无需单独销毁随模块销毁而释放TiKernel kernel ti_get_aot_module_kernel(aot_module, foo); TiComputeGraph compute_graph ti_get_aot_module_compute_graph(aot_module, bar);若指定名称不存在两者均返回TI_NULL_HANDLE实现中会以TI_ERROR_NAME_NOT_FOUND记录错误c_api/src/taichi_core_impl.cpp。以位置参数启动 Kernel启动 Kernel 使用位置参数类型、尺寸与顺序必须与 Python 源码一致TiNdArray ndarray{}; ndarray.memory get_some_memory(); ndarray.shape.dim_count 1; ndarray.shape.dims[0] 16; ndarray.elem_shape.dim_count 2; ndarray.elem_shape.dims[0] 4; ndarray.elem_shape.dims[1] 4; ndarray.elem_type TI_DATA_TYPE_F32; std::arrayTiArgument, 3 args{}; TiArgument arg0 args[0]; arg0.type TI_ARGUMENT_TYPE_I32; arg0.value.i32 123; TiArgument arg1 args[1]; arg1.type TI_ARGUMENT_TYPE_F32; arg1.value.f32 123.0f; TiArgument arg2 args[2]; arg2.type TI_ARGUMENT_TYPE_NDARRAY; arg2.value.ndarray ndarray; ti_launch_kernel(runtime, kernel, args.size(), args.data());其中TiNdArray是包裹在TiMemory上的稠密基本类型多维数组字段包括字段说明memory绑定到 ND-array 的内存shapeND-array 的形状TiNdShapedim_countdims[16]dim_count之后的维度被忽略elem_shape元素形状向量/矩阵 ND-array 时不得为空elem_type元素基本数据类型以命名参数启动 Compute GraphCompute Graph 启动方式类似但参数名必须与 Python 源码一致std::arrayTiNamedArgument, 3 named_args{}; TiNamedArgument named_arg0 named_args[0]; named_arg0.name foo; named_arg0.argument args[0]; TiNamedArgument named_arg1 named_args[1]; named_arg1.name bar; named_arg1.argument args[1]; TiNamedArgument named_arg2 named_args[2]; named_arg2.name baz; named_arg2.argument args[2]; ti_launch_compute_graph(runtime, compute_graph, named_args.size(), named_args.data());TiNamedArgument由nameconst char*与argumentTiArgument组成。源码实现中ti_launch_kernel会对arg_count做上限检查超过taichi_max_num_args_total返回TI_ERROR_ARGUMENT_OUT_OF_RANGE并依据TiArgumentType走不同的LaunchContextBuilder::set_arg路径标量按位宽 memcpy、NDArray 绑定等见 c_api/src/taichi_core_impl.cpp因此参数类型错配会在启动时被报错而不是静默出错。同步与批处理提交启动完本批次所有 Kernel 与 Compute Graph 后需要提交并等待执行完成ti_flush(runtime); ti_wait(runtime);ti_flush把所有先前调用的设备命令提交到卸载设备执行。ti_wait等待所有先前调用的设备命令执行完毕任何尚未提交的命令会先被提交。⚠️警告这一部分将来可能变化官方计划引入多队列multi-queue支持。当前模型下Runtime 内部维护单一命令流宿主需自行保证同步。参数与数据类型体系参数类型TiArgumentType枚举值含义TI_ARGUMENT_TYPE_I3232 位补码有符号整数TI_ARGUMENT_TYPE_F3232 位 IEEE 754 单精度浮点数TI_ARGUMENT_TYPE_NDARRAY包裹TiMemory的 ND-arrayTI_ARGUMENT_TYPE_TEXTURE包裹TiImage的纹理TI_ARGUMENT_TYPE_SCALAR类型化标量1.5.0 起TI_ARGUMENT_TYPE_TENSOR类型化张量TiArgumentValue为联合体包含i32、f32、ndarray、texture、scalar、tensor六个成员。其中i32等价于x32TI_DATA_TYPE_I32f32等价于x32TI_DATA_TYPE_F32。TiScalar/TiScalarValue1.5.0 起稳定用于携带类型化标量TiScalarValue是按 2 的幂位宽表示的联合体x8/x16/x32/x64注意其无符号整数成员只承载位数不反映底层数据类型——例如 32 位浮点标量需*(float*)scalar_value.x32 0.0f16 位有符号整数需*(int16_t*)scalar_value.x16 1实际类型由TiScalar.type指明。数据类型TiDataTypeTiDataType覆盖 F16/F32/F64、I8/I16/I32/I64、U1/U8/U16/U32/U64 以及GEN泛型与UNKNOWN。文档建议由于不同厂商对可用数据类型存在限制若希望多平台分发优先使用 32 位数据类型。C-API 测试 c_api/tests/c_api_numerical_test.cpp 中可看到各数据类型在数值路径上的实际校验。图像与纹理资源分配图像TiImageAllocateInfo iai {}; iai.dimension TI_IMAGE_DIMENSION_2D; iai.extent { width, height, 1, 1 }; iai.mip_level_count 1; iai.format TI_FORMAT_RGBA8; iai.usage TI_IMAGE_USAGE_STORAGE_BIT | TI_IMAGE_USAGE_SAMPLED_BIT; TiImage image ti_allocate_image(runtime, iai);TiImageAllocateInfo字段dimensionTiImageDimension、extentTiImageExtent、mip_level_countmip 级数、formatTiFormat纹素格式、export_sharing是否导出给其他后端、usage。Taichi 要求 Kernel 参数图像以TI_IMAGE_USAGE_STORAGE_BIT和TI_IMAGE_USAGE_SAMPLED_BIT分配。关键枚举TiImageUsageFlagsSTORAGE_BIT任意 Kernel 可读写、SAMPLED_BIT任意 Kernel 只读采样、ATTACHMENT_BIT作为颜色或深度模板附件。TiImageDimension1D / 2D / 3D / 1D_ARRAY / 2D_ARRAY / CUBE其中 CUBE 为 6 层按 X、-X、Y、-Y、Z、-Z 顺序对应面。TiImageLayout包括SHADER_READ、SHADER_WRITE、SHADER_READ_WRITE、COLOR_ATTACHMENT、DEPTH_ATTACHMENT、TRANSFER_DST/SRC、PRESENT_SRC等。由于 Taichi 内部自行跟踪图像布局ti_track_image_ext/ti_transition_image仅在外部程序介入时才需要用于告知或强制布局。TiFormat从 R8、RGBA8、SRGB、深度/模板DEPTH16、DEPTH24STENCIL8、DEPTH32F到 16/32 位整型与浮点格式的完整集合格式可用性取决于运行时支持。TiImageSlice用于图像子区间含offset、extent、mip_level要求每个维度的offset extent不超过图像尺寸TiTexture则将TiImage与TiSampler绑定描述采样行为。错误处理机制C-API 采用“线程级最后错误缓存”机制核心是TiError枚举与ti_get_last_error/ti_set_last_error两个函数实现见 c_api/src/taichi_core_impl.cpp。TiError取值与含义错误码含义TI_ERROR_SUCCESS调用优雅完成TI_ERROR_NOT_SUPPORTED调用的 API 或参数组合不受支持TI_ERROR_CORRUPTED_DATA提供的数据损坏TI_ERROR_NAME_NOT_FOUND提供的名称不指向任何已有条目TI_ERROR_INVALID_ARGUMENT函数参数违反文档约束或 Kernel 参数与 AOT 模块中的参数表不匹配TI_ERROR_ARGUMENT_NULL按引用指针传入的参数为空TI_ERROR_ARGUMENT_OUT_OF_RANGE参数超出可接受范围或枚举参数取值未定义TI_ERROR_ARGUMENT_NOT_FOUND缺少一个或多个 Kernel 参数TI_ERROR_INVALID_INTEROP当前 arch 上无法进行期望的互操作例如从 CUDA Runtime 导出 Vulkan 对象TI_ERROR_INVALID_STATEC-API 进入不可恢复的无效状态相关对象可能已损坏应释放受污染资源TI_ERROR_INCOMPATIBLE_MODULEAOT 模块与当前 Runtime 不兼容获取最近一次错误的语义码与文本消息uint64_t message_size 0; char buffer[1024] {0}; message_size sizeof(buffer); TiError err ti_get_last_error(message_size, buffer);实现细节ti_get_last_error返回线程缓存中的错误码仅当message_size非空时输出文本把实际所需大小写回*message_sizemessage在message_size为 0 时被忽略。ti_set_last_error供 C-API 包装层与辅助库在扩展校验流程中主动设置错误错误码小于TI_ERROR_SUCCESS时缓存错误与消息否则复位为成功。行为测试 c_api/tests/c_api_behavior_test.cpp 覆盖了错误路径如空句柄调用ti_map_memory等边界情况。环境探测与版本ti_get_version()返回当前 Taichi 版本号与taichi_core.h中的TI_C_API_VERSION当前仓库为1007000对应 1.7.0见 c_api/include/taichi/taichi_core.h一致。ti_get_available_archs(arch_count, archs)返回当前平台上可用的 arch 列表。一个 arch 可用需同时满足① Runtime 库编译时带有该支持② 当前平台装有相应硬件或仿真软件。可用的 arch 至少有 1 个设备设备索引 0 恒可用arch 不可用时调用ti_create_runtime必然失败。注意返回顺序未定义。ti_get_runtime_capabilities/ti_set_runtime_capabilities_ext用于查询或强制覆盖 Runtime 实例的能力列表TiCapability枚举涵盖 SPIRV 版本、int8/16/64、float16/64、原子类型、subgroup 特性、physical storage buffer 等 24 项能力TiCapabilityLevelInfo表示整数能力级别且目前不保证高级别与低级别兼容。完整生命周期总览把以上步骤串联为一个最小使用模式// 1. 探测并创建 Runtime TiRuntime runtime ti_create_runtime(TI_ARCH_VULKAN, 0); // 2. 分配设备内存按需设置 host_read/host_write TiMemoryAllocateInfo mai {}; mai.size 1024; mai.host_write TI_TRUE; mai.usage TI_MEMORY_USAGE_STORAGE_BIT; TiMemory memory ti_allocate_memory(runtime, mai); // 3. 加载 AOT 模块并取出 Kernel TiAotModule mod ti_load_aot_module(runtime, /path/to/aot/module); TiKernel kernel ti_get_aot_module_kernel(mod, foo); // 4. 组装参数并启动 TiNdArray ndarray{}; ndarray.memory memory; ndarray.shape.dim_count 1; ndarray.shape.dims[0] 16; ndarray.elem_shape.dim_count 0; ndarray.elem_type TI_DATA_TYPE_F32; TiArgument arg{}; arg.type TI_ARGUMENT_TYPE_NDARRAY; arg.value.ndarray ndarray; ti_launch_kernel(runtime, kernel, 1, arg); // 5. 提交并等待 ti_flush(runtime); ti_wait(runtime); // 6. 清理先资源后模块最后 Runtime ti_free_memory(runtime, memory); ti_destroy_aot_module(mod); ti_destroy_runtime(runtime);错误检查ti_get_last_error应在每个关键调用之后进行销毁顺序遵循“依赖方先销毁TiRuntime最后销毁”的原则。实战注意事项与常见陷阱单线程单 Runtime同一线程不得同时操作多个TiRuntime多实例共存未被官方承诺遇到问题可向官方仓库提 issue。参数严格对齐 Python 源码Kernel 用位置参数顺序/类型/大小Compute Graph 用命名参数名称/类型任何错配都会在启动时报TI_ERROR_INVALID_ARGUMENT。host_read/host_write的代价宿主可访问内存可能因总线带宽限制拖慢 GPU 计算应按需开启、用完即ti_unmap_memory。map 前后的同步ti_map_memory前必须保证设备没有在用该内存ti_unmap_memory后不得再触碰映射地址。图像布局追踪Taichi 内部已跟踪布局ti_track_image_ext与ti_transition_image只在外部程序改写/使用图像时才需要调用。多平台分发选型优先 32 位数据类型与 Vulkan 后端Tier 1、跨平台兼容性最好。TiScalarValue是位容器赋值必须用对应位宽类型的指针强转如*(float*)value.x32不能直接把整数塞进去。延伸阅读本系列的 Vulkan 专属扩展接口docs/lang/articles/c-api/taichi_vulkan.md如导出互操作对象等 Vulkan 特有能力。C-API 完整头文件声明c_api/include/taichi/taichi_core.hC 便捷封装可参考 c_api/include/taichi/cpp/taichi.hpp。底层实现c_api/src/taichi_core_impl.cppRuntime 分发、AOT 加载、参数解析、错误缓存。各后端适配Vulkan 见 c_api/src/taichi_vulkan_impl.cpp、LLVMCUDA/CPU见 c_api/src/taichi_llvm_impl.cpp。端到端示例与测试C-API 行为/数值/互操作测试位于 c_api/testsPython 侧 AOT 导出 API 见 python/taichi/aot/module.py。【免费下载链接】taichiProductive, portable, and performant GPU programming in Python.项目地址: https://gitcode.com/GitHub_Trending/ta/taichi创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考