2011-07-24 29 views
7

Tôi gặp phải một số sự cố khi sử dụng foreach% dopar% khi tải các đối tượng từ đĩa vào bộ nhớ ... Các đối tượng không được tải khi tôi cố tải chúng khi sử dụng foreach% dopar% (nó hoạt động khi tôi chỉ sử dụng% do%) Dưới đây là một ví dụ đơn giản cho thấy vấn đề của tôi.tải không hoạt động với foreach và% dopar%

envir = .GlobalEnv 

x <- "X test" 
y <- "Y test" 
z <- "Z test" 

save(x, file="x.RData") 
save(y, file="y.RData") 
save(z, file="z.RData") 

rm(x) 
rm(y) 
rm(z) 

objectsNamesVector <- c("x", "y", "z") 

foreach(i=1:length(objectsNamesVector), .combine=function (...) NULL, .multicombine=TRUE) %do% { 
    print(paste("Loading object ", objectsNamesVector[i]," - ", i, " of ", length(objectsNamesVector), sep="")) 
    load(file=paste(objectsNamesVector[i], ".RData", sep=""), envir=envir) 
} 

print(x) 
print(y) 
print(z) 

rm(x) 
rm(y) 
rm(z) 

foreach(i=1:length(objectsNamesVector), .combine=function (...) NULL, .multicombine=TRUE) %dopar% { 
    print(paste("Loading object ", objectsNamesVector[i]," - ", i, " of ", length(objectsNamesVector), sep="")) 
    load(file=paste(objectsNamesVector[i], ".RData", sep=""), envir=envir) 
} 

print(x) 
print(y) 
print(z) 

Kết quả thực thi mã này là (không có ">"):

envir = .GlobalEnv 

x <- "X test" 
y <- "Y test" 
z <- "Z test" 

save(x, file="x.RData") 
save(y, file="y.RData") 
save(z, file="z.RData") 

rm(x) 
rm(y) 
rm(z) 

objectsNamesVector <- c("x", "y", "z") 

foreach(i=1:length(objectsNamesVector), .combine=function (...) NULL, .multicombine=TRUE) %do% { 
+ print(paste("Loading object ", objectsNamesVector[i]," - ", i, " of ", length(objectsNamesVector), sep="")) 
+ load(file=paste(objectsNamesVector[i], ".RData", sep=""), envir=envir) 
+ } 
[1] "Loading object x - 1 of 3" 
[1] "Loading object y - 2 of 3" 
[1] "Loading object z - 3 of 3" 
NULL 

print(x) 
[1] "X test" 
print(y) 
[1] "Y test" 
print(z) 
[1] "Z test" 
rm(x) 
rm(y) 
rm(z) 

foreach(i=1:length(objectsNamesVector), .combine=function (...) NULL, .multicombine=TRUE) %dopar% { 
+ print(paste("Loading object ", objectsNamesVector[i]," - ", i, " of ", length(objectsNamesVector), sep="")) 
+ load(file=paste(objectsNamesVector[i], ".RData", sep=""), envir=envir) 
+ } 
NULL 

print(x) 
Error in print(x) : object 'x' not found 
print(y) 
Error in print(y) : object 'y' not found 
print(z) 
Error in print(z) : object 'z' not found 

Tôi hiểu rằng tôi không thể cải thiện IO với foreach từ IO là tuần tự trên kiến ​​trúc của tôi. Tôi chỉ muốn hiểu tại sao điều này không hoạt động ...

Cảm ơn câu trả lời của bạn.

Trân trọng, Samo.

+0

Vì vậy, tôi đoán đây là nó. Có thể ai đó có thể tư vấn về danh sách R-help nào tôi nên đăng câu hỏi này để có câu trả lời? Thnx. – user859821

Trả lời

2

Tôi tin rằng vấn đề là %do% có thể ghi vào môi trường toàn cầu, trong khi %dopar% thì không. Sử dụng %do% rất hữu ích nếu bạn muốn cú pháp foreach() và các tính năng khác, nhưng không cần chương trình phụ trợ song song.

