Skip to content

Commit

Permalink
Merge pull request #68 from snoweye/master
Browse files Browse the repository at this point in the history
0.3-5 on CRAN
  • Loading branch information
snoweye authored Apr 7, 2018
2 parents 20a6534 + 58caec2 commit a6afa69
Show file tree
Hide file tree
Showing 48 changed files with 541 additions and 96 deletions.
26 changes: 24 additions & 2 deletions .travis.yml
Original file line number Diff line number Diff line change
@@ -1,5 +1,10 @@
language: r

branches:
only:
- master
- osx

r:
# - devel
- release
Expand All @@ -11,9 +16,26 @@ before_install:
- sudo apt-get update -q
- sudo apt-get install -y -q libopenmpi-dev openmpi-bin
- LD_PRELOAD=/usr/lib/openmpi/lib/libmpi.so
- mpiexec --version
- mpicc -showme:incdirs
- mpicc -showme:libdirs
- mpicc -showme:compile
- mpicc -showme:link
- mpiexec -np 2 hostname
- cd ../
- R CMD build --no-resave-data --no-manual --no-build-vignettes pbdMPI

# r_packages:
# - rlecuyer

install:
- Rscript -e "install.packages('rlecuyer', repos = 'https://cran.r-project.org/')"
- R CMD check ./pbdMPI_*.tar.gz --as-cran
- cat ./pbdMPI.Rcheck/pbdMPI-Ex.Rout
- cat ./pbdMPI.Rcheck/pbdMPI-Ex.timings

r_packages:
- rlecuyer
script:
- R CMD INSTALL ./pbdMPI_*.tar.gz

sudo: required
dist: trusty
Expand Down
10 changes: 10 additions & 0 deletions ChangeLog
Original file line number Diff line number Diff line change
@@ -1,3 +1,13 @@
2018-02-25: Ver. 0.3-5
* Fix execmpi().
* system(wait = FALSE) doesn't work with MPI correctly in Unix-alike systems.
* Execute MPI in background and dump the results to the log file.
* Read the results back in from the log file when the job is complete.
* Windows system can not do the background job, but wait = TRUE is fine.

2018-02-17: Ver. 0.3-5
* Add execmpi().

2017-12-12: Ver. 0.3-4
* Added comm.localrank().

