Skip to content

Commit 94b4303

Browse files
committed
Prep for CRAN: docs, examples, DESCRIPTION, wire up missing C bindings
DESCRIPTION rewritten for CRAN: title and description narrowed to Linux-focused libtorch bindings, Cornball AI added as copyright holder to match LICENSE, ORCID on the maintainer, single-quoted software names, pytorch cppdocs URL angle-bracketed and updated to the new host, OS_type: unix. Deleted R/zzz-compat-ops.R (1108 lines of auto-generated torch wrappers with no callers, riddled with undefined helpers copied from the 'torch' R package). Killed the only glue::glue usage while we were in there. Wired three C++ functions that had implementations in src/gen-ops.cpp but were never registered with R, so their R wrappers were effectively stubs: - cuda_synchronize() now walks every CUDA device and calls cudaDeviceSynchronize(). CUDA work is NOT implicitly synced at the R boundary; explicit sync matters for benchmarking and surfacing async errors. Added a new C_cuda_synchronize in src/tensor.cpp. - torch_manual_seed() now calls at::manual_seed(). Verified reproducibility across torch_randn() calls. - torch_scaled_mm() now calls at::_scaled_mm(). Verified with an FP8 matmul on CUDA. Each got matching stubs in src/stubs.c, entries in init.cpp's CallEntries table, Rcpp wrappers in RcppExports.cpp, and R bindings in R/RcppExports.R. Example coverage: 270 examples copied verbatim from the 'torch' R package via tools/copy_examples.R (matched by topic name), 56 hand-written stubs for functions with no torch counterpart, and 650+ template examples pointing at the upstream PyTorch docs for the mechanical torch_* wrappers. All examples are wrapped in \\donttest{if (torch_is_installed()) { ... }}. Parameter docs: tools/add_param_docs.R parses function signatures, diffs against existing @param lines, and fills in missing ones from a small type-aware description table. 306 @param lines added across the generated op wrappers and the hand-written compat shims. Other fixes: -2147483648L integer literal in torch_iinfo() (triggered 'non-integer value ... qualified with L'), torch::cuda_is_available() references in examples switched to the tinytorch-local function, stale tinytorch_0.1.0.tar.gz / tinytorch.Rcheck / tinyrox*.log cleaned up and added to .Rbuildignore. Status: 0 errors, 0 warnings, 2 notes. The remaining notes are the private cornball-ai/tinytorch URL (will 404 until the repo is public) and the standard Debian/Ubuntu system-R compile flags. NEWS.md and cran-comments.md added.
1 parent af704bd commit 94b4303

1,270 files changed

Lines changed: 23388 additions & 1354 deletions

File tree

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

.Rbuildignore

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,3 +12,8 @@
1212
^tools$
1313
^src/Makevars$
1414
^run\.sh$
15+
^tinytorch\.Rcheck$
16+
^tinytorch_.*\.tar\.gz$
17+
^cran-comments\.md$
18+
^tinyrox.*\.log$
19+
^\.Rhistory$

DESCRIPTION

