示例#1
0
        private void OnApplicationQuit()
        {
            // static buffers can't be cleared in ondisable or something,
            // because lots of objects might be using them
            m_isEnabled = false;

            m_meshSamplesBuffer?.Dispose();
            m_meshPackedUVsBuffer?.Dispose();
        }
示例#2
0
        void OnDisable()
        {
            faceManager.facesChanged -= OnFaceChanged;

            positionBuffer?.Dispose();
            normalBuffer?.Dispose();

            positionTextureRW?.Release();
            normalTextureRW?.Release();
        }
示例#3
0
 void Resize()
 {
     buffer_?.Dispose();
     if (count_ == 0)
     {
         throw new System.InvalidOperationException(
                   string.Format("Error resizing {0}, the size is 0", name_.ToString().ToUpper()));
     }
     buffer_ = new ComputeBuffer(count_, stride_);
 }
示例#4
0
        private void UpdateVoxelDataBuffer()
        {
            _voxelDataBuffer?.Dispose();

            if (_coordData.Count == 0)
            {
                return;
            }

            _voxelDataBuffer = new ComputeBuffer(_coordData.Count, VoxelData.Size);
            _voxelDataBuffer.SetData(_coordData);
        }
示例#5
0
    public void SetData <T> (Nullable <NativeArray <T> > items, int count, Nullable <SimData.SimFrame> simFrame) where T : struct
    {
        numParticles = count;
        if (items.HasValue)
        {
            int bufferSize = particleBuffer != null ? particleBuffer.count : 1;
            while (bufferSize < items.Value.Length)
            {
                bufferSize *= 2;
            }
            // Grow the bufeer if necessary
            if (bufferSize != particleBuffer?.count)
            {
                particleBuffer?.Dispose();
                particleBuffer = new ComputeBuffer(count, Marshal.SizeOf(typeof(T)));
            }
            particleBuffer.SetData(items.Value);

            if (filterParticles != null)
            {
                System.Diagnostics.Stopwatch sw = new System.Diagnostics.Stopwatch();
                sw.Start();

                // TODO: dynamically grow/clear instead of re-creating
                StartCoroutine(ClearBuffers(filteredBuffers, filteredBufferArgs));
                filteredBuffers    = new Dictionary <int, ComputeBuffer>();
                filteredBufferArgs = new Dictionary <int, ComputeBuffer>();

                var typeId = 110;
                var buffer = new ComputeBuffer(bufferSize, Marshal.SizeOf(typeof(T)), ComputeBufferType.Append);
                buffer.SetCounterValue(0);
                var argBuffer = new ComputeBuffer(5, sizeof(int), ComputeBufferType.IndirectArguments);
                filterParticles.SetBuffer(0, "particles", particleBuffer);
                filterParticles.SetBuffer(0, "filteredParticles", buffer);
                filterParticles.SetInt("type", typeId);
                filterParticles.SetInt("count", items.Value.Length);
                filterParticles.Dispatch(0, bufferSize / 8, 1, 1);
                int[] args = new int[] { 0, 1, 0, 0, 0 };
                argBuffer.SetData(args);
                ComputeBuffer.CopyCount(buffer, argBuffer, 0);
                argBuffer.GetData(args);
                //Debug.Log(string.Format("Filtered {0} particles of type {1}", args[0], typeId));
                args[1] = args[0];
                argBuffer.SetData(args);
                filteredBuffers.Add(typeId, buffer);
                filteredBufferArgs.Add(typeId, argBuffer);

                sw.Stop();
                //Debug.Log("Filtered particles in " + ((double)sw.ElapsedTicks / System.Diagnostics.Stopwatch.Frequency) + "s");
            }
        }
        frame = simFrame;
    }
示例#6
0
    public void Setup()
    {
        Init();
        m_Texture        = Tools.CreateTexture(m_TextureSize);
        m_Output.texture = m_Texture;
        m_Output.SetNativeSize();

        SetTexture("Result", m_Texture);

        m_DispatchArgs?.Dispose();
        m_DispatchArgs = new ComputeBuffer(3, sizeof(float), ComputeBufferType.IndirectArguments);
        m_DispatchArgs.SetData(new[] { m_TextureSize.x, m_TextureSize.y, 1 });
    }
