diff --git a/.github/workflows/scripts/aot-demo.sh b/.github/workflows/scripts/aot-demo.sh index 7c5071a61e362..f949c63f4b7c5 100755 --- a/.github/workflows/scripts/aot-demo.sh +++ b/.github/workflows/scripts/aot-demo.sh @@ -4,11 +4,11 @@ set -ex export TI_SKIP_VERSION_CHECK=ON export TI_CI=1 -export TAICHI_AOT_DEMO_URL=https://github.com/taichi-dev/taichi-aot-demo -export TAICHI_AOT_DEMO_BRANCH=master +export TAICHI_AOT_DEMO_URL=https://github.com/PENGUINLIONG/taichi-aot-demo +export TAICHI_AOT_DEMO_BRANCH=fix-cgraph-demo export TAICHI_UNITY2_URL=https://github.com/taichi-dev/taichi-unity2 -export TAICHI_UNITY2_BRANCH=main +export TAICHI_UNITY2_BRANCH=fix-include export TAICHI_UNITY_EXAMPLE_URL=https://github.com/taichi-dev/Taichi-UnityExample export TAICHI_UNITY_EXAMPLE_BRANCH=main diff --git a/c_api/docs/taichi/taichi_core.h.md b/c_api/docs/taichi/taichi_core.h.md index 0ac8fb4d0f55c..02026722923af 100644 --- a/c_api/docs/taichi/taichi_core.h.md +++ b/c_api/docs/taichi/taichi_core.h.md @@ -35,7 +35,8 @@ The following section provides a brief introduction to the Taichi C-API. You *must* create a runtime instance before working with Taichi, and *only* one runtime per thread. Currently, we do not officially claim that multiple runtime instances can coexist in a process, but please feel free to [file an issue with us](https://github.com/taichi-dev/taichi/issues) if you run into any problem with runtime instance coexistence. ```cpp -TiRuntime runtime = ti_create_runtime(TI_ARCH_VULKAN); +// Create a Taichi Runtime on Vulkan device at index 0. +TiRuntime runtime = ti_create_runtime(TI_ARCH_VULKAN, 0); ``` When your program runs to the end, ensure that: @@ -116,7 +117,7 @@ TiAotModule aot_module = ti_load_aot_module(runtime, "/path/to/aot/module"); `/path/to/aot/module` should point to the directory that contains a `metadata.tcb`. -You can destroy an unused AOT module, but please ensure that there is no kernel or compute graph related to it pending to [`ti_submit`](#function-ti_submit). +You can destroy an unused AOT module, but please ensure that there is no kernel or compute graph related to it pending to [`ti_flush`](#function-ti_flush). ```cpp ti_destroy_aot_module(aot_module); @@ -177,10 +178,10 @@ named_arg2.argument = args[2]; ti_launch_compute_graph(runtime, compute_graph, named_args.size(), named_args.data()); ``` -When you have launched all kernels and compute graphs for this batch, you should `function.submit` and `function.wait` for the execution to finish. +When you have launched all kernels and compute graphs for this batch, you should `function.flush` and `function.wait` for the execution to finish. ```cpp -ti_submit(runtime); +ti_flush(runtime); ti_wait(runtime); ``` @@ -467,6 +468,9 @@ Sets the provided error as the last error raised by Taichi C-API invocations. It Creates a Taichi Runtime with the specified `enumeration.arch`. +- `function.create_runtime.arch`: Arch of Taichi Runtime. +- `function.create_runtime.device_index`: The index of device in `function.create_runtime.arch` to create Taichi Runtime on. + `function.destroy_runtime` Destroys a Taichi Runtime. @@ -502,14 +506,6 @@ Allocates a device image with provided parameters. Frees an image allocation. -`function.create_event` - -Creates an event primitive. - -`function.destroy_event` - -Destroys an event primitive. - `function.copy_memory_device_to_device` Copies the data in a contiguous subsection of the device memory to another subsection. The two subsections *must not* overlap. @@ -534,19 +530,7 @@ Launches a Taichi kernel with the provided arguments. The arguments *must* have Launches a Taichi compute graph with provided named arguments. The named arguments *must* have the same count, names, and types as in the source code. -`function.signal_event` - -Sets an event primitive to a signaled state so that the queues waiting for it can go on execution. If the event has been signaled, you *must* call `function.reset_event` to reset it; otherwise, an undefined behavior would occur. - -`function.reset_event` - -Sets a signaled event primitive back to an unsignaled state. - -`function.wait_event` - -Waits until an event primitive transitions to a signaled state. The awaited event *must* be signaled by an external procedure or a previous invocation to `function.reset_event`; otherwise, an undefined behavior would occur. - -`function.submit` +`function.flush` Submits all previously invoked device commands to the offload device for execution. diff --git a/c_api/include/taichi/cpp/taichi.hpp b/c_api/include/taichi/cpp/taichi.hpp index b88323e709aea..d5a209df2e870 100644 --- a/c_api/include/taichi/cpp/taichi.hpp +++ b/c_api/include/taichi/cpp/taichi.hpp @@ -685,60 +685,6 @@ class AotModule { } }; -class Event { - TiRuntime runtime_{TI_NULL_HANDLE}; - TiEvent event_{TI_NULL_HANDLE}; - bool should_destroy_{false}; - - public: - constexpr bool is_valid() const { - return event_ != nullptr; - } - inline void destroy() { - if (should_destroy_) { - ti_destroy_event(event_); - event_ = TI_NULL_HANDLE; - should_destroy_ = false; - } - } - - Event() { - } - Event(const Event &) = delete; - Event(Event &&b) : event_(b.event_), should_destroy_(b.should_destroy_) { - } - Event(TiRuntime runtime, TiEvent event, bool should_destroy) - : runtime_(runtime), event_(event), should_destroy_(should_destroy) { - } - ~Event() { - destroy(); - } - - Event &operator=(const Event &) = delete; - Event &operator=(Event &&b) { - event_ = detail::move_handle(b.event_); - should_destroy_ = std::exchange(b.should_destroy_, false); - return *this; - } - - void reset(TiEvent event_) { - ti_reset_event(runtime_, event_); - } - void signal(TiEvent event_) { - ti_signal_event(runtime_, event_); - } - void wait(TiEvent event_) { - ti_wait_event(runtime_, event_); - } - - constexpr TiEvent event() const { - return event_; - } - constexpr operator TiEvent() const { - return event_; - } -}; - class CapabilityLevelConfigBuilder; class CapabilityLevelConfig { public: @@ -937,8 +883,10 @@ class Runtime { runtime_(detail::move_handle(b.runtime_)), should_destroy_(std::exchange(b.should_destroy_, false)) { } - Runtime(TiArch arch) - : arch_(arch), runtime_(ti_create_runtime(arch)), should_destroy_(true) { + Runtime(TiArch arch, uint32_t device_index = 0) + : arch_(arch), + runtime_(ti_create_runtime(arch, device_index)), + should_destroy_(true) { } Runtime(TiArch arch, TiRuntime runtime, bool should_destroy) : arch_(arch), runtime_(runtime), should_destroy_(should_destroy) { @@ -1071,8 +1019,8 @@ class Runtime { ti_transition_image(runtime_, image, layout); } - void submit() { - ti_submit(runtime_); + void flush() { + ti_flush(runtime_); } void wait() { ti_wait(runtime_); diff --git a/c_api/include/taichi/taichi.h b/c_api/include/taichi/taichi.h index c02015de0d1b6..6eb5ff4f35ad9 100644 --- a/c_api/include/taichi/taichi.h +++ b/c_api/include/taichi/taichi.h @@ -5,28 +5,14 @@ #include "taichi/taichi_core.h" #ifdef TI_WITH_VULKAN -#ifndef TI_NO_VULKAN_INCLUDES -#include -#endif // TI_NO_VULKAN_INCLUDES - #include "taichi/taichi_vulkan.h" #endif // TI_WITH_VULKAN #ifdef TI_WITH_OPENGL -#ifndef TI_NO_OPENGL_INCLUDES -#include -#endif // TI_NO_OPENGL_INCLUDES - #include "taichi/taichi_opengl.h" #endif // TI_WITH_OPENGL #ifdef TI_WITH_CUDA -#ifndef TI_NO_CUDA_INCLUDES -// Only a few CUDA types is needed, including the entire is overkill -// for this -typedef void *CUdeviceptr; -#endif // TI_NO_CUDA_INCLUDES - #include "taichi/taichi_cuda.h" #endif // TI_WITH_CUDA diff --git a/c_api/include/taichi/taichi_core.h b/c_api/include/taichi/taichi_core.h index d8f7c7febe9da..02739964e3644 100644 --- a/c_api/include/taichi/taichi_core.h +++ b/c_api/include/taichi/taichi_core.h @@ -48,7 +48,8 @@ // any problem with runtime instance coexistence. // // ```cpp -// TiRuntime runtime = ti_create_runtime(TI_ARCH_VULKAN); +// // Create a Taichi Runtime on Vulkan device at index 0. +// TiRuntime runtime = ti_create_runtime(TI_ARCH_VULKAN, 0); // ``` // // When your program runs to the end, ensure that: @@ -144,7 +145,7 @@ // // You can destroy an unused AOT module, but please ensure that there is no // kernel or compute graph related to it pending to -// [`ti_submit`](#function-ti_submit). +// [`ti_flush`](#function-ti_flush). // // ```cpp // ti_destroy_aot_module(aot_module); @@ -211,11 +212,11 @@ // ``` // // When you have launched all kernels and compute graphs for this batch, you -// should [`ti_submit`](#function-ti_submit) and [`ti_wait`](#function-ti_wait) +// should [`ti_flush`](#function-ti_flush) and [`ti_wait`](#function-ti_wait) // for the execution to finish. // // ```cpp -// ti_submit(runtime); +// ti_flush(runtime); // ti_wait(runtime); // ``` // @@ -281,12 +282,6 @@ typedef struct TiRuntime_t *TiRuntime; // kernels and compute graphs. typedef struct TiAotModule_t *TiAotModule; -// Handle `TiEvent` -// -// A synchronization primitive to manage device execution flows in multiple -// queues. -typedef struct TiEvent_t *TiEvent; - // Handle `TiMemory` // // A contiguous allocation of device memory. @@ -845,7 +840,12 @@ TI_DLL_EXPORT void TI_API_CALL ti_set_last_error( // Function `ti_create_runtime` // // Creates a Taichi Runtime with the specified [`TiArch`](#enumeration-tiarch). -TI_DLL_EXPORT TiRuntime TI_API_CALL ti_create_runtime(TiArch arch); +TI_DLL_EXPORT TiRuntime TI_API_CALL ti_create_runtime( + // Arch of Taichi Runtime. + TiArch arch, + // The index of device in `function.create_runtime.arch` to create Taichi + // Runtime on. + uint32_t device_index); // Function `ti_destroy_runtime` // @@ -915,16 +915,6 @@ ti_create_sampler(TiRuntime runtime, const TiSamplerCreateInfo *create_info); TI_DLL_EXPORT void TI_API_CALL ti_destroy_sampler(TiRuntime runtime, TiSampler sampler); -// Function `ti_create_event` -// -// Creates an event primitive. -TI_DLL_EXPORT TiEvent TI_API_CALL ti_create_event(TiRuntime runtime); - -// Function `ti_destroy_event` -// -// Destroys an event primitive. -TI_DLL_EXPORT void TI_API_CALL ti_destroy_event(TiEvent event); - // Function `ti_copy_memory_device_to_device` (Device Command) // // Copies the data in a contiguous subsection of the device memory to another @@ -980,33 +970,11 @@ ti_launch_compute_graph(TiRuntime runtime, uint32_t arg_count, const TiNamedArgument *args); -// Function `ti_signal_event` (Device Command) -// -// Sets an event primitive to a signaled state so that the queues waiting for it -// can go on execution. If the event has been signaled, you *must* call -// [`ti_reset_event`](#function-ti_reset_event-device-command) to reset it; -// otherwise, an undefined behavior would occur. -TI_DLL_EXPORT void TI_API_CALL ti_signal_event(TiRuntime runtime, - TiEvent event); - -// Function `ti_reset_event` (Device Command) -// -// Sets a signaled event primitive back to an unsignaled state. -TI_DLL_EXPORT void TI_API_CALL ti_reset_event(TiRuntime runtime, TiEvent event); - -// Function `ti_wait_event` (Device Command) -// -// Waits until an event primitive transitions to a signaled state. The awaited -// event *must* be signaled by an external procedure or a previous invocation to -// [`ti_reset_event`](#function-ti_reset_event-device-command); otherwise, an -// undefined behavior would occur. -TI_DLL_EXPORT void TI_API_CALL ti_wait_event(TiRuntime runtime, TiEvent event); - -// Function `ti_submit` +// Function `ti_flush` // // Submits all previously invoked device commands to the offload device for // execution. -TI_DLL_EXPORT void TI_API_CALL ti_submit(TiRuntime runtime); +TI_DLL_EXPORT void TI_API_CALL ti_flush(TiRuntime runtime); // Function `ti_wait` // diff --git a/c_api/include/taichi/taichi_vulkan.h b/c_api/include/taichi/taichi_vulkan.h index 2a440092013fb..205980dc2e057 100644 --- a/c_api/include/taichi/taichi_vulkan.h +++ b/c_api/include/taichi/taichi_vulkan.h @@ -89,15 +89,6 @@ typedef struct TiVulkanImageInteropInfo { VkImageUsageFlags usage; } TiVulkanImageInteropInfo; -// Structure `TiVulkanEventInteropInfo` -// -// Necessary detail to share the same Vulkan event synchronization primitive -// between Taichi and the user application. -typedef struct TiVulkanEventInteropInfo { - // Vulkan event handle. - VkEvent event; -} TiVulkanEventInteropInfo; - // Function `ti_create_vulkan_runtime_ext` // // Creates a Vulkan Taichi runtime with user-controlled capability settings. @@ -153,21 +144,6 @@ ti_export_vulkan_image(TiRuntime runtime, TiImage image, TiVulkanImageInteropInfo *interop_info); -// Function `ti_import_vulkan_event` -// -// Imports the Vulkan event owned by Taichi to external procedures. -TI_DLL_EXPORT TiEvent TI_API_CALL -ti_import_vulkan_event(TiRuntime runtime, - const TiVulkanEventInteropInfo *interop_info); - -// Function `ti_export_vulkan_event` -// -// Exports a Vulkan event from external procedures to Taichi. -TI_DLL_EXPORT void TI_API_CALL -ti_export_vulkan_event(TiRuntime runtime, - TiEvent event, - TiVulkanEventInteropInfo *interop_info); - #ifdef __cplusplus } // extern "C" #endif // __cplusplus diff --git a/c_api/src/taichi_core_impl.cpp b/c_api/src/taichi_core_impl.cpp index 6589ebef706e3..1bae3ecb365cf 100644 --- a/c_api/src/taichi_core_impl.cpp +++ b/c_api/src/taichi_core_impl.cpp @@ -138,17 +138,6 @@ Runtime &AotModule::runtime() { return *runtime_; } -Event::Event(Runtime &runtime, std::unique_ptr event) - : runtime_(&runtime), event_(std::move(event)) { -} - -taichi::lang::DeviceEvent &Event::get() { - return *event_; -} -Runtime &Event::runtime() { - return *runtime_; -} - // ----------------------------------------------------------------------------- void ti_get_available_archs(uint32_t *arch_count, TiArch *archs) { @@ -219,9 +208,11 @@ void ti_set_last_error(TiError error, const char *message) { TI_CAPI_TRY_CATCH_END(); } -TiRuntime ti_create_runtime(TiArch arch) { +TiRuntime ti_create_runtime(TiArch arch, uint32_t device_index) { TiRuntime out = TI_NULL_HANDLE; TI_CAPI_TRY_CATCH_BEGIN(); + // FIXME: (penguinliong) Support device selection. + TI_CAPI_NOT_SUPPORTED_IF_RV(device_index != 0); switch (arch) { #ifdef TI_WITH_VULKAN case TI_ARCH_VULKAN: { @@ -470,27 +461,6 @@ void ti_destroy_sampler(TiRuntime runtime, TiSampler sampler) { TI_CAPI_TRY_CATCH_END(); } -TiEvent ti_create_event(TiRuntime runtime) { - TiEvent out = TI_NULL_HANDLE; - TI_CAPI_TRY_CATCH_BEGIN(); - TI_CAPI_ARGUMENT_NULL_RV(runtime); - - Runtime *runtime2 = (Runtime *)runtime; - std::unique_ptr event = - runtime2->get().create_event(); - Event *event2 = new Event(*runtime2, std::move(event)); - out = (TiEvent)event2; - TI_CAPI_TRY_CATCH_END(); - return out; -} -void ti_destroy_event(TiEvent event) { - TI_CAPI_TRY_CATCH_BEGIN(); - TI_CAPI_ARGUMENT_NULL(event); - - delete (Event *)event; - TI_CAPI_TRY_CATCH_END(); -} - void ti_copy_memory_device_to_device(TiRuntime runtime, const TiMemorySlice *dst_memory, const TiMemorySlice *src_memory) { @@ -874,38 +844,11 @@ void ti_launch_compute_graph(TiRuntime runtime, TI_CAPI_TRY_CATCH_END(); } -void ti_signal_event(TiRuntime runtime, TiEvent event) { - TI_CAPI_TRY_CATCH_BEGIN(); - TI_CAPI_ARGUMENT_NULL(runtime); - TI_CAPI_ARGUMENT_NULL(event); - - ((Runtime *)runtime)->signal_event(&((Event *)event)->get()); - TI_CAPI_TRY_CATCH_END(); -} - -void ti_reset_event(TiRuntime runtime, TiEvent event) { - TI_CAPI_TRY_CATCH_BEGIN(); - TI_CAPI_ARGUMENT_NULL(runtime); - TI_CAPI_ARGUMENT_NULL(event); - - ((Runtime *)runtime)->reset_event(&((Event *)event)->get()); - TI_CAPI_TRY_CATCH_END(); -} - -void ti_wait_event(TiRuntime runtime, TiEvent event) { - TI_CAPI_TRY_CATCH_BEGIN(); - TI_CAPI_ARGUMENT_NULL(runtime); - TI_CAPI_ARGUMENT_NULL(event); - - ((Runtime *)runtime)->wait_event(&((Event *)event)->get()); - TI_CAPI_TRY_CATCH_END(); -} - -void ti_submit(TiRuntime runtime) { +void ti_flush(TiRuntime runtime) { TI_CAPI_TRY_CATCH_BEGIN(); TI_CAPI_ARGUMENT_NULL(runtime); - ((Runtime *)runtime)->submit(); + ((Runtime *)runtime)->flush(); TI_CAPI_TRY_CATCH_END(); } void ti_wait(TiRuntime runtime) { diff --git a/c_api/src/taichi_core_impl.h b/c_api/src/taichi_core_impl.h index b7fcf57b94353..02eb3ba54213f 100644 --- a/c_api/src/taichi_core_impl.h +++ b/c_api/src/taichi_core_impl.h @@ -169,16 +169,7 @@ class Runtime { taichi::lang::ImageLayout layout) { TI_NOT_IMPLEMENTED } - virtual void signal_event(taichi::lang::DeviceEvent *event) { - TI_NOT_IMPLEMENTED - } - virtual void reset_event(taichi::lang::DeviceEvent *event) { - TI_NOT_IMPLEMENTED - } - virtual void wait_event(taichi::lang::DeviceEvent *event) { - TI_NOT_IMPLEMENTED - } - virtual void submit() = 0; + virtual void flush() = 0; virtual void wait() = 0; class VulkanRuntime *as_vk(); @@ -201,17 +192,6 @@ class AotModule { Runtime &runtime(); }; -class Event { - Runtime *runtime_; - std::unique_ptr event_; - - public: - Event(Runtime &runtime, std::unique_ptr event); - - taichi::lang::DeviceEvent &get(); - Runtime &runtime(); -}; - namespace { template diff --git a/c_api/src/taichi_gfx_impl.cpp b/c_api/src/taichi_gfx_impl.cpp index ea36cced3b961..f485625b09408 100644 --- a/c_api/src/taichi_gfx_impl.cpp +++ b/c_api/src/taichi_gfx_impl.cpp @@ -54,18 +54,9 @@ void GfxRuntime::transition_image(const taichi::lang::DeviceAllocation &image, taichi::lang::ImageLayout layout) { get_gfx_runtime().transition_image(image, layout); } -void GfxRuntime::submit() { +void GfxRuntime::flush() { get_gfx_runtime().flush(); } -void GfxRuntime::signal_event(taichi::lang::DeviceEvent *event) { - get_gfx_runtime().signal_event(event); -} -void GfxRuntime::reset_event(taichi::lang::DeviceEvent *event) { - get_gfx_runtime().reset_event(event); -} -void GfxRuntime::wait_event(taichi::lang::DeviceEvent *event) { - get_gfx_runtime().wait_event(event); -} void GfxRuntime::wait() { // (penguinliong) It's currently waiting for the entire runtime to stop. // Should be simply waiting for its fence to finish. diff --git a/c_api/src/taichi_gfx_impl.h b/c_api/src/taichi_gfx_impl.h index 86aeb4a3cb78c..e665098ee74cc 100644 --- a/c_api/src/taichi_gfx_impl.h +++ b/c_api/src/taichi_gfx_impl.h @@ -27,9 +27,6 @@ class GfxRuntime : public Runtime { virtual void transition_image( const taichi::lang::DeviceAllocation &image, taichi::lang::ImageLayout layout) override final; - virtual void signal_event(taichi::lang::DeviceEvent *event) override final; - virtual void reset_event(taichi::lang::DeviceEvent *event) override final; - virtual void wait_event(taichi::lang::DeviceEvent *event) override final; - virtual void submit() override final; + virtual void flush() override final; virtual void wait() override final; }; diff --git a/c_api/src/taichi_llvm_impl.cpp b/c_api/src/taichi_llvm_impl.cpp index e83b2382e7a83..ced0c4cf916fc 100644 --- a/c_api/src/taichi_llvm_impl.cpp +++ b/c_api/src/taichi_llvm_impl.cpp @@ -125,8 +125,8 @@ void LlvmRuntime::buffer_copy(const taichi::lang::DevicePtr &dst, TI_NOT_IMPLEMENTED; } -void LlvmRuntime::submit() { - // (penguinliong) Submit in LLVM backends is a nop atm. +void LlvmRuntime::flush() { + // (penguinliong) Flush in LLVM backends is a nop atm. // TI_NOT_IMPLEMENTED; } diff --git a/c_api/src/taichi_llvm_impl.h b/c_api/src/taichi_llvm_impl.h index 51e990810bdd0..1081b6e849d23 100644 --- a/c_api/src/taichi_llvm_impl.h +++ b/c_api/src/taichi_llvm_impl.h @@ -33,7 +33,7 @@ class LlvmRuntime : public Runtime { const taichi::lang::DevicePtr &src, size_t size) override; - void submit() override; + void flush() override; void wait() override; diff --git a/c_api/src/taichi_vulkan_impl.cpp b/c_api/src/taichi_vulkan_impl.cpp index 992b563ec08f9..426d0ab35145a 100644 --- a/c_api/src/taichi_vulkan_impl.cpp +++ b/c_api/src/taichi_vulkan_impl.cpp @@ -335,42 +335,4 @@ void ti_export_vulkan_image(TiRuntime runtime, TI_CAPI_TRY_CATCH_END(); } -TiEvent ti_import_vulkan_event(TiRuntime runtime, - const TiVulkanEventInteropInfo *interop_info) { - TiEvent out = TI_NULL_HANDLE; - TI_CAPI_TRY_CATCH_BEGIN(); - TI_CAPI_ARGUMENT_NULL_RV(runtime); - TI_CAPI_ARGUMENT_NULL_RV(interop_info); - TI_CAPI_ARGUMENT_NULL_RV(interop_info->event); - TI_CAPI_INVALID_INTEROP_ARCH_RV(((Runtime *)runtime)->arch, vulkan); - - Runtime *runtime2 = (Runtime *)runtime; - - vkapi::IVkEvent event = std::make_unique(); - event->device = runtime2->as_vk()->get_vk().vk_device(); - event->event = interop_info->event; - event->external = true; - - std::unique_ptr event2( - new taichi::lang::vulkan::VulkanDeviceEvent(std::move(event))); - - out = (TiEvent) new Event(*runtime2, std::move(event2)); - TI_CAPI_TRY_CATCH_END(); - return out; -} -void ti_export_vulkan_event(TiRuntime runtime, - TiEvent event, - TiVulkanEventInteropInfo *interop_info) { - TI_CAPI_TRY_CATCH_BEGIN(); - TI_CAPI_ARGUMENT_NULL(runtime); - TI_CAPI_ARGUMENT_NULL(event); - TI_CAPI_ARGUMENT_NULL(interop_info); - TI_CAPI_INVALID_INTEROP_ARCH(((Runtime *)runtime)->arch, vulkan); - - auto event2 = - (taichi::lang::vulkan::VulkanDeviceEvent *)(&((Event *)event)->get()); - interop_info->event = event2->vkapi_ref->event; - TI_CAPI_TRY_CATCH_END(); -} - #endif // TI_WITH_VULKAN diff --git a/c_api/taichi.json b/c_api/taichi.json index 1f080b31a7035..94d7ea041afa2 100644 --- a/c_api/taichi.json +++ b/c_api/taichi.json @@ -52,11 +52,6 @@ "type": "handle", "is_dispatchable": true }, - { - "name": "event", - "type": "handle", - "is_dispatchable": true - }, { "name": "memory", "type": "handle", @@ -520,6 +515,10 @@ }, { "type": "enumeration.arch" + }, + { + "name": "device_index", + "type": "uint32_t" } ] }, @@ -689,28 +688,6 @@ } ] }, - { - "name": "create_event", - "type": "function", - "parameters": [ - { - "name": "@return", - "type": "handle.event" - }, - { - "type": "handle.runtime" - } - ] - }, - { - "name": "destroy_event", - "type": "function", - "parameters": [ - { - "type": "handle.event" - } - ] - }, { "name": "copy_memory_device_to_device", "type": "function", @@ -830,46 +807,7 @@ ] }, { - "name": "signal_event", - "type": "function", - "is_device_command": true, - "parameters": [ - { - "type": "handle.runtime" - }, - { - "type": "handle.event" - } - ] - }, - { - "name": "reset_event", - "type": "function", - "is_device_command": true, - "parameters": [ - { - "type": "handle.runtime" - }, - { - "type": "handle.event" - } - ] - }, - { - "name": "wait_event", - "type": "function", - "is_device_command": true, - "parameters": [ - { - "type": "handle.runtime" - }, - { - "type": "handle.event" - } - ] - }, - { - "name": "submit", + "name": "flush", "type": "function", "parameters": [ { @@ -1164,16 +1102,6 @@ } ] }, - { - "name": "vulkan_event_interop_info", - "type": "structure", - "fields": [ - { - "name": "event", - "type": "VkEvent" - } - ] - }, { "name": "create_vulkan_runtime", "type": "function", @@ -1311,41 +1239,6 @@ "by_mut": true } ] - }, - { - "name": "import_vulkan_event", - "type": "function", - "parameters": [ - { - "name": "@return", - "type": "handle.event" - }, - { - "type": "handle.runtime" - }, - { - "name": "interop_info", - "type": "structure.vulkan_event_interop_info", - "by_ref": true - } - ] - }, - { - "name": "export_vulkan_event", - "type": "function", - "parameters": [ - { - "type": "handle.runtime" - }, - { - "type": "handle.event" - }, - { - "name": "interop_info", - "type": "structure.vulkan_event_interop_info", - "by_mut": true - } - ] } ] }, diff --git a/c_api/tests/c_api_behavior_test.cpp b/c_api/tests/c_api_behavior_test.cpp index 8165e3e15e413..686ee21368646 100644 --- a/c_api/tests/c_api_behavior_test.cpp +++ b/c_api/tests/c_api_behavior_test.cpp @@ -8,7 +8,7 @@ TEST_F(CapiTest, TestBehaviorCreateRuntime) { auto inner = [this](TiArch arch) { - TiRuntime runtime = ti_create_runtime(arch); + TiRuntime runtime = ti_create_runtime(arch, 0); TI_ASSERT(runtime == TI_NULL_HANDLE); EXPECT_TAICHI_ERROR(TI_ERROR_NOT_SUPPORTED); }; diff --git a/c_api/tests/comet.cpp b/c_api/tests/comet.cpp index 33a390d2f7ac0..a72622486256a 100644 --- a/c_api/tests/comet.cpp +++ b/c_api/tests/comet.cpp @@ -26,7 +26,7 @@ static void comet_run(TiArch arch, const std::string &folder_dir) { g_init["arr"] = arg_array; g_init.launch(); - runtime.submit(); + runtime.flush(); runtime.wait(); for (int i = 0; i < 10000; i++) { g_update["arg"] = arg_array; diff --git a/docs/lang/articles/c-api/taichi_core.md b/docs/lang/articles/c-api/taichi_core.md index 05ec3e6584cee..704746a448cc9 100644 --- a/docs/lang/articles/c-api/taichi_core.md +++ b/docs/lang/articles/c-api/taichi_core.md @@ -35,7 +35,8 @@ The following section provides a brief introduction to the Taichi C-API. You *must* create a runtime instance before working with Taichi, and *only* one runtime per thread. Currently, we do not officially claim that multiple runtime instances can coexist in a process, but please feel free to [file an issue with us](https://github.com/taichi-dev/taichi/issues) if you run into any problem with runtime instance coexistence. ```cpp -TiRuntime runtime = ti_create_runtime(TI_ARCH_VULKAN); +// Create a Taichi Runtime on Vulkan device at index 0. +TiRuntime runtime = ti_create_runtime(TI_ARCH_VULKAN, 0); ``` When your program runs to the end, ensure that: @@ -116,7 +117,7 @@ TiAotModule aot_module = ti_load_aot_module(runtime, "/path/to/aot/module"); `/path/to/aot/module` should point to the directory that contains a `metadata.tcb`. -You can destroy an unused AOT module, but please ensure that there is no kernel or compute graph related to it pending to [`ti_submit`](#function-ti_submit). +You can destroy an unused AOT module, but please ensure that there is no kernel or compute graph related to it pending to [`ti_flush`](#function-ti_flush). ```cpp ti_destroy_aot_module(aot_module); @@ -177,10 +178,10 @@ named_arg2.argument = args[2]; ti_launch_compute_graph(runtime, compute_graph, named_args.size(), named_args.data()); ``` -When you have launched all kernels and compute graphs for this batch, you should [`ti_submit`](#function-ti_submit) and [`ti_wait`](#function-ti_wait) for the execution to finish. +When you have launched all kernels and compute graphs for this batch, you should [`ti_flush`](#function-ti_flush) and [`ti_wait`](#function-ti_wait) for the execution to finish. ```cpp -ti_submit(runtime); +ti_flush(runtime); ti_wait(runtime); ``` @@ -259,16 +260,6 @@ typedef struct TiAotModule_t* TiAotModule; An ahead-of-time (AOT) compiled Taichi module, which contains a collection of kernels and compute graphs. ---- -### Handle `TiEvent` - -```c -// handle.event -typedef struct TiEvent_t* TiEvent; -``` - -A synchronization primitive to manage device execution flows in multiple queues. - --- ### Handle `TiMemory` @@ -971,12 +962,16 @@ Sets the provided error as the last error raised by Taichi C-API invocations. It ```c // function.create_runtime TI_DLL_EXPORT TiRuntime TI_API_CALL ti_create_runtime( - TiArch arch + TiArch arch, + uint32_t device_index ); ``` Creates a Taichi Runtime with the specified [`TiArch`](#enumeration-tiarch). +- `arch`: Arch of Taichi Runtime. +- `device_index`: The index of device in `arch` to create Taichi Runtime on. + --- ### Function `ti_destroy_runtime` @@ -1118,30 +1113,6 @@ TI_DLL_EXPORT void TI_API_CALL ti_destroy_sampler( ); ``` ---- -### Function `ti_create_event` - -```c -// function.create_event -TI_DLL_EXPORT TiEvent TI_API_CALL ti_create_event( - TiRuntime runtime -); -``` - -Creates an event primitive. - ---- -### Function `ti_destroy_event` - -```c -// function.destroy_event -TI_DLL_EXPORT void TI_API_CALL ti_destroy_event( - TiEvent event -); -``` - -Destroys an event primitive. - --- ### Function `ti_copy_memory_device_to_device` (Device Command) @@ -1229,50 +1200,11 @@ TI_DLL_EXPORT void TI_API_CALL ti_launch_compute_graph( Launches a Taichi compute graph with provided named arguments. The named arguments *must* have the same count, names, and types as in the source code. --- -### Function `ti_signal_event` (Device Command) - -```c -// function.signal_event -TI_DLL_EXPORT void TI_API_CALL ti_signal_event( - TiRuntime runtime, - TiEvent event -); -``` - -Sets an event primitive to a signaled state so that the queues waiting for it can go on execution. If the event has been signaled, you *must* call [`ti_reset_event`](#function-ti_reset_event-device-command) to reset it; otherwise, an undefined behavior would occur. - ---- -### Function `ti_reset_event` (Device Command) - -```c -// function.reset_event -TI_DLL_EXPORT void TI_API_CALL ti_reset_event( - TiRuntime runtime, - TiEvent event -); -``` - -Sets a signaled event primitive back to an unsignaled state. - ---- -### Function `ti_wait_event` (Device Command) - -```c -// function.wait_event -TI_DLL_EXPORT void TI_API_CALL ti_wait_event( - TiRuntime runtime, - TiEvent event -); -``` - -Waits until an event primitive transitions to a signaled state. The awaited event *must* be signaled by an external procedure or a previous invocation to [`ti_reset_event`](#function-ti_reset_event-device-command); otherwise, an undefined behavior would occur. - ---- -### Function `ti_submit` +### Function `ti_flush` ```c -// function.submit -TI_DLL_EXPORT void TI_API_CALL ti_submit( +// function.flush +TI_DLL_EXPORT void TI_API_CALL ti_flush( TiRuntime runtime ); ``` diff --git a/docs/lang/articles/c-api/taichi_vulkan.md b/docs/lang/articles/c-api/taichi_vulkan.md index 5ec2bfc36528a..f6b9d85028ec2 100644 --- a/docs/lang/articles/c-api/taichi_vulkan.md +++ b/docs/lang/articles/c-api/taichi_vulkan.md @@ -91,20 +91,6 @@ Necessary detail to share the same piece of Vulkan image between Taichi and exte - `tiling`: Image tiling. - `usage`: Vulkan image usage. In most cases, Taichi requires the `VK_IMAGE_USAGE_STORAGE_BIT` and the `VK_IMAGE_USAGE_SAMPLED_BIT`. ---- -### Structure `TiVulkanEventInteropInfo` - -```c -// structure.vulkan_event_interop_info -typedef struct TiVulkanEventInteropInfo { - VkEvent event; -} TiVulkanEventInteropInfo; -``` - -Necessary detail to share the same Vulkan event synchronization primitive between Taichi and the user application. - -- `event`: Vulkan event handle. - --- ### Function `ti_create_vulkan_runtime_ext` @@ -201,30 +187,3 @@ TI_DLL_EXPORT void TI_API_CALL ti_export_vulkan_image( ``` Exports a Vulkan image from external procedures to Taichi. - ---- -### Function `ti_import_vulkan_event` - -```c -// function.import_vulkan_event -TI_DLL_EXPORT TiEvent TI_API_CALL ti_import_vulkan_event( - TiRuntime runtime, - const TiVulkanEventInteropInfo* interop_info -); -``` - -Imports the Vulkan event owned by Taichi to external procedures. - ---- -### Function `ti_export_vulkan_event` - -```c -// function.export_vulkan_event -TI_DLL_EXPORT void TI_API_CALL ti_export_vulkan_event( - TiRuntime runtime, - TiEvent event, - TiVulkanEventInteropInfo* interop_info -); -``` - -Exports a Vulkan event from external procedures to Taichi. diff --git a/taichi/rhi/device.h b/taichi/rhi/device.h index 2bbb75ff9a8db..299a01510925f 100644 --- a/taichi/rhi/device.h +++ b/taichi/rhi/device.h @@ -232,12 +232,6 @@ struct ImageCopyParams { uint32_t depth{1}; }; -class DeviceEvent { - public: - virtual ~DeviceEvent() { - } -}; - class CommandList { public: virtual ~CommandList() { @@ -334,15 +328,6 @@ class CommandList { const ImageCopyParams ¶ms) { TI_NOT_IMPLEMENTED } - virtual void signal_event(DeviceEvent *event) { - TI_NOT_IMPLEMENTED - } - virtual void reset_event(DeviceEvent *event) { - TI_NOT_IMPLEMENTED - } - virtual void wait_event(DeviceEvent *event) { - TI_NOT_IMPLEMENTED - } }; struct PipelineSourceDesc { @@ -422,8 +407,6 @@ class Device { const PipelineSourceDesc &src, std::string name = "Pipeline") = 0; - virtual std::unique_ptr create_event(){TI_NOT_IMPLEMENTED} - std::unique_ptr allocate_memory_unique( const AllocParams ¶ms) { return std::make_unique( diff --git a/taichi/rhi/vulkan/vulkan_api.cpp b/taichi/rhi/vulkan/vulkan_api.cpp index fde2670d83e16..949fd0618100d 100644 --- a/taichi/rhi/vulkan/vulkan_api.cpp +++ b/taichi/rhi/vulkan/vulkan_api.cpp @@ -56,12 +56,6 @@ DeviceObjVkFramebuffer::~DeviceObjVkFramebuffer() { vkDestroyFramebuffer(device, framebuffer, nullptr); } -DeviceObjVkEvent::~DeviceObjVkEvent() { - if (!external) { - vkDestroyEvent(device, event, nullptr); - } -} - DeviceObjVkSemaphore::~DeviceObjVkSemaphore() { vkDestroySemaphore(device, semaphore, nullptr); } @@ -102,22 +96,6 @@ IDeviceObj create_device_obj(VkDevice device) { return obj; } -IVkEvent create_event(VkDevice device, - VkSemaphoreCreateFlags flags, - void *pnext) { - IVkEvent obj = std::make_shared(); - obj->device = device; - - VkEventCreateInfo info{}; - info.sType = VK_STRUCTURE_TYPE_EVENT_CREATE_INFO; - info.pNext = pnext; - info.flags = flags; - - VkResult res = vkCreateEvent(device, &info, nullptr, &obj->event); - BAIL_ON_VK_BAD_RESULT_NO_RETURN(res, "failed to create event"); - return obj; -} - IVkSemaphore create_semaphore(VkDevice device, VkSemaphoreCreateFlags flags, void *pnext) { diff --git a/taichi/rhi/vulkan/vulkan_api.h b/taichi/rhi/vulkan/vulkan_api.h index 840a5b114ba14..a20224aad4e94 100644 --- a/taichi/rhi/vulkan/vulkan_api.h +++ b/taichi/rhi/vulkan/vulkan_api.h @@ -18,17 +18,6 @@ struct DeviceObj { using IDeviceObj = std::shared_ptr; IDeviceObj create_device_obj(VkDevice device); -// VkEvent -struct DeviceObjVkEvent : public DeviceObj { - bool external{false}; - VkEvent event{VK_NULL_HANDLE}; - ~DeviceObjVkEvent() override; -}; -using IVkEvent = std::shared_ptr; -IVkEvent create_event(VkDevice device, - VkEventCreateFlags flags, - void *pnext = nullptr); - // VkSemaphore struct DeviceObjVkSemaphore : public DeviceObj { VkSemaphore semaphore{VK_NULL_HANDLE}; diff --git a/taichi/rhi/vulkan/vulkan_device.cpp b/taichi/rhi/vulkan/vulkan_device.cpp index df9bdb64a4ce3..b080ae1a67457 100644 --- a/taichi/rhi/vulkan/vulkan_device.cpp +++ b/taichi/rhi/vulkan/vulkan_device.cpp @@ -1451,24 +1451,6 @@ void VulkanCommandList::blit_image(DeviceAllocation dst_img, buffer_->refs.push_back(src_vk_image); } -void VulkanCommandList::signal_event(DeviceEvent *event) { - VulkanDeviceEvent *event2 = static_cast(event); - vkCmdSetEvent(buffer_->buffer, event2->vkapi_ref->event, - VK_PIPELINE_STAGE_ALL_COMMANDS_BIT); -} -void VulkanCommandList::reset_event(DeviceEvent *event) { - VulkanDeviceEvent *event2 = static_cast(event); - vkCmdResetEvent(buffer_->buffer, event2->vkapi_ref->event, - VK_PIPELINE_STAGE_ALL_COMMANDS_BIT); -} -void VulkanCommandList::wait_event(DeviceEvent *event) { - VulkanDeviceEvent *event2 = static_cast(event); - vkCmdWaitEvents(buffer_->buffer, 1, &event2->vkapi_ref->event, - VK_PIPELINE_STAGE_ALL_COMMANDS_BIT, - VK_PIPELINE_STAGE_ALL_COMMANDS_BIT, 0, nullptr, 0, nullptr, 0, - nullptr); -} - void VulkanCommandList::set_line_width(float width) { if (ti_device_->vk_caps().wide_line) { vkCmdSetLineWidth(buffer_->buffer, width); @@ -1569,11 +1551,6 @@ std::unique_ptr VulkanDevice::create_pipeline( return std::make_unique(params); } -std::unique_ptr VulkanDevice::create_event() { - return std::unique_ptr( - new VulkanDeviceEvent(vkapi::create_event(device_, 0))); -} - DeviceAllocation VulkanDevice::allocate_memory(const AllocParams ¶ms) { AllocationInternal &alloc = allocations_.acquire(); diff --git a/taichi/rhi/vulkan/vulkan_device.h b/taichi/rhi/vulkan/vulkan_device.h index 6941eb4272c11..9818c965a8321 100644 --- a/taichi/rhi/vulkan/vulkan_device.h +++ b/taichi/rhi/vulkan/vulkan_device.h @@ -351,16 +351,6 @@ class VulkanPipeline : public Pipeline { vkapi::IVkPipelineLayout pipeline_layout_{VK_NULL_HANDLE}; }; -class VulkanDeviceEvent : public DeviceEvent { - public: - explicit VulkanDeviceEvent(vkapi::IVkEvent event) : vkapi_ref(event) { - } - ~VulkanDeviceEvent() override { - } - - vkapi::IVkEvent vkapi_ref{nullptr}; -}; - class VulkanCommandList : public CommandList { public: VulkanCommandList(VulkanDevice *ti_device, @@ -425,10 +415,6 @@ class VulkanCommandList : public CommandList { ImageLayout src_img_layout, const ImageCopyParams ¶ms) override; - void signal_event(DeviceEvent *event) override; - void reset_event(DeviceEvent *event) override; - void wait_event(DeviceEvent *event) override; - vkapi::IVkRenderPass current_renderpass(); // Vulkan specific functions @@ -597,7 +583,6 @@ class TI_DLL_EXPORT VulkanDevice : public GraphicsDevice { std::unique_ptr create_pipeline( const PipelineSourceDesc &src, std::string name = "Pipeline") override; - std::unique_ptr create_event() override; DeviceAllocation allocate_memory(const AllocParams ¶ms) override; void dealloc_memory(DeviceAllocation handle) override; diff --git a/taichi/runtime/gfx/runtime.cpp b/taichi/runtime/gfx/runtime.cpp index 7d629570cb307..1a1e2ad6d8999 100644 --- a/taichi/runtime/gfx/runtime.cpp +++ b/taichi/runtime/gfx/runtime.cpp @@ -581,22 +581,6 @@ void GfxRuntime::transition_image(DeviceAllocation image, ImageLayout layout) { last_layout = layout; } -void GfxRuntime::signal_event(DeviceEvent *event) { - ensure_current_cmdlist(); - current_cmdlist_->signal_event(event); - submit_current_cmdlist_if_timeout(); -} -void GfxRuntime::reset_event(DeviceEvent *event) { - ensure_current_cmdlist(); - current_cmdlist_->reset_event(event); - submit_current_cmdlist_if_timeout(); -} -void GfxRuntime::wait_event(DeviceEvent *event) { - ensure_current_cmdlist(); - current_cmdlist_->wait_event(event); - submit_current_cmdlist_if_timeout(); -} - void GfxRuntime::synchronize() { flush(); device_->wait_idle(); diff --git a/taichi/runtime/gfx/runtime.h b/taichi/runtime/gfx/runtime.h index 6bcdcf21286e9..23b672ea2d758 100644 --- a/taichi/runtime/gfx/runtime.h +++ b/taichi/runtime/gfx/runtime.h @@ -111,10 +111,6 @@ class TI_DLL_EXPORT GfxRuntime { void untrack_image(DeviceAllocation image); void transition_image(DeviceAllocation image, ImageLayout layout); - void signal_event(DeviceEvent *event); - void reset_event(DeviceEvent *event); - void wait_event(DeviceEvent *event); - void synchronize(); StreamSemaphore flush();