R Language
समानांतर प्रसंस्करण
खोज…
टिप्पणियों
दूरस्थ मशीनों पर समानांतरीकरण के लिए प्रत्येक मशीन पर पुस्तकालयों को डाउनलोड करने की आवश्यकता होती है। पसंदीदा package::function()
कॉल। कई पैकेज में plyr
मूल रूप से अंतर्निहित है, जिसमें caret
, pls
और plyr
।
Microsoft R Open (रेवोल्यूशन R) मल्टी-थ्रेडेड BLAS / LAPACK लाइब्रेरी का भी उपयोग करता है जो आंतरिक रूप से कई सामान्य कार्यों को समानांतर करता है।
फॉरेक्स पैकेज के साथ समानांतर प्रसंस्करण
foreach
पैकेज आर के समानांतर प्रसंस्करण की शक्ति लाता है। लेकिन इससे पहले कि आप मल्टी कोर सीपीयू का उपयोग करना चाहें, आपको मल्टी कोर क्लस्टर असाइन करना होगा। doSNOW
पैकेज एक संभावना है।
फॉर्च लूप का एक सरल उपयोग 1 से 100000 तक वर्गमूल और सभी संख्याओं के वर्ग की गणना करना है।
library(foreach)
library(doSNOW)
cl <- makeCluster(5, type = "SOCK")
registerDoSNOW(cl)
f <- foreach(i = 1:100000, .combine = c, .inorder = F) %dopar% {
k <- i ** 2 + sqrt(i)
k
}
के उत्पादन की संरचना foreach
द्वारा नियंत्रित किया जाता .combine
तर्क। डिफ़ॉल्ट आउटपुट संरचना एक सूची है। ऊपर दिए गए कोड में, c
का उपयोग वेक्टर को वापस करने के लिए किया जाता है। ध्यान दें कि एक गणना फ़ंक्शन (या ऑपरेटर) जैसे "+"
उपयोग गणना करने और आगे की संसाधित वस्तु को वापस करने के लिए भी किया जा सकता है।
यह उल्लेख करना महत्वपूर्ण है कि प्रत्येक फॉर्च-लूप का परिणाम अंतिम कॉल है। इस प्रकार, इस उदाहरण में k
को परिणाम में जोड़ा जाएगा।
पैरामीटर | विवरण |
---|---|
।जोड़ना | कंबाइन फंक्शन। निर्धारित करता है कि लूप के परिणाम कैसे संयुक्त हैं। संभावित मान हैं c , cbind , rbind , "+" , "*" ... |
।क्रम में | अगर TRUE का परिणाम पुनरावृत्ति वायब्रल (यहाँ i ) के आदेश के अनुसार आदेश दिया गया है। यदि FALSE परिणाम का आदेश नहीं दिया गया है। यह अभिकलन समय पर पोस्टिव प्रभाव डाल सकता है। |
.packages | उन कार्यों के लिए जो base को छोड़कर किसी भी पैकेज द्वारा प्रदान किए जाते हैं, जैसे कि mass , randomForest या फिर, आपको इन पैकेजों को c("mass", "randomForest") |
समानांतर पैकेज के साथ समानांतर प्रसंस्करण
आधार पैकेज parallel
फोर्किंग, सॉकेट्स और यादृच्छिक-संख्या पीढ़ी के माध्यम से समानांतर गणना की अनुमति देता है।
स्थानीय होस्ट पर मौजूद कोर की संख्या का पता लगाएं:
parallel::detectCores(all.tests = FALSE, logical = TRUE)
स्थानीय होस्ट पर कोर का एक समूह बनाएँ:
parallelCluster <- parallel::makeCluster(parallel::detectCores())
सबसे पहले, समानांतरीकरण के लिए उपयुक्त एक फ़ंक्शन बनाया जाना चाहिए। mtcars
डेटासेट पर विचार करें। mpg
पर एक प्रतिगमन को प्रत्येक स्तर के cyl
लिए एक अलग प्रतिगमन मॉडल बनाकर सुधार किया जा सकता है।
data <- mtcars
yfactor <- 'cyl'
zlevels <- sort(unique(data[[yfactor]]))
datay <- data[,1]
dataz <- data[,2]
datax <- data[,3:11]
fitmodel <- function(zlevel, datax, datay, dataz) {
glm.fit(x = datax[dataz == zlevel,], y = datay[dataz == zlevel])
}
एक ऐसा फंक्शन बनाएं, जो zlevels
सभी संभावित पुनरावृत्तियों के माध्यम से लूप कर सके। यह धारावाहिक में अभी भी है, लेकिन एक महत्वपूर्ण कदम है क्योंकि यह सटीक प्रक्रिया को निर्धारित करता है जिसे समानांतर किया जाएगा।
fitmodel <- function(zlevel, datax, datay, dataz) {
glm.fit(x = datax[dataz == zlevel,], y = datay[dataz == zlevel])
}
for (zlevel in zlevels) {
print("*****")
print(zlevel)
print(fitmodel(zlevel, datax, datay, dataz))
}
इस समारोह करी:
worker <- function(zlevel) {
fitmodel(zlevel,datax, datay, dataz)
}
समानांतर का उपयोग करते हुए parallel
कंप्यूटिंग वैश्विक पर्यावरण तक नहीं पहुंच सकता है। सौभाग्य से, प्रत्येक फ़ंक्शन एक स्थानीय वातावरण बनाता है जो parallel
पहुंच सकता है। एक आवरण समारोह का निर्माण समानांतरकरण की अनुमति देता है। लागू किए जाने वाले फ़ंक्शन को भी पर्यावरण के भीतर रखा जाना चाहिए।
wrapper <- function(datax, datay, dataz) {
# force evaluation of all paramters not supplied by parallelization apply
force(datax)
force(datay)
force(dataz)
# these variables are now in an enviroment accessible by parallel function
# function to be applied also in the environment
fitmodel <- function(zlevel, datax, datay, dataz) {
glm.fit(x = datax[dataz == zlevel,], y = datay[dataz == zlevel])
}
# calling in this environment iterating over single parameter zlevel
worker <- function(zlevel) {
fitmodel(zlevel,datax, datay, dataz)
}
return(worker)
}
अब एक क्लस्टर बनाएं और रैपर फ़ंक्शन को चलाएं।
parallelcluster <- parallel::makeCluster(parallel::detectCores())
models <- parallel::parLapply(parallelcluster,zlevels,
wrapper(datax, datay, dataz))
समाप्त होने पर हमेशा क्लस्टर बंद करें।
parallel::stopCluster(parallelcluster)
parallel
पैकेज में संपूर्ण apply()
परिवार शामिल है, जो par
।
रैंडम नंबर जनरेशन
समांतरकरण के साथ एक बड़ी समस्या बीज के रूप में आरएनजी का उपयोग है। संख्या के यादृच्छिक संख्या सत्र की शुरुआत या सबसे हाल के set.seed()
से संचालन की संख्या से पुनरावृत्त होते हैं। सबसे पहले set.seed()
। चूँकि समान कार्य से समानान्तर प्रक्रियाएँ उत्पन्न होती हैं, यह एक ही बीज का उपयोग कर सकता है, संभवतः समान परिणाम देता है! अलग-अलग कोर पर धारावाहिक में कॉल चलेंगे, कोई फायदा नहीं होगा।
बीज का एक सेट उत्पन्न होना चाहिए और प्रत्येक समानांतर प्रक्रिया को भेजा जाना चाहिए। यह स्वचालित रूप से कुछ पैकेजों ( parallel
, snow
, आदि) में किया जाता है, लेकिन दूसरों में स्पष्ट रूप से संबोधित किया जाना चाहिए।
s <- seed
for (i in 1:numofcores) {
s <- nextRNGStream(s)
# send s to worker i as .Random.seed
}
बीज भी प्रजनन योग्यता के लिए निर्धारित किया जा सकता है।
clusterSetRNGStream(cl = parallelcluster, iseed)
mcparallelDo
mcparallelDo
पैकेज यूनिक्स-एक जैसे (जैसे लिनक्स और MacOSX) ऑपरेटिंग सिस्टम पर आर कोड के मूल्यांकन के लिए अनुमति देता है। पैकेज का अंतर्निहित दर्शन कोडिंग के बजाय खोजपूर्ण डेटा विश्लेषण की जरूरतों के साथ गठबंधन किया गया है। अतुल्यकालिक कोडिंग के लिए, future
पैकेज पर विचार करें।
उदाहरण
डेटा बनाएँ
data(ToothGrowth)
एक कांटे पर विश्लेषण करने के लिए ट्रिगर mcparallelDo
mcparallelDo({glm(len ~ supp * dose, data=ToothGrowth)},"interactionPredictorModel")
अन्य काम करें, जैसे
binaryPredictorModel <- glm(len ~ supp, data=ToothGrowth)
gaussianPredictorModel <- glm(len ~ dose, data=ToothGrowth)
McparallelDo से परिणाम आपके लक्ष्य में वापस आ जाता है, जैसे .GlobalEnv, जब यह एक संदेश के साथ पूरा होता है (डिफ़ॉल्ट रूप से)
summary(interactionPredictorModel)
अन्य उदाहरण
# Example of not returning a value until we return to the top level
for (i in 1:10) {
if (i == 1) {
mcparallelDo({2+2}, targetValue = "output")
}
if (exists("output")) print(i)
}
# Example of getting a value without returning to the top level
for (i in 1:10) {
if (i == 1) {
mcparallelDo({2+2}, targetValue = "output")
}
mcparallelDoCheck()
if (exists("output")) print(i)
}