Waits for all Vulkan devices to go idle, then destroys the devices and the Vulkan instance. Call this at the end of a script that used multiple GPUs (tensor / pipeline parallelism), before the process exits.
ggml_vulkan_shutdown(hard = FALSE, status = 0L)Invisibly NULL. Does not return when hard = TRUE
and
the hard-exit path is compiled in (see the section above).
Logical. If TRUE, call _exit(status) after teardown to
skip all exit handlers and guarantee no exit-time segfault; never returns.
Requires a build with --enable-hard-exit (see above); otherwise it
warns and returns normally. Default FALSE (safe to call mid-session).
Integer process exit code used only when hard = TRUE
(passed to _exit()). Defaults to 0L (success). If you call this
from an error path (e.g. a tryCatch handler after a stage failed),
pass a non-zero status so the failed run does not exit 0 and
mask the failure. Ignored when hard = FALSE.
The _exit() path is compiled out by default, because CRAN
Repository Policy forbids a package from terminating the user's R session. In
such a build hard = TRUE performs the normal teardown and emits a
warning — it is never silently ignored — so the exit-time race
described above can still fire. To compile it in, build from source with
R CMD INSTALL . --configure-args="--enable-hard-exit" (on Windows set
Sys.setenv(GGML_VK_HARD_EXIT = "1") first, since R ignores
configure.args there). Check the current build with
ggml_vulkan_hard_exit_available().
Why this exists: with several Vulkan devices active, R's own teardown at
process exit can run after the Vulkan loader / Mesa ICD libraries have
been unmapped, so the device destructors call into unmapped memory and the
process crashes with a segfault after your results were already printed.
Calling ggml_vulkan_shutdown() while the process is still alive runs the
teardown while the loader is still mapped, avoiding that crash. It is only
needed for exit cleanliness — your computed results are unaffected either way.
Idempotent and a no-op if Vulkan was never initialized. After this call the next Vulkan operation transparently re-initializes the instance from scratch, so it is safe to call mid-session too.
The plain teardown alone does not always win the exit-time race: with backends
created inside pipeline / tensor-parallel forwards, the loader-static-destruction
segfault (address ending f1ba0) can still fire flakily after your
results are printed, because no R exit hook runs before R unmaps the loader.
For a guaranteed-clean exit, pass hard = TRUE as the last
statement of a standalone script: after teardown it calls _exit(0),
terminating the process immediately without running R's / the C runtime's exit
handlers or unmapping any shared library — so there is no loader teardown phase
left to crash. Because it bypasses R's normal shutdown, only use
hard = TRUE at the very end of a script, never mid-session or in a
package/interactive context.
ggml_vulkan_hard_exit_available
# \donttest{
if (ggml_vulkan_available() && ggml_vulkan_device_count() >= 2) {
W <- matrix(rnorm(2048 * 64), nrow = 2048)
X <- matrix(rnorm(4 * 64), nrow = 4)
Y <- ggml_vulkan_split_mul_mat(W, X, n_devices = 2)
ggml_vulkan_shutdown() # clean up before the script exits
}
# }
Run the code above in your browser using DataLab