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..d6a78cb3b --- /dev/null +++ b/R-package/DESCRIPTION @@ -0,0 +1,38 @@ +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), + tfdatasets (>= 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..af3467069 --- /dev/null +++ b/R-package/NAMESPACE @@ -0,0 +1,18 @@ +# Generated by roxygen2: do not edit by hand + +export("%>%") +export(install_tensorflow) +export(tf) +export(tf_config) +import(rlang) +import(tfdatasets) +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..8f93111f2 --- /dev/null +++ b/R-package/R/package.R @@ -0,0 +1,87 @@ +#' 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 +#' @import tfdatasets +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/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..06b147c28 --- /dev/null +++ b/R-package/tests/testthat.R @@ -0,0 +1,5 @@ +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..5cbbab790 --- /dev/null +++ b/R-package/tests/testthat/utils.R @@ -0,0 +1,23 @@ +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)) + } +} + +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) + 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)