private static void setExtensionIfAvailable(StringBuilder result, OpenCLNet.Device device, string extension) { if (device.HasExtension(extension)) { result.AppendLine("#pragma OPENCL EXTENSION " + extension + " : enable"); } }
private static string GetOpenCLSourceHeader(OpenCLNet.Platform platform, OpenCLNet.Device device, HlGraphEntry KernelGraphEntry) { StringBuilder result = new System.Text.StringBuilder(); result.AppendLine("// BEGIN GENERATED OpenCL"); setExtensionIfAvailable(result, device, "cl_amd_fp64"); setExtensionIfAvailable(result, device, "cl_khr_fp64"); setExtensionIfAvailable(result, device, "cl_khr_global_int32_base_atomics"); setExtensionIfAvailable(result, device, "cl_khr_global_int32_extended_atomics"); setExtensionIfAvailable(result, device, "cl_khr_local_int32_base_atomics"); setExtensionIfAvailable(result, device, "cl_khr_local_int32_extended_atomics"); if (KernelGraphEntry.HlGraph.RandomStateLocation != null) { result.AppendLine(); result.AppendLine("// Source: http://www.doc.ic.ac.uk/~dt10/research/rngs-gpu-mwc64x.html"); result.AppendLine("uint MWC64X(uint2 *state)"); result.AppendLine("{"); result.AppendLine(" enum{ A=4294883355U };"); result.AppendLine(" uint x=(*state).x, c=(*state).y; // Unpack the state"); result.AppendLine(" uint res=x^c; // Calculate the result"); result.AppendLine(" uint hi=mul_hi(x,A); // Step the RNG"); result.AppendLine(" x=x*A+c;"); result.AppendLine(" c=hi+(x<c);"); result.AppendLine(" *state=(uint2)(x,c); // Pack the state back up"); result.AppendLine(" return res; // Return the next result"); result.AppendLine("}"); } return(result.ToString()); }
private static HlGraphEntry GetHlGraph(MethodInfo Method, int GidParamCount, OpenCLNet.Device device) { HlGraphEntry CacheEntry; if (device == null) { device = OpenCLInterop.GetFirstGpu(); } if (device == null) { device = OpenCLInterop.GetFirstCpu(); } if (device == null) { throw new Exception("No OpenCL Compute Device found in the system!"); } if (hlGraphCache.TryGetValue(device.DeviceID, Method, out CacheEntry)) { return(CacheEntry); } CacheEntry = ConstructKernelHlGraphEntry(Method, GidParamCount); CacheEntry.Device = device; hlGraphCache.SetValue(device.DeviceID, Method, CacheEntry); return(CacheEntry); }
private static string GetOpenCLSourceFooter(OpenCLNet.Platform platform, OpenCLNet.Device device) { StringBuilder result = new System.Text.StringBuilder(); result.AppendLine(); result.AppendLine("// END GENERATED OpenCL"); return(result.ToString()); }
private MemoryInfo getSharedMemory(OpenCLNet.Device device) { switch (device.LocalMemType) { case OpenCLNet.DeviceLocalMemType.GLOBAL: return(null); case OpenCLNet.DeviceLocalMemType.LOCAL: return(new MemoryInfo(MemoryInfo.Type.Shared, device.LocalMemSize)); default: throw new Exception("LocalMemType " + device.LocalMemType.ToString() + " is unknown."); } }
public GpuComputeUnit(OpenCLNet.Device device) { AtomicsSupported = device.Extensions.Contains("atomics"); DoublePrecisionFloatingPointSupported = device.Extensions.Contains("fp64"); ProcessingElements = new List <ProcessingElement>(); for (int i = 0; i < getProcessingElementCount(device); i++) { ProcessingElements.Add(new GpuProcessingElement(device)); } SharedMemory = getSharedMemory(device); Caches = getCaches(device); }
private List <MemoryInfo> getCaches(OpenCLNet.Device device) { List <MemoryInfo> result = new List <MemoryInfo>(); if (device.GlobalMemCacheSize > 0) { result.Add( new MemoryInfo(MemoryInfo.Type.Cache, mapCacheAccess(device.GlobalMemCacheType), device.GlobalMemCacheSize) ); } result.Add( new MemoryInfo(MemoryInfo.Type.Cache, MemoryInfo.Access.ReadOnly, device.MaxConstantBufferSize) ); return(result); }
private ComputeDevice.DeviceTypes getDeviceType(OpenCLNet.Device device) { ComputeDevice.DeviceTypes deviceType = ComputeDevice.DeviceTypes.Unknown; if (device.DeviceType == OpenCLNet.DeviceType.CPU) { deviceType = ComputeDevice.DeviceTypes.Cpu; } if (device.DeviceType == OpenCLNet.DeviceType.GPU) { deviceType = ComputeDevice.DeviceTypes.Gpu; } if (device.DeviceType == OpenCLNet.DeviceType.ACCELERATOR) { deviceType = ComputeDevice.DeviceTypes.Accelerator; } return(deviceType); }
public GpuComputeDevice(OpenCLNet.Device device) { this.device = device; DeviceType = getDeviceType(device); Name = device.Name; Manufacturer = device.Vendor; DeviceId = device.DeviceID.ToString(); // TODO: get real device id from handle ComputeUnits = new List <ComputeUnit>(); for (int i = 0; i < device.MaxComputeUnits; i++) { ComputeUnits.Add(new GpuComputeUnit(device)); } GlobalMemory = new MemoryInfo(MemoryInfo.Type.Global, device.GlobalMemSize); // TODO L2Cache }
private uint getProcessingElementCount(OpenCLNet.Device device) { return(8); // TODO: Get Real Values. }
internal static void CallOpenCLNet(int[] WorkSize, HlGraphEntry CacheEntry, InvokeContext ctx, HighLevel.HlGraph HLgraph, OpenCLNet.Device device) { // We can invoke the kernel using the arguments from ctx now :) if (device == null) { device = GetFirstGpu(); if (device == null) { device = GetFirstCpu(); } if (device == null) { throw new ArgumentNullException("device"); } } OpenCLNet.Platform Platform = device.Platform; OpenCLNet.Context context; OpenCLNet.Program program; lock (CacheEntry) { context = CacheEntry.Context; if (context == null) { IntPtr[] properties = new IntPtr[] { new IntPtr((long)OpenCLNet.ContextProperties.PLATFORM), Platform.PlatformID, IntPtr.Zero, }; context = CacheEntry.Context = Platform.CreateContext(properties, new OpenCLNet.Device[] { device }, null, IntPtr.Zero); } program = CacheEntry.Program; if (program == null) { StringBuilder source = new StringBuilder(); source.Append(GetOpenCLSourceHeader(Platform, device, CacheEntry)); source.Append(CacheEntry.Source); source.Append(GetOpenCLSourceFooter(Platform, device)); program = context.CreateProgramWithSource(source.ToString()); try { program.Build(); } catch (Exception ex) { string err = program.GetBuildLog(device); throw new Exception(err, ex); } CacheEntry.Program = program; } } using (CallContext CallContext = new CallContext(context, device, OpenCLNet.CommandQueueProperties.PROFILING_ENABLE, program.CreateKernel(HLgraph.MethodName))) { OpenCLNet.CommandQueue commandQueue = CallContext.CommandQueue; for (int i = 0; i < ctx.Arguments.Count; i++) { ctx.Arguments[i].WriteToKernel(CallContext, i); } //OpenCLNet.Event StartEvent, EndEvent; //commandQueue.EnqueueMarker(out StartEvent); IntPtr[] GlobalWorkSize = new IntPtr[WorkSize.Length]; for (int i = 0; i < WorkSize.Length; i++) { GlobalWorkSize[i] = new IntPtr(WorkSize[i]); } commandQueue.EnqueueNDRangeKernel(CallContext.Kernel, (uint)GlobalWorkSize.Length, null, GlobalWorkSize, null); for (int i = 0; i < ctx.Arguments.Count; i++) { ctx.Arguments[i].ReadFromKernel(CallContext, i); } commandQueue.Finish(); //commandQueue.EnqueueMarker(out EndEvent); //commandQueue.Finish(); //ulong StartTime, EndTime; //StartEvent.GetEventProfilingInfo(OpenCLNet.ProfilingInfo.QUEUED, out StartTime); //EndEvent.GetEventProfilingInfo(OpenCLNet.ProfilingInfo.END, out EndTime); } }
public CallContext(OpenCLNet.Context Context, OpenCLNet.Device Device, OpenCLNet.CommandQueueProperties CqProperties, OpenCLNet.Kernel Kernel) { this.Context = Context; this.CommandQueue = Context.CreateCommandQueue(Device, CqProperties); this.Kernel = Kernel; }
public static void ForGpu(int fromInclusiveX, int toExclusiveX, int fromInclusiveY, int toExclusiveY, Action <int, int> action, OpenCLNet.Device device) { HlGraphEntry hlGraphEntry = GetHlGraph(action.Method, 2, device); System.Diagnostics.Debug.Assert(hlGraphEntry.fromInclusiveLocation != null && hlGraphEntry.fromInclusiveLocation.Count == 2); System.Diagnostics.Debug.Assert(hlGraphEntry.toExclusiveLocation != null && hlGraphEntry.toExclusiveLocation.Count == 2); using (InvokeContext ctx = new InvokeContext(hlGraphEntry.HlGraph)) { if (hlGraphEntry.fromInclusiveLocation.Count > 0) { ctx.PutArgument(hlGraphEntry.fromInclusiveLocation[0], fromInclusiveX); } if (hlGraphEntry.toExclusiveLocation.Count > 0) { ctx.PutArgument(hlGraphEntry.toExclusiveLocation[0], toExclusiveX); } if (hlGraphEntry.fromInclusiveLocation.Count > 1) { ctx.PutArgument(hlGraphEntry.fromInclusiveLocation[1], fromInclusiveY); } if (hlGraphEntry.toExclusiveLocation.Count > 1) { ctx.PutArgument(hlGraphEntry.toExclusiveLocation[1], toExclusiveY); } DoInvoke(new int[] { toExclusiveX - fromInclusiveX, toExclusiveY - fromInclusiveY }, action.Target, hlGraphEntry, ctx, device); } }
private static void DoInvoke(int[] WorkSize, object Target, HlGraphEntry CacheEntry, InvokeContext ctx, OpenCLNet.Device device) { HighLevel.HlGraph HLgraph = CacheEntry.HlGraph; foreach (KeyValuePair <FieldInfo, HighLevel.ArgumentLocation> Entry in HLgraph.StaticFieldMap) { ctx.PutArgument(Entry.Value, Entry.Key.GetValue(null)); } SetArguments(ctx, Target, HLgraph.RootPathEntry); /* * foreach (KeyValuePair<FieldInfo, HighLevel.ArgumentLocation> Entry in HLgraph.ThisFieldMap) * { * ctx.PutArgument(Entry.Value, Entry.Key.GetValue(Target)); * } * foreach (KeyValuePair<FieldInfo, Dictionary<FieldInfo, HighLevel.ArgumentLocation>> Entry in HLgraph.OuterThisFieldMap) { * object RealThis = Entry.Key.GetValue(Target); * foreach (KeyValuePair<FieldInfo, HighLevel.ArgumentLocation> SubEntry in Entry.Value) { * ctx.PutArgument(SubEntry.Value, SubEntry.Key.GetValue(RealThis)); * } * }*/ foreach (KeyValuePair <HighLevel.ArgumentLocation, HighLevel.ArrayInfo> Entry in HLgraph.MultiDimensionalArrayInfo) { System.Diagnostics.Debug.Assert(Entry.Key.Index >= 0 && Entry.Key.Index < ctx.Arguments.Count); InvokeArgument BaseArrayArg = ctx.Arguments[Entry.Key.Index]; System.Diagnostics.Debug.Assert(BaseArrayArg != null && BaseArrayArg.Value != null && BaseArrayArg.Value.GetType() == Entry.Key.DataType); System.Diagnostics.Debug.Assert(Entry.Key.DataType.IsArray && Entry.Key.DataType.GetArrayRank() == Entry.Value.DimensionCount); System.Diagnostics.Debug.Assert(BaseArrayArg.Value is Array); Array BaseArray = (System.Array)BaseArrayArg.Value; long BaseFactor = 1; for (int Dimension = 1; Dimension < Entry.Value.DimensionCount; Dimension++) { int ThisDimensionLength = BaseArray.GetLength(Entry.Value.DimensionCount - 1 - (Dimension - 1)); BaseFactor *= ThisDimensionLength; ctx.PutArgument(Entry.Value.ScaleArgument[Dimension], (int)BaseFactor); } } ctx.Complete(); OpenCLInterop.CallOpenCLNet(WorkSize, CacheEntry, ctx, HLgraph, device); }
public GpuProcessingElement(OpenCLNet.Device device) { ClockSpeed = device.MaxClockFrequency; }