Ngoài ra, khi %do% được thực hiện theo trình tự, việc giữ môi trường toàn cầu sạch sẽ có thể được để lại cho người dùng, vì sẽ không có điều kiện chủng tộc. Trong trường hợp song song, bạn có thể có các điều kiện chủng tộc (nghĩa là một số nhiệm vụ song song có thể hoàn thành trước những điều kiện khác và có thể tạo ra các kết quả ngẫu nhiên, khó tái sản xuất).

Do điều kiện chủng tộc, không nên có loại hoạt động này trực tiếp ghi vào môi trường toàn cầu, nếu bạn có thể tránh được điều đó. Người dùng sau có thể lấy mã tuần tự như vậy và thay thế %do% bằng %dopar%, hy vọng nhận được kết quả nhanh hơn nhưng không nhận được kết quả tương tự. Để tín dụng của bạn, bạn đã tìm thấy một ví dụ rõ ràng về nơi có thể xảy ra.

+0

Cảm ơn. Tôi bắt đầu sử dụng% dopar% mà không hiểu cách backend song song trong R thực sự hoạt động như thế nào do các quan niệm sai lầm của tôi. – user859821

2

Thật khó để nói chính xác những gì đang xảy ra mà không biết:

  1. gì hệ điều hành của bạn.
  2. gì phụ trợ song song bạn đã đăng ký% dopar%

Nếu bạn đang sử dụng doMC, sau đó mã trong khối foreach thực hiện trong vòng một fork() 'quá trình ed. Điều này có nghĩa rằng nó có không gian bộ nhớ riêng của nó, và trong khi nó sẽ sửa đổi .GlobalEnv cục bộ, nó sẽ không sửa đổi nó trong quá trình "master". Tức là, bạn sẽ sửa đổi một bản sao của .GlobalEnv.

Nếu bạn thực thi mã này không có đăng ký phụ trợ, nó thực thi "đúng", bởi vì% dopar% kết thúc thực thi như% do%.

Một cách để xử lý tình huống này có thể là tải các đối tượng vào môi trường mới, và sau đó sử dụng tham số .combine của foreach() để sao chép nội dung của mỗi đối tượng vào .GlobalEnv.

+0

Cảm ơn bạn đã giải thích. Bây giờ tôi hiểu điều gì đang diễn ra đằng sau hậu trường. – user859821

1

Tôi đã gặp vấn đề tương tự khi cố gắng sử dụng "foreach" + "doSnow" để chạy chương trình song song trên máy tính 32 lõi. "foreach" ngừng làm việc và nói: một ĐỐI TƯỢNG KHÔNG TÌM THẤY! Tôi đã sử dụng ".export" trong "foreach" để bao gồm đối tượng bên ngoài đó, nhưng nó vẫn nói rằng OBJECT NOT FOUND! Khi tôi thử "doParallel" NOT "doSnow", nó đã hoạt động!

external_object <-1

thư viện (foreach)
thư viện (doParallel)
registerDoParallel (lõi = 32)
getDoParWorkers()

foreach (i = 1: 32, .combine = c .multicombine = TRUE, .export = c ("external_object"))% dopar% { external_object }

+0

Đây là một vấn đề khác với chủ đề của câu hỏi này, đó là về tác động phụ của môi trường toàn cầu trong vòng lặp foreach. Ngoài ra, ví dụ của bạn làm việc cho tôi với doSNOW, ngoại trừ một cảnh báo được đưa ra nói rằng 'external_object' đã được xuất, cho biết rằng bạn không cần sử dụng' .export'. Tôi không chắc chắn những gì đã sai với ví dụ doSNOW của bạn, nhưng doParallel thường hoạt động khi doSNOW thất bại trên Linux và Mac OS X do việc sử dụng dopparallel của mclapply chứ không phải là clusterApplyLB. –

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