2011-01-22 42 views
16

Tôi đang cố gắng sử dụng foreach để làm máy tính đa lõi trong R.không thể tìm thấy chức năng bên trong foreach vòng lặp

A <-function(....) { 
    foreach(i=1:10) %dopar% { 
    B() 
    } 
} 

sau đó tôi gọi hàm A trong giao diện điều khiển. Vấn đề là tôi đang gọi một hàm Posdef bên trong B được xác định trong tệp tập lệnh khác mà tôi nguồn. Tôi phải đặt Posdef vào danh sách đối số xuất của foreach: .export=c("Posdef"). Tuy nhiên, tôi nhận được lỗi sau:

Error in { : task 3 failed - "could not find function "Posdef"" 

Tại sao không thể tìm thấy hàm được xác định này?

+1

Tôi khuyên bạn nên tìm kiếm thông tin về phạm vi động với R. Nó không hề trực quan và bạn sẽ tìm thấy rất nhiều câu hỏi về SO chi tiết mọi người gặp sự cố khi xác định hàm trong hàm. –

+0

Chúng tôi sẽ đánh giá cao một ví dụ tái sản xuất. Ngoài ra, bạn đã thử tuyết rơi cho multicoring chưa? Tôi thấy nó trực quan hơn và dễ điều chỉnh hơn (sửa đổi các hàm áp dụng). –

+0

cùng một vấn đề, không tìm thấy bất kỳ câu trả lời đơn giản nào cho bây giờ. Tôi quản lý để làm cho nó hoạt động bằng cách gọi 4 lõi foreach (j = 1: N, .combine = rbind, .packages = c (VECTOR BAO BÌ CẦN GỌI TẤT CẢ CÁC CHỨC NĂNG CỦA BẠN))% dopar% fun (j). Nó cải thiện tốc độ, nhưng không chia cho 4 (bởi 2 chỉ) Tôi không chắc chắn những gì tôi làm như vậy không sao chép này .. – RockScience

Trả lời

7

Câu trả lời ngắn gọn là rằng đây là một lỗi trong backends song song như doSNOW , doParalleldoMPI, nhưng từ đó đã được sửa.

Câu trả lời hơi dài hơn là foreach chức năng xuất cho người lao động sử dụng môi trường "xuất" đặc biệt, chứ không phải môi trường toàn cầu. Điều đó được sử dụng để gây ra các vấn đề cho các hàm được tạo trong môi trường toàn cục, vì môi trường "xuất" không nằm trong phạm vi của chúng, mặc dù chúng đã được định nghĩa trong cùng một môi trường "xuất". Do đó, họ không thể thấy bất kỳ chức năng hoặc biến nào khác được xác định trong môi trường "xuất", chẳng hạn như "Posdef" trong trường hợp của bạn.

Các doSNOW, doParalleldoMPI các chương trình phụ trợ bây giờ thay đổi môi trường liên quan từ các chức năng được xuất qua ".export" và dường như đã giải quyết được các vấn đề này.

11

Vì vậy, tôi có thể tái sản xuất này, cho tò mò:

require(doSNOW) 
registerDoSNOW(makeCluster(5, type="SOCK")) 
getDoParWorkers() 
getDoParName() 
getDoParVersion() 

fib <- function(n) { 
    if (n <= 1) { return(1) } 
    return(fib(n-1) + fib(n-2)) 
} 

my.matrix <- matrix(runif(2500, 10, 50), nrow=50) 

calcLotsaFibs <- function() { 
    result <- foreach(row.num=1:nrow(my.matrix), .export=c("fib", "my.matrix")) %dopar% { 
    return(Vectorize(fib)(my.matrix[row.num,])) 
    } 
    return(result) 
} 

lotsa.fibs <- calcLotsaFibs() 

tôi đã có thể làm được việc này bằng cách đặt các chức năng trong tập tin khác và tải tập tin đó trong cơ thể của foreach. Bạn cũng có thể rõ ràng di chuyển định nghĩa hàm vào cơ thể của chính foreach.

[EDIT - Tôi trước đây gợi ý rằng có lẽ .export không hoạt động đúng với tên hàm, nhưng đã được sửa chữa dưới đây.]

+1

".export" có thể lấy tên hàm. Đây là một ví dụ thú vị, tuy nhiên, vì tôi tin rằng vấn đề là lỗi xảy ra khi 'fib' thực hiện một cuộc gọi đệ quy cho chính nó, vì' fib' không nằm trong phạm vi riêng của nó, như tôi giải thích trong câu trả lời của tôi. –

+0

bạn có nghĩa là nó có thể làm việc nếu chúng ta bọc chức năng tùy chỉnh trong một gói R? – agenis

0

nhanh sửa chữa cho vấn đề với foreach% dopar% là cài đặt lại những gói:

install.packages("doSNOW") 

install.packages("doParallel") 

install.packages("doMPI") 

Nó làm việc trong trường hợp của tôi.

Các vấn đề liên quan