Reputation: 11
I have been looking for answers and working on a solution on this for the last week, but was not successful at all.
I want to set up a network of entities that depend on each other. Entities have certain thresholds: one which requires them to react to survive and one for their certain death. So if entity A dies, this may force entity B to act, but entity C may still be ok with the loss of A. The triggered reactions may in turn trigger reactions from formerly unaffected entities.
The loop is supposed to find and document the effects of every single entity on the network if it were to die.
My R code below works perfectly fine when executed on its own but runs until infinity if used in a foreach loop (I had it run for ~9 hours).
Since the network is randomly generated and different for each iteration, I need to go for as many randomly generated networks as possible. My idea that each parallel process generates an entire network and goes through the effects of every single entity’s death.
My code looks like this (shortened version):
library(foreach)
library(doParallel)
iterations <- … # number of iterations of the model
cl <- makeCluster((detectCores() -1), outfile = "")
registerDoParallel(cl)
parallel_loop <- foreach(iteration=(1:iterations), .packages=c("VGAM","network","igraph")) %dopar%{
# generate data set
data <- … # VGAM package is needed for this
adjacency_matrix <- …
data$reaction <- 1 # need this later for a while loop
documentation <- matrix(0, nrow = number_entities, ncol = 6) # for documentation (obviously)
documentation <- as.data.frame(documentation)
some_network_analysis # network and igraph packages are needed for this
save(data, file=”data”)
save(adjacency_matrix, file =”adjacency_matrix”)
# define functions
check_effect_function <- function{… # determines the effect of the dead entity on the others, sets data$reaction[affected_entity] <- 1 if the effect on an entity is sufficiently strong to require a reaction
quick_reaction_test <- function{… # quick and dirty test if the triggered reactions do not cause other entities to react. == 1 if yes, ==0 if not
reaction_function <- function{… # a reaction function for affected entities
documentation_function <- function{… # filling data frame “documentation”
# the killing loop
for (dead_entity in 1:number_entities) {
load(data) # so we have clean data and no remnants of earlier runs
load(adjacency_matrix)
adjacency_matrix[,dead_entity] <- 0 # the effect of the entity’s death
while (sum(data$reaction) != 0) { # finding new equilibrium
data$reaction <- 0
effect_function() # sets data$reaction[entity] <- 1 if threshold is exceeded
if (sum(data$reaction) != 0) {
quick_test_function()
if (quick_test ==1)
{documentation_function() # end of the loop
} else reaction_function()
} else {documentation_function} # end of the loop
if (reaction_needed == 0) {documentation_function()} # end of the loop
} # end of the killing loop
return(documentation)
} # end of foreach loop
docu_loop <- as.data.frame(do.call(rbind,lapply(parallel_loop,function(x){x}))) # to get me the documentation file
stopCluster(cl)
If I run the code manually (i.e. all of it but the foreach part), it finishes in under a minute. Once I include the foreach part, keeps running and running. Even if I just have 1 iteration, it does not stop. Even stranger, once I manually stop the calculations, R remains at a very high processor usage and significantly slows down the system. I can only stop this by restarting R completely.
FYI:
- The functions include for and while loops cycling through all entities. But that should work even in parallel, right?
- I have listed the used packages in case they interfere with the parallelization
What am I doing wrong in my foreach commands? This exact foreach code worked fine for some other arbitrary code I tried. Help is highly appreciated, thank you in advance!
++++ SOLUTION ++++
Should anyone ever have this problem as well, I have found the solution: In this bit
while (sum(data$reaction) != 0) { # finding new equilibrium
data$reaction <- 0
I accidentally had
data$reaction <<- 0
which works fine for manual runs of the code, but does not work in parallelization. I should've been rubber ducking this part better.
Upvotes: 0
Views: 369
Reputation: 11
Should anyone ever have this problem as well, I have found the solution: In this bit
while (sum(data$reaction) != 0) { # finding new equilibrium
data$reaction <- 0
I accidentally had
data$reaction <<- 0
which works fine for manual runs of the code, but does not work in parallelization. I should've been rubber ducking this part better.
Upvotes: 1