private T InitRR <T>(T rr, MyMemoryBlock <float> targetMemBlock, MyMemoryBlock <float> targetDepthMemBlock, Action <T> initializer = null) where T : class, IRenderRequestBase { if (initializer != null) { initializer.Invoke(rr); } rr.FlipYAxis = true; targetMemBlock.ExternalPointer = 0; // first reset ExternalPointer // Setup image copying from RR through Cpu if (Owner.CopyDataThroughCPU) { ImageSettings imageSettings = new ImageSettings(RenderRequestImageCopyingMode.Cpu) { CopyDepth = Owner.CopyDepthData && targetDepthMemBlock != null, }; imageSettings.OnSceneBufferPrepared += (request, data, depthData) => { int width = rr.Resolution.Width; int stride = width * sizeof(uint); int lines = data.Length / width; for (int i = 0; i < lines; ++i) { Buffer.BlockCopy(data, i * stride, targetMemBlock.Host, i * width * sizeof(uint), stride); } if (imageSettings.CopyDepth) { for (int i = 0; i < lines; ++i) { Buffer.BlockCopy(depthData, i * stride, targetDepthMemBlock.Host, i * width * sizeof(float), stride); } } // targetMemBlock.SafeCopyToDevice(); this needs to be called on the BrainSim thread // targetDepthMemBlock.SafeCopyToDevice(); this needs to be called on the BrainSim thread }; rr.Image = imageSettings; return(rr); } // Setup image copying from RR through Pbo ImageSettings image = new ImageSettings(RenderRequestImageCopyingMode.OpenglPbo) { CopyDepth = Owner.CopyDepthData && targetDepthMemBlock != null, }; // Setup data copying to our unmanaged memblocks uint renderTextureHandle = 0; uint depthRenderTextureHandle = 0; CudaOpenGLBufferInteropResource renderResource = null; CudaOpenGLBufferInteropResource depthRenderResource = null; image.OnPreRenderingEvent += (sender, vbo, depthVbo) => { if (renderResource != null && renderResource.IsMapped) { renderResource.UnMap(); } if (image.CopyDepth) { if (depthRenderResource != null && depthRenderResource.IsMapped) { depthRenderResource.UnMap(); } } }; image.OnPostRenderingEvent += (sender, vbo, depthVbo) => { // Vbo can be allocated during drawing, create the resource after that (post-rendering) MyKernelFactory.Instance.GetContextByGPU(Owner.GPU).SetCurrent(); // Fill color memblock if (renderResource == null || vbo != renderTextureHandle) { if (renderResource != null) { renderResource.Dispose(); } renderTextureHandle = vbo; try { renderResource = new CudaOpenGLBufferInteropResource(renderTextureHandle, image.CopyDepth ? CUGraphicsRegisterFlags.None : CUGraphicsRegisterFlags.ReadOnly); // Read only by CUDA } catch (Exception e) { MyLog.ERROR.WriteLine("calling CudaOpenGLBufferInteropResource returns " + e + ". Go to World properties and in Runtime section set Copy data through CPU to True"); throw e; } } renderResource.Map(); targetMemBlock.ExternalPointer = renderResource.GetMappedPointer <uint>().DevicePointer.Pointer; targetMemBlock.FreeDevice(); targetMemBlock.AllocateDevice(); // Fill depth memblock if (image.CopyDepth) { if (depthRenderResource == null || depthVbo != depthRenderTextureHandle) { if (depthRenderResource != null) { depthRenderResource.Dispose(); } depthRenderTextureHandle = depthVbo; depthRenderResource = new CudaOpenGLBufferInteropResource( depthRenderTextureHandle, CUGraphicsRegisterFlags.ReadOnly); // Read only by CUDA } depthRenderResource.Map(); targetDepthMemBlock.ExternalPointer = depthRenderResource.GetMappedPointer <float>().DevicePointer.Pointer; targetDepthMemBlock.FreeDevice(); targetDepthMemBlock.AllocateDevice(); } }; rr.Image = image; // Initialize the target memory block // Use a dummy number that will get replaced on first Execute call to suppress MemBlock error during init targetMemBlock.ExternalPointer = 1; if (targetDepthMemBlock != null) { targetDepthMemBlock.ExternalPointer = 1; } return(rr); }
// Sets up the genetic task public override void Init(int nGPU) { currentGen = 0; m_weights = 0; // Load the relevant kernels m_coeffGenKernel = MyKernelFactory.Instance.Kernel(nGPU, @"Genetic\CosyneGenetics", "generateCoefficients"); m_geneticKernel = MyKernelFactory.Instance.Kernel(nGPU, @"Genetic\CosyneGenetics", "grow"); m_extractKernel = MyKernelFactory.Instance.Kernel(nGPU, @"Genetic\CosyneGenetics", "extractCoeffs"); m_cosineGenKernel = MyKernelFactory.Instance.Kernel(nGPU, @"Genetic\CosyneGenetics", "createCosineMatrix"); m_implantKernel = MyKernelFactory.Instance.Kernel(nGPU, @"Genetic\CosyneGenetics", "implantCoeffs"); // Init the random generator m_rand = new Random(); // Set up coefficient Generation m_coeffGenKernel.SetupExecution(Owner.PopulationSize); // Set up genetic recombination m_geneticKernel.SetupExecution(Owner.PopulationSize); // This finds the first nn group in the network. Possibility of getting a list of networks and evolving them all seperately? List<MyNode> ch = Owner.Owner.Network.Children; foreach (MyNode n in ch) { if (n is MyNeuralNetworkGroup) { nn = n as MyNeuralNetworkGroup; MyLog.INFO.WriteLine("Evolving the layers of node: " + nn.Name); break; } } if (nn == null) { throw new NullReferenceException("There is no top level NeuralNetworkGroup."); } // Construct the layerlist which is to be read from and written to constructLayerList(nn); // This is how big the weight matrix will be arr_size = (int)Math.Ceiling(Math.Sqrt(m_weights)); // Get the relevant execution plan m_executionPlan = Owner.Owner.SimulationHandler.Simulation.ExecutionPlan[0]; #region MemoryBlocks // Initialise the population population = new List<MyMemoryBlock<float>>(); outputPop = new List<MyMemoryBlock<float>>(); for (int i = 0; i < Owner.PopulationSize; i++) { population.Add(new MyMemoryBlock<float>()); population[i].Owner = Owner; population[i].Count = arr_size * arr_size; population[i].AllocateMemory(); outputPop.Add(new MyMemoryBlock<float>()); outputPop[i].Owner = Owner; outputPop[i].Count = arr_size * arr_size; outputPop[i].AllocateMemory(); } // Allocate space to manipulate weight matrices on the device cudaMatrices = new MyMemoryBlock<float>(); cudaMatrices.Owner = Owner; cudaMatrices.Count = arr_size * arr_size * Owner.PopulationSize; cudaMatrices.AllocateDevice(); // Allocate a memory block for the Cosine matrix multiplier = new MyMemoryBlock<float>(); multiplier.Owner = Owner; multiplier.Count = arr_size * arr_size; multiplier.AllocateDevice(); // Fill the cosine Matrices m_cosineGenKernel.SetupExecution(arr_size); m_cosineGenKernel.Run(multiplier, arr_size); // Allocate space needed for chromosomes chromosomePop = new MyMemoryBlock<float>(); chromosomePop.Owner = Owner; if (DirectEvolution) chromosomePop.Count = m_weights * Owner.PopulationSize; else chromosomePop.Count = CoefficientsSaved * Owner.PopulationSize; chromosomePop.AllocateMemory(); // Allocate some space for noise to seed the cuda_rand generator noise = new MyMemoryBlock<float>(); noise.Owner = Owner; noise.Count = Owner.PopulationSize; noise.AllocateMemory(); // Write some noise to the initial array for (int i = 0; i < Owner.PopulationSize; i++) { noise.Host[i] = (float)m_rand.NextDouble() * 100000 + (float)m_rand.NextDouble() * 40; } noise.SafeCopyToDevice(); // Allocate space for the fitnesses fitnesses = new MyMemoryBlock<float>(); fitnesses.Owner = Owner; fitnesses.Count = Owner.PopulationSize; fitnesses.AllocateMemory(); // Allocate some temporary storage tempMB = new MyMemoryBlock<float>(); tempPop = new MyMemoryBlock<float>(); tempMB.Owner = Owner; tempMB.Count = CoefficientsSaved; tempMB.AllocateDevice(); tempPop.Owner = Owner; tempPop.Count = arr_size * arr_size; tempPop.AllocateDevice(); marking = new MyMemoryBlock<int>(); marking.Owner = Owner; marking.Count = CoefficientsSaved * Owner.PopulationSize; marking.AllocateDevice(); #endregion // Check saved Coeffs size if (CoefficientsSaved > m_weights) { MyLog.WARNING.Write("Saving more Coefficients than exist in the weight matrix. Setting to max permissable value\n"); CoefficientsSaved = m_weights; } if (CoefficientsSaved == m_weights) { MyLog.INFO.Write("Saving a coefficient for every weight. Evolving weights directly\n"); DirectEvolution = true; } if (DirectEvolution) CoefficientsSaved = m_weights; // Generate the rest of the population if (DirectEvolution) m_coeffGenKernel.Run(chromosomePop, CoefficientsSaved, noise, Owner.PopulationSize, WeightMagnitude); else m_coeffGenKernel.Run(chromosomePop, CoefficientsSaved, noise, Owner.PopulationSize, Alpha); //Disable Backprop tasks in Network if (nn.GetActiveBackpropTask() != null) { if (!nn.GetActiveBackpropTask().DisableLearning) { MyLog.WARNING.WriteLine("Disabling backprop learning for Neural Network"); nn.GetActiveBackpropTask().DisableLearning = true; } } }
// Sets up the genetic task public override void Init(int nGPU) { currentGen = 0; m_weights = 0; // Load the relevant kernels m_coeffGenKernel = MyKernelFactory.Instance.Kernel(nGPU, @"Genetic\CosyneGenetics", "generateCoefficients"); m_geneticKernel = MyKernelFactory.Instance.Kernel(nGPU, @"Genetic\CosyneGenetics", "grow"); m_extractKernel = MyKernelFactory.Instance.Kernel(nGPU, @"Genetic\CosyneGenetics", "extractCoeffs"); m_cosineGenKernel = MyKernelFactory.Instance.Kernel(nGPU, @"Genetic\CosyneGenetics", "createCosineMatrix"); m_implantKernel = MyKernelFactory.Instance.Kernel(nGPU, @"Genetic\CosyneGenetics", "implantCoeffs"); // Init the random generator m_rand = new Random(); // Set up coefficient Generation m_coeffGenKernel.SetupExecution(Owner.PopulationSize); // Set up genetic recombination m_geneticKernel.SetupExecution(Owner.PopulationSize); // This finds the first nn group in the network. Possibility of getting a list of networks and evolving them all seperately? List <MyNode> ch = Owner.Owner.Network.Children; foreach (MyNode n in ch) { if (n is MyNeuralNetworkGroup) { nn = n as MyNeuralNetworkGroup; MyLog.INFO.WriteLine("Evolving the layers of node: " + nn.Name); break; } } if (nn == null) { throw new NullReferenceException("There is no top level NeuralNetworkGroup."); } // Construct the layerlist which is to be read from and written to constructLayerList(nn); // This is how big the weight matrix will be arr_size = (int)Math.Ceiling(Math.Sqrt(m_weights)); // Get the relevant execution plan m_executionPlan = Owner.Owner.SimulationHandler.Simulation.ExecutionPlan; #region MemoryBlocks // Initialise the population population = new List <MyMemoryBlock <float> >(); outputPop = new List <MyMemoryBlock <float> >(); for (int i = 0; i < Owner.PopulationSize; i++) { population.Add(new MyMemoryBlock <float>()); population[i].Owner = Owner; population[i].Count = arr_size * arr_size; population[i].AllocateMemory(); outputPop.Add(new MyMemoryBlock <float>()); outputPop[i].Owner = Owner; outputPop[i].Count = arr_size * arr_size; outputPop[i].AllocateMemory(); } // Allocate space to manipulate weight matrices on the device cudaMatrices = new MyMemoryBlock <float>(); cudaMatrices.Owner = Owner; cudaMatrices.Count = arr_size * arr_size * Owner.PopulationSize; cudaMatrices.AllocateDevice(); // Allocate a memory block for the Cosine matrix multiplier = new MyMemoryBlock <float>(); multiplier.Owner = Owner; multiplier.Count = arr_size * arr_size; multiplier.AllocateDevice(); // Fill the cosine Matrices m_cosineGenKernel.SetupExecution(arr_size); m_cosineGenKernel.Run(multiplier, arr_size); // Allocate space needed for chromosomes chromosomePop = new MyMemoryBlock <float>(); chromosomePop.Owner = Owner; if (DirectEvolution) { chromosomePop.Count = m_weights * Owner.PopulationSize; } else { chromosomePop.Count = CoefficientsSaved * Owner.PopulationSize; } chromosomePop.AllocateMemory(); // Allocate some space for noise to seed the cuda_rand generator noise = new MyMemoryBlock <float>(); noise.Owner = Owner; noise.Count = Owner.PopulationSize; noise.AllocateMemory(); // Write some noise to the initial array for (int i = 0; i < Owner.PopulationSize; i++) { noise.Host[i] = (float)m_rand.NextDouble() * 100000 + (float)m_rand.NextDouble() * 40; } noise.SafeCopyToDevice(); // Allocate space for the fitnesses fitnesses = new MyMemoryBlock <float>(); fitnesses.Owner = Owner; fitnesses.Count = Owner.PopulationSize; fitnesses.AllocateMemory(); // Allocate some temporary storage tempMB = new MyMemoryBlock <float>(); tempPop = new MyMemoryBlock <float>(); tempMB.Owner = Owner; tempMB.Count = CoefficientsSaved; tempMB.AllocateDevice(); tempPop.Owner = Owner; tempPop.Count = arr_size * arr_size; tempPop.AllocateDevice(); marking = new MyMemoryBlock <int>(); marking.Owner = Owner; marking.Count = CoefficientsSaved * Owner.PopulationSize; marking.AllocateDevice(); #endregion // Check saved Coeffs size if (CoefficientsSaved > m_weights) { MyLog.WARNING.Write("Saving more Coefficients than exist in the weight matrix. Setting to max permissable value\n"); CoefficientsSaved = m_weights; } if (CoefficientsSaved == m_weights) { MyLog.INFO.Write("Saving a coefficient for every weight. Evolving weights directly\n"); DirectEvolution = true; } if (DirectEvolution) { CoefficientsSaved = m_weights; } // Generate the rest of the population if (DirectEvolution) { m_coeffGenKernel.Run(chromosomePop, CoefficientsSaved, noise, Owner.PopulationSize, WeightMagnitude); } else { m_coeffGenKernel.Run(chromosomePop, CoefficientsSaved, noise, Owner.PopulationSize, Alpha); } //Disable Backprop tasks in Network if (nn.GetActiveBackpropTask() != null) { if (!nn.GetActiveBackpropTask().DisableLearning) { MyLog.WARNING.WriteLine("Disabling backprop learning for Neural Network"); nn.GetActiveBackpropTask().DisableLearning = true; } } }