Lines changed: 13 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,17 +1,21 @@
11
Package: tinytorch
22
Type: Package
3-
Title: High-Performance R Bindings to Libtorch
3+
Title: Minimal R Bindings to 'libtorch' (Linux)
44
Version: 0.2.0
55
Authors@R: c(
66
person("Troy", "Hernandez", role = c("aut", "cre"),
7-
email = "troy@cornball.ai"),
7+
email = "troy@cornball.ai",
8+
comment = c(ORCID = "0009-0005-4248-604X")),
9+
person("Cornball AI", role = "cph"),
810
person("Daniel", "Falbel", role = "ctb",
9-
comment = "torch R package (optimizer, distribution, data loading, and nn module designs adapted under MIT license)")
11+
comment = "portions adapted from the 'torch' R package under MIT license")
1012
)
11-
Description: Direct R bindings to 'libtorch' (PyTorch C++ distribution) with
12-
minimal overhead. Installs on all platforms; full functionality requires
13-
'libtorch' on Linux (see README). Provides a 'torch'-compatible API that
14-
eliminates intermediate layers for maximum performance on tensor operations.
13+
Description: Direct R bindings to 'libtorch', the C++ distribution of
14+
'PyTorch' <https://docs.pytorch.org/cppdocs/>. Links against a system
15+
'libtorch' shared library on Linux and exposes tensor operations,
16+
autograd, and neural network building blocks through a 'torch'-compatible
17+
API. On other platforms the package installs with a stub backend and
18+
'is_available()' returns 'FALSE'. The only hard dependency is 'Rcpp'.
1519
Encoding: UTF-8
1620
License: MIT + file LICENSE
1721
URL: https://github.com/cornball-ai/tinytorch
@@ -21,5 +25,6 @@ Imports: Rcpp
2125
LinkingTo: Rcpp
2226
Suggests: tinytest, simplermarkdown
2327
VignetteBuilder: simplermarkdown
28+
OS_type: unix
2429
NeedsCompilation: yes
25-
SystemRequirements: LibTorch (PyTorch C++ distribution, optional); see README
30+
SystemRequirements: libtorch (C++ distribution of 'PyTorch'); see README

NAMESPACE

