From 322b2bc658e3a0b98c1d26ab09ed0ece70db7053 Mon Sep 17 00:00:00 2001 From: "Randall C. O'Reilly" Date: Fri, 2 Jun 2023 14:48:40 -0700 Subject: [PATCH] got various GPU bugs sorted -- only 1 real bug, in NewStateNeuron -- filed issue #234 --- axon/gpu.go | 62 +++++++++++++++--- axon/gpu_hlsl/gpu_cycleinc.hlsl | 2 +- axon/gpu_hlsl/gpu_cyclepost.hlsl | 4 +- axon/gpu_hlsl/gpu_newstate_neuron.hlsl | 57 ++++++++++++++++ ...u_newstate.hlsl => gpu_newstate_pool.hlsl} | 9 --- axon/layer_compute.go | 13 ++++ axon/network.go | 11 ++-- axon/shaders/gpu_cycleinc.spv | Bin 7404 -> 7404 bytes axon/shaders/gpu_cyclepost.spv | Bin 229140 -> 229140 bytes axon/shaders/gpu_newstate.spv | Bin 48820 -> 0 bytes axon/shaders/gpu_newstate_neuron.spv | Bin 0 -> 36516 bytes axon/shaders/gpu_newstate_pool.spv | Bin 0 -> 37216 bytes examples/boa/approach_env.go | 2 +- examples/boa/boa.go | 28 ++++++-- 14 files changed, 157 insertions(+), 31 deletions(-) create mode 100644 axon/gpu_hlsl/gpu_newstate_neuron.hlsl rename axon/gpu_hlsl/{gpu_newstate.hlsl => gpu_newstate_pool.hlsl} (89%) delete mode 100644 axon/shaders/gpu_newstate.spv create mode 100644 axon/shaders/gpu_newstate_neuron.spv create mode 100644 axon/shaders/gpu_newstate_pool.spv diff --git a/axon/gpu.go b/axon/gpu.go index 2a0d53ebe..f91431519 100644 --- a/axon/gpu.go +++ b/axon/gpu.go @@ -203,7 +203,8 @@ func (gp *GPU) Config(ctx *Context, net *Network) { gp.Sys.NewComputePipelineEmbed("SynCa", content, "shaders/gpu_synca.spv") gp.Sys.NewComputePipelineEmbed("CyclePost", content, "shaders/gpu_cyclepost.spv") - gp.Sys.NewComputePipelineEmbed("NewState", content, "shaders/gpu_newstate.spv") + gp.Sys.NewComputePipelineEmbed("NewStatePool", content, "shaders/gpu_newstate_pool.spv") + gp.Sys.NewComputePipelineEmbed("NewStateNeuron", content, "shaders/gpu_newstate_neuron.spv") gp.Sys.NewComputePipelineEmbed("MinusPool", content, "shaders/gpu_minuspool.spv") gp.Sys.NewComputePipelineEmbed("MinusNeuron", content, "shaders/gpu_minusneuron.spv") gp.Sys.NewComputePipelineEmbed("PlusStart", content, "shaders/gpu_plusstart.spv") @@ -216,6 +217,7 @@ func (gp *GPU) Config(ctx *Context, net *Network) { gp.Sys.NewComputePipelineEmbed("ApplyExts", content, "shaders/gpu_applyext.spv") gp.Sys.NewEvent("MemCopyTo") + gp.Sys.NewEvent("MemCopyTo2") gp.Sys.NewEvent("MemCopyFm") gp.Sys.NewEvent("CycleEnd") gp.Sys.NewEvent("CycleInc") @@ -460,6 +462,19 @@ func (gp *GPU) SyncStateToGPU() { gp.SyncMemToGPU() } +// SyncStateGBufToGPU copies LayVals, Pools, Neurons, GBuf state to GPU +// this is typically sufficient for most syncing -- +// only missing the Synapses which must be copied separately. +// Calls SyncMemToGPU -- use when this is the only copy taking place. +func (gp *GPU) SyncStateGBufToGPU() { + if !gp.On { + return + } + gp.CopyStateToStaging() + gp.CopyGBufToStaging() + gp.SyncMemToGPU() +} + // SyncAllToGPU copies LayerVals, Pools, Neurons, Synapses to GPU. // Calls SyncMemToGPU -- use when this is the only copy taking place. func (gp *GPU) SyncAllToGPU() { @@ -497,10 +512,8 @@ func (gp *GPU) SyncSynapsesToGPU() { gp.SyncMemToGPU() } -// SyncGBufToGPU copies the GBuf and GSyns memory to the GPU. -// This is a temporary measure to be replaced with a simple kernel to init gbuf, -// needed for InitActs. -func (gp *GPU) SyncGBufToGPU() { +// CopyGBufToStaging copies the GBuf and GSyns memory to staging. +func (gp *GPU) CopyGBufToStaging() { if !gp.On { return } @@ -508,6 +521,14 @@ func (gp *GPU) SyncGBufToGPU() { gbv.CopyFromBytes(unsafe.Pointer(&gp.Net.PrjnGBuf[0])) _, gsv, _ := gp.Syns.ValByIdxTry("GSyns", 0) gsv.CopyFromBytes(unsafe.Pointer(&gp.Net.PrjnGSyns[0])) +} + +// SyncGBufToGPU copies the GBuf and GSyns memory to the GPU. +func (gp *GPU) SyncGBufToGPU() { + if !gp.On { + return + } + gp.CopyGBufToStaging() gp.SyncMemToGPU() } @@ -816,8 +837,8 @@ func (gp *GPU) RunApplyExtsCmd() vk.CommandBuffer { glr := gp.SyncRegionStruct("Globals") gp.StartRunCmd(cmd) gp.Sys.ComputeCmdCopyToGPUCmd(cmd, exr, cxr, glr) - gp.Sys.ComputeSetEventCmd(cmd, "MemCopyTo") - gp.RunPipelineCmd(cmd, "ApplyExts", neurDataN, "MemCopyTo", "") + gp.Sys.ComputeSetEventCmd(cmd, "MemCopyTo2") + gp.RunPipelineCmd(cmd, "ApplyExts", neurDataN, "MemCopyTo2", "") gp.Sys.ComputeCmdEndCmd(cmd) return cmd } @@ -1005,8 +1026,33 @@ func (gp *GPU) RunCycleSeparateFuns() { // ThetaCycle trial. // The caller must check the On flag before running this, to use CPU vs. GPU func (gp *GPU) RunNewState() { + // todo: we're not actually calling this now, due to bug in NewStateNeuron + cmd := gp.RunNewStateCmd() + gnm := "GPU:NewState" + gp.Net.FunTimerStart(gnm) + gp.Sys.ComputeSubmitWaitCmd(cmd) + gp.Net.FunTimerStop(gnm) +} + +// RunNewStateCmd returns the commands to +// run the NewState shader to update variables +// at the start of a new trial. +func (gp *GPU) RunNewStateCmd() vk.CommandBuffer { + cnm := "RunNewState" + cmd, err := gp.Sys.CmdBuffByNameTry(cnm) + if err == nil { + return cmd + } + cmd = gp.Sys.NewCmdBuff(cnm) + + neurDataN := int(gp.Net.NNeurons) * int(gp.Net.MaxData) poolDataN := len(gp.Net.Pools) - gp.RunPipelineWait("NewState", poolDataN) + + gp.StartRunCmd(cmd) + gp.RunPipelineCmd(cmd, "NewStatePool", poolDataN, "", "PoolGi") + gp.RunPipelineCmd(cmd, "NewStateNeuron", neurDataN, "PoolGi", "") // todo: this has NrnV read = 0 bug + gp.Sys.ComputeCmdEndCmd(cmd) + return cmd } // RunMinusPhase runs the MinusPhase shader to update snapshot variables diff --git a/axon/gpu_hlsl/gpu_cycleinc.hlsl b/axon/gpu_hlsl/gpu_cycleinc.hlsl index 17f2fc835..daaed225e 100644 --- a/axon/gpu_hlsl/gpu_cycleinc.hlsl +++ b/axon/gpu_hlsl/gpu_cycleinc.hlsl @@ -27,7 +27,7 @@ // Set 2: main network structs and vals -- all are writable [[vk::binding(0, 2)]] RWStructuredBuffer Ctx; // [0] -[numthreads(1, 1, 1)] +[numthreads(64, 1, 1)] void main(uint3 idx : SV_DispatchThreadID) { // over Context if(idx.x == 0) { Ctx[0].CycleInc(); diff --git a/axon/gpu_hlsl/gpu_cyclepost.hlsl b/axon/gpu_hlsl/gpu_cyclepost.hlsl index ea1a3bade..af652927a 100644 --- a/axon/gpu_hlsl/gpu_cyclepost.hlsl +++ b/axon/gpu_hlsl/gpu_cyclepost.hlsl @@ -98,8 +98,8 @@ void CyclePost(inout Context ctx, in LayerParams ly, int li, uint di) { CyclePost2(ctx, ly, uint(li), di, LayVals[ly.Idxs.ValsIdx(di)], Pools[ly.Idxs.PoolIdx(0, di)]); } -[numthreads(1, 1, 1)] -void main(uint3 idx : SV_DispatchThreadID) { // todo: iterate over global Data parallel +[numthreads(64, 1, 1)] +void main(uint3 idx : SV_DispatchThreadID) { if (idx.x >= Ctx[0].NetIdxs.NData) { return; } diff --git a/axon/gpu_hlsl/gpu_newstate_neuron.hlsl b/axon/gpu_hlsl/gpu_newstate_neuron.hlsl new file mode 100644 index 000000000..c1cefd4f9 --- /dev/null +++ b/axon/gpu_hlsl/gpu_newstate_neuron.hlsl @@ -0,0 +1,57 @@ +// Copyright (c) 2022, The Emergent Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +// does NewState Update on each Neuron +// note: anything *reading from neuron level must be called at neuron level! + +#include "synmem.hlsl" + +// note: all must be visible always because accessor methods refer to them +[[vk::binding(0, 1)]] StructuredBuffer NeuronIxs; // [Neurons][Idxs] +[[vk::binding(1, 1)]] StructuredBuffer SynapseIxs; // [Layer][SendPrjns][SendNeurons][Syns] +[[vk::binding(1, 2)]] RWStructuredBuffer Neurons; // [Neurons][Vars][Data] +[[vk::binding(2, 2)]] RWStructuredBuffer NeuronAvgs; // [Neurons][Vars] +[[vk::binding(5, 2)]] RWStructuredBuffer Globals; // [NGlobals] +[[vk::binding(0, 3)]] RWStructuredBuffer Synapses; // [Layer][SendPrjns][SendNeurons][Syns] +[[vk::binding(1, 3)]] RWStructuredBuffer SynapseCas; // [Layer][SendPrjns][SendNeurons][Syns][Data] + +#include "context.hlsl" +#include "layerparams.hlsl" + +// note: binding is var, set + +// Set 0: uniform layer params -- could not have prjns also be uniform.. +[[vk::binding(0, 0)]] StructuredBuffer Layers; // [Layer] + +// Set 1: effectively uniform prjn params as structured buffers in storage + +// Set 2: main network structs and vals -- all are writable +[[vk::binding(0, 2)]] StructuredBuffer Ctx; // [0] +[[vk::binding(3, 2)]] RWStructuredBuffer Pools; // [Layer][Pools][Data] +[[vk::binding(4, 2)]] RWStructuredBuffer LayVals; // [Layer][Data] + + +void NewStateNeuron2(in Context ctx, in LayerParams ly, uint ni, uint di) { + ly.NewStateNeuron(ctx, ni, di, LayVals[ly.Idxs.ValsIdx(di)]); +} + +void NewStateNeuron(in Context ctx, uint ni, uint di) { + uint li = NrnI(ctx, ni, NrnLayIdx); + NewStateNeuron2(ctx, Layers[li], ni, di); +} + +[numthreads(64, 1, 1)] +void main(uint3 idx : SV_DispatchThreadID) { // over Neurons * Data + uint ni = Ctx[0].NetIdxs.ItemIdx(idx.x); + if (!Ctx[0].NetIdxs.NeurIdxIsValid(ni)) { + return; + } + uint di = Ctx[0].NetIdxs.DataIdx(idx.x); + if (!Ctx[0].NetIdxs.DataIdxIsValid(di)) { + return; + } + NewStateNeuron(Ctx[0], ni, di); +} + + diff --git a/axon/gpu_hlsl/gpu_newstate.hlsl b/axon/gpu_hlsl/gpu_newstate_pool.hlsl similarity index 89% rename from axon/gpu_hlsl/gpu_newstate.hlsl rename to axon/gpu_hlsl/gpu_newstate_pool.hlsl index e2cdd4357..972f0fc8e 100644 --- a/axon/gpu_hlsl/gpu_newstate.hlsl +++ b/axon/gpu_hlsl/gpu_newstate_pool.hlsl @@ -49,24 +49,15 @@ void InitPrjnGBuffs(in Context ctx, in PrjnParams pj) { } } -void NewStateNeuron(in Context ctx, in LayerParams ly, uint ni, uint di, in LayerVals vals) { - ly.NewStateNeuron(ctx, ni, di, vals); -} - void NewState2(in Context ctx, in LayerParams ly, uint di, inout Pool pl, inout LayerVals vals) { ly.NewStatePool(ctx, pl); if (pl.IsLayPool == 0) { return; } ly.NewStateLayer(ctx, pl, vals); - for (uint lni = pl.StIdx; lni < pl.EdIdx; lni++) { - NewStateNeuron(ctx, ly, lni + ly.Idxs.NeurSt, di, vals); - } - // if (ly.Act.Decay.Glong != 0) { // clear pipeline of incoming spikes, assuming time has passed for (uint pi = 0; pi < ly.Idxs.RecvN; pi++) { InitPrjnGBuffs(ctx, Prjns[ly.Idxs.RecvSt + pi]); } - // } } void NewState(in Context ctx, uint di, inout Pool pl) { diff --git a/axon/layer_compute.go b/axon/layer_compute.go index 0df7e897f..bd9815f51 100644 --- a/axon/layer_compute.go +++ b/axon/layer_compute.go @@ -318,6 +318,19 @@ func (ly *Layer) NewState(ctx *Context) { ly.InitPrjnGBuffs(ctx) } +// NewStateNeurons only calls the neurons part of new state -- for misbehaving GPU +func (ly *Layer) NewStateNeurons(ctx *Context) { + nn := ly.NNeurons + for di := uint32(0); di < ctx.NetIdxs.NData; di++ { + vals := ly.LayerVals(di) + for lni := uint32(0); lni < nn; lni++ { + ni := ly.NeurStIdx + lni + // note: this calls the basic neuron-level DecayState + ly.Params.NewStateNeuron(ctx, ni, di, vals) + } + } +} + // DecayState decays activation state by given proportion // (default decay values are ly.Params.Acts.Decay.Act, Glong) func (ly *Layer) DecayState(ctx *Context, di uint32, decay, glong, ahp float32) { diff --git a/axon/network.go b/axon/network.go index 7ebba0ac6..d22fd5f3b 100644 --- a/axon/network.go +++ b/axon/network.go @@ -86,16 +86,19 @@ func (nt *Network) UpdateParams() { // properly prior to calling this and subsequent Cycle methods. func (nt *Network) NewState(ctx *Context) { nt.NData = ctx.NetIdxs.NData - if nt.GPU.On { - nt.GPU.RunNewState() - return - } + // if nt.GPU.On { // todo: this has a bug in neuron-level access in updating SpkPrv + // nt.GPU.RunNewState() + // return + // } for _, ly := range nt.Layers { if ly.IsOff() { continue } ly.NewState(ctx) } + if nt.GPU.On { + nt.GPU.SyncStateGBufToGPU() + } } // Cycle runs one cycle of activation updating using threading methods. diff --git a/axon/shaders/gpu_cycleinc.spv b/axon/shaders/gpu_cycleinc.spv index 43fdb6a2f4564ed4926d07b51caf141381fd78b2..17c0c0c1a1c7d76ccc2a568a2299b6b7e9bdf0da 100644 GIT binary patch delta 12 TcmaE3`NndB52M3I-}y2CC8q@; delta 12 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%0D_ita{vGU diff --git a/axon/shaders/gpu_newstate_neuron.spv b/axon/shaders/gpu_newstate_neuron.spv new file mode 100644 index 0000000000000000000000000000000000000000..e79ad3d0f56352db05590f054c1f82c8c413cd37 GIT binary patch literal 36516 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 Q`lsa!f3DwFgqzg=7bJnVQUCw| literal 0 HcmV?d00001 diff --git a/axon/shaders/gpu_newstate_pool.spv b/axon/shaders/gpu_newstate_pool.spv new file mode 100644 index 0000000000000000000000000000000000000000..e5f5a2023e3e25f081f448a8deddd157262395f1 GIT binary patch literal 37216 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 Mw|40r^sd(b1tSq3c>n+a literal 0 HcmV?d00001 diff --git a/examples/boa/approach_env.go b/examples/boa/approach_env.go index 739de8cf4..90f2c9d23 100644 --- a/examples/boa/approach_env.go +++ b/examples/boa/approach_env.go @@ -81,7 +81,7 @@ func (ev *Approach) Defaults() { // Config configures the world func (ev *Approach) Config() { - // ev.Rand.NewRand(ev.RndSeed) + ev.Rand.NewRand(ev.RndSeed) ev.CSTot = ev.NDrives * ev.CSPerDrive ev.ActMap = make(map[string]int) for i, act := range ev.Acts { diff --git a/examples/boa/boa.go b/examples/boa/boa.go index 8de7511f7..0fa7b4461 100644 --- a/examples/boa/boa.go +++ b/examples/boa/boa.go @@ -74,9 +74,9 @@ type SimParams struct { // Defaults sets default params func (ss *SimParams) Defaults() { ss.NData = 1 - ss.EnvSameSeed = false + ss.EnvSameSeed = false // set to true to test ndata ss.PctCortexMax = 1.0 - ss.PctCortexStEpc = 5 + ss.PctCortexStEpc = 10 ss.PctCortexNEpc = 5 ss.PctCortexInterval = 1 ss.PCAInterval = 10 @@ -329,6 +329,7 @@ func (ss *Sim) ConfigNet(net *axon.Network) { return } net.Defaults() + net.SetNThreads(4) ss.Params.SetObject("Network") ss.InitWts(net) } @@ -480,6 +481,14 @@ func (ss *Sim) ConfigLoops() { } else { axon.LooperUpdtNetView(man, &ss.ViewUpdt, ss.Net) axon.LooperUpdtPlots(man, &ss.GUI) + for _, m := range man.Stacks { + m.Loops[etime.Cycle].OnEnd.Prepend("GUI:CounterUpdt", func() { + ss.NetViewCounters() + }) + m.Loops[etime.Trial].OnEnd.Prepend("GUI:CounterUpdt", func() { + ss.NetViewCounters() + }) + } } if Debug { @@ -693,10 +702,16 @@ func (ss *Sim) StatCounters(di int) { ss.Stats.SetFloat32("CS", float32(ev.CS)) ss.Stats.SetFloat32("US", float32(ev.US)) ss.Stats.SetFloat32("HasRew", axon.GlbV(ctx, uint32(di), axon.GvHasRew)) - ss.Stats.SetString("TrialName", "trl") - if di == 0 { - ss.ViewUpdt.Text = ss.Stats.Print([]string{"Run", "Epoch", "Trial", "Cycle", "NetAction", "Instinct", "ActAction", "ActMatch", "JustGated", "Should", "Rew"}) + ss.Stats.SetString("TrialName", "trl") // todo: could have dist, US etc +} + +func (ss *Sim) NetViewCounters() { + if ss.GUI.ViewUpdt.View == nil { + return } + di := ss.GUI.ViewUpdt.View.Di + ss.StatCounters(di) + ss.ViewUpdt.Text = ss.Stats.Print([]string{"Run", "Epoch", "Trial", "Cycle", "NetAction", "Instinct", "ActAction", "ActMatch", "JustGated", "Should", "Rew"}) } // TrialStats computes the trial-level statistics. @@ -997,7 +1012,8 @@ func (ss *Sim) Log(mode etime.Modes, time etime.Times) { switch { case time == etime.Cycle: - row = ss.Stats.Int("Cycle") + return /// not doing cycle-level logging -- too slow for gpu in general + // row = ss.Stats.Int("Cycle") case time == etime.Trial: if mode == etime.Train { trl := ss.Loops.GetLoop(mode, etime.Trial).Counter.Cur