/// <summary> /// Creates a new <see cref="ComputeProgram"/> from a specified list of binaries. /// </summary> /// <param name="context"> A <see cref="ComputeContext"/>. </param> /// <param name="binaries"> A list of binaries, one for each item in <paramref name="devices"/>. </param> /// <param name="devices"> A subset of the <see cref="ComputeContext.Devices"/>. If <paramref name="devices"/> is <c>null</c>, OpenCL will associate every binary from <see cref="ComputeProgram.Binaries"/> with a corresponding <see cref="ComputeDevice"/> from <see cref="ComputeContext.Devices"/>. </param> public ComputeProgram(ComputeContext context, IList <byte[]> binaries, IList <ComputeDevice> devices) { int count; CLDeviceHandle[] deviceHandles = (devices != null) ? ComputeTools.ExtractHandles(devices, out count) : ComputeTools.ExtractHandles(context.Devices, out count); IntPtr[] binariesPtrs = new IntPtr[count]; IntPtr[] binariesLengths = new IntPtr[count]; int[] binariesStats = new int[count]; ComputeErrorCode error = ComputeErrorCode.Success; GCHandle[] binariesGCHandles = new GCHandle[count]; try { for (int i = 0; i < count; i++) { binariesGCHandles[i] = GCHandle.Alloc(binaries[i], GCHandleType.Pinned); binariesPtrs[i] = binariesGCHandles[i].AddrOfPinnedObject(); binariesLengths[i] = new IntPtr(binaries[i].Length); } Handle = CL12.CreateProgramWithBinary( context.Handle, count, deviceHandles, binariesLengths, binariesPtrs, binariesStats, out error); ComputeException.ThrowOnError(error); } finally { for (int i = 0; i < count; i++) { binariesGCHandles[i].Free(); } } this.binaries = new ReadOnlyCollection <byte[]>(binaries); this.context = context; this.devices = new ReadOnlyCollection <ComputeDevice>( (devices != null) ? devices : context.Devices); Trace.WriteLine("Create " + this + " in Thread(" + Thread.CurrentThread.ManagedThreadId + ").", "Information"); }