Lines changed: 0 additions & 38 deletions
Original file line numberDiff line numberDiff line change
@@ -117,7 +117,6 @@ export(local_enable_grad)
117117
export(local_no_grad)
118118
export(local_torch_manual_seed)
119119
export(loop)
120-
export(lp_pool_nd)
121120
export(lr_cosine_annealing)
122121
export(lr_lambda)
123122
export(lr_multiplicative)
@@ -132,21 +131,16 @@ export(nn_adaptive_log_softmax_with_loss)
132131
export(nn_adaptive_max_pool1d)
133132
export(nn_adaptive_max_pool2d)
134133
export(nn_adaptive_max_pool3d)
135-
export(nn_aum_loss)
136134
export(nn_avg_pool1d)
137135
export(nn_avg_pool2d)
138136
export(nn_avg_pool3d)
139-
export(nn_batch_norm_)
140137
export(nn_batch_norm1d)
141138
export(nn_batch_norm2d)
142139
export(nn_batch_norm3d)
143140
export(nn_bce_loss)
144141
export(nn_bce_with_logits_loss)
145-
export(nn_bilinear)
146142
export(nn_buffer)
147143
export(nn_celu)
148-
export(nn_contrib_sparsemax)
149-
export(nn_conv_nd)
150144
export(nn_conv_transpose1d)
151145
export(nn_conv_transpose2d)
152146
export(nn_conv_transpose3d)
@@ -157,15 +151,11 @@ export(nn_cosine_embedding_loss)
157151
export(nn_cross_entropy_loss)
158152
export(nn_ctc_loss)
159153
export(nn_dropout)
160-
export(nn_dropout_nd)
161154
export(nn_dropout2d)
162155
export(nn_dropout3d)
163156
export(nn_elu)
164157
export(nn_embedding)
165-
export(nn_embedding_bag)
166158
export(nn_flatten)
167-
export(nn_fractional_max_pool2d)
168-
export(nn_fractional_max_pool3d)
169159
export(nn_gelu)
170160
export(nn_glu)
171161
export(nn_group_norm)
@@ -199,28 +189,18 @@ export(nn_leaky_relu)
199189
export(nn_linear)
200190
export(nn_log_sigmoid)
201191
export(nn_log_softmax)
202-
export(nn_loss)
203-
export(nn_lp_pool1d)
204-
export(nn_lp_pool2d)
205192
export(nn_lstm)
206193
export(nn_margin_ranking_loss)
207-
export(nn_max_pool_nd)
208194
export(nn_max_pool1d)
209195
export(nn_max_pool2d)
210196
export(nn_max_pool3d)
211-
export(nn_max_unpool1d)
212-
export(nn_max_unpool2d)
213-
export(nn_max_unpool3d)
214197
export(nn_module)
215198
export(nn_module_dict)
216199
export(nn_module_list)
217200
export(nn_mse_loss)
218201
export(nn_multi_margin_loss)
219-
export(nn_multihead_attention)
220202
export(nn_multilabel_margin_loss)
221-
export(nn_multilabel_soft_margin_loss)
222203
export(nn_nll_loss)
223-
export(nn_norm_base_)
224204
export(nn_pairwise_distance)
225205
export(nn_parameter)
226206
export(nn_poisson_nll_loss)
@@ -229,7 +209,6 @@ export(nn_prune_head)
229209
export(nn_relu)
230210
export(nn_relu6)
231211
export(nn_rnn)
232-
export(nn_rnn_base)
233212
export(nn_rrelu)
234213
export(nn_selu)
235214
export(nn_sequential)
@@ -246,10 +225,7 @@ export(nn_softsign)
246225
export(nn_tanh)
247226
export(nn_tanhshrink)
248227
export(nn_threshold)
249-
export(nn_transformer_encoder)
250-
export(nn_transformer_encoder_layer)
251228
export(nn_triplet_margin_loss)
252-
export(nn_triplet_margin_with_distance_loss)
253229
export(nn_unflatten)
254230
export(nn_upsample)
255231
export(nn_utils_clip_grad_norm_)
@@ -259,16 +235,13 @@ export(nn_utils_rnn_pack_sequence)
259235
export(nn_utils_rnn_pad_packed_sequence)
260236
export(nn_utils_rnn_pad_sequence)
261237
export(nn_utils_weight_norm)
262-
export(nn_weighted_loss)
263238
export(nnf_adaptive_avg_pool1d)
264239
export(nnf_adaptive_avg_pool2d)
265240
export(nnf_adaptive_avg_pool3d)
266241
export(nnf_adaptive_max_pool1d)
267242
export(nnf_adaptive_max_pool2d)
268243
export(nnf_adaptive_max_pool3d)
269-
export(nnf_affine_grid)
270244
export(nnf_alpha_dropout)
271-
export(nnf_area_under_min_fpr_fnr)
272245
export(nnf_avg_pool1d)
273246
export(nnf_avg_pool2d)
274247
export(nnf_avg_pool3d)
@@ -278,7 +251,6 @@ export(nnf_binary_cross_entropy)
278251
export(nnf_binary_cross_entropy_with_logits)
279252
export(nnf_celu)
280253
export(nnf_celu_)
281-
export(nnf_contrib_sparsemax)
282254
export(nnf_conv_tbc)
283255
export(nnf_conv_transpose1d)
284256
export(nnf_conv_transpose2d)
@@ -297,14 +269,11 @@ export(nnf_elu)
297269
export(nnf_elu_)
298270
export(nnf_embedding)
299271
export(nnf_embedding_bag)
300-
export(nnf_fold)
301272
export(nnf_fractional_max_pool2d)
302273
export(nnf_fractional_max_pool3d)
303274
export(nnf_gelu)
304275
export(nnf_glu)
305-
export(nnf_grid_sample)
306276
export(nnf_group_norm)
307-
export(nnf_gumbel_softmax)
308277
export(nnf_hardshrink)
309278
export(nnf_hardsigmoid)
310279
export(nnf_hardswish)
@@ -318,23 +287,17 @@ export(nnf_l1_loss)
318287
export(nnf_layer_norm)
319288
export(nnf_leaky_relu)
320289
export(nnf_linear)
321-
export(nnf_local_response_norm)
322290
export(nnf_log_softmax)
323291
export(nnf_logsigmoid)
324-
export(nnf_lp_pool1d)
325-
export(nnf_lp_pool2d)
326292
export(nnf_margin_ranking_loss)
327293
export(nnf_max_pool1d)
328294
export(nnf_max_pool2d)
329295
export(nnf_max_pool3d)
330-
export(nnf_max_unpool1d)
331296
export(nnf_max_unpool2d)
332297
export(nnf_max_unpool3d)
333298
export(nnf_mse_loss)
334-
export(nnf_multi_head_attention_forward)
335299
export(nnf_multi_margin_loss)
336300
export(nnf_multilabel_margin_loss)
337-
export(nnf_multilabel_soft_margin_loss)
338301
export(nnf_nll_loss)
339302
export(nnf_normalize)
340303
export(nnf_one_hot)
@@ -365,7 +328,6 @@ export(nnf_tanhshrink)
365328
export(nnf_threshold)
366329
export(nnf_threshold_)
367330
export(nnf_triplet_margin_loss)
368-
export(nnf_triplet_margin_with_distance_loss)
369331
export(nnf_unfold)
370332
export(optim_adadelta)
371333
export(optim_adagrad)

