Exemplo n.º 1
0
            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;
                    }
                }
            }