Nothing
# Tests for extended backend and graph introspection functions
test_that("async graph compute works", {
skip_on_cran()
ctx <- ggml_init(16 * 1024 * 1024, no_alloc = TRUE)
on.exit(ggml_free(ctx))
# Create simple computation
a <- ggml_new_tensor_1d(ctx, GGML_TYPE_F32, 4)
b <- ggml_new_tensor_1d(ctx, GGML_TYPE_F32, 4)
c <- ggml_add(ctx, a, b)
# Build graph
graph <- ggml_build_forward_expand(ctx, c)
# Get CPU backend
backend <- ggml_backend_cpu_init()
skip_if(is.null(backend), "CPU backend not available")
on.exit(ggml_backend_free(backend), add = TRUE)
# Allocate tensors (requires no_alloc = TRUE context)
buffer <- ggml_backend_alloc_ctx_tensors(ctx, backend)
on.exit(ggml_backend_buffer_free(buffer), add = TRUE)
# Set data
ggml_backend_tensor_set_data(a, c(1, 2, 3, 4))
ggml_backend_tensor_set_data(b, c(5, 6, 7, 8))
# Async compute
status <- ggml_backend_graph_compute_async(backend, graph)
expect_type(status, "integer")
# Synchronize
ggml_backend_synchronize(backend)
# Check result
result <- ggml_backend_tensor_get_data(c)
expect_equal(result, c(6, 8, 10, 12), tolerance = 1e-5)
})
test_that("multi-buffer functions work", {
skip_on_cran()
backend <- ggml_backend_cpu_init()
skip_if(is.null(backend), "CPU backend not available")
on.exit(ggml_backend_free(backend), add = TRUE)
# This test checks if the functions exist and work at basic level
# Creating actual multi-buffers requires lower-level buffer allocation
# Test is_multi_buffer on regular buffer
ctx <- ggml_init(1024 * 1024, no_alloc = TRUE)
on.exit(ggml_free(ctx), add = TRUE)
a <- ggml_new_tensor_1d(ctx, GGML_TYPE_F32, 10)
# Allocate tensors (requires no_alloc = TRUE context)
buffer <- ggml_backend_alloc_ctx_tensors(ctx, backend)
on.exit(ggml_backend_buffer_free(buffer), add = TRUE)
# Regular buffer should not be multi-buffer
is_multi <- ggml_backend_buffer_is_multi_buffer(buffer)
expect_type(is_multi, "logical")
expect_false(is_multi)
})
test_that("graph_view works", {
ctx <- ggml_init(16 * 1024 * 1024)
on.exit(ggml_free(ctx))
# Create a chain of operations
a <- ggml_new_tensor_1d(ctx, GGML_TYPE_F32, 4)
b <- ggml_add(ctx, a, a)
c <- ggml_mul(ctx, b, b)
d <- ggml_sqrt(ctx, c)
# Build graph
graph <- ggml_build_forward_expand(ctx, d)
# Check graph has nodes
n_nodes <- ggml_graph_n_nodes(graph)
expect_gte(n_nodes, 3)
# Create view of first 2 nodes
if (n_nodes >= 2) {
view <- ggml_graph_view(graph, 0, 2)
expect_false(is.null(view))
}
})
test_that("op_can_inplace works", {
# Test some known operations
# ADD operation (op code 1) can typically be inplace
# We test that the function returns logical values
result <- ggml_op_can_inplace(1L) # GGML_OP_ADD
expect_type(result, "logical")
result <- ggml_op_can_inplace(0L) # GGML_OP_NONE
expect_type(result, "logical")
})
test_that("are_same_layout works", {
ctx <- ggml_init(1024 * 1024)
on.exit(ggml_free(ctx))
# Same shape and type -> same layout
a <- ggml_new_tensor_2d(ctx, GGML_TYPE_F32, 4, 4)
b <- ggml_new_tensor_2d(ctx, GGML_TYPE_F32, 4, 4)
expect_true(ggml_are_same_layout(a, b))
# Different shape -> different layout
c <- ggml_new_tensor_2d(ctx, GGML_TYPE_F32, 4, 8)
expect_false(ggml_are_same_layout(a, c))
# Different type -> different layout
d <- ggml_new_tensor_2d(ctx, GGML_TYPE_F16, 4, 4)
expect_false(ggml_are_same_layout(a, d))
# 1D tensors with same size
e <- ggml_new_tensor_1d(ctx, GGML_TYPE_F32, 16)
f <- ggml_new_tensor_1d(ctx, GGML_TYPE_F32, 16)
expect_true(ggml_are_same_layout(e, f))
})
test_that("backend_register and device_register exist", {
# These are advanced functions that require registry/device pointers
# We just check that they exist and are callable
expect_true(is.function(ggml_backend_register))
expect_true(is.function(ggml_backend_device_register))
})
test_that("ggml_backend_load returns NULL for a missing shared object", {
# Loading a non-existent backend plugin must not crash; it warns and
# returns NULL (the C dlopen fails).
res <- ggml_backend_load("/nonexistent/libggml-doesnotexist.so")
expect_null(res)
})
test_that("ggml_backend_multi_buffer_alloc_buffer wraps real buffers", {
skip_on_cran()
backend <- ggml_backend_cpu_init()
skip_if(is.null(backend), "CPU backend not available")
on.exit(ggml_backend_free(backend), add = TRUE)
ctx1 <- ggml_init(1024 * 1024, no_alloc = TRUE)
on.exit(ggml_free(ctx1), add = TRUE)
ctx2 <- ggml_init(1024 * 1024, no_alloc = TRUE)
on.exit(ggml_free(ctx2), add = TRUE)
ggml_new_tensor_1d(ctx1, GGML_TYPE_F32, 10)
ggml_new_tensor_1d(ctx2, GGML_TYPE_F32, 20)
buf1 <- ggml_backend_alloc_ctx_tensors(ctx1, backend)
buf2 <- ggml_backend_alloc_ctx_tensors(ctx2, backend)
multi <- ggml_backend_multi_buffer_alloc_buffer(list(buf1, buf2))
on.exit(ggml_backend_buffer_free(multi), add = TRUE)
expect_false(is.null(multi))
# The wrapper around several backend buffers must report as a multi-buffer.
expect_true(ggml_backend_buffer_is_multi_buffer(multi))
})
test_that("ggml_backend_multi_buffer_set_usage runs on a multi-buffer", {
skip_on_cran()
backend <- ggml_backend_cpu_init()
skip_if(is.null(backend), "CPU backend not available")
on.exit(ggml_backend_free(backend), add = TRUE)
ctx <- ggml_init(1024 * 1024, no_alloc = TRUE)
on.exit(ggml_free(ctx), add = TRUE)
ggml_new_tensor_1d(ctx, GGML_TYPE_F32, 16)
buf <- ggml_backend_alloc_ctx_tensors(ctx, backend)
multi <- ggml_backend_multi_buffer_alloc_buffer(list(buf))
on.exit(ggml_backend_buffer_free(multi), add = TRUE)
# Setting usage on every wrapped buffer must succeed silently.
expect_silent(
ggml_backend_multi_buffer_set_usage(multi, ggml_backend_buffer_usage_weights())
)
})
Any scripts or data that you put into this service are public.
Add the following code to your website.
For more information on customizing the embed code, read Embedding Snippets.