Skip to content
Snippets Groups Projects
Commit 76a7751c authored by fjn1g13's avatar fjn1g13
Browse files

400k spreads

parent 9736d76b
No related branches found
No related tags found
No related merge requests found
......@@ -3,6 +3,7 @@
<PropertyGroup>
<OutputType>Exe</OutputType>
<TargetFrameworks>netcoreapp2.1;netcoreapp3.1;net5.0</TargetFrameworks>
<DefaultItemExcludes>$(DefaultItemExcludes);**\*.dat;**\*.pdf</DefaultItemExcludes>
</PropertyGroup>
<ItemGroup>
......
......@@ -22,10 +22,6 @@ namespace IVMCTrim
// none of our matrices are big enough to warrent multi-threading
MathNet.Numerics.Control.UseSingleThread();
// repeats with Z=0.95
RunRepeats("Z095", Configurations.Standard(Z: 0.95), baseSeed: 2042, repeats: 40, startFrom: 4);
return;
// runs a bunch of experiments with the 'standard' configuration, only varying Z
// seeds should match those used in the paper
Run("Z000", Configurations.Standard(Z: 0.0), seed: 42); // (no dual-peaked environments)
......@@ -39,6 +35,12 @@ namespace IVMCTrim
Run("Z095L2", Configurations.StandardL2(Z: 0.95), seed: 2042); // (example with super-additive cost function (quadratic/Ridge))
Run("Z095MMSO", Configurations.StandardMMSO(Z: 0.95), seed: 2042); // (example with sub-additive cost function)
Run("Z050E204", Configurations.Standard204(Z: 0.95), seed: 42, reportingPeriodMultiplier: 10); // (example with more modules; this one takes a while to run)
// Vary λ spread (will take many days...)
RunSpread("VaryL", new[] { 0.00, 0.02, 0.04, 0.06, 0.08, 0.10, 0.12, 0.14, 0.16, 0.18, 2.00 }, λ => Configurations.Standard(Z: 0.95, λ: λ), λ => (100 * λ).ToString("000"), 42, 40);
// Vary Z spread (will take many many days...)
RunSpread("VaryZ", new[] { 0.0, 0.1, 0.2, 0.3, 0.4, 0.5, 0.6, 0.7, 0.8, 0.9, 1.0, 0.05, 0.15, 0.25, 0.35, 0.45, 0.55, 0.65, 0.75, 0.85, 0.95 }, z => Configurations.Standard(Z: z), z => (100 * z).ToString("000"), 42, 40);
}
/// <summary>
......@@ -46,7 +48,7 @@ namespace IVMCTrim
/// </summary>
public static void Run(string outputDirectory, Parameters parameters, int seed, int reportingPeriodMultiplier = 1)
{
Console.WriteLine($"Running into {outputDirectory}");
Console.WriteLine($"Running into {outputDirectory} with seed {seed}");
System.IO.Directory.CreateDirectory(outputDirectory);
// initialise reporter
......@@ -56,12 +58,10 @@ namespace IVMCTrim
var ctx = new ExecutionContext(new MersenneTwister(seed, false));
// run the actual experiment
var runonFrequency = Model.RunExperiment(ctx, parameters, reporter);
var runonSolveFrequency = Model.RunExperiment(ctx, parameters, reporter);
// produce output from recorders
Recording.ProduceOutput(outputDirectory, parameters, recorders);
Console.WriteLine($"{outputDirectory} runon frequency: {runonFrequency}");
Recording.ProduceOutput(outputDirectory, parameters, recorders, runonSolveFrequency);
}
/// <summary>
......@@ -85,10 +85,62 @@ namespace IVMCTrim
tasks.Add(new Action(() => Run(dir, parameters, seed, reportingPeriodMultiplier)));
}
// wait until they've all finished
// (scheduling will be down to the thread pool, so it may be unpredictable)
// run them all in parallel
Parallel.ForEach(tasks, new ParallelOptions { MaxDegreeOfParallelism = 8 }, x => x());
}
/// <summary>
/// Run a spread of experiments with different parameters.
/// </summary>
public static void RunSpread<T>(string outputDirectory, T[] spread, Func<T, Parameters> parameterFunc, Func<T, string> formatter, int baseSeed, int repeats, int startFrom = 0, int reportingPeriodMultiplier = 1) where T : IComparable<T>
{
// perform runs
foreach (var t in spread)
{
var subDir = Path.Combine(outputDirectory, formatter(t));
var parameters = parameterFunc(t);
RunRepeats(subDir, parameters, baseSeed, repeats, startFrom, reportingPeriodMultiplier);
baseSeed += 100;
}
// generate runon solve frequency plot
PlotRunonSolveFrequencies(outputDirectory);
}
public static void PlotRunonSolveFrequencies(string directory)
{
var runonSolveFrequenciesTable = new Dictionary<string, double[]>();
foreach (var subDir in Directory.GetDirectories(directory))
{
var subName = Path.GetFileName(subDir);
var list = new List<double>();
foreach (var runDir in Directory.GetDirectories(subDir))
{
var runName = Path.GetFileName(runDir);
var fileContents = File.ReadAllText(Path.Combine(runDir, "runonSolveFrequency.txt"));
list.Add(double.Parse(fileContents));
}
runonSolveFrequenciesTable.Add(subName, list.ToArray());
}
var runonSolveFrequencyPlot = new PlotModel();
var xaxis = new CategoryAxis() { Position = AxisPosition.Bottom };
var yaxis = new LinearAxis() { Position = AxisPosition.Left, Title = "Mean Frequency of Max Fitness Phenotype" };
runonSolveFrequencyPlot.Axes.Add(xaxis);
runonSolveFrequencyPlot.Axes.Add(yaxis);
var columns = new ColumnSeries();
foreach (var t in runonSolveFrequenciesTable.Keys.OrderBy(x => x))
{
xaxis.Labels.Add(t);
columns.Items.Add(new ColumnItem(runonSolveFrequenciesTable[t].Average()));
}
runonSolveFrequencyPlot.Series.Add(columns);
runonSolveFrequencyPlot.ExportPdf(Path.Combine(directory, "meanRunonSolveFrequency.pdf"), 1.0, false);
}
}
/*
......@@ -876,13 +928,8 @@ namespace IVMCTrim
if (episode % (reportingPeriodMultiplier * 1000) == 0)
{
// this is totally pointless: we have the win count already, which is just as informative
// runon solve frequency
var ctx = new ExecutionContext(new MersenneTwister()); // use random seed: we don't need these to be reproducable, and we don't want any sampling bias
var runonFrequency = 0;// Model.MeasureRunonSolveFrequency(ctx, parameters, individual);
// report progress
Console.WriteLine($"{outputDirectory}: {episode}/{parameters.TotalEpisodes} ({(double)episode / parameters.TotalEpisodes:P})\tf={evaluation.Fitness}\t{runonFrequency:P}");
Console.WriteLine($"{outputDirectory}: {episode}/{parameters.TotalEpisodes} ({(double)episode / parameters.TotalEpisodes:P})\tf={evaluation.Fitness}");
// produce grn plot
var grnPlot = PlotHelpers.IntegralCartesianAxes($"Episode {episode}", "row", "col");
......@@ -891,7 +938,7 @@ namespace IVMCTrim
grnPlot.ExportPdf(path($"episode{episode}.pdf"), 0.5, true);
// run tracee
ctx = new ExecutionContext(new MersenneTwister(3)); // common seed (chosen so that it has a mix of cL and C0)
var ctx = new ExecutionContext(new MersenneTwister(3)); // common seed (chosen so that it has a mix of cL and C0)
var env = new IvmcEnvironment(parameters.ModuleSize, parameters.ModuleCount);
var clone = individual.Clone(); // don't want to modify the real guy
......@@ -924,12 +971,15 @@ namespace IVMCTrim
return endOfEpisode;
}
public static void ProduceOutput(string outDir, Parameters parameters, Recorders recorders)
public static void ProduceOutput(string outDir, Parameters parameters, Recorders recorders, double runonSolveFrequency)
{
string path(string f) => System.IO.Path.Combine(outDir, f);
const double plotSize = 0.5;
Console.WriteLine($"{outDir} runon frequency: {runonSolveFrequency}");
System.IO.File.WriteAllText(path("runonSolveFrequency.txt"), runonSolveFrequency.ToString("R"));
// data export and mindless plotting
var rcsData = recorders.GetRcsDataFlat();
TrajectoryHelpers.SaveTrajectories(path("rcs_t.dat"), rcsData, recorders.Grns.SamplePeriod);
......
......@@ -20,22 +20,22 @@ $runName = "One"
$repeats = repeats(4) # full batches were all 40 (CPUs per node on IRIDIS)
# standard Z
. .\genSpread.ps1 "Standard" "Standard" 120000 Z r Z r $twentyHalf $repeats {param($x, $y) "Z=$x"} $runName 100 $commonParamFile $noGen
. .\genSpread.ps1 "Standard" "Standard" 400000 Z r Z r $twentyHalf $repeats {param($x, $y) "Z=$x"} $runName 100 $commonParamFile $noGen
# perfect G
. .\genSpread.ps1 "PerfectG" "PerfectG" 120000 Z r Z r $twentyHalf $repeats {param($x, $y) "Z=$x gresetprob=1 resetoperation=perfect"} $runName 100 $commonParamFile $noGen
. .\genSpread.ps1 "PerfectG" "PerfectG" 400000 Z r Z r $twentyHalf $repeats {param($x, $y) "Z=$x gresetprob=1 resetoperation=perfect"} $runName 100 $commonParamFile $noGen
# fixed high
. .\genSpread.ps1 "FixHigh" "FixHigh" 120000 Z r Z r $one $repeats {param($x, $y) "Z=$x targetpackage=ivmc:custom targetstring=++++++++++++++++ modulesstring=4*4 ivmcvmpos=hhhh ivmcvmmos=0000 mg=0 g0string=++++++++++++++++"} $runName 100 $commonParamFile $noGen
. .\genSpread.ps1 "FixHigh" "FixHigh" 400000 Z r Z r $one $repeats {param($x, $y) "Z=$x targetpackage=ivmc:custom targetstring=++++++++++++++++ modulesstring=4*4 ivmcvmpos=hhhh ivmcvmmos=0000 mg=0 g0string=++++++++++++++++"} $runName 100 $commonParamFile $noGen
# L2 (common super-additive; Ridge)
. .\genSpread.ps1 "LTwo" "LTwo" 120000 Z r Z r $twentyHalf $repeats {param($x, $y) "Z=$x"} $runName 100 $commonParamFile $noGen "regfunc=l2"
. .\genSpread.ps1 "LTwo" "LTwo" 400000 Z r Z r $twentyHalf $repeats {param($x, $y) "Z=$x"} $runName 100 $commonParamFile $noGen "regfunc=l2"
# MMSO (somewhat arbitrary strictly sub-additive)
. .\genSpread.ps1 "MMSO" "MMSO" 120000 Z r Z r $twentyHalf $repeats {param($x, $y) "Z=$x"} $runName 100 $commonParamFile $noGen "regfunc=mmsolinAQ1;0.8"
. .\genSpread.ps1 "MMSO" "MMSO" 400000 Z r Z r $twentyHalf $repeats {param($x, $y) "Z=$x"} $runName 100 $commonParamFile $noGen "regfunc=mmsolinAQ1;0.8"
# E204
. .\genSpread.ps1 "E204" "E204" 120000 Z r Z r $twentyHalf $repeats {param($x, $y) "Z=$x targetpackage=ivmc:custom targetstring=80*+ modulesstring=20*4 K=2000 mb=2E-4"} $runName 100 $commonParamFile $noGen
. .\genSpread.ps1 "E204" "E204" 400000 Z r Z r $twentyHalf $repeats {param($x, $y) "Z=$x targetpackage=ivmc:custom targetstring=80*+ modulesstring=20*4 K=2000 mb=2E-4"} $runName 100 $commonParamFile $noGen
# VaryLambda
. .\genSpread.ps1 "VaryL" "VaryL" 400000 Lambda r L r $lambdas $repeats {param($x, $y) "Lambda=$x"}$runName 100 $commonParamFile $noGen "Z=0.95"
\ No newline at end of file
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment