/// <summary> /// Called every time a new frame shows up from the camera /// </summary> /// <param name="sender"></param> /// <param name="e"></param> private void provider_ImageTransaction(object sender, ImageReceivedEventArgs e) { if (stopping || e == null || e.PixelData == null) { return; } if (Monitor.TryEnter(this)) { imgGPU.Scatter(e.PixelData); if (calibrating) { // compute a running mean of each pixel worker.Launch(RunningMean_Kernel, lp, e.Width, imgGPU.Ptr, meanImg.Ptr, numCalibrationSamples); numCalibrationSamples++; // compute the mean over the full mean image, using a reduction operation addReduce.Reduce(meanImg.Ptr, scalarOutput.Ptr, numPixels); var mean = scalarOutput.GatherScalar(); mean /= numPixels; // update the correction factor for each pixel worker.Launch(UpdateCorrectionFactor_Kernel, lp, e.Width, meanImg.Ptr, correctionFactor.Ptr, mean); } if (correctBrightness) { worker.Launch(ApplyCorrectionFactor_Kernel, lp, e.Width, correctionFactor.Ptr, imgGPU.Ptr); imgGPU.Gather(e.PixelData); } img.Bytes = e.PixelData; // note: have to do this last, because if you set it earlier but then modify the bytes it won't update the image // trigger a new frame event OnFrameAvailable(new VideoFrame { Image = img, ImageGPU = imgGPU, Timestamp = e.TimeStamp }); Monitor.Exit(this); } }
protected override bool Execute(Assignment assignment, ILValue <T> output) { var input = assignment.GetInput(Input).ToRValue(); var reduce = Reduction; var reductionIndices = ReductionIndices; var shape = Shape; // unit stride case and reduction is full reduction (to scalar) if (input.Layout.IsFullyUnitStride && shape.Rank == 0) { var length = input.Layout.Shape.Length; Util.EnsureTrue(length > 0L); var read = input.BufferReader.GetFlatReader1(); var write = output.Buffer.FlatWriter1; if (assignment.Context.Type == ContextType.Gpu) { var stream = assignment.Context.ToGpuContext().Stream; var numItems = (int)length; Func <int, T> sourceOp = i => read(i); Action <int, T> outputOp = (i, value) => write(i, value); // first pass, get the size of temp memory var tempStorageSize = 0; DeviceReduce.Reduce(stream, new deviceptr <byte>(), ref tempStorageSize, numItems, sourceOp, outputOp, reduce); // now allocate temp memory using (var tempMemoryRcpt = assignment.Context.Device.ToGpuDevice().MemoryRepository.Acquire <byte>(tempStorageSize)) { DeviceReduce.Reduce(stream, tempMemoryRcpt.Memory.Ptr, ref tempStorageSize, numItems, sourceOp, outputOp, reduce); } return(true); } if (assignment.Context.Type == ContextType.Cpu) { var acc = read(0L); for (var i = 1L; i < length; ++i) { acc = reduce(acc, read(i)); } write(0L, acc); return(true); } } // currently we only support matrix partial reduce, need TODO to fix this with more generic cases if (input.Layout.IsFullyUnitStride && input.Layout.Rank == 2 && reductionIndices.Length == 1) { var rows = input.Layout.Shape[0]; var cols = input.Layout.Shape[1]; var read = input.BufferReader.GetReader2(); var write = output.Buffer.FlatWriter1; if (reductionIndices[0] == 1) { if (assignment.Context.Type == ContextType.Gpu) { var stream = assignment.Context.ToGpuContext().Stream; var numSegments = (int)rows; var numItems = (int)cols; Func <int, int, T> sourceOp = (i, j) => read(i, j); Action <int, int, T> outputOp = (i, _, value) => write(i, value); // first pass, get the size of temp memory var tempStorageSize = 0; DeviceReduce.Reduce(stream, new deviceptr <byte>(), ref tempStorageSize, numSegments, numItems, sourceOp, outputOp, reduce); // now allocate temp memory // TODO: move to assigmnet, manage the temp memory using (var tempMemoryRcpt = assignment.Context.Device.ToGpuDevice().MemoryRepository.Acquire <byte>(tempStorageSize)) { DeviceReduce.Reduce(stream, tempMemoryRcpt.Memory.Ptr, ref tempStorageSize, numSegments, numItems, sourceOp, outputOp, reduce); } return(true); } if (assignment.Context.Type == ContextType.Cpu) { for (var row = 0L; row < rows; ++row) { var acc = read(row, 0L); for (var col = 1L; col < cols; ++col) { acc = reduce(acc, read(row, col)); } write(row, acc); } return(true); } } if (reductionIndices[0] == 0) { if (assignment.Context.Type == ContextType.Gpu) { var stream = assignment.Context.ToGpuContext().Stream; // This is a quick fix, it is not good performance stream.LongFor(0L, cols, col => { var acc = read(0L, col); for (var row = 1L; row < rows; ++row) { acc = reduce(acc, read(row, col)); } write(col, acc); }); return(true); } if (assignment.Context.Type == ContextType.Cpu) { for (var col = 0L; col < cols; ++col) { var acc = read(0L, col); for (var row = 1L; row < rows; ++row) { acc = reduce(acc, read(row, col)); } write(col, acc); } return(true); } } } return(false); }