示例#7
0
        private void OnDisable()
        {
#if UNITY_EDITOR
            CompilationPipeline.compilationStarted -= OnCompilationStarted;
            EditorApplication.playModeStateChanged -= OnPlayModeStateChanged;
#endif

            m_isEnabled = false;
            IsReady     = false;

            m_dataBuffer?.Dispose();
            m_settingsBuffer?.Dispose();
        }
示例#8
0
        void Cleanup()
        {
            RenderPipelineManager.beginCameraRendering -= BeginCameraRendering;
            if (_depthCam)
            {
                _depthCam.targetTexture = null;
                SafeDestroy(_depthCam.gameObject);
            }
            if (_depthTex)
            {
                SafeDestroy(_depthTex);
            }

            waveBuffer?.Dispose();
        }
示例#9
0
    protected override void OnDestroyManager()
    {
        meshInstancedArgs.Dispose();
        trailElementBuffer?.Dispose();
        segmentBuffer?.Dispose();

        if (trailElements.IsCreated)
        {
            trailElements.Dispose();
        }
        if (segments.IsCreated)
        {
            segments.Dispose();
        }
    }
示例#10
0
 void OnDestroy()
 {
     ScopeRT?.Release();
     _BufferX.Dispose();
     _ScopeDataBuffer?.Dispose();
     _Initialized = false;
 }
示例#11
0
        void DisposeData()
        {
            if (m_Result.IsCreated)
            {
                m_Result.Dispose();
            }

            if (m_RaycastCommand.IsCreated)
            {
                m_RaycastCommand.Dispose();
            }

            m_Buffer?.Dispose();

            if (m_LidarDetectionData.IsCreated)
            {
                m_LidarDetectionData.Dispose();
            }

            if (m_WorldDetectionData.IsCreated)
            {
                m_WorldDetectionData.Dispose();
            }

            if (m_RayAngles.IsCreated)
            {
                m_RayAngles.Dispose();
            }
        }
    private int[] GetClosestCenterForPixels()
    {
        //Send the data to the compute shader so the GPU can do the hard work
        CellData[]    cellData             = new CellData[generator.cells.Count];
        ComputeBuffer cellDataBuffer       = new ComputeBuffer(generator.cells.Count, sizeof(int) * 2);
        ComputeBuffer cellIdByPixeldBuffer = new ComputeBuffer(resolution.x * resolution.y, sizeof(int));         //This is the buffer we're gonna read from

        for (int i = 0; i < cellData.Length; i++)
        {
            CellCenter c = generator.cells[i];
            cellData[i] = new CellData()
            {
                position = MapGraphCoordToTextureCoords(c.position.x, c.position.y)
            };
        }

        cellDataBuffer.SetData(cellData);
        cellIdByPixeldBuffer.SetData(new int[resolution.x * resolution.y]);         //we pass an empty array, since we just want to retrieve this data
        computeShader.SetBuffer(findClosestCellKernelIndex, "_CellData", cellDataBuffer);
        computeShader.SetBuffer(findClosestCellKernelIndex, "_CellIDByPixel", cellIdByPixeldBuffer);
        computeShader.SetInt("_Resolution", resolution.x);

        computeShader.Dispatch(findClosestCellKernelIndex, resolution.x / 8, resolution.y / 8, 1);

        //Get the result data back from the GPU
        int[] centersIDs = new int[resolution.x * resolution.y];
        cellIdByPixeldBuffer.GetData(centersIDs);

        cellDataBuffer?.Dispose();
        cellIdByPixeldBuffer?.Dispose();

        return(centersIDs);
    }
示例#13
0
 public void Dispose()
 {
     LumaBuffer?.Dispose();
     UBuffer?.Dispose();
     VBuffer?.Dispose();
     RgbaBuffer?.Dispose();
 }
