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 string GetOpenCLSourceFooter(OpenCLNet.Platform platform, OpenCLNet.Device device) { StringBuilder result = new System.Text.StringBuilder(); result.AppendLine(); result.AppendLine("// END GENERATED OpenCL"); return(result.ToString()); }
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); } }