Expand Down
6 changes: 3 additions & 3 deletions DESCRIPTION
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
Package: pbdMPI
Version: 0.3-4
Date: 2018-01-03
Version: 0.3-5
Date: 2018-02-25
Title: Programming with Big Data -- Interface to MPI
Authors@R: c(person("Wei-Chen", "Chen", role = c("aut", "cre"), email =
"[email protected]"),
Expand All @@ -27,7 +27,7 @@ SystemRequirements: OpenMPI (>= 1.5.4) on Solaris, Linux, Mac, and
Pack 2012 R2 MS-MPI Redistributable Package) on Windows.
License: Mozilla Public License 2.0
URL: http://r-pbd.org/
BugReports: http://group.r-pbd.org/
BugReports: https://github.com/snoweye/pbdMPI/issues
MailingList: Please send questions and comments regarding pbdR to
[email protected]
NeedsCompilation: yes
Expand Down
3 changes: 3 additions & 0 deletions NAMESPACE
Original file line number Diff line number Diff line change
Expand Up @@ -77,6 +77,9 @@ export(
"task.pull.master",
"task.pull",

### "R/util_*.r"
"execmpi",

### "R/000_pbd_opt.r"
"pbd_opt" #,

Expand Down
130 changes: 130 additions & 0 deletions R/util_execmpi.r
Original file line number Diff line number Diff line change
@@ -0,0 +1,130 @@
### Utility

execmpi <- function(spmd.code = NULL, spmd.file = NULL,
mpicmd = NULL, nranks = 2L, verbose = TRUE){
### Check # of ranks.
nranks <- as.integer(nranks)
if(nranks <= 0){
stop("argument 'nranks' must be a integer and greater than 0.")
}

### Input checks
if(! is.null(spmd.code)){
if(!is.character(spmd.code)){
stop("argument 'spmd.code' must be a character string")
} else if(length(spmd.code) == 0){
stop("argument 'spmd.code' must be a non-empty character string")
} else if (length(spmd.code) > 1){
warning("spmd.code has length > 1; only the first element will be used")
spmd.code <- spmd.code[1L]
}

### Dump spmd.code to a temp file, execute
spmd.file <- tempfile()
on.exit(unlink(spmd.file))
conn <- file(spmd.file, open = "wt")
writeLines(spmd.code, conn)
close(conn)
} else{
if(is.null(spmd.file)){
stop("Either spmd.code or spmd.file should be provided.")
}
}
if(! file.exists(spmd.file)){
stop("spmd.file does not exist.")
}

### Find MPI executable.
if(is.null(mpicmd)){
if(Sys.info()[['sysname']] == "Windows"){
mpicmd <- try(system("mpiexec", intern = TRUE), silent = TRUE)
if(class(mpicmd) == "try-error"){
warning("No MPI executable can be found from PATH.")
return(invisible(NULL))
} else{
mpicmd <- "mpiexec"
}
} else{
mpicmd <- system("which mpiexec", intern = TRUE)
if(! is.null(attr(mpicmd, "status"))){
mpicmd <- system("which mpirun", intern = TRUE)
if(! is.null(attr(mpicmd, "status"))){
mpicmd <- system("which orterun", intern = TRUE)
if(! is.null(attr(mpicmd, "status"))){
mpicmd <- get.conf("MPIEXEC")
if(mpicmd == ""){
mpicmd <- get.conf("MPIRUN")
if(mpicmd == ""){
mpicmd <- get.conf("ORTERUN")
if(mpicmd == ""){
warning("No MPI executable can be found.")
return(invisible(NULL))
}
}
}
}
}
}
}
}

### Find Rscript.
if(Sys.info()[['sysname']] == "Windows"){
rscmd <- paste(Sys.getenv("R_HOME"), "/bin", Sys.getenv("R_ARCH_BIN"),
"/Rscript", sep = "")
} else{
rscmd <- paste(Sys.getenv("R_HOME"), "/bin/Rscript", sep = "")
}

### Make a cmd.
if(Sys.info()[['sysname']] == "Windows"){
cmd <- paste(mpicmd, "-np", nranks, rscmd, spmd.file, sep = " ")
### Redirect to log.file will get the message below and fail.
### The process cannot access the file because it is being used by
### another process.
} else{
log.file <- tempfile()
on.exit(unlink(log.file), add = TRUE)
cmd <- paste(mpicmd, "-np", nranks, rscmd, spmd.file,
">", log.file, "2>&1 & echo \"PID=$!\" &", sep = " ")
}
if(verbose){
cat(">>> MPI command:\n", cmd, "\n", sep = "")
}

### Run the cmd.
if(Sys.info()[['sysname']] == "Windows"){
ret <- system(cmd, intern = TRUE, ignore.stdout = FALSE,
ignore.stderr = FALSE, wait = TRUE)
} else{
tmp <- system(cmd, intern = TRUE, ignore.stdout = FALSE,
ignore.stderr = FALSE, wait = FALSE)
if(verbose){
cat(">>> MPI PID:\n", paste(tmp, collapse = "\n"), "\n", sep = "")
}

### Check if the job is finished, otherwise wait for it.
pid <- gsub("^PID=(.*)$", "\\1", tmp)
cmd.pid <- paste("ps -p", pid, sep = " ")
while(TRUE){
tmp.pid <- suppressWarnings(system(cmd.pid, intern = TRUE))
if(is.null(attr(tmp.pid, "status"))){
Sys.sleep(1)
} else{
break
}
}
}

### Get the output from the log file.
if(Sys.info()[['sysname']] != "Windows"){
ret <- readLines(log.file)
}
if(verbose){
cat(">>> MPI results:\n", paste(ret, collapse = "\n"), "\n", sep = "")
}

### Return
invisible(ret)
} # End of execmpi().

2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
* **Version:** 0.3-4
* **License:** [![License](http://img.shields.io/badge/license-MPL%202-orange.svg?style=flat)](https://www.mozilla.org/MPL/2.0/)
* **Download:** [![Download](http://cranlogs.r-pkg.org/badges/pbdMPI)](https://cran.r-project.org/package=pbdMPI)
* **Status:** [![Build Status](https://travis-ci.org/snoweye/pbdMPI.png)](https://travis-ci.org/snoweye/pbdMPI)
* **Status:** [![Build Status](https://travis-ci.org/snoweye/pbdMPI.png)](https://travis-ci.org/snoweye/pbdMPI) [![Appveyor Build status](https://ci.appveyor.com/api/projects/status/32r7s2skrgm9ubva?svg=true)](https://ci.appveyor.com/project/snoweye/pbdMPI)
* **Author:** See section below.


Expand Down
56 changes: 56 additions & 0 deletions appveyor.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
# DO NOT CHANGE the "init" and "install" sections below

# Download script file from GitHub
init:
ps: |
$ErrorActionPreference = "Stop"
Invoke-WebRequest http://raw.github.com/krlmlr/r-appveyor/master/scripts/appveyor-tool.ps1 -OutFile "..\appveyor-tool.ps1"
Import-Module '..\appveyor-tool.ps1'
install:
- ps: Bootstrap
- cd ..
### Install HPC Pack 2012 R2 Update 3 SDK
# - ps: (New-Object Net.WebClient).DownloadFile("https://download.microsoft.com/download/7/B/5/7B582B17-AF1E-454A-B86B-E6733010EB47/sdk_x64.msi", "sdk_x64.msi")
# - ps: msiexec /i sdk_x64.msi /quiet /qn /norestart /log install.log PROPERTY1=value1 PROPERTY2=value2
### Install MS-MPI v9.0
- ps: Start-FileDownload 'https://download.microsoft.com/download/2/E/C/2EC96D7F-687B-4613-80F6-E10F670A2D97/msmpisetup.exe'
- MSMpiSetup.exe -unattend
- dir "C:\Program Files\Microsoft MPI"
- dir "C:\Program Files\Microsoft MPI\Bin"
### Install MS-MPI v9.0 SDK
- ps: Start-FileDownload 'https://download.microsoft.com/download/2/E/C/2EC96D7F-687B-4613-80F6-E10F670A2D97/msmpisdk.msi'
- msmpisdk.msi /passive
- dir "C:\Program Files (x86)\Microsoft SDKs\MPI"
- dir "C:\Program Files (x86)\Microsoft SDKs\MPI\Include"
- dir "C:\Program Files (x86)\Microsoft SDKs\MPI\Lib"
### Set PATH
- set MPI_EXEC=C:\Program Files\Microsoft MPI
- set MPI_ROOT=C:\Program Files (x86)\Microsoft SDKS\MPI
- set PATH=%MPI_EXEC%\Bin;%PATH%
### Check MS-MPI
- mpiexec -help
# - mpiexec -help2
# - mpiexec -help3

environment:
global:
WARNINGS_ARE_ERRORS:
RTOOLS_VERSION: 34
USE_RTOOLS: true

matrix:
- R_VERSION: release
R_ARCH: x64

build_script:
- cd pbdMPI
- travis-tool.sh install_deps
- cd ..
- R CMD build --no-build-vignettes --no-manual --no-resave-data pbdMPI
- R CMD INSTALL pbdMPI*.tar.gz
- R CMD check pbdMPI*.tar.gz --as-cran --no-manual --no-vignettes --no-clean
- dir pbdMPI.Rcheck
# - type pbdMPI.Rcheck\00check.log
- type pbdMPI.Rcheck\pbdMPI-Ex_x64.Rout

21 changes: 16 additions & 5 deletions configure
Original file line number Diff line number Diff line change
Expand Up @@ -672,6 +672,7 @@ infodir
docdir
oldincludedir
includedir
runstatedir
localstatedir
sharedstatedir
sysconfdir
Expand Down Expand Up @@ -749,6 +750,7 @@ datadir='${datarootdir}'
sysconfdir='${prefix}/etc'
sharedstatedir='${prefix}/com'
localstatedir='${prefix}/var'
runstatedir='${localstatedir}/run'
includedir='${prefix}/include'
oldincludedir='/usr/include'
docdir='${datarootdir}/doc/${PACKAGE}'
Expand Down Expand Up @@ -1001,6 +1003,15 @@ do
| -silent | --silent | --silen | --sile | --sil)
silent=yes ;;

-runstatedir | --runstatedir | --runstatedi | --runstated \
| --runstate | --runstat | --runsta | --runst | --runs \
| --run | --ru | --r)
ac_prev=runstatedir ;;
-runstatedir=* | --runstatedir=* | --runstatedi=* | --runstated=* \
| --runstate=* | --runstat=* | --runsta=* | --runst=* | --runs=* \
| --run=* | --ru=* | --r=*)
runstatedir=$ac_optarg ;;

-sbindir | --sbindir | --sbindi | --sbind | --sbin | --sbi | --sb)
ac_prev=sbindir ;;
-sbindir=* | --sbindir=* | --sbindi=* | --sbind=* | --sbin=* \
Expand Down Expand Up @@ -1138,7 +1149,7 @@ fi
for ac_var in exec_prefix prefix bindir sbindir libexecdir datarootdir \
datadir sysconfdir sharedstatedir localstatedir includedir \
oldincludedir docdir infodir htmldir dvidir pdfdir psdir \
libdir localedir mandir
libdir localedir mandir runstatedir
do
eval ac_val=\$$ac_var
# Remove trailing slashes.
Expand Down Expand Up @@ -1291,6 +1302,7 @@ Fine tuning of the installation directories:
--sysconfdir=DIR read-only single-machine data [PREFIX/etc]
--sharedstatedir=DIR modifiable architecture-independent data [PREFIX/com]
--localstatedir=DIR modifiable single-machine data [PREFIX/var]
--runstatedir=DIR modifiable per-process data [LOCALSTATEDIR/run]
--libdir=DIR object code libraries [EPREFIX/lib]
--includedir=DIR C header files [PREFIX/include]
--oldincludedir=DIR C header files for non-gcc [/usr/include]
Expand Down Expand Up @@ -4252,10 +4264,9 @@ case "$MPITYPE" in
esac
if test "$MPIRUN" = "F" -a "$MPIEXEC" = "F" -a "$ORTERUN" = "F" ; then
echo ">>>> MPI executable is not in PATH ..."
echo ">>>> Please export or setenv PATH ..."
fi
MPIRUN=`which mpirun`
MPIEXEC=`which mpiexec`
ORTERUN=`which orterun`
# Check whether --enable-pbdPROF was given.
Expand Down
7 changes: 3 additions & 4 deletions configure.ac
Original file line number Diff line number Diff line change
Expand Up @@ -623,10 +623,9 @@ esac


dnl Echo all flags to see if they are set properly
if test "$MPIRUN" = "F" -a "$MPIEXEC" = "F" -a "$ORTERUN" = "F" ; then
echo ">>>> MPI executable is not in PATH ..."
echo ">>>> Please export or setenv PATH ..."
fi
MPIRUN=`which mpirun`
MPIEXEC=`which mpiexec`
ORTERUN=`which orterun`


dnl pbdPROF
Expand Down
19 changes: 13 additions & 6 deletions man/00_pbdMPI-package.Rd
Original file line number Diff line number Diff line change
Expand Up @@ -90,12 +90,19 @@
\dontrun{
### Under command mode, run the demo with 2 processors by
### (Use Rscript.exe for windows system)
mpiexec -np 2 Rscript -e "demo(allgather,'pbdMPI',ask=F,echo=F)"
mpiexec -np 2 Rscript -e "demo(allreduce,'pbdMPI',ask=F,echo=F)"
mpiexec -np 2 Rscript -e "demo(bcast,'pbdMPI',ask=F,echo=F)"
mpiexec -np 2 Rscript -e "demo(gather,'pbdMPI',ask=F,echo=F)"
mpiexec -np 2 Rscript -e "demo(reduce,'pbdMPI',ask=F,echo=F)"
mpiexec -np 2 Rscript -e "demo(scatter,'pbdMPI',ask=F,echo=F)"
# mpiexec -np 2 Rscript -e "demo(allgather,'pbdMPI',ask=F,echo=F)"
# mpiexec -np 2 Rscript -e "demo(allreduce,'pbdMPI',ask=F,echo=F)"
# mpiexec -np 2 Rscript -e "demo(bcast,'pbdMPI',ask=F,echo=F)"
# mpiexec -np 2 Rscript -e "demo(gather,'pbdMPI',ask=F,echo=F)"
# mpiexec -np 2 Rscript -e "demo(reduce,'pbdMPI',ask=F,echo=F)"
# mpiexec -np 2 Rscript -e "demo(scatter,'pbdMPI',ask=F,echo=F)"
### Or
# execmpi("demo(allgather,'pbdMPI',ask=F,echo=F)", nranks = 2L)
# execmpi("demo(allreduce,'pbdMPI',ask=F,echo=F)", nranks = 2L)
# execmpi("demo(bcast,'pbdMPI',ask=F,echo=F)", nranks = 2L)
# execmpi("demo(gather,'pbdMPI',ask=F,echo=F)", nranks = 2L)
# execmpi("demo(reduce,'pbdMPI',ask=F,echo=F)", nranks = 2L)
# execmpi("demo(scatter,'pbdMPI',ask=F,echo=F)", nranks = 2L)
}
}
\keyword{package}
Loading

0 comments on commit a6afa69

Please sign in to comment.