示例#14
0
 public void SetOriginalTexture(Texture tex)
 {
     originalTexture = tex;
     data            = new Int32[originalTexture.height * originalTexture.width / 10];
     buffer?.Dispose();
     buffer = new ComputeBuffer(data.Length, 4);
 }
    private void RefreshBuffer()
    {
        m_objectBuffer?.Dispose();
        m_objectTransformBuffer?.Dispose();

        m_objectBuffer          = new ComputeBuffer(m_objects.Count, SDF_GPU_Data.Stride);
        m_objectTransformBuffer = new ComputeBuffer(m_objects.Count, sizeof(float) * 16);

        Shader.SetGlobalBuffer(SDF_OBJECT_BUFFER_PROPERTY, m_objectBuffer);
        Shader.SetGlobalBuffer(SDF_OBJECT_TRANSFORM_BUFFER_PROPERTY, m_objectTransformBuffer);
        Shader.SetGlobalInt(SDF_OBJECT_COUNT_PROPERTY, m_objects.Count);
        Shader.SetGlobalFloat(SMOOTHING_PROPERTY, m_smoothing);

        UpdateObjectData();
        UpdateTransforms();
    }
    private void ApplyChangesToTexture()
    {
        //Create a new Buffer
        ComputeBuffer shaderBuffer = new ComputeBuffer(resolution.x * resolution.y, sizeof(float) * 4 + sizeof(int) * 2);         //4 because a color has 4 channels, 2 because the position has X and Y

        ColorData[] colorData = new ColorData[resolution.x * resolution.y];

        for (int x = 0; x < resolution.x; x++)
        {
            for (int y = 0; y < resolution.y; y++)
            {
                ColorData data = new ColorData()
                {
                    position = new Vector2Int(x, y),
                    color    = texColors[x, y]
                };

                colorData[x + y * resolution.y] = data;
            }
        }

        shaderBuffer.SetData(colorData);
        computeShader.SetBuffer(buildTextureKernelIndex, "_ColorData", shaderBuffer);
        computeShader.SetInt("_Resolution", resolution.x);

        computeShader.Dispatch(buildTextureKernelIndex, resolution.x / 8, resolution.y / 8, 1);
        shaderBuffer?.Dispose();
    }
示例#17
0
        void OnDisable()
        {
            _preprocessed?.Dispose();
            _preprocessed = null;

            _worker?.Dispose();
            _worker = null;
        }
示例#18
0
        void OnDisable()
        {
            _detector?.Dispose();
            _detector = null;

            _drawArgs?.Dispose();
            _drawArgs = null;
        }
示例#19
0
    void OnDisable()
    {
        _buffer?.Dispose();
        _buffer = null;

        _detector?.Dispose();
        _detector = null;
    }
 public void Dispose()
 {
     networkInputBuffer?.Dispose();
     outputBuffer?.Dispose();
     worldLandmarkBuffer?.Dispose();
     segmentationRT.Release();
     woker?.Dispose();
 }
示例#21
0
 public void Dispose()
 {
     if (m_UseStructuredBuffer)
     {
         m_WorldToLightBuffer?.Dispose();
         m_AtlasUVRectBuffer?.Dispose();
         m_LightTypeBuffer?.Dispose();
     }
 }
示例#22
0
    private void OnDestroy()
    {
        buffer?.Dispose();

        if (maskTexture != null)
        {
            DestroyImmediate(maskTexture);
        }
    }
示例#23
0
        public void Dispose()
        {
            argsBuffer?.Dispose();
            objectPositionsBuffer?.Dispose();
            objectRotationsBuffer?.Dispose();
            textureCoordinatesBuffer?.Dispose();

            count = -1;
        }
示例#24
0
    public void Setup()
    {
        Init();
        m_Texture        = Tools.CreateTexture(m_TextureSize);
        m_Output.texture = m_Texture;
        m_Output.SetNativeSize();

        SetTexture("Result", m_Texture);

        m_DispatchArgs?.Dispose();
        m_DispatchArgs = new ComputeBuffer(3, sizeof(float), ComputeBufferType.IndirectArguments);
        m_DispatchArgs.SetData(new[] { m_TextureSize.x, m_TextureSize.y, 1 });

        m_TargetsData = new Vector4[m_Targets.Length];
        m_TargetsBuffer?.Dispose();
        m_TargetsBuffer = new ComputeBuffer(m_TargetsData.Length, sizeof(float) * 4);
        SetBuffer("data", m_TargetsBuffer);
    }
