diff --git a/CMakeLists.txt b/CMakeLists.txt index d278da11..ad3064f8 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -91,11 +91,6 @@ option(BUILD_SLIMGUI "Build the Qt5-based GUI for SLiM" OFF) # This is supported only for the command-line tools, not for SLiMgui; do not set BUILD_SLIMGUI option(PARALLEL "Build parallel versions of eidos and slim" OFF) -if(PARALLEL) - # BCH 12/4/2023: Parallel SLiM is presently unreleased and unsupported. Caveat lector. - message(FATAL_ERROR "Multithreaded SLiM is not released, not thoroughly tested, and generally not yet ready for prime time. It is not recommended for end-user use, especially not for "production" runs, and the documentation for it is not yet public. Please do not ask for any kind of support for this feature if you choose to experiment with it.") -endif(PARALLEL) - # Add "-D PROFILE=ON" to the CMake command to make a build of command-line slim with runtime profiling # This makes SLiM slower, so it is not for production use. It may be set ON only for Release builds. option(PROFILE "Build slim for runtime profiling" OFF) diff --git a/QtSLiM/recipes.qrc b/QtSLiM/recipes.qrc index bcaa1cb3..23d65051 100644 --- a/QtSLiM/recipes.qrc +++ b/QtSLiM/recipes.qrc @@ -202,5 +202,6 @@ recipes/Recipe 19.6 - A coevolutionary host-parasitoid trait-matching model.txt recipes/Recipe 19.7 - A coevolutionary host-parasite matching-allele model.txt recipes/Recipe 19.8 - Within-host reproduction in a host-pathogen model.txt + recipes/Recipe 22.7 - Parallelizing nonWF reproduction and spatial interactions.txt diff --git a/QtSLiM/recipes/Recipe 22.7 - Parallelizing nonWF reproduction and spatial interactions.txt b/QtSLiM/recipes/Recipe 22.7 - Parallelizing nonWF reproduction and spatial interactions.txt new file mode 100644 index 00000000..3327d8fa --- /dev/null +++ b/QtSLiM/recipes/Recipe 22.7 - Parallelizing nonWF reproduction and spatial interactions.txt @@ -0,0 +1,62 @@ +initialize() { + initializeSLiMModelType("nonWF"); + initializeSLiMOptions(dimensionality="xy"); + defineConstant("K", 100000); // carrying-capacity density + defineConstant("S", 0.005); // sigma_S, the spatial interaction width + defineConstant("M", 0.025); // sigma_M, the spatial mating width + + initializeMutationType("m1", 0.5, "f", 0.0); + m1.convertToSubstitution = T; + + initializeGenomicElementType("g1", m1, 1.0); + initializeGenomicElement(g1, 0, 1e8 - 1); + initializeMutationRate(1e-7); + initializeRecombinationRate(1e-8); + + // competition kernel + initializeInteractionType(1, "xy", reciprocal=T, maxDistance=S * 2); + i1.setInteractionFunction("n", 1.0, S); + + // mating kernel + initializeInteractionType(2, "xy", reciprocal=T, maxDistance=M * 2); + i1.setInteractionFunction("n", 1.0, M); +} +2: first() { + i2.evaluate(p1); +} +reproduction() { + inds = p1.individuals; + mates = i2.drawByStrength(inds, 1, returnDict=T); + order = mates.compactIndices(); + inds = inds[order]; + num = rpois(size(inds), 5); + nonzero_indices = which(num > 0); + + for (i in nonzero_indices) + { + ind = inds[i]; + offspring = p1.addCrossed(ind, mates.getValue(i), count=num[i], defer=T); + offspring.setSpatialPosition(ind.spatialPosition); + } + + self.active = 0; +} +1 early() { + sim.addSubpop("p1", K); + p1.individuals.setSpatialPosition(p1.pointUniform(K)); +} +early() { + // deviate offspring from their maternal positions + newborns = p1.subsetIndividuals(maxAge=0); + old_pos = newborns.spatialPosition; + new_pos = p1.pointReflected(old_pos + rnorm(size(old_pos), 0, 0.02)); + newborns.setSpatialPosition(new_pos); +} +early() { + // spatial competition + i1.evaluate(p1); + inds = p1.individuals; + competition = i1.localPopulationDensity(inds); + inds.fitnessScaling = K / competition; +} +100 late() { } diff --git a/SLiMgui/Recipes/Recipe 22.7 - Parallelizing nonWF reproduction and spatial interactions.txt b/SLiMgui/Recipes/Recipe 22.7 - Parallelizing nonWF reproduction and spatial interactions.txt new file mode 100644 index 00000000..3327d8fa --- /dev/null +++ b/SLiMgui/Recipes/Recipe 22.7 - Parallelizing nonWF reproduction and spatial interactions.txt @@ -0,0 +1,62 @@ +initialize() { + initializeSLiMModelType("nonWF"); + initializeSLiMOptions(dimensionality="xy"); + defineConstant("K", 100000); // carrying-capacity density + defineConstant("S", 0.005); // sigma_S, the spatial interaction width + defineConstant("M", 0.025); // sigma_M, the spatial mating width + + initializeMutationType("m1", 0.5, "f", 0.0); + m1.convertToSubstitution = T; + + initializeGenomicElementType("g1", m1, 1.0); + initializeGenomicElement(g1, 0, 1e8 - 1); + initializeMutationRate(1e-7); + initializeRecombinationRate(1e-8); + + // competition kernel + initializeInteractionType(1, "xy", reciprocal=T, maxDistance=S * 2); + i1.setInteractionFunction("n", 1.0, S); + + // mating kernel + initializeInteractionType(2, "xy", reciprocal=T, maxDistance=M * 2); + i1.setInteractionFunction("n", 1.0, M); +} +2: first() { + i2.evaluate(p1); +} +reproduction() { + inds = p1.individuals; + mates = i2.drawByStrength(inds, 1, returnDict=T); + order = mates.compactIndices(); + inds = inds[order]; + num = rpois(size(inds), 5); + nonzero_indices = which(num > 0); + + for (i in nonzero_indices) + { + ind = inds[i]; + offspring = p1.addCrossed(ind, mates.getValue(i), count=num[i], defer=T); + offspring.setSpatialPosition(ind.spatialPosition); + } + + self.active = 0; +} +1 early() { + sim.addSubpop("p1", K); + p1.individuals.setSpatialPosition(p1.pointUniform(K)); +} +early() { + // deviate offspring from their maternal positions + newborns = p1.subsetIndividuals(maxAge=0); + old_pos = newborns.spatialPosition; + new_pos = p1.pointReflected(old_pos + rnorm(size(old_pos), 0, 0.02)); + newborns.setSpatialPosition(new_pos); +} +early() { + // spatial competition + i1.evaluate(p1); + inds = p1.individuals; + competition = i1.localPopulationDensity(inds); + inds.fitnessScaling = K / competition; +} +100 late() { } diff --git a/eidos/eidos_openmp.h b/eidos/eidos_openmp.h index f49c80c0..e6f0e553 100644 --- a/eidos/eidos_openmp.h +++ b/eidos/eidos_openmp.h @@ -64,19 +64,6 @@ #include -/* - * For simplicity, ongoing work related to the parallelization of SLiM with OpenMP now resides in the master branch. - * However, multithreaded SLiM is not released, not thoroughly tested, and generally not yet ready for prime time. - * It is not recommended for end-user use, especially not for "production" runs, and the documentation for it is - * not yet public. Please do not ask for any kind of support for this feature if you choose to experiment with it. - * - * - BCH 12/4/2023 - */ -#ifdef _OPENMP -#error Building multithreaded SLiM is presently disabled and unsupported. This feature is still under development. -#endif - - // This is the largest number of threads we allow the user to set. There is no hard limit in the code; // this is primarily just to prevent people from doing anything stupid. #define EIDOS_OMP_MAX_THREADS 1024