Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Allow package version designation for CRAN packages w/ estimator #310

Merged
merged 13 commits into from
Apr 9, 2020
1 change: 1 addition & 0 deletions NAMESPACE
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ export(complete_run)
export(container_registry)
export(convert_to_dataset_with_csv_files)
export(convert_to_dataset_with_parquet_files)
export(cran_package)
export(create_aks_compute)
export(create_aml_compute)
export(create_child_run)
Expand Down
76 changes: 59 additions & 17 deletions R/environment.R
Original file line number Diff line number Diff line change
Expand Up @@ -256,29 +256,71 @@ generate_docker_file <- function(custom_docker_image = NULL,

if (!is.null(cran_packages)) {
for (package in cran_packages) {

package$repo <- sprintf("c(\'%s\')", package$repo)

base_dockerfile <- paste0(
base_dockerfile,
sprintf("RUN R -e \"install.packages(\'%s\', ", package),
"repos = \'https://cloud.r-project.org/\')\"\n")
base_dockerfile,
paste0("RUN R -e \"remotes::install_version",
sprintf("(\'%s\'", package$name),
sprintf(", version = \'%s\'", package$version),
sprintf(", repos = %s", package$repo),
")\"\n"
)
)
}
}

if (!is.null(github_packages)) {
for (package in github_packages) {
base_dockerfile <- paste0(
base_dockerfile,
sprintf("RUN R -e \"remotes::install_github(\'%s\')\"\n", package))
}

if (!is.null(github_packages)) {
for (package in github_packages) {
base_dockerfile <- paste0(
base_dockerfile,
sprintf("RUN R -e \"remotes::install_github(\'%s\')\"\n", package))
}
}

if (!is.null(custom_url_packages)) {
for (package in custom_url_packages) {
base_dockerfile <- paste0(
base_dockerfile,
sprintf("RUN R -e \"install.packages(\'%s\', repos = NULL)\"\n",
package))
}
if (!is.null(custom_url_packages)) {
for (package in custom_url_packages) {
base_dockerfile <- paste0(
base_dockerfile,
sprintf("RUN R -e \"install.packages(\'%s\', repos = NULL)\"\n",
package))
}
}

invisible(base_dockerfile)
}

#' Specifies a CRAN package to install in environment
#'
#' @description
#' Specifies a CRAN package to install in run environment
#'
#' @param name The package name
#' @param version A string of the package version. If not provided, version
#' will default to latest
#' @param repo The base URL of the repository to use, e.g., the URL of a
#' CRAN mirror. If not provided, the package will be pulled from
#' "https://cloud.r-project.org".
#' @return A named list containing the package specifications
#' @export
#' @section Examples:
#' ```
#' pkg1 <- cran_package("ggplot2", version = "3.3.0")
#' pkg2 <- cran_package("stringr")
#' pkg3 <- cran_package("ggplot2", version = "0.9.1",
#' repo = "http://cran.us.r-project.org")
#'
#' est <- estimator(source_directory = ".",
#' entry_script = "train.R",
#' cran_packages = list(pkg1, pkg2, pkg3),
#' compute_target = compute_target)
#' ```
#' @seealso [r_environment()], [estimator()]
#' @md
cran_package <- function(name, version = NULL, repo = "https://cloud.r-project.org") {
cran_package <- list(name = name, version = version, repo = repo)

invisible(base_dockerfile)
return(cran_package)
}
17 changes: 13 additions & 4 deletions R/estimator.R
Original file line number Diff line number Diff line change
Expand Up @@ -71,11 +71,20 @@
#' objects to use as input.
#' @return The `Estimator` object.
#' @export
#' @section Examples:
#' ```
#' pkg1 <- cran_package("ggplot2", version = "3.3.0")
#' pkg2 <- cran_package("stringr")
#'
#' est <- estimator(source_directory = ".",
#' entry_script = "train.R",
#' cran_packages = list(pkg1, pkg2),
#' compute_target = compute_target)
#' ```
#' @seealso
#' \code{\link{r_environment}}
#' \code{\link{container_registry}}
#' \code{\link{submit_experiment}}
#' \code{\link{dataset_consumption_config}}
#' [r_environment()], [container_registry()], [submit_experiment()],
#' [dataset_consumption_config()], [cran_package()]
#'
#' @md
estimator <- function(source_directory,
compute_target = NULL,
Expand Down
1 change: 1 addition & 0 deletions _pkgdown.yml
Original file line number Diff line number Diff line change
Expand Up @@ -158,6 +158,7 @@ reference:
- '`log_row_to_run`'
- '`log_table_to_run`'
- '`view_run_details`'
- '`cran_package`'
- title: Hyperparameter tuning
desc: Functions for configuring and managing hyperparameter tuning (HyperDrive) experiments. Azure ML's HyperDrive functionality enables you to automate hyperparameter tuning of your machine learning models. For example, you can define the parameter search space as discrete or continuous, and a sampling method over the search space as random, grid, or Bayesian. Also, you can specify a primary metric to optimize in the hyperparameter tuning experiment, and whether to minimize or maximize that metric. You can also define early termination policies in which poorly performing experiment runs are canceled and new ones started.
contents:
Expand Down
41 changes: 41 additions & 0 deletions man/cran_package.Rd

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

14 changes: 13 additions & 1 deletion man/estimator.Rd

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

41 changes: 24 additions & 17 deletions tests/testthat/test_environment.R
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ test_that("create environment and check parameters", {
expect_equal(env$version, "1")
expect_equal(env$docker$enabled, TRUE)
expect_equal(env$docker$base_image, NULL)

# use custom docker image
custom_docker_image_name = "temp_image"
env <- r_environment(env_name, custom_docker_image = custom_docker_image_name)
Expand All @@ -25,15 +25,15 @@ test_that("create environment and check parameters", {
test_that("create, register, and get environment", {
skip_if_no_subscription()
ws <- existing_ws

env_name <- "testenv"

# Create environment
env <- r_environment(env_name, version = "1")

# Register environment
register_environment(env, ws)

# Get environment
environ <- get_environment(ws, env_name, "1")
expect_equal(env$name, environ$name)
Expand All @@ -49,30 +49,37 @@ test_that("create dockerfile", {
"RUN R -e \"remotes::install_cran('azuremlsdk'",
", repos = 'https://cloud.r-project.org/', ",
"upgrade = FALSE)\"\n"))

# cran packages
cran_pkg_1 <- cran_package("ggplot2")
cran_pkg_2 <- cran_package("stringr", "0.0.0", "https://some-other-repo.com/")
cran_pkg_3 <- cran_package('shiny', "1.14")
dockerfile <- generate_docker_file(custom_docker_image = "ubuntu-18.04",
cran_packages = c("ggplot2"),
cran_packages = list(cran_pkg_1,
cran_pkg_2,
cran_pkg_3),
install_system_packages = FALSE)
expect_equal(dockerfile, paste0("FROM ubuntu-18.04\nRUN R -e \"install.",
"packages('ggplot2', repos = \'https://",
"cloud.r-project.org/\')\"\n"))

expected_dockerfile <- paste0("FROM ubuntu-18.04\n",
"RUN R -e \"remotes::install_version('ggplot2', repos = c('https://cloud.r-project.org'))\"\n",
"RUN R -e \"remotes::install_version('stringr', version = '0.0.0', repos = c('https://some-other-repo.com/'))\"\n",
"RUN R -e \"remotes::install_version('shiny', version = '1.14', repos = c('https://cloud.r-project.org'))\"\n")
expect_equal(dockerfile, expected_dockerfile)

# github packages
dockerfile <- generate_docker_file(github_packages = c(
"https://github/user/repo1",
"https://github/user/repo2"),
install_system_packages = FALSE)
"https://github/user/repo1",
"https://github/user/repo2"),
install_system_packages = FALSE)
expected_dockerfile <- paste0(
"RUN R -e \"remotes::install_github(\'https://github/user/repo1\')\"\n",
"RUN R -e \"remotes::install_github(\'https://github/user/repo2\')\"\n")
expect_equal(dockerfile, expected_dockerfile)

# custom url
dockerfile <- generate_docker_file(custom_url_packages = c(
"https://url/pak1.tar",
"https://url/pak2.tar"),
install_system_packages = FALSE)
"https://url/pak1.tar",
"https://url/pak2.tar"),
install_system_packages = FALSE)
expected_dockerfile <- paste0(
"RUN R -e \"install.packages(\'https://url/pak1.tar\', repos = NULL)\"\n",
"RUN R -e \"install.packages(\'https://url/pak2.tar\', repos = NULL)\"\n")
Expand Down
3 changes: 2 additions & 1 deletion tests/testthat/test_estimator.R
Original file line number Diff line number Diff line change
Expand Up @@ -2,10 +2,11 @@ context("estimator")

test_that("create estimator", {
skip_if_no_azureml()

est <- estimator(".",
compute_target = "local",
script_params = list("param1" = 1),
cran_packages = c("ggplot2"),
cran_packages = list(cran_package("ggplot2")),
use_gpu = TRUE,
environment_variables = list("var1" = "val1"))

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -119,7 +119,7 @@ To create the estimator, define the following:
est <- estimator(source_directory = ".",
entry_script = "cifar10_cnn.R",
compute_target = compute_target,
cran_packages = c("keras"),
cran_packages = list(cran_package("keras")),
use_gpu = TRUE)
```

Expand Down
2 changes: 1 addition & 1 deletion vignettes/train-with-tensorflow/train-with-tensorflow.Rmd
Original file line number Diff line number Diff line change
Expand Up @@ -103,7 +103,7 @@ To create the estimator, define the following:
est <- estimator(source_directory = ".",
entry_script = "tf_mnist.R",
compute_target = compute_target,
cran_packages = c("tensorflow"),
cran_packages = list(cran_package("tensorflow")),
use_gpu = TRUE)
```

Expand Down