internal static unsafe CLError LaunchKernelWithStreamBinding( CLStream stream, CLKernel kernel, RuntimeKernelConfig config) { var binding = stream.BindScoped(); var gridDim = config.GridDim; var blockDim = config.GroupDim; IntPtr *globalWorkSizes = stackalloc IntPtr[3]; globalWorkSizes[0] = new IntPtr(gridDim.X * blockDim.X); globalWorkSizes[1] = new IntPtr(gridDim.Y * blockDim.Y); globalWorkSizes[2] = new IntPtr(gridDim.Z * blockDim.Z); IntPtr *localWorkSizes = stackalloc IntPtr[3]; localWorkSizes[0] = new IntPtr(blockDim.X); localWorkSizes[1] = new IntPtr(blockDim.Y); localWorkSizes[2] = new IntPtr(blockDim.Z); var result = LaunchKernelUnsafe( stream.CommandQueue, kernel.KernelPtr, 3, null, globalWorkSizes, localWorkSizes); binding.Recover(); return(result); }
public static unsafe CLError LaunchKernelWithStreamBinding( CLStream stream, CLKernel kernel, int gridDimX, int gridDimY, int gridDimZ, int blockDimX, int blockDimY, int blockDimZ) { var binding = stream.BindScoped(); IntPtr *globalWorkSizes = stackalloc IntPtr[3]; globalWorkSizes[0] = new IntPtr(gridDimX); globalWorkSizes[1] = new IntPtr(gridDimY); globalWorkSizes[2] = new IntPtr(gridDimZ); IntPtr *localWorkSizes = stackalloc IntPtr[3]; localWorkSizes[0] = new IntPtr(blockDimX); localWorkSizes[1] = new IntPtr(blockDimY); localWorkSizes[2] = new IntPtr(blockDimZ); var result = LaunchKernelUnsafe( stream.CommandQueue, kernel.KernelPtr, 3, null, globalWorkSizes, localWorkSizes); binding.Recover(); return(result); }
private static String GetKernelInfoString(CLKernel openclKernel, CLKernelInfo kernelInfo, Int32 kernelInfoBufferSize) { byte[] buffer = GetKernelInfoBuffer(openclKernel, kernelInfo, kernelInfoBufferSize); Int32 count = Array.IndexOf <Byte>(buffer, 0, 0); return(System.Text.ASCIIEncoding.ASCII.GetString(buffer, 0, count < 0 ? buffer.Length : count)); }
public AnySignalEditor(CLKernel kernel, Texture texture) { if (kernel != null && !_kernels.Contains(kernel)) { _kernels.Add(kernel); } Texture = texture ?? new Texture(TextureTarget.Texture2D); }
internal override void SetAsKernelArgument(CLKernel kernel, int index) { var clMem = new CLMem { Value = openCLSampler.Value }; OpenCLError.Validate(OpenCLDriver.clSetKernelArg(kernel, index, new SizeT(IntPtr.Size), ref clMem)); }
public readonly CLError PreLaunchKernel( CLStream stream, CLKernel kernel, RuntimeKernelConfig config) => SetKernelArgumentUnsafeWithKernel( kernel, 0, config.SharedMemoryConfig.DynamicArraySize, null);
public static CLError SetKernelArgumentUnsafeWithKernel( CLKernel kernel, int index, int size, void *value) => NativeMethods.SetKernelArg( kernel.KernelPtr, index, new IntPtr(size), value);
internal Kernel(CLKernel openclKernel, Program program, CommandQueue commandQueue, String name) { this.CLKernel = openclKernel; this.Program = program; this.Context = program.Context; this.CommandQueue = commandQueue; this.Name = name; }
public static Kernel Create(String name, CommandQueue commandQueue, Program sources, params Argument[] arguments) { CLError error = CLError.None; CLKernel openclKernel = OpenCLDriver.clCreateKernel(sources.CLProgram, name, ref error); Kernel result = new Kernel(openclKernel, sources, commandQueue, name.Length + 1); result.InitializeArguments(arguments); return(result); }
internal override void SetAsKernelArgument(CLKernel kernel, int index) { GCHandle handle = GCHandle.Alloc(Value, GCHandleType.Pinned); try { OpenCLError.Validate(OpenCLDriver.clSetKernelArg(kernel, index, new SizeT(Marshal.SizeOf(typeof(T))), handle.AddrOfPinnedObject())); } finally { handle.Free(); } }
private static T GetKernelInfo <T>(CLKernel openclKernel, CLKernelInfo kernelInfo) { Byte[] buffer = GetKernelInfoBuffer(openclKernel, kernelInfo, Marshal.SizeOf(typeof(T))); GCHandle bufferHandle = GCHandle.Alloc(buffer, GCHandleType.Pinned); try { return((T)Marshal.PtrToStructure(bufferHandle.AddrOfPinnedObject(), typeof(T))); } finally { bufferHandle.Free(); } }
public void SignatureParsing() { CLAPI instance = CLAPI.GetInstance(); KernelDatabase db = new KernelDatabase(DataVectorTypes.Uchar1); CLProgram program = db.AddProgram(instance, TEST_KERNEL, "./", true, out CLProgramBuildResult result); CLKernel kernel = program.ContainedKernels["set_value"]; Assert.True(CheckParameter(kernel.Parameter["arr"], "arr", true, 0, DataVectorTypes.Uchar1, MemoryScope.Global)); Assert.True(CheckParameter(kernel.Parameter["value"], "value", false, 1, DataVectorTypes.Uchar1, MemoryScope.None)); db.Dispose(); instance.Dispose(); }
/// <summary> /// Setup OpenCL /// </summary> internal static void Setup() { try { // ADD YOUR CODE HERE CLError err; uint num_entries = 0;// get platform CLPlatformID[] platforms = new CLPlatformID[5]; err = OpenCLDriver.clGetPlatformIDs(5, platforms, ref num_entries); if (num_entries == 0) { throw new Exception("No Platform Entries found!"); } //get device ID CLDeviceID[] devices = new CLDeviceID[1]; err = OpenCLDriver.clGetDeviceIDs(platforms[0], CLDeviceType.GPU, 1, devices, ref num_entries); // create context ctx = OpenCLDriver.clCreateContext(null, 1, devices, null, IntPtr.Zero, ref err); if (err != CLError.Success) { throw new Exception(err.ToString()); } // create command queue comQ = OpenCLDriver.clCreateCommandQueue(ctx, devices[0], 0, ref err); if (err != CLError.Success) { throw new Exception(err.ToString()); } // Compile Program string[] progString = new string[1]; progString[0] = File.ReadAllText("..\\..\\prog.cl"); program = OpenCLDriver.clCreateProgramWithSource(ctx, 1, progString, null, ref err); err = OpenCLDriver.clBuildProgram(program, 1, devices, "", null, IntPtr.Zero); //create kernel kernel_mult = OpenCLDriver.clCreateKernel(program, "multiply", ref err); } catch (Exception exc) { MessageBox.Show(exc.ToString()); } }
internal static Kernels CreateInternal(CommandQueue commandQueue, Program program, Int32 kernelsCount, Int32 kernelInfoBufferSize) { Validate(commandQueue, program); Int32 numKernelsRet = 0; CLKernel[] openclKernels = new CLKernel[kernelsCount]; OpenCLError.Validate(OpenCLDriver.clCreateKernelsInProgram(program.CLProgram, openclKernels.Length, openclKernels, ref numKernelsRet)); Kernel[] result = new Kernel[numKernelsRet]; for (int i = 0; i < numKernelsRet; i++) { result[i] = new Kernel(openclKernels[i], program, commandQueue, kernelInfoBufferSize); } return(new Kernels(result)); }
private string GenerateKernelWrapper(string programSourceHandle, CLKernel kernel) { string header = $"public void {kernel.Name}("; foreach (KeyValuePair <string, KernelParameter> kernelParameter in kernel.Parameter) { header += $"{( kernelParameter.Value.IsArray ? "FLBuffer" : "float" )} {kernelParameter.Key},"; } if (kernel.Parameter.Count != 0) { header = header.Remove(header.Length - 1, 1); } header += ")"; string body = $"//Initialize CL Program\nthis.{programSourceHandle}();\n// Execute Kernel: {kernel.Name}"; return(header + "\n{\n" + body + "\n}\n"); }
public static void Test() { if (test == null) { test = CL.GetKernel("myKernelFunction"); } const int BUFFERSIZE = 10; CLBuffer buf = CL.GenBuffer(new float[BUFFERSIZE]); test.SetArgument(0, buf); CL.EnqueueRange(test, new MultiDimension(BUFFERSIZE), new MultiDimension(1)); float[] readBack = new float[BUFFERSIZE]; CL.ReadBuffer(buf, readBack); foreach (var v in readBack) { Console.WriteLine(v); } }
private static Byte[] GetKernelInfoBuffer(CLKernel openclKernel, CLKernelInfo kernelInfo, Int32 kernelInfoBufferSize) { SizeT bufferSize = SizeT.Zero; Byte[] buffer = new Byte[kernelInfoBufferSize]; GCHandle bufferHandle = GCHandle.Alloc(buffer, GCHandleType.Pinned); IntPtr bufferPtr = bufferHandle.AddrOfPinnedObject(); try { OpenCLError.Validate(OpenCLDriver.clGetKernelInfo(openclKernel, kernelInfo, new SizeT(buffer.Length), bufferPtr, ref bufferSize)); } finally { bufferHandle.Free(); } Array.Resize(ref buffer, (int)bufferSize); return(buffer); }
public static void FillRectangle(CLBuffer trg, IBRectangle trgSize, PixelData color, IBRectangle rect) { if (fillRect == null) { fillRect = CL.GetKernel("fillRect"); } int[] _trgSize = new int[] { (int)trgSize.Width, (int)trgSize.Height }; int[] _offset = new int[] { (int)rect.OffsetX, (int)rect.OffsetY }; int[] _size = new int[] { (int)rect.Width, (int)rect.Height }; float[] _color = new float[] { color.b / 255.0f, color.g / 255.0f, color.r / 255.0f, color.a / 255.0f }; CLBuffer __trgSize = CL.GenBuffer(_trgSize); CLBuffer __offset = CL.GenBuffer(_offset); CLBuffer __size = CL.GenBuffer(_size); CLBuffer __color = CL.GenBuffer(_color); fillRect.SetArgument(0, trg.InternalPointer); fillRect.SetArgument(1, __trgSize); fillRect.SetArgument(2, __color); fillRect.SetArgument(3, __offset); fillRect.SetArgument(4, __size); CL.EnqueueRange(fillRect, new MultiDimension(1080), new MultiDimension(1)); }
internal override void SetAsKernelArgument(CLKernel kernel, int index) { OpenCLError.Validate(OpenCLDriver.clSetKernelArg(kernel, index, new SizeT(IntPtr.Size), ref openCLMem)); }
private FLLineAnalysisResult AnalyzeLine(FLInstructionData data) { if (data.InstructionType != FLInstructionType.FlFunction && data.InstructionType != FLInstructionType.ClKernel) { return(FLLineAnalysisResult.ParseError); } if (leaveStack) //This keeps the stack when returning from a "function" { leaveStack = false; } else { currentArgStack = new Stack <object>(); } FLLineAnalysisResult ret = FLLineAnalysisResult.IncreasePc; for (; currentWord < data.Arguments.Count; currentWord++) //loop through the words. start value can be != 0 when returning from a function specified as an argument to a kernel { if (data.Arguments[currentWord].argType == FLArgumentType.Function) { bool keepBuffer = data.InstructionType == FLInstructionType.FlFunction && ((FLInterpreterFunctionInfo)data.Instruction).LeaveStack; JumpTo((int)data.Arguments[currentWord].value, keepBuffer); ret = FLLineAnalysisResult.Jump; //We Jumped to another point in the code. currentArgStack .Push(null); //Push null to signal the interpreter that he returned before assigning the right value. break; } if (data.Arguments[currentWord].argType != FLArgumentType.Unknown) { currentArgStack.Push(data.Arguments[currentWord].value); } } if (currentWord == data.Arguments.Count && ret != FLLineAnalysisResult.Jump) { if (data.InstructionType == FLInstructionType.FlFunction) { ((FLInterpreterFunctionInfo)data.Instruction).Run(); return(FLLineAnalysisResult.IncreasePc); } CLKernel k = (CLKernel)data.Instruction; if (k == null || data.Arguments.Count != k.Parameter.Count - FL_HEADER_ARG_COUNT) { throw new FLInvalidFunctionUseException(this.data.Source[currentIndex], "Not the right amount of arguments."); } //Execute filter for (int i = k.Parameter.Count - 1; i >= FL_HEADER_ARG_COUNT; i--) { object obj = currentArgStack.Pop(); //Get the arguments and set them to the kernel if (obj is CLBufferInfo buf) //Unpack the Buffer from the CLBuffer Object. { obj = buf.Buffer; } k.SetArg(i, obj); } Logger.Log(DebugChannel.Log | DebugChannel.OpenFL, Verbosity.Level8, "Running kernel: " + k.Name); CLAPI.Run(instance, k, currentBuffer.Buffer, new int3(width, height, depth), KernelParameter.GetDataMaxSize(kernelDb.GenDataType), activeChannelBuffer, channelCount); //Running the kernel } return(ret); }
public KernelFLInstruction(float genMaxSize, CLKernel kernel, List <FLInstructionArgument> arguments) : base(arguments) { Kernel = kernel; GenMaxSize = genMaxSize; }
private LineAnalysisResult AnalyzeLine(FLInstructionData data) { if (data.InstructionType != FLInstructionType.FLFunction && data.InstructionType != FLInstructionType.CLKernel) { Logger.Crash(new FLParseError(Data.Source[_currentIndex]), true); return(LineAnalysisResult.ParseError); } if (_leaveStack) //This keeps the stack when returning from a "function" { _leaveStack = false; } else { _currentArgStack = new Stack <object>(); } LineAnalysisResult ret = LineAnalysisResult.IncreasePC; for (; _currentWord < data.Arguments.Count; _currentWord++) //loop through the words. start value can be != 0 when returning from a function specified as an argument to a kernel { if (data.Arguments[_currentWord].argType == FLArgumentType.Function) { bool KeepBuffer = data.InstructionType == FLInstructionType.FLFunction && ((FLFunctionInfo)data.Instruction).LeaveStack; JumpTo((int)data.Arguments[_currentWord].value, KeepBuffer); ret = LineAnalysisResult.Jump; //We Jumped to another point in the code. _currentArgStack .Push(null); //Push null to signal the interpreter that he returned before assigning the right value. break; } if (data.Arguments[_currentWord].argType != FLArgumentType.Unknown) { _currentArgStack.Push(data.Arguments[_currentWord].value); } } if (_currentWord == data.Arguments.Count && ret != LineAnalysisResult.Jump) { if (data.InstructionType == FLInstructionType.FLFunction) { ((FLFunctionInfo)data.Instruction).Run(); return(LineAnalysisResult.IncreasePC); } CLKernel K = (CLKernel)data.Instruction; if (K == null || data.Arguments.Count != K.Parameter.Count - FLHeaderArgCount) { Logger.Crash(new FLInvalidFunctionUseException(Data.Source[_currentIndex], "Not the right amount of arguments."), true); return(LineAnalysisResult.ParseError); } //Execute filter for (int i = K.Parameter.Count - 1; i >= FLHeaderArgCount; i--) { object obj = _currentArgStack.Pop(); //Get the arguments and set them to the kernel if (obj is CLBufferInfo buf) //Unpack the Buffer from the CLBuffer Object. { obj = buf.Buffer; } K.SetArg(i, obj); } Logger.Log("Running kernel: " + K.Name, DebugChannel.Log | DebugChannel.OpenFL, 8); CLAPI.Run(K, _currentBuffer.Buffer, new int3(_width, _height, _depth), KernelParameter.GetDataMaxSize(_kernelDb.GenDataType), _activeChannelBuffer, _channelCount); //Running the kernel } return(ret); }
/// <summary> /// Setup OpenCL /// </summary> internal static void Setup() { try { // ADD YOUR CODE HERE CLError err; uint num_entries = 0;// get platform CLPlatformID[] platforms = new CLPlatformID[5]; err = OpenCLDriver.clGetPlatformIDs(5, platforms, ref num_entries); if (num_entries == 0) throw new Exception("No Platform Entries found!"); //get device ID CLDeviceID[] devices = new CLDeviceID[1]; err = OpenCLDriver.clGetDeviceIDs(platforms[0], CLDeviceType.GPU, 1, devices, ref num_entries); // create context ctx = OpenCLDriver.clCreateContext(null, 1, devices, null, IntPtr.Zero, ref err); if (err != CLError.Success) throw new Exception(err.ToString()); // create command queue comQ = OpenCLDriver.clCreateCommandQueue(ctx, devices[0], 0, ref err); if (err != CLError.Success) throw new Exception(err.ToString()); // Compile Program string[] progString = new string[1]; progString[0] = File.ReadAllText("..\\..\\prog.cl"); program = OpenCLDriver.clCreateProgramWithSource(ctx, 1, progString, null, ref err); err = OpenCLDriver.clBuildProgram(program, 1, devices, "", null, IntPtr.Zero); //create kernel kernel_mult = OpenCLDriver.clCreateKernel(program, "multiply", ref err); } catch (Exception exc) { MessageBox.Show(exc.ToString()); } }
static void Main(string[] args) { ToGrayscale.ConvertToGrayscale("image.jpg"); //Get the ids of available opencl platforms CL.GetPlatformIds(0, null, out uint platformCount); CLPlatform[] platformIds = new CLPlatform[platformCount]; CL.GetPlatformIds(platformCount, platformIds, out _); Console.WriteLine(platformIds.Length); foreach (CLPlatform platform in platformIds) { Console.WriteLine(platform.Handle); CL.GetPlatformInfo(platform, PlatformInfo.Name, out byte[] val); } //Get the device ids for each platform foreach (IntPtr platformId in platformIds) { CL.GetDeviceIds(new CLPlatform(platformId), DeviceType.All, out CLDevice[] deviceIds); CLContext context = CL.CreateContext(IntPtr.Zero, (uint)deviceIds.Length, deviceIds, IntPtr.Zero, IntPtr.Zero, out CLResultCode result); if (result != CLResultCode.Success) { throw new Exception("The context couldn't be created."); } string code = @" __kernel void add(__global float* A, __global float* B,__global float* result, const float mul) { int i = get_global_id(0); result[i] = (A[i] + B[i])*mul; }"; CLProgram program = CL.CreateProgramWithSource(context, code, out result); CL.BuildProgram(program, (uint)deviceIds.Length, deviceIds, null, IntPtr.Zero, IntPtr.Zero); CLKernel kernel = CL.CreateKernel(program, "add", out result); int arraySize = 20; float[] A = new float[arraySize]; float[] B = new float[arraySize]; for (int i = 0; i < arraySize; i++) { A[i] = 1; B[i] = i; } CLBuffer bufferA = CL.CreateBuffer(context, MemoryFlags.ReadOnly | MemoryFlags.CopyHostPtr, A, out result); CLBuffer bufferB = CL.CreateBuffer(context, MemoryFlags.ReadOnly | MemoryFlags.CopyHostPtr, B, out result); float[] pattern = new float[] { 1, 3, 5, 7 }; CLBuffer resultBuffer = new CLBuffer(CL.CreateBuffer(context, MemoryFlags.WriteOnly, new UIntPtr((uint)(arraySize * sizeof(float))), IntPtr.Zero, out result)); try { CL.SetKernelArg(kernel, 0, bufferA); CL.SetKernelArg(kernel, 1, bufferB); CL.SetKernelArg(kernel, 2, resultBuffer); CL.SetKernelArg(kernel, 3, -1f); CLCommandQueue commandQueue = new CLCommandQueue( CL.CreateCommandQueueWithProperties(context, deviceIds[0], IntPtr.Zero, out result)); CL.EnqueueFillBuffer(commandQueue, bufferB, pattern, UIntPtr.Zero, (UIntPtr)(arraySize * sizeof(float)), null, out _); //CL.EnqueueNDRangeKernel(commandQueue, kernel, 1, null, new UIntPtr[] {new UIntPtr((uint)A.Length)}, // null, 0, null, out CLEvent eventHandle); CL.EnqueueNDRangeKernel(commandQueue, kernel, 1, null, new UIntPtr[] { new UIntPtr((uint)A.Length) }, null, 0, null, out CLEvent eventHandle); CL.Finish(commandQueue); CL.SetEventCallback(eventHandle, (int)CommandExecutionStatus.Complete, (waitEvent, data) => { float[] resultValues = new float[arraySize]; CL.EnqueueReadBuffer(commandQueue, resultBuffer, true, UIntPtr.Zero, resultValues, null, out _); StringBuilder line = new StringBuilder(); foreach (float res in resultValues) { line.Append(res); line.Append(", "); } Console.WriteLine(line.ToString()); }); //get rid of the buffers because we no longer need them CL.ReleaseMemoryObject(bufferA); CL.ReleaseMemoryObject(bufferB); CL.ReleaseMemoryObject(resultBuffer); //Release the program kernels and queues CL.ReleaseProgram(program); CL.ReleaseKernel(kernel); CL.ReleaseCommandQueue(commandQueue); CL.ReleaseContext(context); CL.ReleaseEvent(eventHandle); } catch (Exception e) { Console.WriteLine(e.ToString()); throw; } } }
internal override void SetAsKernelArgument(CLKernel kernel, int index) { throw new NotImplementedException(); }
/// <summary> /// 現在のコマンドキューを使ってカーネルを並列実行します /// </summary> /// <param name="kernel"></param> /// <param name="globalWorkSize"></param> /// <param name="localWorkSize"></param> public static void EnqueueRange(CLKernel kernel, MultiDimension globalWorkSize, MultiDimension localWorkSize) { CommandQueue.EnqueueRange(kernel, globalWorkSize, localWorkSize); }
public GPUArrangeInstructionCreator(CLKernel arrangeKernel) { ArrangeKernel = arrangeKernel; }
/// <summary> /// 現在のコマンドキューを使ってカーネルを実行します /// </summary> /// <param name="kernel"></param> public static void EnqueueTask(CLKernel kernel) { CommandQueue.EnqueueTask(kernel); }
public static void Add() { CLResultCode error = CLResultCode.Success; CLPlatform[] platforms = new CLPlatform[1]; CL.GetPlatformIds(1, platforms, out _); CLDevice[] devices = new CLDevice[1]; CL.GetDeviceIds(platforms[0], DeviceType.All, 1, devices, out _); CLContext context = CL.CreateContext(IntPtr.Zero, devices, IntPtr.Zero, IntPtr.Zero, out _); CLProgram program = CL.CreateProgramWithSource(context, File.ReadAllText("Kernels/add_arrays.cl"), out error); error = CL.BuildProgram(program, 1, devices, null, IntPtr.Zero, IntPtr.Zero); if (error != CLResultCode.Success) { throw new Exception(error.ToString()); } CLKernel kernel = CL.CreateKernel(program, "add", out error); Span <float> inputA = new float[] { 1, 24, 5, 43, 41, 56 }; Span <float> inputB = new float[] { 72, -323, -1, 43, -41, -26 }; Span <float> output = stackalloc float[inputA.Length]; CLBuffer bufferA = CL.CreateBuffer(context, MemoryFlags.ReadOnly | MemoryFlags.CopyHostPtr, inputA, out _); CLBuffer bufferB = CL.CreateBuffer(context, MemoryFlags.ReadOnly | MemoryFlags.CopyHostPtr, inputB, out _); CLBuffer outputBuffer = CL.CreateBuffer(context, MemoryFlags.WriteOnly, (UIntPtr)(output.Length * sizeof(float)), IntPtr.Zero, out _); //For outputs I wouldn't use that also enqueueing a ReadBuffer is needed regardless //CLBuffer outputBuffer = CL.CreateBuffer(context, MemoryFlags.WriteOnly | MemoryFlags.UseHostPtr, output, out _); CL.SetKernelArg(kernel, 0, bufferA); CL.SetKernelArg(kernel, 1, bufferB); CL.SetKernelArg(kernel, 2, outputBuffer); CLCommandQueue queue = CL.CreateCommandQueueWithProperties(context, devices[0], IntPtr.Zero, out error); CL.EnqueueNDRangeKernel(queue, kernel, 1, null, new[] { (UIntPtr)inputA.Length }, null, 0, null, out _); CL.EnqueueReadBuffer(queue, outputBuffer, true, UIntPtr.Zero, output, null, out _); foreach (float f in output) { Console.WriteLine(f); } CL.ReleaseMemoryObject(bufferA); CL.ReleaseMemoryObject(bufferB); CL.ReleaseMemoryObject(outputBuffer); CL.ReleaseCommandQueue(queue); CL.ReleaseKernel(kernel); CL.ReleaseProgram(program); CL.ReleaseContext(context); }
public GPUArrangeFLInstruction(List <FLInstructionArgument> arguments, CLKernel arrangeKernel) : base(arguments) { ArrangeKernel = arrangeKernel; }
public SignalEditor(CLKernel kernel, Texture texture) : base(kernel, texture) { }