示例#25
0
        protected virtual void OnDisable()
        {
            Buffer?.Dispose();
            Buffer = null;

#if UNITY_EDITOR
            sceneViewBuffer?.Dispose();
            sceneViewBuffer = null;
#endif
        }
示例#26
0
        public void Dispose()
        {
            worker?.Dispose();
            worker = null;

            preBuffer?.Dispose();
            outputLandmarkBuffer?.Dispose();
            outputLandmarkWorldBuffer?.Dispose();
            segmentRT.Release();
        }
示例#27
0
 private void OnDisable()
 {
     _cmd?.Dispose();
     if (_material != null)
     {
         DestroyImmediate(_material);
         _material = null;
     }
     _volumes?.Dispose();
 }
示例#28
0
 public override void Dispose()
 {
     base.Dispose();
     if (outputTex != null)
     {
         outputTex.Release();
         Object.Destroy(outputTex);
     }
     outputBuffer?.Dispose();
 }
        void DeallocateObjects()
        {
            _preBuffer?.Dispose();
            _preBuffer = null;

            _postBuffer?.Dispose();
            _postBuffer = null;

            _worker?.Dispose();
            _worker = null;
        }
示例#30
0
 void OnDestroy()
 {
     if (_material != null)
     {
         Destroy(_material);
     }
     _xyTable?.Dispose();
     _colorBuffer?.Dispose();
     _depthBuffer?.Dispose();
     _driver?.Dispose();
 }
示例#31
0
        public void Run(ComputeContext context, TextWriter log)
        {
            try
            {
                ComputeCommandQueue commands = new ComputeCommandQueue(context, context.Devices[0], ComputeCommandQueueFlags.None);

                log.WriteLine("Original content:");

                Random rand = new Random();
                int count = 6;
                long[] bufferContent = new long[count];
                for (int i = 0; i < count; i++)
                {
                    bufferContent[i] = (long)(rand.NextDouble() * long.MaxValue);
                    log.WriteLine("\t" + bufferContent[i]);
                }

                ComputeBuffer<long> buffer = new ComputeBuffer<long>(context, ComputeMemoryFlags.CopyHostPointer, bufferContent);
                
                IntPtr mappedPtr = commands.Map(buffer, true, ComputeMemoryMappingFlags.Read, 0, bufferContent.Length, null);

                log.WriteLine("Mapped content:");

                for (int i = 0; i < bufferContent.Length; i++)
                {
                    IntPtr ptr = new IntPtr(mappedPtr.ToInt64() + i * sizeof(long));
                    log.WriteLine("\t" + Marshal.ReadInt64(ptr));
                }

                commands.Unmap(buffer, ref mappedPtr, null);

                // wait for the unmap to happen
                commands.Finish();
                // cleanup buffer
                buffer.Dispose();
                // cleanup commands
                commands.Dispose();
            }
            catch (Exception e)
            {
                log.WriteLine(e.ToString());
            }
        }
