From c10a8ef6d3f8d6c14192a013617916338121f43f Mon Sep 17 00:00:00 2001 From: terrytangyuan Date: Sat, 8 Dec 2018 22:14:12 -0500 Subject: [PATCH 1/4] Set up R package structure and infra --- R-package/.Rbuildignore | 3 + R-package/.gitignore | 5 ++ R-package/DESCRIPTION | 37 +++++++++ R-package/NAMESPACE | 17 ++++ R-package/R/package.R | 86 ++++++++++++++++++++ R-package/R/reexports.R | 23 ++++++ R-package/R/utils.R | 0 R-package/README.md | 3 + R-package/man/pipe.Rd | 12 +++ R-package/man/reexports.Rd | 18 ++++ R-package/man/tfio.Rd | 12 +++ R-package/tests/testthat.R | 10 +++ R-package/tests/testthat/test-datasets-ops.R | 7 ++ R-package/tests/testthat/utils.R | 18 ++++ R-package/tfio.Rproj | 21 +++++ R-package/vignettes/introduction.Rmd | 27 ++++++ 16 files changed, 299 insertions(+) create mode 100644 R-package/.Rbuildignore create mode 100644 R-package/.gitignore create mode 100644 R-package/DESCRIPTION create mode 100644 R-package/NAMESPACE create mode 100644 R-package/R/package.R create mode 100644 R-package/R/reexports.R create mode 100644 R-package/R/utils.R create mode 100644 R-package/README.md create mode 100644 R-package/man/pipe.Rd create mode 100644 R-package/man/reexports.Rd create mode 100644 R-package/man/tfio.Rd create mode 100644 R-package/tests/testthat.R create mode 100644 R-package/tests/testthat/test-datasets-ops.R create mode 100644 R-package/tests/testthat/utils.R create mode 100644 R-package/tfio.Rproj create mode 100644 R-package/vignettes/introduction.Rmd diff --git a/R-package/.Rbuildignore b/R-package/.Rbuildignore new file mode 100644 index 000000000..fc28d4b80 --- /dev/null +++ b/R-package/.Rbuildignore @@ -0,0 +1,3 @@ +^.*\.Rproj$ +^\.Rproj\.user$ +^man-roxygen/ diff --git a/R-package/.gitignore b/R-package/.gitignore new file mode 100644 index 000000000..7b732e723 --- /dev/null +++ b/R-package/.gitignore @@ -0,0 +1,5 @@ +.Rproj.user +.Rhistory +.RData +.Ruserdata +.DS_Store diff --git a/R-package/DESCRIPTION b/R-package/DESCRIPTION new file mode 100644 index 000000000..a32facc5a --- /dev/null +++ b/R-package/DESCRIPTION @@ -0,0 +1,37 @@ +Package: tfio +Type: Package +Title: Interface to 'TensorFlow IO' +Version: 0.0.9000 +Authors@R: c( + person("Yuan", "Tang", role = c("aut", "cre"), + email = "terrytangyuan@gmail.com", + comment = c(ORCID = "0000-0001-5243-233X")), + person("TensorFlow IO SIG", role = c("aut", "cph"), + email = "io@tensorflow.org"), + person("RStudio", role = c("cph")), + person(family = "TensorFlow Authors", role = c("cph")) + ) +Description: Interface to 'TensorFlow IO', Datasets and filesystem extensions maintained by SIG-IO. +License: Apache License 2.0 +URL: https://github.com/tensorflow/io +BugReports: https://github.com/tensorflow/io/issues +SystemRequirements: TensorFlow >= 1.4 (https://www.tensorflow.org/) +Encoding: UTF-8 +LazyData: true +Depends: + R (>= 3.1) +Imports: + reticulate (>= 1.10), + tensorflow (>= 1.9), + magrittr, + rlang, + tidyselect, + stats +Roxygen: list(markdown = TRUE) +RoxygenNote: 6.1.0 +Suggests: + testthat, + knitr, + tfestimators, + keras +VignetteBuilder: knitr diff --git a/R-package/NAMESPACE b/R-package/NAMESPACE new file mode 100644 index 000000000..cdbb2dc95 --- /dev/null +++ b/R-package/NAMESPACE @@ -0,0 +1,17 @@ +# Generated by roxygen2: do not edit by hand + +export("%>%") +export(install_tensorflow) +export(tf) +export(tf_config) +import(rlang) +import(tidyselect) +importFrom(magrittr,"%>%") +importFrom(reticulate,import) +importFrom(reticulate,py_has_attr) +importFrom(reticulate,py_last_error) +importFrom(reticulate,py_str) +importFrom(reticulate,tuple) +importFrom(tensorflow,install_tensorflow) +importFrom(tensorflow,tf) +importFrom(tensorflow,tf_config) diff --git a/R-package/R/package.R b/R-package/R/package.R new file mode 100644 index 000000000..0fe06726e --- /dev/null +++ b/R-package/R/package.R @@ -0,0 +1,86 @@ +#' TensorFlow IO API for R +#' +#' This library provides an R interface to the +#' \href{https://github.com/tensorflow/io}{TensorFlow IO} API +#' that provides datasets and filesystem extensions maintained by SIG-IO. +#' +#' @docType package +#' @name tfio +NULL + +#' @importFrom reticulate py_last_error tuple py_str py_has_attr import +#' @import tidyselect +#' @import rlang +NULL + +tfio_lib <- NULL + +.onLoad <- function(libname, pkgname) { + + # Delay load handler + displayed_warning <- FALSE + delay_load <- list( + + priority = 5, + + environment = "r-tensorflow-io", + + on_load = function() { + check_tensorflow_version(displayed_warning) + }, + + on_error = function(e) { + stop(tf_config()$error_message, call. = FALSE) + } + ) + + # TODO: This is commented out for now until we add the wrappers. + # tfio_lib <<- import("tensorflow_io", delay_load = delay_load) + +} + +check_tensorflow_version <- function(displayed_warning) { + current_tf_ver <- tf_version() + required_least_ver <- "1.12" + if (current_tf_ver < required_least_ver) { + if (!displayed_warning) { + message("tfio requires TensorFlow version > ", required_least_ver, " ", + "(you are currently running version ", current_tf_ver, ").\n") + displayed_warning <<- TRUE + } + } +} + +.onUnload <- function(libpath) { + +} + +.onAttach <- function(libname, pkgname) { + +} + +.onDetach <- function(libpath) { + +} + +# Reusable function for registering a set of methods with S3 manually. The +# methods argument is a list of character vectors, each of which has the form +# c(package, genname, class). +registerMethods <- function(methods) { + lapply(methods, function(method) { + pkg <- method[[1]] + generic <- method[[2]] + class <- method[[3]] + func <- get(paste(generic, class, sep = ".")) + if (pkg %in% loadedNamespaces()) { + registerS3method(generic, class, func, envir = asNamespace(pkg)) + } + setHook( + packageEvent(pkg, "onLoad"), + function(...) { + registerS3method(generic, class, func, envir = asNamespace(pkg)) + } + ) + }) +} + diff --git a/R-package/R/reexports.R b/R-package/R/reexports.R new file mode 100644 index 000000000..acd6b6096 --- /dev/null +++ b/R-package/R/reexports.R @@ -0,0 +1,23 @@ +#' Pipe operator +#' +#' See \code{\link[magrittr]{\%>\%}} for more details. +#' +#' @name %>% +#' @rdname pipe +#' @keywords internal +#' @export +#' @importFrom magrittr %>% +#' @usage lhs \%>\% rhs +NULL + +#' @importFrom tensorflow tf +#' @export +tensorflow::tf + +#' @importFrom tensorflow install_tensorflow +#' @export +tensorflow::install_tensorflow + +#' @importFrom tensorflow tf_config +#' @export +tensorflow::tf_config diff --git a/R-package/R/utils.R b/R-package/R/utils.R new file mode 100644 index 000000000..e69de29bb diff --git a/R-package/README.md b/R-package/README.md new file mode 100644 index 000000000..eb88bb26c --- /dev/null +++ b/R-package/README.md @@ -0,0 +1,3 @@ +## R interface to TensorFlow IO + +This is the R interface to datasets and filesystem extensions maintained by SIG-IO. diff --git a/R-package/man/pipe.Rd b/R-package/man/pipe.Rd new file mode 100644 index 000000000..5e85fd0c2 --- /dev/null +++ b/R-package/man/pipe.Rd @@ -0,0 +1,12 @@ +% Generated by roxygen2: do not edit by hand +% Please edit documentation in R/reexports.R +\name{\%>\%} +\alias{\%>\%} +\title{Pipe operator} +\usage{ +lhs \%>\% rhs +} +\description{ +See \code{\link[magrittr]{\%>\%}} for more details. +} +\keyword{internal} diff --git a/R-package/man/reexports.Rd b/R-package/man/reexports.Rd new file mode 100644 index 000000000..8a1dd55e5 --- /dev/null +++ b/R-package/man/reexports.Rd @@ -0,0 +1,18 @@ +% Generated by roxygen2: do not edit by hand +% Please edit documentation in R/reexports.R +\docType{import} +\name{reexports} +\alias{reexports} +\alias{tf} +\alias{install_tensorflow} +\alias{tf_config} +\title{Objects exported from other packages} +\keyword{internal} +\description{ +These objects are imported from other packages. Follow the links +below to see their documentation. + +\describe{ + \item{tensorflow}{\code{\link[tensorflow]{tf}}, \code{\link[tensorflow]{install_tensorflow}}, \code{\link[tensorflow]{tf_config}}} +}} + diff --git a/R-package/man/tfio.Rd b/R-package/man/tfio.Rd new file mode 100644 index 000000000..9015c1960 --- /dev/null +++ b/R-package/man/tfio.Rd @@ -0,0 +1,12 @@ +% Generated by roxygen2: do not edit by hand +% Please edit documentation in R/package.R +\docType{package} +\name{tfio} +\alias{tfio} +\alias{tfio-package} +\title{TensorFlow IO API for R} +\description{ +This library provides an R interface to the +\href{https://github.com/tensorflow/io}{TensorFlow IO} API +that provides datasets and filesystem extensions maintained by SIG-IO. +} diff --git a/R-package/tests/testthat.R b/R-package/tests/testthat.R new file mode 100644 index 000000000..de20dd5f8 --- /dev/null +++ b/R-package/tests/testthat.R @@ -0,0 +1,10 @@ +library(testthat) +library(tensorflow) +library(tfio) + +test_check("tfio") + + + + + diff --git a/R-package/tests/testthat/test-datasets-ops.R b/R-package/tests/testthat/test-datasets-ops.R new file mode 100644 index 000000000..f21796778 --- /dev/null +++ b/R-package/tests/testthat/test-datasets-ops.R @@ -0,0 +1,7 @@ +context("TensorFlow IO dataset ops") + +source("utils.R") + +test_succeeds("All TensorFlow IO dataset ops work", { + print("Placeholder for now") +}) diff --git a/R-package/tests/testthat/utils.R b/R-package/tests/testthat/utils.R new file mode 100644 index 000000000..4e7e52b32 --- /dev/null +++ b/R-package/tests/testthat/utils.R @@ -0,0 +1,18 @@ +library(tensorflow) + +skip_if_no_tensorflow <- function(required_version = NULL) { + if (!reticulate::py_module_available("tensorflow")) + skip("TensorFlow not available for testing") + else if (!is.null(required_version)) { + if (tensorflow::tf_version() < required_version) + skip(sprintf("Required version of TensorFlow (%s) not available for testing", + required_version)) + } +} + +test_succeeds <- function(desc, expr, required_version = NULL) { + test_that(desc, { + skip_if_no_tensorflow(required_version) + expect_error(force(expr), NA) + }) +} diff --git a/R-package/tfio.Rproj b/R-package/tfio.Rproj new file mode 100644 index 000000000..270314b87 --- /dev/null +++ b/R-package/tfio.Rproj @@ -0,0 +1,21 @@ +Version: 1.0 + +RestoreWorkspace: Default +SaveWorkspace: Default +AlwaysSaveHistory: Default + +EnableCodeIndexing: Yes +UseSpacesForTab: Yes +NumSpacesForTab: 2 +Encoding: UTF-8 + +RnwWeave: Sweave +LaTeX: pdfLaTeX + +AutoAppendNewline: Yes +StripTrailingWhitespace: Yes + +BuildType: Package +PackageUseDevtools: Yes +PackageInstallArgs: --no-multiarch --with-keep.source +PackageRoxygenize: rd,collate,namespace diff --git a/R-package/vignettes/introduction.Rmd b/R-package/vignettes/introduction.Rmd new file mode 100644 index 000000000..70d266de0 --- /dev/null +++ b/R-package/vignettes/introduction.Rmd @@ -0,0 +1,27 @@ +--- +title: "R interface to TensorFlow IO API" +output: + rmarkdown::html_vignette: default +vignette: > + %\VignetteIndexEntry{Introduction} + %\VignetteEngine{knitr::rmarkdown} + %\VignetteEncoding{UTF-8} +type: docs +repo: https://github.com/tensorflow/io +menu: + main: + name: "Using TensorFlow IO" + identifier: "tools-tfio-using" + parent: "tfio-top" + weight: 10 +--- + +```{r setup, include=FALSE} +knitr::opts_chunk$set(eval = FALSE) +``` + +## Overview + +This is the R interface to datasets and filesystem extensions maintained by SIG-IO. + +(TBA) From c411fc3fd04e418ee05dadd894d6e8d0297849ff Mon Sep 17 00:00:00 2001 From: terrytangyuan Date: Sat, 8 Dec 2018 22:17:10 -0500 Subject: [PATCH 2/4] Additional test utility function --- R-package/R/utils.R | 0 R-package/tests/testthat/utils.R | 5 +++++ 2 files changed, 5 insertions(+) delete mode 100644 R-package/R/utils.R diff --git a/R-package/R/utils.R b/R-package/R/utils.R deleted file mode 100644 index e69de29bb..000000000 diff --git a/R-package/tests/testthat/utils.R b/R-package/tests/testthat/utils.R index 4e7e52b32..5cbbab790 100644 --- a/R-package/tests/testthat/utils.R +++ b/R-package/tests/testthat/utils.R @@ -10,6 +10,11 @@ skip_if_no_tensorflow <- function(required_version = NULL) { } } +skip_if_no_tensorflow_io <- function(required_version = NULL) { + if (!reticulate::py_module_available("tensorflow_io")) + skip("TensorFlow not available for testing") +} + test_succeeds <- function(desc, expr, required_version = NULL) { test_that(desc, { skip_if_no_tensorflow(required_version) From 5c6ee366f9f6179f550197a9745c493b525f75f0 Mon Sep 17 00:00:00 2001 From: terrytangyuan Date: Sat, 8 Dec 2018 22:18:38 -0500 Subject: [PATCH 3/4] Remove redundant newlines --- R-package/tests/testthat.R | 5 ----- 1 file changed, 5 deletions(-) diff --git a/R-package/tests/testthat.R b/R-package/tests/testthat.R index de20dd5f8..06b147c28 100644 --- a/R-package/tests/testthat.R +++ b/R-package/tests/testthat.R @@ -3,8 +3,3 @@ library(tensorflow) library(tfio) test_check("tfio") - - - - - From 47a45db5e326ce6b40a1e6d3338ceefec7194a20 Mon Sep 17 00:00:00 2001 From: terrytangyuan Date: Sat, 8 Dec 2018 22:32:29 -0500 Subject: [PATCH 4/4] Added import for tfdatasets --- R-package/DESCRIPTION | 1 + R-package/NAMESPACE | 1 + R-package/R/package.R | 1 + 3 files changed, 3 insertions(+) diff --git a/R-package/DESCRIPTION b/R-package/DESCRIPTION index a32facc5a..d6a78cb3b 100644 --- a/R-package/DESCRIPTION +++ b/R-package/DESCRIPTION @@ -23,6 +23,7 @@ Depends: Imports: reticulate (>= 1.10), tensorflow (>= 1.9), + tfdatasets (>= 1.9), magrittr, rlang, tidyselect, diff --git a/R-package/NAMESPACE b/R-package/NAMESPACE index cdbb2dc95..af3467069 100644 --- a/R-package/NAMESPACE +++ b/R-package/NAMESPACE @@ -5,6 +5,7 @@ export(install_tensorflow) export(tf) export(tf_config) import(rlang) +import(tfdatasets) import(tidyselect) importFrom(magrittr,"%>%") importFrom(reticulate,import) diff --git a/R-package/R/package.R b/R-package/R/package.R index 0fe06726e..8f93111f2 100644 --- a/R-package/R/package.R +++ b/R-package/R/package.R @@ -11,6 +11,7 @@ NULL #' @importFrom reticulate py_last_error tuple py_str py_has_attr import #' @import tidyselect #' @import rlang +#' @import tfdatasets NULL tfio_lib <- NULL