{"id":296,"date":"2016-03-06T20:30:22","date_gmt":"2016-03-06T19:30:22","guid":{"rendered":"https:\/\/blogs.fu-berlin.de\/gruenstaeudl\/?p=296"},"modified":"2016-03-06T20:40:22","modified_gmt":"2016-03-06T19:40:22","slug":"phylogenetics-and-rmpi-an-example","status":"publish","type":"post","link":"https:\/\/blogs.fu-berlin.de\/gruenstaeudl\/2016\/03\/06\/phylogenetics-and-rmpi-an-example\/","title":{"rendered":"Phylogenetics and Rmpi \u2013 An Example"},"content":{"rendered":"<p><strong>Better parallel than serial<\/strong><\/p>\n<p>In one of my <a href=\"https:\/\/onlinelibrary.wiley.com\/doi\/10.1111\/1755-0998.12435\/abstract\" target=\"_blank\">past projects<\/a>, I implemented the usage of multiple CPUs for time-intensive phylogenetic computations. I hereby used the R library <em>Rmpi<\/em> for the coordination of parallel processes. <em>Rmpi<\/em> is an R wrapper for the MPI communications protocol. The speed gains that my code execution was experiencing through this process parallelization was considerable, and it may, hence, be of interest to a wider audience. I therefore present here a small example of using <em>Rmpi<\/em> in phylogenetic investigations.<\/p>\n<p>First, let us set up a set of calculations that warrant process parallelization. In a maximum parsimony tree search, for example, multiple starting trees may wished to be evaluated. A parsimony ratchet can be executed in parallel on these starting trees, as the runs are independent of each another.<\/p>\n<div style=\"background-color: #ffebdb\">\n<p style=\"padding-left: 30px\">\n<code>library(ape)<br \/>\nlibrary(phangorn)<br \/>\ndata = read.phyDat(\"alignment.phy\") # Alignment of 47 taxa with 1,000,000 bp length<br \/>\ntrees = read.tree(\"trees.tre\") # Set of 500 phylogenetic trees<br \/>\nmyFunc = function(tree,data) {<br \/>\nreturn(phangorn::pratchet(data,start=tree))<br \/>\n}<br \/>\n<\/code>\n<\/p>\n<\/div>\n<p>Second, let us execute the parsimony ratchet serially (where an MP analysis is executed with the first starting tree, then the second, then the third, etc.). As we can see, MP inference performed serially on my data set takes roughly 10 min.<\/p>\n<div style=\"background-color: #ffebdb\">\n<p style=\"padding-left: 30px\">\n<code>tme=proc.time()<br \/>\nsout=lapply(trees,myFunc,data)<br \/>\nproc.time()-tme<br \/>\n<\/code><br \/>\n<samp>user system elapsed<br \/>\n584.513 1.070 584.977<br \/>\n<\/samp>\n<\/p>\n<\/div>\n<p>Third, let us execute the parsimony ratchet in parallel, using the maximum number of CPUs available on my system (nproc = 8). As we can see, the MP inference performed in parallel on my data set takes roughly 4 min.<\/p>\n<div style=\"background-color: #ffebdb\">\n<p style=\"padding-left: 30px\">\n<code># Infer number of processors (i.e. CPUs) on system<br \/>\nnproc = as.numeric(system(\"nproc\",intern=T))<br \/>\n# Specify one master and nproc-1 slaves<br \/>\nmpi.spawn.Rslaves(nslaves=nproc-1)<br \/>\n# Pass various functions to the Rmpi slaves<br \/>\nmpi.bcast.Robj2slave(is.rooted)<br \/>\nmpi.bcast.Robj2slave(is.binary.tree)<br \/>\nmpi.bcast.Robj2slave(unroot)<br \/>\nmpi.bcast.Robj2slave(stree)<br \/>\ntme=proc.time()<br \/>\n# Parallel apply the parsimony ratchet function on all starting trees;<br \/>\n# use load balancing for CPU assignment<br \/>\npout=mpi.parLapply(trees,myFunc,data)<br \/>\nproc.time()-tme<br \/>\n# Close slaves<br \/>\nmpi.close.Rslaves()<br \/>\n<\/code><br \/>\n<samp>user.self sys.self elapsed user.child sys.child<br \/>\n129.244 93.736 224.178 0.000 0.000<br \/>\n<\/samp>\n<\/p>\n<\/div>\n<p>Utilizing all 8 CPUs on my computer (one for the master process, the rest for the slave processes) is not necessarily the most efficient parallelization. Spawning each slave process requires a certain amount of CPU resources, and these resources may be larger than the benefit of the added calculation speed (i.e. law of diminishing returns).<\/p>\n<p>&nbsp;<\/p>\n","protected":false},"excerpt":{"rendered":"<p>Better parallel than serial In one of my past projects, I implemented the usage of multiple CPUs for time-intensive phylogenetic computations. I hereby used the R library Rmpi for the coordination of parallel processes. Rmpi is an R wrapper for the MPI communications protocol. The speed gains that my code execution was experiencing through this [&hellip;]<\/p>\n","protected":false},"author":2306,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[57598],"tags":[],"class_list":["post-296","post","type-post","status-publish","format-standard","hentry","category-bioinformatics"],"_links":{"self":[{"href":"https:\/\/blogs.fu-berlin.de\/gruenstaeudl\/wp-json\/wp\/v2\/posts\/296","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/blogs.fu-berlin.de\/gruenstaeudl\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/blogs.fu-berlin.de\/gruenstaeudl\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/blogs.fu-berlin.de\/gruenstaeudl\/wp-json\/wp\/v2\/users\/2306"}],"replies":[{"embeddable":true,"href":"https:\/\/blogs.fu-berlin.de\/gruenstaeudl\/wp-json\/wp\/v2\/comments?post=296"}],"version-history":[{"count":6,"href":"https:\/\/blogs.fu-berlin.de\/gruenstaeudl\/wp-json\/wp\/v2\/posts\/296\/revisions"}],"predecessor-version":[{"id":302,"href":"https:\/\/blogs.fu-berlin.de\/gruenstaeudl\/wp-json\/wp\/v2\/posts\/296\/revisions\/302"}],"wp:attachment":[{"href":"https:\/\/blogs.fu-berlin.de\/gruenstaeudl\/wp-json\/wp\/v2\/media?parent=296"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/blogs.fu-berlin.de\/gruenstaeudl\/wp-json\/wp\/v2\/categories?post=296"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/blogs.fu-berlin.de\/gruenstaeudl\/wp-json\/wp\/v2\/tags?post=296"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}