From bdc3ccaad7f0772a566acdcfcf543c4e433c6ae8 Mon Sep 17 00:00:00 2001 From: empathicqubit Date: Sat, 24 Apr 2021 01:18:06 -0400 Subject: [PATCH] Sort species by number of genomes to speed up parallelization. Add constant ID to species. --- pool.lua | 8 +++++++- runner-process.lua | 23 +++++++++++++---------- runner-wrapper.lua | 12 +++++++++--- runner.lua | 16 +++++++--------- xpra-run.sh | 8 ++++++-- 5 files changed, 42 insertions(+), 25 deletions(-) diff --git a/pool.lua b/pool.lua index 1ac685f..72fdabf 100644 --- a/pool.lua +++ b/pool.lua @@ -276,6 +276,7 @@ end local function newPool() local pool = {} + pool.speciesId = 1 pool.species = {} pool.generation = 0 pool.innovation = Outputs @@ -286,6 +287,8 @@ end local function newSpecies() local species = {} + species.id = pool.speciesId + pool.speciesId = pool.speciesId + 1 species.topFitness = 0 species.staleness = 0 species.genomes = {} @@ -626,6 +629,10 @@ local function newGeneration() local child = children[c] addToSpecies(child) end + + table.sort(pool.species, function(a,b) + return (#a.genomes < #b.genomes) + end) pool.generation = pool.generation + 1 @@ -687,7 +694,6 @@ local function mainLoop(currentSpecies) runner.run( slice, pool.generation, - currentSpecies, function() -- Genome callback end, diff --git a/runner-process.lua b/runner-process.lua index 5affc86..2579b1e 100644 --- a/runner-process.lua +++ b/runner-process.lua @@ -15,9 +15,13 @@ end runnerData = runnerData() -local speciesIndex = runnerData[3] +local species = runnerData[1] -local filename = runnerData[4] +local speciesId = species.id + +local generationIndex = runnerData[2] + +local filename = runnerData[3] local outFile = io.open(filename, "w") @@ -35,7 +39,7 @@ runner.onMessage(function(msg, color) outContents, serpent.dump({ type = 'onMessage', - speciesIndex = speciesIndex, + speciesId = speciesId, msg = msg, color = color, }) @@ -66,7 +70,7 @@ runner.onSave(function(filename) serpent.dump({ type = 'onSave', filename = filename, - speciesIndex = speciesIndex, + speciesId = speciesId, }) ) end) @@ -77,15 +81,14 @@ runner.onLoad(function(filename) serpent.dump({ type = 'onLoad', filename = filename, - speciesIndex = speciesIndex, + speciesId = speciesId, }) ) end) runner.run( - runnerData[1], - runnerData[2], - speciesIndex, + species, + generationIndex, function(genome, index) table.insert( outContents, @@ -93,7 +96,7 @@ runner.run( type = 'onGenome', genome = genome, genomeIndex = index, - speciesIndex = speciesIndex, + speciesId = speciesId, }) ) end, @@ -102,7 +105,7 @@ runner.run( outContents, serpent.dump({ type = 'onFinish', - speciesIndex = speciesIndex, + speciesId = speciesId, }) ) outFile:write(table.concat(outContents, "\n")) diff --git a/runner-wrapper.lua b/runner-wrapper.lua index 7d69dd1..a6e1525 100644 --- a/runner-wrapper.lua +++ b/runner-wrapper.lua @@ -64,14 +64,14 @@ return function() onLoad(_M, handler) end - _M.run = function(species, generationIdx, speciesIdx, genomeCallback, finishCallback) + _M.run = function(species, generationIdx, genomeCallback, finishCallback) local poppets = {} for i=1,#species,1 do local outputFileName = tmpFileName..'_output_'..i local inputFileName = tmpFileName.."_input_"..i local inputFile = io.open(inputFileName, 'w') - inputFile:write(serpent.dump({species[i], generationIdx, speciesIdx + i - 1, outputFileName})) + inputFile:write(serpent.dump({species[i], generationIdx, outputFileName})) inputFile:close() local cmd = "RUNNER_DATA=\""..inputFileName.."\" lsnes \"--rom="..config.ROM.."\" --unpause \"--lua="..base.."/runner-process.lua\"" @@ -109,7 +109,13 @@ return function() elseif obj.type == 'onSave' then save(_M, obj.filename) elseif obj.type == 'onGenome' then - species[obj.speciesIndex - speciesIdx + 1].genomes[obj.genomeIndex] = obj.genome + for i=1,#species,1 do + local s = species[i] + if s.id == obj.speciesId then + s.genomes[obj.genomeIndex] = obj.genome + break + end + end genomeCallback(obj.genome, obj.index) elseif obj.type == 'onFinish' then finishCallback() diff --git a/runner.lua b/runner.lua index 2e02048..4ada7ef 100644 --- a/runner.lua +++ b/runner.lua @@ -258,7 +258,7 @@ function displayForm(_M) gui.text(5, 30, "Timeout: " .. _M.timeout) gui.text(5, 5, "Generation: " .. _M.currentGenerationIndex) - gui.text(130, 5, "Species: " .. _M.currentSpeciesIndex) + gui.text(130, 5, "Species: " .. _M.currentSpecies.id) gui.text(230, 5, "Genome: " .. _M.currentGenomeIndex) gui.text(130, 30, "Max: " .. math.floor(_M.maxFitness)) --gui.text(330, 5, "Measured: " .. math.floor(measured/total*100) .. "%") @@ -302,7 +302,7 @@ local function evaluateNetwork(network, inputs, inputDeltas) table.insert(inputs, 1) table.insert(inputDeltas,99) if #inputs ~= Inputs then - print("Incorrect number of neural network inputs.") + message(_M, "Incorrect number of neural network inputs.", 0x00990000) return {} end @@ -401,7 +401,7 @@ local function mainLoop(_M, genome) if not pcall(function() displayGenome(genome) end) then - message(_M, "Could not render genome graph") + message(_M, "Could not render genome graph", 0x00990000) end end @@ -557,7 +557,7 @@ local function mainLoop(_M, genome) _M.genomeCallback(genome, _M.currentGenomeIndex) end - message(_M, string.format("Gen %d species %d genome %d fitness: %d", _M.currentGenerationIndex, _M.currentSpeciesIndex, _M.currentGenomeIndex, fitness)) + message(_M, string.format("Gen %d species %d genome %d fitness: %d", _M.currentGenerationIndex, _M.currentSpecies.id, _M.currentGenomeIndex, fitness)) _M.currentGenomeIndex = 1 while fitnessAlreadyMeasured(_M) do _M.currentGenomeIndex = _M.currentGenomeIndex + 1 @@ -792,11 +792,10 @@ local function saveLoadInput(_M) end end -local function run(_M, species, generationIdx, speciesIdx, genomeCallback, finishCallback) +local function run(_M, species, generationIdx, genomeCallback, finishCallback) game.registerHandlers() _M.currentGenerationIndex = generationIdx - _M.currentSpeciesIndex = speciesIdx _M.currentSpecies = species _M.currentGenomeIndex = 1 _M.genomeCallback = genomeCallback @@ -841,7 +840,6 @@ end return function() local _M = { currentGenerationIndex = 1, - currentSpeciesIndex = 1, currentSpecies = nil, finishCallback = nil, genomeCallback = nil, @@ -897,8 +895,8 @@ return function() onLoad(_M, handler) end - _M.run = function(species, generationIdx, speciesIdx, genomeCallback, finishCallback) - run(_M, species, generationIdx, speciesIdx, genomeCallback, finishCallback) + _M.run = function(species, generationIdx, genomeCallback, finishCallback) + run(_M, species, generationIdx, genomeCallback, finishCallback) end return _M diff --git a/xpra-run.sh b/xpra-run.sh index 939ee1e..34782f6 100755 --- a/xpra-run.sh +++ b/xpra-run.sh @@ -1,4 +1,8 @@ #! /bin/bash SCRIPT_DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" &> /dev/null && pwd )" -xpra start --bind-tcp=127.0.0.1:5309 --html=on --start-child="lsnes --lua=$SCRIPT_DIR/neat-donk.lua" --exit-with-child=yes --start-new-commands=no -xdg-open http://127.0.0.1:5309 +PORT=5309 +xpra start --bind-tcp=127.0.0.1:$PORT --html=on --start-child="lsnes --lua=$SCRIPT_DIR/neat-donk.lua" --exit-with-child=yes --start-new-commands=no +while ! nc -z localhost $PORT ; do + sleep 0.1 +done +xdg-open http://127.0.0.1:$PORT