ANTsR
ANTsR copied to clipboard
Parallelizing permutations with `foreach` ?
I am trying to build a parallel routine to run some permutation analysis.
When done on a serial manner, each permutation updates a single variable which keeps count of how many times a voxel exceeds the statistical value in permutations to later establish pvalues. The use of a single central variable decreases the memory footprint. Saving, or loading the result of each permutation would be too heavy (i.e., think 10,000 images loaded in memory).
When parallelizing this, I need each worker to update a single variable. However, this does not seem as easy as it looks. Some people advise to use pointer. Since our antsImages are S4 pointers, I thought that would work, I still cannot get the foreach
loop to update the image.
Does anybody have any idea how to resolve this?
Here is some code that I played around with:
library(ANTsR)
img = antsImageRead('/home/dorian/svr-lesymap/1000perms/mask_img.nii.gz') # just a 3D mask of a hemisphere
imgtest = antsImageClone(img)
vector = imageListToMatrix(list(img), img)[1,]
randomvec = sample(1:length(vector), size = 100000)
temp = vector
temp[-(randomvec)] = 0
randomask = makeImage(img, temp)
runs = 100
###########################################
library(doParallel)
ncores = 15
registerDoParallel(cores=ncores)
###############################
max(imgtest)
temp =foreach (i=1:100, .combine='c') %dopar% {
imgtest[randomask] = imgtest[randomask] + 1
}
max(imgtest)
Still looking for a solution to this. Opened also a thread on Stackoverflow, maybe R experts come up with an idea. https://stackoverflow.com/questions/54613330/update-single-common-variable-in-parallel-foreach-loop
The issue is simple: there is no way to update a common vector/S4/antsImage using foreach in R.
Here is some reproducible code:
library(ANTsR)
# load example image and make a mask
img = antsImageRead(getANTsRData( "r16" ))
mask = getMask(img)
###########################################
library(doParallel)
ncores = 2
registerDoParallel(cores=ncores)
###############################
# parallel loop cannot update img S4 object
foreach (i=1:10, .combine='c', .export = c('img','mask'),
.packages = c('ITKR', 'ANTsRCore', 'ANTsR') ) %dopar% {
# max(img) # output: 254
# print(img@pointer) # output: <pointer: (nil)>
img[mask] = 0 # output: no change to img
}
# standard for loop works
for (i in 1:10) {
# print(img@pointer) output: <pointer: 0x5510610>
# max(img) # output: 254
img[mask] = 0 # output: img black
}
Are you sure the last line of the foreach shouldn't be img? e.g.:
foreach (i=1:10, .combine='c', .export = c('img','mask'), .packages = c('ITKR', 'ANTsRCore', 'ANTsR') ) %dopar% {
# max(img) # output: 254
# print(img@pointer) # output: <pointer: (nil)>
img[mask] = 0 # output: no change to img
img
}
Also, to compare to a for loop, you should use %do%
rather than %dopar%
:
sum(img)
foreach (i=1:10, .combine='c', .export = c('img','mask'),
.packages = c('ITKR', 'ANTsRCore', 'ANTsR') ) %do% {
# max(img) # output: 254
# print(img@pointer) # output: <pointer: (nil)>
img[mask] = 0 # output: no change to img
}
sum(img)
John
On Sat, Feb 9, 2019 at 6:33 PM dorianps [email protected] wrote:
Still looking for a solution to this. Opened also a thread on Stackoverflow, maybe R experts come up with an idea.
https://stackoverflow.com/questions/54613330/update-single-common-variable-in-parallel-foreach-loop
The issue is simple: there is not way to update a common vector/S4/antsImage using foreach in R.
Here is some reproducible code:
library(ANTsR)
load example image and make a mask
img = antsImageRead(getANTsRData( "r16" )) mask = getMask(img)
###########################################
library(doParallel) ncores = 2 registerDoParallel(cores=ncores)
###############################
parallel loop cannot update img S4 object
foreach (i=1:10, .combine='c', .export = c('img','mask'), .packages = c('ITKR', 'ANTsRCore', 'ANTsR') ) %dopar% {
max(img) # output: 254
print(img@pointer) # output: <pointer: (nil)>
img[mask] = 0 # output: no change to img }
standard for loop works
for (i in 1:10) {
print(img@pointer) output: <pointer: 0x5510610>
max(img) # output: 254
img[mask] = 0 # output: img black }
— You are receiving this because you are subscribed to this thread. Reply to this email directly, view it on GitHub https://github.com/ANTsX/ANTsR/issues/245#issuecomment-462103000, or mute the thread https://github.com/notifications/unsubscribe-auth/ABBnrv8yJrDIeJBvI3mlzTf0TULkaB5Tks5vL6EegaJpZM4YPXXB .
Well... the problem is not what each foreach
worker is returning, they may return NULL for what I care. The problem is that the workers should update the same antsImage which points at <pointer: 0x5510610>
, and when the loop is finished I can access the same antsImage to find the results of all "independent" workers. The question is: how to make all workers update some sort of common variable. It can be an antsImage or any other object.