示例#32
0
        public void TakeGif(IGifableControl control, Action<string> displayInformation)
        {
            _kernelInUse++;
            var encoder = new AnimatedGifEncoder();
            encoder.Start(Ext.UniqueFilename("sequence", "gif"));
            encoder.SetDelay(1000 / StaticSettings.Fetch.GifFramerate);
            encoder.SetRepeat(0);
            var endIgnoreControl = control.StartIgnoreControl();

            var ccontext = _kernel.ComputeContext;
            var queue = new ComputeCommandQueue(ccontext, ccontext.Devices[0], ComputeCommandQueueFlags.None);
            var screenshotHeight = StaticSettings.Fetch.GifHeight;
            var screenshotWidth = (int)(screenshotHeight * ScreenshotAspectRatio);
            var computeBuffer = new ComputeBuffer<Vector4>(ccontext, ComputeMemoryFlags.ReadWrite, screenshotWidth * screenshotHeight);

            var fdc = control as IFrameDependantControl;
            for (var i = 0; i < StaticSettings.Fetch.GifFramecount + 1; i++)
            {
                if (fdc != null)
                    fdc.Frame = i;
                var teardown = control.SetupGif((double)i / StaticSettings.Fetch.GifFramecount);
                _kernel.Render(computeBuffer, queue, _parameters, new Size(screenshotWidth, screenshotHeight));
                queue.Finish();
                teardown();
            }
            for (var i = 1; i < StaticSettings.Fetch.GifFramecount + 1; i++)
            {
                if (fdc != null)
                    fdc.Frame = i;
                displayInformation(string.Format("{0}% done with gif", (int)(100.0 * (i - 1) / StaticSettings.Fetch.GifFramecount)));
                var teardown = control.SetupGif((double)(i - 1) / StaticSettings.Fetch.GifFramecount);
                _kernel.Render(computeBuffer, queue, _parameters, new Size(screenshotWidth, screenshotHeight));
                if (encoder.AddFrame(Download(queue, computeBuffer, screenshotWidth, screenshotHeight)) == false)
                    throw new Exception("Could not add frame to gif");
                teardown();
            }
            endIgnoreControl();
            encoder.Finish();
            computeBuffer.Dispose();
            queue.Dispose();
            displayInformation("Done with gif");
            _kernelInUse--;
        }
示例#33
0
文件: GPUT.cs 项目: ruarai/Trigrad
        public static void Calculate(List<Calculation> calculations)
        {
            Stopwatch s = new Stopwatch();
            s.Start();

            int count = calculations.Count;

            IntVec2[] p_p = new IntVec2[count];

            IntVec2[] p_a = new IntVec2[count];
            IntVec2[] p_b = new IntVec2[count];
            IntVec2[] p_c = new IntVec2[count];

            FloatVec3[] c = new FloatVec3[count];

            int[] c_valid = new int[count];

            Parallel.For(0, count, i =>
            {
                var calc = calculations[i];

                p_p[i] = new IntVec2(calc.P);
                p_a[i] = new IntVec2(calc.A);
                p_b[i] = new IntVec2(calc.B);
                p_c[i] = new IntVec2(calc.C);
            });

            mark(s, "memory init");

            ComputeBuffer<IntVec2> _p_p = new ComputeBuffer<IntVec2>(context, ComputeMemoryFlags.ReadOnly | ComputeMemoryFlags.CopyHostPointer, p_p);

            ComputeBuffer<IntVec2> _p_a = new ComputeBuffer<IntVec2>(context, ComputeMemoryFlags.ReadOnly | ComputeMemoryFlags.CopyHostPointer, p_a);

            ComputeBuffer<IntVec2> _p_b = new ComputeBuffer<IntVec2>(context, ComputeMemoryFlags.ReadOnly | ComputeMemoryFlags.CopyHostPointer, p_b);

            ComputeBuffer<IntVec2> _p_c = new ComputeBuffer<IntVec2>(context, ComputeMemoryFlags.ReadOnly | ComputeMemoryFlags.CopyHostPointer, p_c);

            ComputeBuffer<FloatVec3> _c = new ComputeBuffer<FloatVec3>(context, ComputeMemoryFlags.WriteOnly, c.Length);
            ComputeBuffer<int> _c_valid = new ComputeBuffer<int>(context, ComputeMemoryFlags.WriteOnly, c_valid.Length);

            mark(s, "memory buffer init");

            ComputeKernel kernel = program.CreateKernel("Barycentric");
            kernel.SetMemoryArgument(0, _p_p);

            kernel.SetMemoryArgument(1, _p_a);

            kernel.SetMemoryArgument(2, _p_b);

            kernel.SetMemoryArgument(3, _p_c);

            kernel.SetMemoryArgument(4, _c);
            kernel.SetMemoryArgument(5, _c_valid);

            mark(s, "memory init 2");

            ComputeEventList eventList = new ComputeEventList();

            ComputeCommandQueue commands = new ComputeCommandQueue(context, context.Devices[0], ComputeCommandQueueFlags.None);

            commands.Execute(kernel, null, new long[] { count }, null, eventList);

            mark(s, "execute");

            commands.ReadFromBuffer(_c, ref c, false, eventList);
            commands.ReadFromBuffer(_c_valid, ref c_valid, false, eventList);
            commands.Finish();

            mark(s, "read 1");

            Parallel.For(0, count, i =>
            {
                var calc = calculations[i];
                calc.Coords = new BarycentricCoordinates(c[i].U,c[i].V,c[i].W);

                if (c_valid[i] == 1)
                {
                    lock (calc.Tri)
                        calc.Tri.Points.Add(new DrawPoint(calc.Coords, calc.P));
                }
            });

            mark(s, "read 2");

            // cleanup commands
            commands.Dispose();

            // cleanup events
            foreach (ComputeEventBase eventBase in eventList)
            {
                eventBase.Dispose();
            }
            eventList.Clear();

            // cleanup kernel
            kernel.Dispose();

            _p_p.Dispose();

            _p_a.Dispose();
            _p_b.Dispose();
            _p_c.Dispose();

            _c.Dispose();
            _c_valid.Dispose();

            mark(s, "dispose");
        }
