Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Parallelizing permutations with foreach ? #245

Open
dorianps opened this issue Nov 5, 2018 · 3 comments
Open

Parallelizing permutations with foreach ? #245

dorianps opened this issue Nov 5, 2018 · 3 comments

Comments

@dorianps
Copy link
Collaborator

dorianps commented Nov 5, 2018

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)
@dorianps
Copy link
Collaborator Author

dorianps commented Feb 10, 2019

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
}

@muschellij2
Copy link
Collaborator

muschellij2 commented Feb 10, 2019 via email

@dorianps
Copy link
Collaborator Author

dorianps commented Feb 11, 2019

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.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants