Sort species by number of genomes to speed up parallelization. Add

constant ID to species.
This commit is contained in:
Empathic Qubit 2021-04-24 01:18:06 -04:00
parent 16a5aab443
commit bdc3ccaad7
5 changed files with 42 additions and 25 deletions

View file

@ -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,

View file

@ -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"))

View file

@ -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()

View file

@ -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

View file

@ -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