public static MemoryBuffer Copy <T>(CLAPI instance, MemoryBuffer input) where T : struct { CLKernel k = null; if (CopyKernels.ContainsKey(instance)) { k = CopyKernels[instance]; } else { string clt = KernelParameter.GetDataString(KernelParameter.GetEnumFromType(typeof(T))); string src = COPY_KERNEL_SOURCE.Replace("__TYPE__", clt); CLProgram.TryBuildProgram(instance, src, "internal_copy_kernel.cl", out CLProgram prog); k = prog.ContainedKernels["copy"]; CopyKernels[instance] = k; } MemoryBuffer mb = CreateEmpty <T>( instance, ( int )input.Size, input.Flags, "CopyOf:" + input, true ); k.SetBuffer(0, mb); k.SetBuffer(1, input); Run(instance, k, ( int )mb.Size); return(mb); }
/// <summary> /// Runs a kernel with a valid FL kernel signature /// </summary> /// <param name="instance">CLAPI Instance for the current thread</param> /// <param name="kernel">The CLKernel to be executed</param> /// <param name="image">The image buffer that serves as input</param> /// <param name="dimensions">The dimensions of the input buffer</param> /// <param name="genTypeMaxVal">The max valuee of the generic type that is used.(byte = 255)</param> /// <param name="enabledChannels">The enabled channels for the kernel</param> /// <param name="channelCount">The amount of active channels.</param> public static void Run( CLAPI instance, CLKernel kernel, MemoryBuffer image, int3 dimensions, float genTypeMaxVal, MemoryBuffer enabledChannels, int channelCount) { kernel.Run(instance.commandQueue, image, dimensions, genTypeMaxVal, enabledChannels, channelCount); }
//Optimization private static MemoryBuffer CreateEmptyOptimized <T>( CLAPI instance, int size, MemoryFlag flags, object handleIdentifier) where T : struct { //return CreateBuffer(instance, new byte[size], flags, handleIdentifier); int bufByteSize = Marshal.SizeOf <T>() * size; return(instance.context.CreateBuffer(flags | MemoryFlag.AllocateHostPointer, bufByteSize, handleIdentifier)); }
/// <summary> /// Casts the supplied value to the specified type /// </summary> /// <param name="instance">CLAPI Instance for the current thread</param> /// <param name="value">the value casted to the required type for the parameter</param> /// <returns></returns> public object CastToType(CLAPI instance, object value) { if (IsArray) { throw new OpenClException("Can not Change types on an array."); } return(CastToType(Converters[( int )DataType], value)); }
/// <summary> /// Writes random values to a Memory Buffer /// </summary> /// <typeparam name="T">Type of the values</typeparam> /// <param name="instance">CLAPI Instance for the current thread</param> /// <param name="buf">MemoryBuffer containing the values to overwrite</param> /// <param name="rnd">the RandomFunc delegate providing the random numbers.</param> /// <param name="enabledChannels">the channels that are enables(aka. get written with bytes)</param> public static void WriteRandom <T>( CLAPI instance, MemoryBuffer buf, RandomFunc <T> rnd, byte[] enabledChannels) where T : struct { WriteRandom(instance, buf, rnd, enabledChannels, true); }
public CLProgram AddProgram(CLAPI instance, string file, bool throwEx, out CLProgramBuildResult ex) { ex = new CLProgramBuildResult(file, "", new List <CLProgramBuildError>()); if (!File.Exists(file)) { Exception e = new FileNotFoundException("File not found: " + file); if (throwEx) { throw e; } ex.BuildErrors.Add(new CLProgramBuildError(ErrorType.ProgramBuild, e)); } string path = file; Logger.Log(LogType.Log, "Creating CLProgram from file: " + file, 3); CLProgramBuildResult br = CLProgram.TryBuildProgram(instance, path, out CLProgram program); ex.Source = br.Source; if (!br) { if (throwEx) { throw br.GetAggregateException(); } ex.BuildErrors.AddRange(br.BuildErrors); return(null); } loadedPrograms.Add(program); foreach (KeyValuePair <string, CLKernel> containedKernel in program.ContainedKernels) { if (!loadedKernels.ContainsKey(containedKernel.Key)) { Logger.Log(LogType.Log, "Adding Kernel: " + containedKernel.Key, 4); loadedKernels.Add(containedKernel.Key, containedKernel.Value); } else { Logger.Log( LogType.Log, "Kernel with name: " + containedKernel.Key + " is already loaded. Skipping...", 5 ); } } return(program); }
public static CLProgramBuildResult TryBuildProgram(CLAPI instance, string filePath, out CLProgram program) { //string source = TextProcessorAPI.PreprocessSource(IOManager.ReadAllLines(filePath), // Path.GetDirectoryName(filePath), Path.GetExtension(filePath), new Dictionary<string, bool>()); string source = TextProcessorAPI.PreprocessSource(filePath, new Dictionary <string, bool>()); // program = null; return(TryBuildProgram(instance, source, filePath, out program)); }
/// <summary> /// Creates an empty buffer of type T with the specified size and MemoryFlags /// </summary> /// <typeparam name="T">The type of the struct</typeparam> /// <param name="instance">CLAPI Instance for the current thread</param> /// <param name="size">The size of the buffer(Total size in bytes: size*sizeof(T)</param> /// <param name="flags">The memory flags for the buffer creation</param> /// <returns></returns> public static MemoryBuffer CreateEmpty <T>( CLAPI instance, int size, MemoryFlag flags, object handleIdentifier, bool optimize = false) where T : struct { if (!optimize) { return(CreateBuffer(instance, new byte[size], flags, handleIdentifier)); } return(CreateEmptyOptimized <T>(instance, size, flags, handleIdentifier)); }
internal static Program CreateClProgramFromSource(CLAPI instance, string source) { try { return(instance.context.CreateAndBuildProgramFromString(source)); } catch (Exception e) { throw new OpenClException("Could not compile file", e); } }
/// <summary> /// Creates a Buffer with the specified content and Memory Flags /// </summary> /// <typeparam name="T">Type of the struct</typeparam> /// <param name="instance">CLAPI Instance for the current thread</param> /// <param name="data">The array of T</param> /// <param name="flags">The memory flags for the buffer creation</param> /// <returns></returns> public static MemoryBuffer CreateBuffer <T>( CLAPI instance, T[] data, MemoryFlag flags, object handleIdentifier) where T : struct { object[] arr = Array.ConvertAll(data, x => ( object )x); return(CreateBuffer(instance, arr, typeof(T), flags, handleIdentifier)); }
public static void UpdateBitmap(CLAPI instance, Bitmap target, byte[] bytes) { BGRAtoARGB(bytes); BitmapData data = target.LockBits( new Rectangle(0, 0, target.Width, target.Height), ImageLockMode.WriteOnly, PixelFormat.Format32bppArgb ); Marshal.Copy(bytes, 0, data.Scan0, bytes.Length); target.UnlockBits(data); }
public static MemoryBuffer CreateBuffer( CLAPI instance, object[] data, Type t, MemoryFlag flags, object handleIdentifier) { MemoryBuffer mb = instance.context.CreateBuffer( flags | MemoryFlag.CopyHostPointer, t, data, handleIdentifier ); return(mb); }
/// <summary> /// Writes random values to a MemoryBuffer /// </summary> /// <typeparam name="T">Type of the values</typeparam> /// <param name="instance">CLAPI Instance for the current thread</param> /// <param name="buf">MemoryBuffer containing the values to overwrite</param> /// <param name="rnd">the RandomFunc delegate providing the random numbers.</param> /// <param name="enabledChannels">the channels that are enables(aka. get written with bytes)</param> /// <param name="uniform">Should every channel receive the same value on the same pixel?</param> public static void WriteRandom <T>( CLAPI instance, MemoryBuffer buf, RandomFunc <T> rnd, byte[] enabledChannels, bool uniform) where T : struct { MemoryBuffer buffer = buf; T[] data = instance.commandQueue.EnqueueReadBuffer <T>(buffer, (int)buffer.Size); WriteRandom(data, enabledChannels, rnd, uniform); instance.commandQueue.EnqueueWriteBuffer(buffer, data); }
/// <summary> /// Public constructor /// </summary> /// <param name="instance">CLAPI Instance for the current thread</param> /// <param name="folderName">Folder name where the kernels are located</param> /// <param name="genDataVectorType">The DataVectorTypes used to compile the FL Database</param> public KernelDatabase(CLAPI instance, string folderName, DataVectorTypes genDataVectorType) : base( OpenCLDebugConfig.Settings, "DB" ) { GenDataType = KernelParameter.GetDataString(genDataVectorType); loadedPrograms = new List <CLProgram>(); loadedKernels = new Dictionary <string, CLKernel>(); if (Directory.Exists(folderName)) { LoadFolder(instance, folderName); } }
/// <summary> /// Constructor /// </summary> /// <param name="instance">CLAPI Instance for the current thread</param> /// <param name="k">The Compiled and Linked Kernel</param> /// <param name="name">The name of the kernel</param> /// <param name="parameter">The parsed KernelParameter</param> public CLKernel(CLAPI instance, Kernel k, string name, KernelParameter[] parameter) { this.instance = instance; Kernel = k; Name = name; Parameter = new Dictionary <string, KernelParameter>(); IEnumerable <KeyValuePair <string, KernelParameter> > l = parameter.Select( x => new KeyValuePair <string, KernelParameter>(x.Name, x) ); foreach (KeyValuePair <string, KernelParameter> keyValuePair in l) { Parameter.Add(keyValuePair.Key, keyValuePair.Value); } }
public CLProgram AddProgram( CLAPI instance, string source, string filePath, bool throwEx, out CLProgramBuildResult ex) { ex = new CLProgramBuildResult(filePath, "", new List <CLProgramBuildError>()); CLProgramBuildResult br = CLProgram.TryBuildProgram(instance, source, filePath, out CLProgram program); ex.Source = br.Source; if (!br) { if (throwEx) { throw br.GetAggregateException(); } ex.BuildErrors.AddRange(br.BuildErrors); return(null); } loadedPrograms.Add(program); foreach (KeyValuePair <string, CLKernel> containedKernel in program.ContainedKernels) { if (!loadedKernels.ContainsKey(containedKernel.Key)) { Logger.Log(LogType.Log, "Adding Kernel: " + containedKernel.Key, 4); loadedKernels.Add(containedKernel.Key, containedKernel.Value); } else { Logger.Log( LogType.Log, "Kernel with name: " + containedKernel.Key + " is already loaded. Skipping...", 5 ); } } return(program); }
/// <summary> /// Initializes the Kernel Database /// </summary> public void LoadFolder(CLAPI instance, string folderName) { string[] files = IOManager.GetFiles(folderName, "*.cl"); List <CLProgramBuildResult> results = new List <CLProgramBuildResult>(); bool throwEx = false; foreach (string file in files) { AddProgram(instance, file, false, out CLProgramBuildResult res); throwEx |= !res; results.Add(res); } if (throwEx) { throw new CLBuildException(results); } }
/// <summary> /// Creates a buffer with the content of an image and the specified Memory Flags /// </summary> /// <param name="instance">CLAPI Instance for the current thread</param> /// <param name="bmp">The image that holds the data</param> /// <param name="flags">The memory flags for the buffer creation</param> /// <returns></returns> public static MemoryBuffer CreateFromImage( CLAPI instance, Bitmap bmp, MemoryFlag flags, object handleIdentifier) { BitmapData data = bmp.LockBits( new Rectangle(0, 0, bmp.Width, bmp.Height), ImageLockMode.ReadOnly, PixelFormat.Format32bppArgb ); byte[] buffer = new byte[bmp.Width * bmp.Height * 4]; Marshal.Copy(data.Scan0, buffer, 0, buffer.Length); bmp.UnlockBits(data); ARGBtoBGRA(buffer); MemoryBuffer mb = CreateBuffer(instance, buffer, flags, handleIdentifier); return(mb); }
internal static Program CreateClProgramFromSource(CLAPI instance, string[] source) { return(instance.context.CreateAndBuildProgramFromString(source)); }
/// <summary> /// Writes values to a MemoryBuffer /// </summary> /// <typeparam name="T">Type of the values</typeparam> /// <param name="instance">CLAPI Instance for the current thread</param> /// <param name="buf">MemoryBuffer containing the values to overwrite</param> /// <param name="values">The values to be written to the buffer</param> public static void WriteToBuffer <T>(CLAPI instance, MemoryBuffer buf, T[] values) where T : struct { instance.commandQueue.EnqueueWriteBuffer(buf, values); }
public static void UpdateBitmap(CLAPI instance, Bitmap target, MemoryBuffer buffer) { byte[] bs = ReadBuffer <byte>(instance, buffer, ( int )buffer.Size); UpdateBitmap(instance, target, bs); }
public static void Run(CLAPI instance, CLKernel kernel, int groupSize) { kernel.Run(instance.commandQueue, 1, groupSize); }
/// <summary> /// Reinitializes the CL API /// Used by The unit tests when requireing actual CL api calls(e.g. not in NO_CL mode) /// </summary> public static void Reinitialize() { Instance = new CLAPI(); }
/// <summary> /// Writes values to a MemoryBuffer /// </summary> /// <typeparam name="T">Type of the values</typeparam> /// <param name="instance">CLAPI Instance for the current thread</param> /// <param name="buf">MemoryBuffer containing the values to overwrite</param> /// <param name="size">The count of structs to be read from the buffer</param> /// <returns>The content of the buffer</returns> public static T[] ReadBuffer <T>(CLAPI instance, MemoryBuffer buf, int size) where T : struct { return(instance.commandQueue.EnqueueReadBuffer <T>(buf, size)); }
public static void Flush(CLAPI instance) { instance.commandQueue.Flush(); }
/// <summary> /// Returns the Command queue(dont use, its just for debugging if something is wrong) /// </summary> /// <returns>The Internal Command queue</returns> internal static CommandQueue GetQueue(CLAPI instance) { return(instance.commandQueue); }
/// <summary> /// Manually adds a Program to the database /// </summary> /// <param name="instance">CLAPI Instance for the current thread</param> /// <param name="file">Path fo the file</param> public void AddProgram(CLAPI instance, string file) { AddProgram(instance, file, true, out CLProgramBuildResult _); }
public static CLProgramBuildResult TryBuildProgram( CLAPI instance, string source, string filePath, out CLProgram program) { CLProgramBuildResult result = new CLProgramBuildResult( filePath, source, new List <CLProgramBuildError>() ); string[] kernelNames = FindKernelNames(source); if (kernelNames.Length == 0) { program = new CLProgram(filePath, new Dictionary <string, CLKernel>(), source); return(result); } Program prgHandle; try { prgHandle = CLAPI.CreateClProgramFromSource(instance, source); } catch (Exception e) { result.BuildErrors.Add(new CLProgramBuildError(ErrorType.ProgramBuild, e)); program = null; return(result); //We can not progress } Dictionary <string, CLKernel> kernels = new Dictionary <string, CLKernel>(); foreach (string kernelName in kernelNames) { try { Kernel k = CLAPI.CreateKernelFromName(prgHandle, kernelName); int kernelNameIndex = source.IndexOf(" " + kernelName + " (", StringComparison.InvariantCulture); kernelNameIndex = kernelNameIndex == -1 ? source.IndexOf(" " + kernelName + "(", StringComparison.InvariantCulture) : kernelNameIndex; KernelParameter[] parameter = KernelParameter.CreateKernelParametersFromKernelCode( source, kernelNameIndex, source.Substring( kernelNameIndex, source.Length - kernelNameIndex ). IndexOf( ')' ) + 1 ); if (k == null) { result.BuildErrors.Add( new CLProgramBuildError( ErrorType.KernelBuild, new OpenClException( $"Header parser completed on {kernelName} but the kernel could not be loaded." ) ) ); kernels.Add(kernelName, new CLKernel(instance, null, kernelName, parameter)); } else { kernels.Add(kernelName, new CLKernel(instance, k, kernelName, parameter)); } } catch (Exception e) { result.BuildErrors.Add(new CLProgramBuildError(ErrorType.KernelBuild, e)); //We can try other kernels } } program = new CLProgram(filePath, kernels, source); program.ClProgramHandle = prgHandle; return(result); }
public static void DisposeInstance() { Instance.Dispose(); Instance = null; }