示例#34
0
        public Bitmap GetScreenshot(CameraConfig camera, int screenshotHeight, int slowRender)
        {
            var screenshotWidth = (int)(screenshotHeight * ScreenshotAspectRatio);
            var computeBuffer = new ComputeBuffer<Vector4>(_program.Context, ComputeMemoryFlags.ReadWrite, screenshotWidth * screenshotHeight);
            var queue = new ComputeCommandQueue(_program.Context, _program.Context.Devices[0], ComputeCommandQueueFlags.None);

            var globalSize = GlobalLaunchsizeFor(screenshotWidth, screenshotHeight);

            for (var i = 0; i < slowRender; i++)
                CoreRender(computeBuffer, queue, _kernels, new Vector4((Vector3)camera.Position), new Vector4((Vector3)camera.Lookat), new Vector4((Vector3)camera.Up), i, camera.Fov, slowRender, camera.FocalDistance, screenshotWidth, screenshotHeight, globalSize, _localSize);
            for (var i = 0; i < camera.Frame * slowRender; i++)
                CoreRender(computeBuffer, queue, _kernels, new Vector4((Vector3)camera.Position), new Vector4((Vector3)camera.Lookat), new Vector4((Vector3)camera.Up), i, camera.Fov, slowRender, camera.FocalDistance, screenshotWidth, screenshotHeight, globalSize, _localSize);

            var pixels = new Vector4[screenshotWidth * screenshotHeight];
            queue.ReadFromBuffer(computeBuffer, ref pixels, true, null);
            queue.Finish();

            computeBuffer.Dispose();
            queue.Dispose();

            var bmp = new Bitmap(screenshotWidth, screenshotHeight);
            var destBuffer = new int[screenshotWidth * screenshotHeight];
            for (var y = 0; y < screenshotHeight; y++)
            {
                for (var x = 0; x < screenshotWidth; x++)
                {
                    var pixel = pixels[x + y * screenshotWidth];
                    if (float.IsNaN(pixel.X) || float.IsNaN(pixel.Y) || float.IsNaN(pixel.Z))
                    {
                        Console.WriteLine("Warning! Caught NAN pixel while taking screenshot!");
                        continue;
                    }
                    destBuffer[y * screenshotWidth + x] = (byte)(pixel.X * 255) << 16 | (byte)(pixel.Y * 255) << 8 | (byte)(pixel.Z * 255);
                }
            }
            var bmpData = bmp.LockBits(new Rectangle(0, 0, screenshotWidth, screenshotHeight), ImageLockMode.ReadWrite, PixelFormat.Format32bppRgb);
            Marshal.Copy(destBuffer, 0, bmpData.Scan0, destBuffer.Length);
            bmp.UnlockBits(bmpData);

            return bmp;
        }
