2013-06-20 28 views
5

Tôi có một mã R liên quan đến một số công nhân foreach để thực hiện một số tác vụ song song. Tôi đang sử dụng foreach và doMC cho mục đích này. Tôi muốn để cho mỗi công nhân foreach tuyển dụng một số công nhân mới và phân phối một số phần của mã của họ, mà là song song, với họ.Cho phép nhân viên foreach đăng ký và phân phối các nhiệm vụ phụ cho những người lao động khác

Mã hiện trông giống như:

require(doMC) 
require(foreach) 
registerDoMC(cores = 8) 

foreach (i = (1:8)) %dopar% { 
<<some code here>> 
    for (j in c(1:4)) { 
    <<some other code here>> 
    } 
} 

Tôi đang tìm kiếm một mã số lý tưởng mà sẽ trông như thế:

require(doMC) 
require(foreach) 
registerDoMC(cores = 8) 

foreach (i = (1:8)) %dopar% { 
<<some code here>> 
    foreach (j = (1:4)) %dopar% { 
    <<some other code here>> 
    } 
} 

tôi thấy một ví dụ về mô hình đa xử lý song song sử dụng doSNOW và doMC here (https://www.rmetrics.org/files/Meielisalp2009/Presentations/Lewis.pdf#page=17) . Tuy nhiên, tôi không biết liệu nó có làm những gì tôi muốn hay không.

Ngoài ra, có vẻ như Nested foreach không áp dụng được vì nó yêu cầu hợp nhất hai vòng (see here), trong trường hợp của tôi, điều này không được ưu tiên; vòng lặp thứ hai chỉ giúp phần đầu tiên cho một phần của mã. Hãy sửa tôi nếu tôi sai.

Cảm ơn.

+0

Có thể không chính xác những gì bạn muốn, nhưng bạn có thể có các biểu thức 'foreach' lồng nhau: http://cran.r-project.org/web/packages/foreach/vignettes/nested.pdf. Tuy nhiên, tôi không biết về việc tuyển dụng nhiều công nhân hơn trong vòng lặp. – ialm

+0

Cảm ơn. Tuy nhiên, có vẻ như forested lồng nhau không áp dụng cho trường hợp của tôi vì nó yêu cầu hợp nhất hai vòng lồng nhau, trong khi tôi cần một vòng lặp nội bộ được gọi chỉ cho một phần của mã. Tôi sẽ cập nhật câu hỏi để phản ánh điều này. – imriss

Trả lời

6

Không có vấn đề gì đặc biệt khi có vòng lặp foreach bên trong vòng lặp foreach. Dưới đây là một ví dụ về một vòng lặp doMC bên trong một vòng lặp doSNOW:

library(doSNOW) 
hosts <- c('host-1', 'host-2') 
cl <- makeSOCKcluster(hosts) 
registerDoSNOW(cl) 
r <- foreach(i=1:4, .packages='doMC') %dopar% { 
    registerDoMC(2) 
    foreach(j=1:8, .combine='c') %dopar% { 
    i * j 
    } 
} 
stopCluster(cl) 

Dường như tự nhiên để tôi sử dụng doMC cho vòng lặp bên trong, nhưng bạn có thể làm điều đó anyway bạn muốn. Bạn cũng có thể sử dụng doSNOW cho cả hai vòng, nhưng sau đó bạn sẽ cần phải tạo và dừng cụm tuyết bên trong vòng lặp foreach bên ngoài.

Dưới đây là một ví dụ của việc sử dụng doMC bên trong một vòng lặp doMC:

library(doMC) 
registerDoMC(2) 
r <- foreach(i=1:2, .packages='doMC') %dopar% { 
    ppid <- Sys.getpid() 
    registerDoMC(2) 
    foreach(j=1:2) %dopar% { 
    c(ppid, Sys.getpid()) 
    } 
} 

Kết quả chứng minh rằng tổng cộng sáu quá trình được chia hai bởi gói doMC, mặc dù chỉ có bốn thực hiện cơ thể của vòng lặp bên trong:

> r 
[[1]] 
[[1]][[1]] 
[1] 14946 14949 

[[1]][[2]] 
[1] 14946 14951 


[[2]] 
[[2]][[1]] 
[1] 14947 14948 

[[2]][[2]] 
[1] 14947 14950 

Tất nhiên, bạn cần cẩn thận không bắt đầu quá nhiều quy trình trên một nút. Tôi thấy loại tổ này hơi khó xử, dẫn đến sự phát triển của toán tử làm tổ.

+0

Cảm ơn. Tôi đang sử dụng MOAB để gửi các công việc, do đó tôi không thể chọn tên máy chủ. Có cách nào tốt nhất để thiết lập số lượng nút và bộ xử lý trong yêu cầu MOAB để tránh Affinity Processor? Ví dụ: trong ví dụ đầu tiên ở trên, tôi có nên hỏi các nút = 4; ppn = 8 không? – imriss

+0

@imriss Bạn có muốn sử dụng một MPI hoặc một cụm SOCK không? Nếu MPI, bạn đang sử dụng Open MPI hay cái gì khác? Và bạn đang sử dụng Torque làm người quản lý tài nguyên với Moab? –

+0

Dòng lệnh msub bắt đầu bằng #PBS, do đó tôi nghĩ đó là mô-men xoắn/Moab. Trong mã hiện tại, tôi sử dụng doMC và foreach cho vòng lặp bên ngoài, trong khi vòng lặp bên trong là nối tiếp. Tôi không có đặc quyền quản trị, nhưng tôi có thể cài đặt các gói trong thư mục chính của mình. Cảm ơn. – imriss

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