using System; using System.IO; using System.Runtime.InteropServices; using System.Diagnostics; using System.Text; using Cloo; using OpenTK; using OpenTK.Compute.CL10; using System.Collections.Generic; namespace AsyncReadTest { [StructLayout(LayoutKind.Sequential, Pack = 8)] struct TestStruct { public int testInt; public float testFloat; } class AsyncReadTest { public void Run() { #region Create Context StreamReader sourceReader = File.OpenText("Kernel.cl"); string testKernel = sourceReader.ReadToEnd(); sourceReader.Close(); ComputeContextPropertyList cpl = new ComputeContextPropertyList(ComputePlatform.Platforms[0]); ComputeContext context = new ComputeContext(ComputeDeviceTypes.Default, cpl, null, IntPtr.Zero); ComputeProgram program = new ComputeProgram(context, new string[] { testKernel }); try { program.Build(null, null, null, IntPtr.Zero); } catch (ComputeException) { } finally { string errorMessages = program.GetBuildLog(context.Devices[0]); StreamWriter errorSW = new StreamWriter("BuildLog.txt"); errorSW.Write(errorMessages); errorSW.Close(); Console.WriteLine(errorMessages); } ComputeKernel kernel = program.CreateKernel("KernelTest"); ComputeCommandQueue queue = new ComputeCommandQueue(context, context.Devices[0], ComputeCommandQueueFlags.None); ComputeEventList events = new ComputeEventList(); #endregion List hMemList = new List(); TestStruct inputStruct = new TestStruct(); inputStruct.testInt = 12345; inputStruct.testFloat = 1.2345f; TestStruct outputStruct = new TestStruct(); outputStruct.testInt = -1; outputStruct.testFloat = -1; GCHandle outputStructPtr = GCHandle.Alloc(outputStruct, GCHandleType.Pinned); ClooHelpers.SetKernelArg(ref inputStruct, ref context, ref hMemList, ref kernel, MemFlags.MemReadOnly | MemFlags.MemCopyHostPtr, 0); ClooHelpers.SetKernelArg(ref outputStruct, ref context, ref hMemList, ref kernel, MemFlags.MemReadWrite | MemFlags.MemCopyHostPtr, 1); Console.WriteLine("---Async Read Demo---"); Console.WriteLine("Executing....."); queue.Execute(kernel, null, new long[] { 1 }, null, null); queue.Finish(); // True for blocking, false for an async read outputStruct.testInt = -1; outputStruct.testFloat = -1; ClooHelpers.ReadKernelArg(ref outputStruct, ref queue, hMemList[1], true, outputStructPtr); queue.Finish(); // Should output 12345 and 1.2345 if the read was successful Console.WriteLine("Blocking Output:"); Console.WriteLine("testInt: " + outputStruct.testInt); Console.WriteLine("testFloat: " + outputStruct.testFloat); Console.WriteLine(); // True for blocking, false for an async read outputStruct.testInt = -1; outputStruct.testFloat = -1; //ClooHelpers.ReadKernelArg(ref outputStruct, ref queue, hMemList[1], false, outputStructPtr); unsafe { CL.EnqueueReadBuffer( queue.Handle, hMemList[1], false, new IntPtr( 0 ), new IntPtr( Marshal.SizeOf( outputStruct ) ), new IntPtr( &outputStruct ), //ref outputStruct, 0, ( IntPtr* )null, ( IntPtr* )null ); } queue.Finish(); // Should output 12345 and 1.2345 if the read was successful Console.WriteLine("Async Output:"); Console.WriteLine("testInt: " + outputStruct.testInt); Console.WriteLine("testFloat: " + outputStruct.testFloat); Console.WriteLine(); // Cleanup for (int i = 0; i < hMemList.Count; i++) { CL.ReleaseMemObject(hMemList[i]); } outputStructPtr.Free(); } } }