diff --git a/.Rbuildignore b/.Rbuildignore index e3d55ea..93068a5 100644 --- a/.Rbuildignore +++ b/.Rbuildignore @@ -36,3 +36,4 @@ ^cran-comments\.md$ ^CRAN-SUBMISSION$ ^configure\.log$ +^\.claude$ diff --git a/.github/workflows/check.yaml b/.github/workflows/check.yaml index 3e1f161..ca3fb39 100644 --- a/.github/workflows/check.yaml +++ b/.github/workflows/check.yaml @@ -48,7 +48,7 @@ jobs: - name: Install Python libraries used for testing continue-on-error: true run: | - reticulate::py_install(c("tbparse", "tensorflow"), pip = TRUE) + reticulate::py_install(c('tbparse', 'tensorflow'), pip = TRUE) shell: Rscript {0} - uses: r-lib/actions/check-r-package@v2 diff --git a/.github/workflows/pkgdown.yaml b/.github/workflows/pkgdown.yaml index 1a405f6..4a9ff1e 100644 --- a/.github/workflows/pkgdown.yaml +++ b/.github/workflows/pkgdown.yaml @@ -21,6 +21,7 @@ jobs: group: pkgdown-${{ github.event_name != 'pull_request' || github.run_id }} env: GITHUB_PAT: ${{ secrets.GITHUB_TOKEN }} + CHROMOTE_CHROME: google-chrome-stable permissions: contents: write steps: @@ -41,7 +42,7 @@ jobs: - name: Install Python deps run: | - reticulate::py_install('tensorflow', pip = TRUE) + reticulate::py_install(c('tensorflow==2.10', 'numpy<2', 'setuptools<70'), pip = TRUE, python_version = '3.10') shell: Rscript {0} - name: Build site diff --git a/.github/workflows/test-coverage.yaml b/.github/workflows/test-coverage.yaml index 3aa3378..811487a 100644 --- a/.github/workflows/test-coverage.yaml +++ b/.github/workflows/test-coverage.yaml @@ -32,7 +32,7 @@ jobs: - name: Install Python libraries used for testing run: | - reticulate::py_install(c("tbparse", "tensorflow"), pip = TRUE) + reticulate::py_install(c('tbparse', 'tensorflow'), pip = TRUE) shell: Rscript {0} - name: Test coverage diff --git a/DESCRIPTION b/DESCRIPTION index 5c39c49..0d95da7 100644 --- a/DESCRIPTION +++ b/DESCRIPTION @@ -1,8 +1,9 @@ Package: tfevents Title: Write Events for 'TensorBoard' -Version: 0.0.4.9000 +Version: 0.0.5 Authors@R: c( - person("Daniel", "Falbel", email = "daniel@posit.co", role = c("aut", "cre", "cph")), + person("Daniel", "Falbel", email = "daniel@posit.co", role = c("aut", "cph")), + person("Tomasz", "Kalinowski", email = "tomasz@posit.co", role = c("cre")), person(family = "Posit, PBC", role = c("cph")), person(family = "The tl::optional authors", role = c("cph"), comment = "For the vendored tl::optional code."), person("Mark", "Adler", role = c("cph"), comment = "For the included crc32c code.") @@ -13,7 +14,7 @@ Description: Provides a convenient way to log scalars, images, audio, and histog License: MIT + file LICENSE Encoding: UTF-8 Roxygen: list(markdown = TRUE) -RoxygenNote: 7.2.3 +RoxygenNote: 7.3.3 LinkingTo: Rcpp Imports: diff --git a/NAMESPACE b/NAMESPACE index 8fbee98..a95a22a 100644 --- a/NAMESPACE +++ b/NAMESPACE @@ -4,6 +4,10 @@ S3method(as_event,character) S3method(as_event,list) S3method(as_event,numeric) S3method(as_event,tfevents_summary_values) +S3method(as_tensor_proto,array) +S3method(as_tensor_proto,blob) +S3method(as_tensor_proto,character) +S3method(as_tensor_proto,list) S3method(format,tfevents_event) S3method(format,tfevents_summary) S3method(format,tfevents_summary_values) diff --git a/NEWS.md b/NEWS.md index 53eeb9b..8e93f2c 100644 --- a/NEWS.md +++ b/NEWS.md @@ -1,4 +1,6 @@ -# tfevents (development version) +# tfevents 0.0.5 + +* Changed maintainer to Tomasz Kalinowski. # tfevents 0.0.4 diff --git a/R/audio.R b/R/audio.R index 815141c..8892634 100644 --- a/R/audio.R +++ b/R/audio.R @@ -7,7 +7,7 @@ #' @param sample_rate The sample rate in Hz associated to the audio values. #' @returns An audio summary that can be logged with [log_event()]. #' @family summary -#' @examples +#' @examplesIf rlang::is_installed("wav") #' tmp <- tempfile() #' with_logdir(tmp, { #' summary_audio(array(runif(100), dim = c(1,100, 1))) diff --git a/R/tensor.R b/R/tensor.R index ef6988a..25d1a67 100644 --- a/R/tensor.R +++ b/R/tensor.R @@ -15,6 +15,7 @@ as_tensor_proto <- function(x, dtype = NA, ...) { UseMethod("as_tensor_proto") } +#' @exportS3Method as_tensor_proto.blob <- function(x, dtype = NA, ...) { if (is.na(dtype)) dtype <- "string" if (!dtype %in% c("string")) @@ -22,6 +23,7 @@ as_tensor_proto.blob <- function(x, dtype = NA, ...) { tensor_proto(list(x), shape = new_tensor_shape(dim = length(x)), dtype = dtype) } +#' @exportS3Method as_tensor_proto.character <- function(x, dtype = NA, ...) { if (is.na(dtype)) dtype <- "string" if (!dtype %in% c("string")) @@ -29,6 +31,7 @@ as_tensor_proto.character <- function(x, dtype = NA, ...) { tensor_proto(list(x), shape = new_tensor_shape(dim = length(x)), dtype = dtype) } +#' @exportS3Method as_tensor_proto.array <- function(x, dtype = NA, ...) { dims <- dim(x) # proto store tensor data in C ordering, thus we need to reshape values @@ -37,6 +40,7 @@ as_tensor_proto.array <- function(x, dtype = NA, ...) { tensor_proto(x, shape = new_tensor_shape(dim = list(dims)), dtype = dtype) } +#' @exportS3Method as_tensor_proto.list <- function(x, dtype, ...) { c(x, dtype) %<-% vec_recycle_common(x, dtype) results <- lapply(seq_along(x), function(i) { diff --git a/configure b/configure index c68582e..207549e 100755 --- a/configure +++ b/configure @@ -108,10 +108,17 @@ if [ ! -d "generated" ]; then 'protoc -I "proto" --cpp_out="generated" {}' \; fi -# copied from protolite: -# Suppress wanrings about pragmas in the autogenerated protobuf headers. -# Uwe + BDR have said this is OK and there is nothing we can do about this. +# Remove pragma diagnostic directives from autogenerated protobuf headers +# to avoid CRAN NOTEs about pragmas suppressing diagnostics. find ./ -type f -name "*.pb.h" -exec sed -i.bak "s@ #pragma@/*nowarn*/#pragma@g" {} \; +find ./ -type f -name "*.pb.h" -exec sed -i.bak '/#pragma GCC diagnostic/d' {} \; + +# Strip [[deprecated]] and [[nodiscard]] attributes from generated protobuf +# code to avoid compilation warnings on CRAN. +find ./ -type f \( -name "*.pb.h" -o -name "*.pb.cc" \) -exec sed -i.bak \ + -e 's/\[\[deprecated\]\]//g' \ + -e 's/\[\[nodiscard\]\]//g' \ + -e 's/enum \(.*\) : int/enum \1 : int/' {} \; PB_SRC=$(echo $(find generated -type f -name "*.pb.cc" -print)) CPP_SRC=$(echo $(find *.cpp -print)) diff --git a/man/summary_audio.Rd b/man/summary_audio.Rd index ddb5c87..f833da2 100644 --- a/man/summary_audio.Rd +++ b/man/summary_audio.Rd @@ -47,10 +47,12 @@ containing WAV encoded audio files. }} \examples{ +\dontshow{if (rlang::is_installed("wav")) withAutoprint(\{ # examplesIf} tmp <- tempfile() with_logdir(tmp, { summary_audio(array(runif(100), dim = c(1,100, 1))) }) +\dontshow{\}) # examplesIf} } \seealso{ Other summary: diff --git a/src/reader.cpp b/src/reader.cpp index dbdfd94..cb8384c 100644 --- a/src/reader.cpp +++ b/src/reader.cpp @@ -45,7 +45,7 @@ tensorboard::Event EventFileIterator::get_next () { file.read(&buffer[0], length); tensorboard::Event event; - event.ParseFromString(std::string(buffer.begin(), buffer.end())); + (void)event.ParseFromString(std::string(buffer.begin(), buffer.end())); file.read(reinterpret_cast(&crc), sizeof(std::uint32_t)); diff --git a/tests/testthat/helper-tbparse.R b/tests/testthat/helper-tbparse.R index bd3127a..7ba9f0b 100644 --- a/tests/testthat/helper-tbparse.R +++ b/tests/testthat/helper-tbparse.R @@ -2,6 +2,12 @@ skip_if_tbparse_not_available <- function() { skip_if(inherits(try(reticulate::import("tbparse"), silent = TRUE), "try-error")) } +skip_if_no_tensorflow <- function() { + skip_on_cran() + skip_if_not_installed("tensorflow") + skip_if(inherits(try(reticulate::import("tensorflow"), silent = TRUE), "try-error")) +} + if (inherits(try(reticulate::import("tbparse"), silent = TRUE), "try-error")) { tbparse <- NULL } else { diff --git a/tests/testthat/test-audio.R b/tests/testthat/test-audio.R index 09d1ae2..75ba54e 100644 --- a/tests/testthat/test-audio.R +++ b/tests/testthat/test-audio.R @@ -1,4 +1,5 @@ test_that("can write an audio file", { + skip_if_not_installed("wav") f <- wav::read_wav(test_path("resources/test-audio.wav")) audio <- array(t(f), dim = c(1, rev(dim(f)))) @@ -21,6 +22,7 @@ test_that("can write an audio file", { }) test_that("can write multiple audio files from a array", { + skip_if_not_installed("wav") f <- wav::read_wav(test_path("resources/test-audio.wav")) f_t <- t(f) audio <- array(0, dim = c(10, rev(dim(f)))) diff --git a/tests/testthat/test-image.R b/tests/testthat/test-image.R index 8534a26..9eda47f 100644 --- a/tests/testthat/test-image.R +++ b/tests/testthat/test-image.R @@ -12,6 +12,7 @@ test_that("write image", { skip_if_tbparse_not_available() + skip_if_no_tensorflow() reader <- tbparse$SummaryReader(temp) buf <- reader$tensors$value[[1]][[3]] # TODO: in theory we don't need tensorflow for this, but couldnt find a way to diff --git a/tests/testthat/test-read.R b/tests/testthat/test-read.R index 0f9c83f..3f6f7d9 100644 --- a/tests/testthat/test-read.R +++ b/tests/testthat/test-read.R @@ -81,6 +81,7 @@ test_that("can iterate over events", { }) test_that("can extract value", { + skip_if_not_installed("wav") temp <- tempfile()