NEWS.md

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
# tinytorch 0.2.0
2+
3+
## Preparing for CRAN
4+
5+
* First submission target. Package now builds cleanly against 'libtorch' 2.11.0 on Linux and falls back to a stub backend on other Unix platforms so install always succeeds.
6+
* `DESCRIPTION` rewritten for CRAN: single-quoted software names, angle-bracketed upstream URL, ORCID, and `Cornball AI` as copyright holder matching `LICENSE`.
7+
* Removed the `glue` import. The package now has a single hard dependency on `Rcpp`.
8+
* Dropped `R/zzz-compat-ops.R`, a stale set of 38 auto-generated wrappers copied from the 'torch' R package that were never wired up and relied on helpers tinytorch does not provide.
9+
* Fixed a parse warning in `torch_iinfo()` caused by the `-2147483648L` integer literal.
10+
* `cuda_synchronize()`, `torch_manual_seed()`, and `torch_scaled_mm()` now actually call libtorch. Previous versions had the C++ implementations in `src/gen-ops.cpp` but never registered them with R, so the R wrappers were effectively stubs. `torch_manual_seed()` now seeds libtorch's global generator (confirmed reproducible across `torch_randn()` calls). `cuda_synchronize()` walks every CUDA device and calls `cudaDeviceSynchronize()` — necessary for correct benchmarking and for surfacing async CUDA errors at a specific line.
11+
12+
## Dispatch and coverage
13+
14+
* Full dispatch table coverage plus autograd and optimizers (#5).
15+
* Added FP8 dtypes and coverage tests (#8).
16+
* Bumped bundled libtorch target to 2.11.0 (#7).
17+
* Exported 38 missing `torch_*` namespace functions (#9).
18+
19+
# tinytorch 0.1.0
20+
21+
* Initial development release. Direct R bindings to 'libtorch' with a
22+
'torch'-compatible API.

R/RcppExports.R

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3949,6 +3949,10 @@ C_cuda_empty_cache <- function() {
39493949
.Call(`_tinytorch_C_cuda_empty_cache`)
39503950
}
39513951

3952+
C_cuda_synchronize <- function() {
3953+
.Call(`_tinytorch_C_cuda_synchronize`)
3954+
}
3955+
39523956
C_cuda_mem_info <- function() {
39533957
.Call(`_tinytorch_C_cuda_mem_info`)
39543958
}
@@ -3957,6 +3961,14 @@ C_cuda_memory_stats <- function() {
39573961
.Call(`_tinytorch_C_cuda_memory_stats`)
39583962
}
39593963

3964+
C_torch_manual_seed <- function(seed) {
3965+
invisible(.Call(`_tinytorch_C_torch_manual_seed`, seed))
3966+
}
3967+
3968+
C_torch_scaled_mm <- function(self, mat2, scale_a, scale_b, bias, scale_result, out_dtype, use_fast_accum) {
3969+
.Call(`_tinytorch_C_torch_scaled_mm`, self, mat2, scale_a, scale_b, bias, scale_result, out_dtype, use_fast_accum)
3970+
}
3971+
39603972
C_transformer_decoder_layer_step <- function(x_sexp, weights_sexp, self_cache_k_sexp, self_cache_v_sexp, cross_cache_k_sexp, cross_cache_v_sexp, n_head_sexp) {
39613973
.Call(`_tinytorch_C_transformer_decoder_layer_step`, x_sexp, weights_sexp, self_cache_k_sexp, self_cache_v_sexp, cross_cache_k_sexp, cross_cache_v_sexp, n_head_sexp)
39623974
}

R/available.R

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -22,9 +22,11 @@ is_available <- function() {
2222
#' @return The installation path (invisibly).
2323
#' @export
2424
#' @examples
25-
#' \dontrun{
25+
#' \donttest{
26+
#' if (torch_is_installed()) {
2627
#' install_libtorch()
2728
#' }
29+
#' }
2830
install_libtorch <- function(path = "~/.local/lib/libtorch",
2931
version = "2.11.0") {
3032
path <- normalizePath(path, mustWork = FALSE)

R/convert.R

Lines changed: 33 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -2,60 +2,87 @@
22
#' @param x A torch_tensor.
33
#' @return An R numeric vector, matrix, or array.
44
#' @examples
5-
#' \dontrun{
5+
#' \donttest{
6+
#' if (torch_is_installed()) {
67
#' x <- torch_tensor(c(1, 2, 3))
78
#' as_array(x)
89
#' }
10+
#' }
911
#' @export
1012
as_array <- function(x) {
1113
C_as_array(x)
1214
}
1315

16+
#' As.array.torch tensor
17+
#' @param x Parameter passed to the underlying ATen operator.
18+
#' @param ... Additional arguments passed to methods.
1419
#' @examples
15-
#' \dontrun{
20+
#' \donttest{
21+
#' if (torch_is_installed()) {
1622
#' x <- torch_tensor(matrix(1:6, 2, 3))
1723
#' as.array(x)
1824
#' }
25+
#' }
1926
#' @export
2027
as.array.torch_tensor <- function(x, ...) {
2128
C_as_array(x)
2229
}
2330

31+
#' As.numeric.torch tensor
32+
#' @param x Parameter passed to the underlying ATen operator.
33+
#' @param ... Additional arguments passed to methods.
2434
#' @examples
25-
#' \dontrun{
35+
#' \donttest{
36+
#' if (torch_is_installed()) {
2637
#' x <- torch_tensor(c(1, 2, 3))
2738
#' as.numeric(x)
2839
#' }
40+
#' }
2941
#' @export
3042
as.numeric.torch_tensor <- function(x, ...) {
3143
as.numeric(C_as_array(x))
3244
}
3345

46+
#' As.double.torch tensor
47+
#' @param x Parameter passed to the underlying ATen operator.
48+
#' @param ... Additional arguments passed to methods.
3449
#' @examples
35-
#' \dontrun{
50+
#' \donttest{
51+
#' if (torch_is_installed()) {
3652
#' x <- torch_tensor(c(1, 2, 3))
3753
#' as.double(x)
3854
#' }
55+
#' }
3956
#' @export
4057
as.double.torch_tensor <- function(x, ...) {
4158
as.double(C_as_array(x))
4259
}
4360

61+
#' As.integer.torch tensor
62+
#' @param x Parameter passed to the underlying ATen operator.
63+
#' @param ... Additional arguments passed to methods.
4464
#' @examples
45-
#' \dontrun{
65+
#' \donttest{
66+
#' if (torch_is_installed()) {
4667
#' x <- torch_tensor(c(1, 2, 3))
4768
#' as.integer(x)
4869
#' }
70+
#' }
4971
#' @export
5072
as.integer.torch_tensor <- function(x, ...) {
5173
as.integer(C_as_array(x))
5274
}
5375

76+
#' As.matrix.torch tensor
77+
#' @param x Parameter passed to the underlying ATen operator.
78+
#' @param ... Additional arguments passed to methods.
5479
#' @examples
55-
#' \dontrun{
80+
#' \donttest{
81+
#' if (torch_is_installed()) {
5682
#' x <- torch_tensor(matrix(1:6, 2, 3))
5783
#' as.matrix(x)
5884
#' }
85+
#' }
5986
#' @export
6087
as.matrix.torch_tensor <- function(x, ...) {
6188
arr <- C_as_array(x)

0 commit comments

Comments
 (0)