Nothing
# Chain tests: Positional encoding patterns (RoBERTa-style)
# Shape → Add → ConstantOfShape → NonZero → Gather
#
# Tests cval propagation through shape ops — the pattern that
# caused real bugs in RoBERTa model loading.
run_onnx <- function(path, inputs, device = "cpu") {
m <- onnx_load(path, device = device)
res <- onnx_run(m, inputs)
res[[1]]
}
# ── Minimal (3 ops): Shape → ConstantOfShape → NonZero ───────
test_that("chain position: Shape→ConstantOfShape→NonZero (minimal cval)", {
# Input: X[4] (1D tensor of length 4)
# Shape(X) → [4] (shape tensor: cval=[4])
# ConstantOfShape([4], value=1.0) → [4] filled with 1.0
# NonZero → [1, 4] (all indices since all elements are 1)
# Output should be [0, 1, 2, 3] reshaped as [1, 4]
inp <- .onnx_value_info("X", 1L, c(4L))
outp <- .onnx_value_info("Y", 1L, c(1L, 4L))
# ConstantOfShape value attribute: scalar 1.0
val_tensor_raw <- .float_bytes(1.0)
cos_attr <- .onnx_attr_tensor("value", c(1L), 1L, val_tensor_raw)
shape_node <- .onnx_node("Shape", "X", "shape_out")
cos_node <- .onnx_node("ConstantOfShape", "shape_out", "cos_out",
attrs = list(cos_attr))
nz_node <- .onnx_node("NonZero", "cos_out", "Y")
graph <- .onnx_graph("test",
list(shape_node, cos_node, nz_node),
list(inp), list(outp))
path <- tempfile(fileext = ".onnx")
writeBin(.onnx_model(graph), path)
x <- c(10, 20, 30, 40) # values don't matter, only shape
result <- run_onnx(path, list(X = x))
r <- as.numeric(result)
expect_equal(length(r), 4)
expect_equal(r, c(0, 1, 2, 3), tolerance = 1e-4)
})
# ── Real (5 ops): Shape → Add → ConstantOfShape → NonZero → Gather ──
test_that("chain position: Shape→Add→ConstantOfShape→NonZero→Gather (RoBERTa)", {
# Simulates RoBERTa position embedding construction:
# Shape(X) → [seq_len] (cval = [seq_len])
# Add([seq_len], offset=2) → [seq_len + 2] (RoBERTa offset)
# ConstantOfShape([seq_len + 2]) → ones tensor of length seq_len+2
# NonZero → [0, 1, 2, ..., seq_len+1] (position indices)
# Gather(pos_embed_table, indices) → position embeddings
seq_len <- 3L
inp <- .onnx_value_info("X", 1L, c(seq_len))
# Position embedding table: [5, 2] (seq_len+2=5 positions, dim=2)
pos_data <- c(0.1, 0.2, # pos 0
0.3, 0.4, # pos 1
0.5, 0.6, # pos 2
0.7, 0.8, # pos 3
0.9, 1.0) # pos 4
pos_raw <- unlist(lapply(pos_data, .float_bytes))
pos_t <- .onnx_tensor("PT", c(5L, 2L), 1L, pos_raw)
pos_vi <- .onnx_value_info("PT", 1L, c(5L, 2L))
outp <- .onnx_value_info("Y", 1L, c(5L, 2L))
# Offset constant: scalar 2 (as int64 → float for Add)
offset_raw <- .float_bytes(2.0)
offset_t <- .onnx_tensor("offset", c(1L), 1L, offset_raw)
offset_vi <- .onnx_value_info("offset", 1L, c(1L))
# ConstantOfShape value = 1.0
val_raw <- .float_bytes(1.0)
cos_attr <- .onnx_attr_tensor("value", c(1L), 1L, val_raw)
shape_node <- .onnx_node("Shape", "X", "s1")
add_node <- .onnx_node("Add", c("s1", "offset"), "s2")
cos_node <- .onnx_node("ConstantOfShape", "s2", "ones",
attrs = list(cos_attr))
nz_node <- .onnx_node("NonZero", "ones", "indices")
gather_node <- .onnx_node("Gather", c("PT", "indices"), "Y",
attrs = list(.onnx_attr_int("axis", 0L)))
graph <- .onnx_graph("test",
list(shape_node, add_node, cos_node, nz_node, gather_node),
list(inp, pos_vi, offset_vi),
list(outp),
list(pos_t, offset_t))
path <- tempfile(fileext = ".onnx")
writeBin(.onnx_model(graph), path)
x <- c(99, 99, 99) # values irrelevant — only shape matters
result <- run_onnx(path, list(X = x))
r <- as.numeric(result)
# Should gather all 5 positions [0..4] from table
expect_equal(length(r), 10)
expect_equal(r, pos_data, tolerance = 1e-4)
})
# ── Boundary: scalar shape (seq_len=1) ───────────────────────
test_that("chain position: seq_len=1 scalar shape (boundary)", {
# Shape(X[1]) → [1]
# ConstantOfShape([1]) → [1.0]
# NonZero → [0]
inp <- .onnx_value_info("X", 1L, c(1L))
outp <- .onnx_value_info("Y", 1L, c(1L, 1L))
val_raw <- .float_bytes(1.0)
cos_attr <- .onnx_attr_tensor("value", c(1L), 1L, val_raw)
shape_node <- .onnx_node("Shape", "X", "s1")
cos_node <- .onnx_node("ConstantOfShape", "s1", "ones",
attrs = list(cos_attr))
nz_node <- .onnx_node("NonZero", "ones", "Y")
graph <- .onnx_graph("test",
list(shape_node, cos_node, nz_node),
list(inp), list(outp))
path <- tempfile(fileext = ".onnx")
writeBin(.onnx_model(graph), path)
result <- run_onnx(path, list(X = c(42)))
r <- as.numeric(result)
expect_equal(length(r), 1)
expect_equal(r, 0, tolerance = 1e-4)
})
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.