Closed smingerson closed 10 months ago
Thanks for this feedback! 🙌 I think you are right that we need to document this more clearly somewhere.
My initial thought for the best fit would be in the "Optimizations and Parallel Processing" vignette that folks find here.
I'm no longer sure if this issue is real, I cannot reproduce on another computer (both Windows 10, R 4.0.3). I'll see if I can figure out what's different.
I can reproduce it on Ubuntu 20.04. reprex below:
library(doParallel)
#> Loading required package: foreach
#> Loading required package: iterators
#> Loading required package: parallel
library(tidymodels)
#> ── Attaching packages ────────────────────────────────────── tidymodels 0.1.3 ──
#> ✓ broom 0.7.6 ✓ recipes 0.1.16
#> ✓ dials 0.0.9 ✓ rsample 0.0.9
#> ✓ dplyr 1.0.5 ✓ tibble 3.1.1
#> ✓ ggplot2 3.3.3 ✓ tidyr 1.1.3
#> ✓ infer 0.5.4 ✓ tune 0.1.5
#> ✓ modeldata 0.1.0 ✓ workflows 0.2.2
#> ✓ parsnip 0.1.5 ✓ workflowsets 0.0.2
#> ✓ purrr 0.3.4 ✓ yardstick 0.0.8
#> ── Conflicts ───────────────────────────────────────── tidymodels_conflicts() ──
#> x purrr::accumulate() masks foreach::accumulate()
#> x purrr::discard() masks scales::discard()
#> x dplyr::filter() masks stats::filter()
#> x dplyr::lag() masks stats::lag()
#> x recipes::step() masks stats::step()
#> x purrr::when() masks foreach::when()
#> • Use tidymodels_prefer() to resolve common conflicts.
data(mtcars)
square_root <- function(x) {
sqrt(x)
}
lm_spec <- decision_tree() %>%
set_mode("regression") %>%
set_engine("rpart") %>%
set_args(cost_complexity = tune())
resamples <- vfold_cv(mtcars, v = 2)
preprocessor <- mtcars %>%
recipe(mpg ~ .) %>%
step_mutate(hp = square_root(hp))
grid_params <- grid_regular(
cost_complexity(),
levels = 2
)
cl <- makePSOCKcluster(2)
registerDoParallel(cl)
# parallel::clusterExport(cl, c("square_root")) # uncomment this line to make it work
result <- tune_grid(
lm_spec,
preprocessor = preprocessor,
resamples = resamples,
grid = grid_params,
metrics = metric_set(rmse)
)
#> Warning: All models failed. See the `.notes` column.
stopCluster(cl)
result
#> Warning: This tuning result has notes. Example notes on model fitting include:
#> preprocessor 1/1: Error: Problem with `mutate()` input `hp`.
#> x could not find function "square_root"
#> ℹ Input `hp` is `square_root(hp)`.
#> preprocessor 1/1: Error: Problem with `mutate()` input `hp`.
#> x could not find function "square_root"
#> ℹ Input `hp` is `square_root(hp)`.
#> # Tuning results
#> # 2-fold cross-validation
#> # A tibble: 2 x 4
#> splits id .metrics .notes
#> <list> <chr> <list> <list>
#> 1 <split [16/16]> Fold1 <NULL> <tibble [1 × 1]>
#> 2 <split [16/16]> Fold2 <NULL> <tibble [1 × 1]>
Created on 2021-05-05 by the reprex package (v0.3.0)
The Optimizations vignette now includes some notes on troubleshooting issues with parallel processing. As further changes haven't made it to the top of our to-do list in the last few years, I'm going to go ahead and close. Thank you for the issue. :)
This issue has been automatically locked. If you believe you have found a related problem, please file a new issue (with a reprex: https://reprex.tidyverse.org) and link to this issue.
I've been running into problems with necessary objects not being brought along when tuning workflows. This crops up in two places. Below is an example with a function defined in a script and used in
step_mutate()
. It works fitting locally, but not in parallel. If I useparallel::clusterExport(cl, c("add1"))
prior to callingtune::tune_grid()
, it works, but this would get rather clunky with a real problem.Another place (I think) this crops up is a custom parsnip model not defined in a package. It does not appear to propagate the settings from
parsnip::set_*()
functions. I think to fix this I would have to callparallel::clusterEvalQ()
with theparsnip::set_*()
calls in the expression.I think some documentation pointing to these workarounds would be great. I'd be happy to create a PR to this effect if desired. Alternatively,
control_grid()
could contain aprework
argument, similar todrake::drake_config()
'sprework
argument, to register an expression to be run throughclusterEvalQ()
, or perhaps via atune::cluster_setup()
function, so it is not re-run when using the same cluster across multipletune_*()
calls. I'd be happy to attempt a PR here too.Instead of that last error, I see the following when running in a clean R session. Maybe some weird interaction with how
reprex::reprex()
is called and parallelization?