示例#35
0
        public void Run(ComputeContext context, TextWriter log)
        {
            try
            {
                // Create the arrays and fill them with random data.
                int count = 10;
                float[] arrA = new float[count];
                float[] arrB = new float[count];
                float[] arrC = new float[count];

                Random rand = new Random();
                for (int i = 0; i < count; i++)
                {
                    arrA[i] = (float)(rand.NextDouble() * 100);
                    arrB[i] = (float)(rand.NextDouble() * 100);
                }

                // Create the input buffers and fill them with data from the arrays.
                // Access modifiers should match those in a kernel.
                // CopyHostPointer means the buffer should be filled with the data provided in the last argument.
                ComputeBuffer<float> a = new ComputeBuffer<float>(context, ComputeMemoryFlags.ReadOnly | ComputeMemoryFlags.CopyHostPointer, arrA);
                ComputeBuffer<float> b = new ComputeBuffer<float>(context, ComputeMemoryFlags.ReadOnly | ComputeMemoryFlags.CopyHostPointer, arrB);
                
                // The output buffer doesn't need any data from the host. Only its size is specified (arrC.Length).
                ComputeBuffer<float> c = new ComputeBuffer<float>(context, ComputeMemoryFlags.WriteOnly, arrC.Length);

                // Create and build the opencl program.
                program = new ComputeProgram(context, clProgramSource);
                program.Build(null, null, null, IntPtr.Zero);

                // Create the kernel function and set its arguments.
                ComputeKernel kernel = program.CreateKernel("VectorAdd");
                kernel.SetMemoryArgument(0, a);
                kernel.SetMemoryArgument(1, b);
                kernel.SetMemoryArgument(2, c);

                // Create the event wait list. An event list is not really needed for this example but it is important to see how it works.
                // Note that events (like everything else) consume OpenCL resources and creating a lot of them may slow down execution.
                // For this reason their use should be avoided if possible.
                ComputeEventList eventList = new ComputeEventList();
                
                // Create the command queue. This is used to control kernel execution and manage read/write/copy operations.
                ComputeCommandQueue commands = new ComputeCommandQueue(context, context.Devices[0], ComputeCommandQueueFlags.None);

                // Execute the kernel "count" times. After this call returns, "eventList" will contain an event associated with this command.
                // If eventList == null or typeof(eventList) == ReadOnlyCollection<ComputeEventBase>, a new event will not be created.
                commands.Execute(kernel, null, new long[] { count }, null, eventList);
                
                // Read back the results. If the command-queue has out-of-order execution enabled (default is off), ReadFromBuffer 
                // will not execute until any previous events in eventList (in our case only eventList[0]) are marked as complete 
                // by OpenCL. By default the command-queue will execute the commands in the same order as they are issued from the host.
                // eventList will contain two events after this method returns.
                commands.ReadFromBuffer(c, ref arrC, false, eventList);

                // A blocking "ReadFromBuffer" (if 3rd argument is true) will wait for itself and any previous commands
                // in the command queue or eventList to finish execution. Otherwise an explicit wait for all the opencl commands 
                // to finish has to be issued before "arrC" can be used. 
                // This explicit synchronization can be achieved in two ways:

                // 1) Wait for the events in the list to finish,
                //eventList.Wait();

                // 2) Or simply use
                commands.Finish();

                // Print the results to a log/console.
                for (int i = 0; i < count; i++)
                    log.WriteLine("{0} + {1} = {2}", arrA[i], arrB[i], arrC[i]);

                // cleanup commands
                commands.Dispose();

                // cleanup events
                foreach (ComputeEventBase eventBase in eventList)
                {
                    eventBase.Dispose();
                }
                eventList.Clear();

                // cleanup kernel
                kernel.Dispose();

                // cleanup program
                program.Dispose();

                // cleanup buffers
                a.Dispose();
                b.Dispose();
                c.Dispose();
            }
            catch (Exception e)
            {
                log.WriteLine(e.ToString());
            }
        }