/// <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(); }
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 }
// 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); }