Skip to content

Commit

Permalink
[r] Support for dense current domain with core 2.27 (#3180)
Browse files Browse the repository at this point in the history
* [r] Support for dense current domain with core 2.27

* fix unit-test cases
  • Loading branch information
johnkerl authored Oct 17, 2024
1 parent ce88795 commit 7683e1e
Show file tree
Hide file tree
Showing 5 changed files with 70 additions and 58 deletions.
5 changes: 5 additions & 0 deletions apis/r/R/Init.R
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,11 @@
.pkgenv[["use_current_domain_transitional_internal_only"]]
}

.dense_arrays_can_have_current_domain <- function() {
triple <- tiledb_embedded_version()
return(triple[[1]] >= 2 && triple[[2]] >= 27)
}

## An .onAttach() function is not allowed to use cat() etc but _must_ communicate via
## packageStartupMessage() as this function can be 'muzzled' as desired. See Writing R Extensions.
.onAttach <- function(libname, pkgname) {
Expand Down
36 changes: 36 additions & 0 deletions apis/r/R/SOMANDArrayBase.R
Original file line number Diff line number Diff line change
Expand Up @@ -90,6 +90,42 @@ SOMANDArrayBase <- R6::R6Class(
#' @return Logical
tiledbsoma_has_upgraded_shape = function() {
has_current_domain(self$uri, private$.soma_context)
},

#' @description Increases the shape of the array as specfied. Raises an error
#' if the new shape is less than the current shape in any dimension. Raises
#' an error if the new shape exceeds maxshape in any dimension. Raises an
#' error if the array doesn't already have a shape: in that case please call
#' tiledbsoma_upgrade_shape.
#' @param new_shape A vector of integerish, of the same length as the array's `ndim`.
#' @return No return value
resize = function(new_shape) {
stopifnot(
"resize is not supported for dense arrays until tiledbsoma 1.15" =
.dense_arrays_can_have_current_domain() || private$.is_sparse,
"'new_shape' must be a vector of integerish values, of the same length as maxshape" =
rlang::is_integerish(new_shape, n = self$ndim()) ||
(bit64::is.integer64(new_shape) && length(new_shape) == self$ndim())
)
# Checking slotwise new shape >= old shape, and <= max_shape, is already done in libtiledbsoma
resize(self$uri, new_shape, private$.soma_context)
},

#' @description Allows the array to have a resizeable shape as described in the
#' TileDB-SOMA 1.15 release notes. Raises an error if the shape exceeds maxshape in any
#' dimension. Raises an error if the array already has a shape.
#' @param shape A vector of integerish, of the same length as the array's `ndim`.
#' @return No return value
tiledbsoma_upgrade_shape = function(shape) {
stopifnot(
"tiledbsoma_upgrade_shape is not supported for dense arrays until tiledbsoma 1.15" =
.dense_arrays_can_have_current_domain() || private$.is_sparse,
"'shape' must be a vector of integerish values, of the same length as maxshape" =
rlang::is_integerish(shape, n = self$ndim()) ||
(bit64::is.integer64(shape) && length(shape) == self$ndim())
)
# Checking slotwise new shape >= old shape, and <= max_shape, is already done in libtiledbsoma
tiledbsoma_upgrade_shape(self$uri, shape, private$.soma_context)
}

),
Expand Down
34 changes: 0 additions & 34 deletions apis/r/R/SOMASparseNDArray.R
Original file line number Diff line number Diff line change
Expand Up @@ -190,40 +190,6 @@ SOMASparseNDArray <- R6::R6Class(
#' @return A scalar with the number of non-zero elements
nnz = function() {
nnz(self$uri, private$.soma_context)
},

#' @description Increases the shape of the array as specfied. Raises an error
#' if the new shape is less than the current shape in any dimension. Raises
#' an error if the new shape exceeds maxshape in any dimension. Raises an
#' error if the array doesn't already have a shape: in that case please call
#' tiledbsoma_upgrade_shape.
#' @param new_shape A vector of integerish, of the same length as the array's `ndim`.
#' @return No return value
resize = function(new_shape) {
# TODO: move this to SOMANDArrayBase.R once core offers current-domain support for dense arrays.
# https://github.com/single-cell-data/TileDB-SOMA/issues/2955

stopifnot("'new_shape' must be a vector of integerish values, of the same length as maxshape" = rlang::is_integerish(new_shape, n = self$ndim()) ||
(bit64::is.integer64(new_shape) && length(new_shape) == self$ndim())
)
# Checking slotwise new shape >= old shape, and <= max_shape, is already done in libtiledbsoma
resize(self$uri, new_shape, private$.soma_context)
},

#' @description Allows the array to have a resizeable shape as described in the
#' TileDB-SOMA 1.15 release notes. Raises an error if the shape exceeds maxshape in any
#' dimension. Raises an error if the array already has a shape.
#' @param shape A vector of integerish, of the same length as the array's `ndim`.
#' @return No return value
tiledbsoma_upgrade_shape = function(shape) {
# TODO: move this to SOMANDArrayBase.R once core offers current-domain support for dense arrays.
# https://github.com/single-cell-data/TileDB-SOMA/issues/2955

stopifnot("'shape' must be a vector of integerish values, of the same length as maxshape" = rlang::is_integerish(shape, n = self$ndim()) ||
(bit64::is.integer64(shape) && length(shape) == self$ndim())
)
# Checking slotwise new shape >= old shape, and <= max_shape, is already done in libtiledbsoma
tiledbsoma_upgrade_shape(self$uri, shape, private$.soma_context)
}

),
Expand Down
5 changes: 1 addition & 4 deletions apis/r/R/utils-arrow.R
Original file line number Diff line number Diff line change
Expand Up @@ -571,10 +571,7 @@ get_domain_and_extent_array <- function(shape, is_sparse) {
# expansion.
ind_max_dom <- arrow_type_unsigned_range(ind_col_type) - c(0,ind_ext)

# TODO: support current domain for dense arrays once we have that support
# from core.
# https://github.com/single-cell-data/TileDB-SOMA/issues/2955
if (.new_shape_feature_flag_is_enabled() && is_sparse) {
if (.new_shape_feature_flag_is_enabled() && (is_sparse || .dense_arrays_can_have_current_domain())) {
aa <- arrow::arrow_array(c(ind_max_dom, ind_ext, ind_cur_dom), ind_col_type)
} else {
aa <- arrow::arrow_array(c(ind_cur_dom, ind_ext), ind_col_type)
Expand Down
48 changes: 28 additions & 20 deletions apis/r/tests/testthat/test-shape.R
Original file line number Diff line number Diff line change
Expand Up @@ -435,7 +435,8 @@ test_that("SOMASparseNDArray shape", {

# Test resize up
new_shape <- c(500, 600)
expect_no_error(ndarray$resize(new_shape))
####expect_no_error(ndarray$resize(new_shape))
ndarray$resize(new_shape)

# Test writes within new bounds
soma_dim_0 <- c(200,300)
Expand Down Expand Up @@ -478,13 +479,17 @@ test_that("SOMADenseNDArray shape", {
readback_shape <- ndarray$shape()
readback_maxshape <- ndarray$maxshape()
expect_equal(length(readback_shape), length(readback_maxshape))
# TODO: Awaiting core support for new shape in dense arrays.
# https://github.com/single-cell-data/TileDB-SOMA/issues/2955
#if (.new_shape_feature_flag_is_enabled()) {
# expect_true(all(readback_shape < readback_maxshape))
#} else {
# expect_true(all(readback_shape == readback_maxshape))
#}

if (.new_shape_feature_flag_is_enabled()) {
if (.dense_arrays_can_have_current_domain()) {
expect_true(all(readback_shape < readback_maxshape))
} else {
expect_true(all(readback_shape == readback_maxshape))
}
} else {
expect_true(all(readback_shape == readback_maxshape))
}

expect_true(all(readback_shape == readback_maxshape))

ndarray$close()
Expand Down Expand Up @@ -523,26 +528,29 @@ test_that("SOMADenseNDArray shape", {

# Test resize up
new_shape <- c(500, 600)
# TODO: Awaiting core support for new shape in dense arrays.
# https://github.com/single-cell-data/TileDB-SOMA/issues/2955
# expect_no_error(ndarray$resize(new_shape))
expect_error(ndarray$resize(new_shape))
if (tiledbsoma:::.dense_arrays_can_have_current_domain()) {
expect_no_error(ndarray$resize(new_shape))
} else {
expect_error(ndarray$resize(new_shape))
}

# Test writes within new bounds
ndarray <- SOMADenseNDArrayOpen(uri, "WRITE")
mat <- create_dense_matrix_with_int_dims(300, 400)
# TODO: Awaiting core support for new shape in dense arrays.
# https://github.com/single-cell-data/TileDB-SOMA/issues/2955
# expect_no_error(ndarray$write(sm))
expect_error(ndarray$write(sm))
if (tiledbsoma:::.dense_arrays_can_have_current_domain()) {
expect_no_error(ndarray$write(sm))
} else {
expect_error(ndarray$write(sm))
}
ndarray$close()

ndarray <- SOMADenseNDArrayOpen(uri)
coords <- list(bit64::as.integer64(c(101,202)), bit64::as.integer64(c(3,4)))
# TODO: Awaiting core support for new shape in dense arrays.
# https://github.com/single-cell-data/TileDB-SOMA/issues/2955
# expect_no_error(x <- ndarray$read(coords=coords)$tables()$concat())
expect_error(x <- ndarray$read(coords=coords)$tables()$concat())
if (tiledbsoma:::.dense_arrays_can_have_current_domain()) {
expect_no_condition(x <- ndarray$read(coords=coords)$tables()$concat())
} else {
expect_error(x <- ndarray$read(coords=coords)$tables()$concat())
}
ndarray$close()
}

Expand Down

0 comments on commit 7683e1e

Please sign in to comment.