Esempio n. 1
0
        /// <summary>
        /// Gets the values for an explicit input
        /// </summary>
        /// <param name="input">The explicit input</param>
        /// <param name="output">The output values</param>
        public void GetValues(Single3[] input, ref float[] output)
        {
            if (context == null || kernelExplicit == null)
            {
                throw new Exception("Compile first!");
            }

            int inputLength = input.Length;

            // IO length changed
            if (lastLength != inputLength)
            {
                lastLength   = inputLength;
                outputBuffer = new Cloo.ComputeBuffer <float>(context, ComputeMemoryFlags.WriteOnly | ComputeMemoryFlags.AllocateHostPointer, inputLength);
                kernelExplicit.SetMemoryArgument(2, outputBuffer);
            }

            // Setup IO Buffers
            ComputeBuffer <Single3> bufIn = new Cloo.ComputeBuffer <Single3>(context, ComputeMemoryFlags.ReadOnly | ComputeMemoryFlags.CopyHostPointer, input);

            // Arrange params
            kernelExplicit.SetMemoryArgument(0, bufIn);

            // Exec and read
            queue.Execute(kernelExplicit, null, new long[] { input.Length }, null, null);
            GCHandle outHandle = GCHandle.Alloc(output, GCHandleType.Pinned);

            queue.Read <float>(outputBuffer, true, 0, inputLength, outHandle.AddrOfPinnedObject(), null); // Read saves about 500 - 1000 ticks. Sweet for small queues
            outHandle.Free();

            queue.Finish();
        }
Esempio n. 2
0
    public void Calc(Vector3[] positions, Vector3[] velocities, FlockInfo frInfo)
    {
        System.Array.Clear(_pointCounters, 0, _pointCounters.Length);
        System.Array.Clear(_pointIndices, 0, _pointIndices.Length);
        _queue.WriteToBuffer(_pointCounters, _pointCountersBuffer, false, _events);
        _queue.WriteToBuffer(_pointIndices, _pointIndicesBuffer, false, _events);

        var positionsBuffer = new Cloo.ComputeBuffer<Vector3>(
            _context, ComputeMemoryFlags.CopyHostPointer, positions);
        var velocitiesBuffer = new Cloo.ComputeBuffer<Vector3>(
            _context, ComputeMemoryFlags.CopyHostPointer, velocities);

        _boundaryKernel.SetMemoryArgument(0, positionsBuffer);

        _updateGridKernel.SetMemoryArgument(0, positionsBuffer);

        _updateBoidsKernel.SetMemoryArgument(0, positionsBuffer);
        _updateBoidsKernel.SetMemoryArgument(1, velocitiesBuffer);
        _updateBoidsKernel.SetValueArgument(5, frInfo);

        //var startTime = Time.realtimeSinceStartup;
        _queue.Execute(_boundaryKernel, null, new long[]{ positions.Length }, null, _events);
        _queue.Execute(_updateGridKernel, null, new long[]{ positions.Length }, null, _events);
        _queue.Execute(_updateBoidsKernel, null, new long[]{ positions.Length }, null, _events);
        _queue.ReadFromBuffer(_pointCountersBuffer, ref _pointCounters, false, _events);
        _queue.ReadFromBuffer(_pointIndicesBuffer, ref _pointIndices, false, _events);
        _queue.ReadFromBuffer(positionsBuffer, ref positions, false, _events);
        _queue.ReadFromBuffer(velocitiesBuffer, ref velocities, false, _events);
        _queue.Finish();
        //Debug.Log("Elapsed: " + (Time.realtimeSinceStartup - startTime));

        #if false
        var counterSum = _pointCounters.Sum();
        if (positions.Length != counterSum)
            Debug.Log(string.Format("Counter sum must be {0} but {1}", positions.Length, counterSum));
        for (int i = 0; i < positions.Length; i++) {
            var p = positions[i];
            var cellPos = new Vector3(
                (p.x - _gridInfo.worldOrigin.x) / _gridInfo.cellSize.x,
                (p.y - _gridInfo.worldOrigin.y) / _gridInfo.cellSize.y,
                (p.z - _gridInfo.worldOrigin.z) / _gridInfo.cellSize.z);
            var cellId = (int)(cellPos.x) + _gridInfo.nGridPartitions
                * ((int)(cellPos.y) + _gridInfo.nGridPartitions * (int)(cellPos.z));
            if (!Enumerable.Range(cellId * _gridInfo.maxIndices, _gridInfo.maxIndices).Any(iter => _pointIndices[iter] == i))
                Debug.Log(string.Format("Index is wrong at {0}", i));
        }
        #endif
    }
Esempio n. 3
0
    // Use this for initialization
    void Awake()
    {
        var platform = ComputePlatform.Platforms[0];
        _context = new ComputeContext(ComputeDeviceTypes.Cpu,
            new ComputeContextPropertyList(platform), null, System.IntPtr.Zero);
        _queue = new ComputeCommandQueue(_context, _context.Devices[0], ComputeCommandQueueFlags.None);
        string clSource = System.IO.File.ReadAllText(clProgramPath);
        _program = new ComputeProgram(_context, clSource);
        try {
            _program.Build(null, null, null, System.IntPtr.Zero);
        } catch(BuildProgramFailureComputeException) {
            Debug.Log(_program.GetBuildLog(_context.Devices[0]));
            throw;
        }
        _events = new ComputeEventList();
        _updateGridKernel = _program.CreateKernel(clUpdateGridKernelName);
        _updateBoidsKernel = _program.CreateKernel(clUpdateBoidsKernelName);
        _boundaryKernel = _program.CreateKernel(clBoundaryKernelName);

        _pointCounters = new int[nGridPartitions * nGridPartitions * nGridPartitions];
        _pointIndices = new int[_pointCounters.Length * maxIndices];

        _pointCountersBuffer = new Cloo.ComputeBuffer<int>(
            _context, ComputeMemoryFlags.WriteOnly, _pointCounters.Length);
        _pointIndicesBuffer = new Cloo.ComputeBuffer<int>(
            _context, ComputeMemoryFlags.WriteOnly, _pointIndices.Length);

        _gridInfo = new GridInfo() {
            worldOrigin = gridbounds.min,
            worldSize = gridbounds.size,
            cellSize = gridbounds.size * (1f / nGridPartitions),
            nGridPartitions = nGridPartitions,
            maxIndices = maxIndices
        };

        _boundaryKernel.SetValueArgument(1, _gridInfo);

        _updateGridKernel.SetMemoryArgument(1, _pointCountersBuffer);
        _updateGridKernel.SetMemoryArgument(2, _pointIndicesBuffer);
        _updateGridKernel.SetValueArgument(3, _gridInfo);

        _updateBoidsKernel.SetMemoryArgument(2, _pointCountersBuffer);
        _updateBoidsKernel.SetMemoryArgument(3, _pointIndicesBuffer);
        _updateBoidsKernel.SetValueArgument(4, _gridInfo);
    }