Sto cercando di utilizzare parLapply()
su Windows all'interno di un oggetto R6
e ho notato (che in alcuni casi almeno) che non è necessario esportare le funzioni o i dati R6 ai nodi.parLapply all'interno delle classi R6
Ecco un esempio in cui posso accedere ai metodi privati entro parLapply()
:
require(R6);require(parallel)
square <-
R6Class("square",
public = list(
numbers = NA,
squares = NA,
initialize = function(numbers,integer) {
self$numbers <- numbers
squares <- private$square.numbers()
}
),
private = list(
square = function(x) {
return(x^2)
},
square.numbers = function() {
cl <- makeCluster(detectCores())
self$squares <- parLapply(cl,
self$numbers,
function (x) private$square(x)
)
stopCluster(cl)
}
))
##Test
test <- square$new(list(1,2,3))
print(test$squares)
# [[1]]
# [1] 1
#
# [[2]]
# [1] 4
#
# [[3]]
# [1] 9
E un secondo esempio in cui posso anche accedere ai membri pubblici:
square2 <-
R6Class("square2",
public = list(
numbers = NA,
squares = NA,
integer = NA,
initialize = function(numbers,integer) {
self$numbers <- numbers
self$integer <- integer
squares <- private$square.numbers()
}
),
private = list(
square = function(x) {
return(x^2)
},
square.numbers = function() {
cl <- makeCluster(detectCores())
self$squares <- parLapply(cl,
self$numbers,
function (x) private$square(x)+self$integer
)
stopCluster(cl)
}
))
##Test
test2 <- square2$new(list(1,2,3),2)
print(test2$squares)
#[[1]]
#[1] 3
#
#[[2]]
#[1] 6
#
#[[3]]
#[1] 11
La mia domanda è duplice: (1) Per quanto riguarda R6, ciò è possibile in modo che non sia necessario esportare oggetti e funzioni dati; e (2) posso fare affidamento su questo comportamento o è un artefatto di questi esempi specifici?
UPDATE:
Questo comportamento appare anche a lavorare con metodi pubblici e membri dopo che l'oggetto è stato istanziato:
square3 <- R6Class(
classname = "square3",
public = list(
numbers = NA,
squares = NA,
integer = NA,
square = function(x) {
return(x^2)
},
square.numbers = function() {
cl <- makeCluster(detectCores())
self$squares <- parLapply(cl,
self$numbers,
function (x) self$square(x)+self$integer
)
stopCluster(cl)
},
initialize = function(numbers,integer) {
self$numbers <- numbers
self$integer <- integer
}
)
)
test3.obj <- square3$new(list(1,2,3),2)
test3.obj$square.numbers()
test3.obj$squares
# [[1]]
# [1] 3
#
# [[2]]
# [1] 6
#
# [[3]]
# [1] 11
grazie! questo è un grande aiuto – chandler
Sono un po 'perplesso da questa spiegazione: non dovrebbe funzionare lo stesso anche con S3, semplicemente perché ogni fork di R ottiene la propria copia del working set (il kernel del sistema operativo gestisce questo, non R) ? Ad ogni modo, ho sempre usato 'mclapply' come questo (non uso' parLapply' o cluster espliciti), non ho mai dovuto esportare nulla. –
Sembra che tu stia lavorando su os x/linux. Dalla mia (limitata) comprensione, su questi sistemi operativi il "fork" ottiene l'intera directory di lavoro, cosa che non succede su Windows. Ecco perché ero così curioso di questo comportamento in quanto non ci richiederebbe agli utenti di Windows di esportare metodi o membri (e quindi rendere l'implementazione parallela molto più comoda). Inoltre, non ho lavorato molto con s3, quindi non posso commentare il suo comportamento in una situazione simile – chandler