public void Run(ComputeContext context, TextWriter log)
        {
            try
            {
                ComputeProgram program = new ComputeProgram(context, kernelSources);
                program.Build(null, null, null, IntPtr.Zero);
                log.WriteLine("Program successfully built.");
                ICollection<ComputeKernel> kernels = program.CreateAllKernels();
                log.WriteLine("Kernels successfully created.");

                // cleanup kernels
                foreach (ComputeKernel kernel in kernels)
                {
                    kernel.Dispose();
                }
                kernels.Clear();

                // cleanup program
                program.Dispose();
            }
            catch (Exception e)
            {
                log.WriteLine(e.ToString());
            }
        }
Beispiel #2
0
        public KernelManager(GraphicsInterop interop, InputManager input, string source)
        {
            _input = input;
            var localSizeSingle = (long)Math.Sqrt(interop.Device.MaxWorkGroupSize);
            _localSize = new[] { localSizeSingle, localSizeSingle };
            //_localSize = new[] { interop.Device.MaxWorkGroupSize, 1 };

            _program = new ComputeProgram(interop.Context, source);
            try
            {
                _program.Build(new[] { interop.Device }, "", null, IntPtr.Zero);
            }
            catch (InvalidBinaryComputeException)
            {
                Console.WriteLine(_program.GetBuildLog(interop.Device));
                return;
            }
            catch (BuildProgramFailureComputeException)
            {
                Console.WriteLine(_program.GetBuildLog(interop.Device));
                return;
            }
            Console.WriteLine(_program.GetBuildLog(interop.Device));
            _kernels = _program.CreateAllKernels().ToArray();
        }
Beispiel #3
0
 protected override void RunInternal()
 {
     ComputeProgram program = new ComputeProgram(context, new string[] { kernelSource });
     program.Build(null, null, null, IntPtr.Zero);
     byte[] bytes = program.Binaries[0];
     Console.WriteLine("Compiled program head:");
     Console.WriteLine(BitConverter.ToString(bytes, 0, 16) + "...");
 }
Beispiel #4
0
        internal OpenCLProgram(OpenCLContext context, ComputeProgram program)
        {
            Contract.Requires(context != null);
            Contract.Requires(program != null);

            Context = context;
            ComputeProgram = program;
        } 
Beispiel #5
0
        public virtual void Initialize() {
            platform = ComputePlatform.Platforms[0];
            device = platform.Devices[0];

            properties = new ComputeContextPropertyList(platform);
            context = new ComputeContext(new[] { device }, properties, null, IntPtr.Zero);
            program = new ComputeProgram(context, KernelSrc);
        }
Beispiel #6
0
        internal ComputeKernel(CLKernelHandle handle, ComputeProgram program)
        {
            Handle = handle;
            SetID(Handle.Value);

            context      = program.Context;
            functionName = GetStringInfo <CLKernelHandle, ComputeKernelInfo>(Handle, ComputeKernelInfo.FunctionName, CLInterface.CL12.GetKernelInfo);
            this.program = program;
        }
Beispiel #7
0
        public static void Run(TextWriter log, ComputeContext context)
        {
            StartTest(log, "Vector addition test");

            try
            {
                int count = 10;
                float[] arrA = new float[count];
                float[] arrB = new float[count];
                float[] arrC = new float[count];

                Random rand = new Random();

                for (int i = 0; i < count; i++)
                {
                    arrA[i] = (float)(rand.NextDouble() * 100);
                    arrB[i] = (float)(rand.NextDouble() * 100);
                }

                ComputeBuffer<float> a = new ComputeBuffer<float>(context, ComputeMemoryFlags.ReadOnly | ComputeMemoryFlags.CopyHostPointer, arrA);
                ComputeBuffer<float> b = new ComputeBuffer<float>(context, ComputeMemoryFlags.ReadOnly | ComputeMemoryFlags.CopyHostPointer, arrB);
                ComputeBuffer<float> c = new ComputeBuffer<float>(context, ComputeMemoryFlags.WriteOnly, arrC.Length);

                ComputeProgram program = new ComputeProgram(context, kernelSource);
                program.Build(null, null, null, IntPtr.Zero);
                ComputeKernel kernel = program.CreateKernel("VectorAdd");
                kernel.SetMemoryArgument(0, a);
                kernel.SetMemoryArgument(1, b);
                kernel.SetMemoryArgument(2, c);

                ComputeCommandQueue commands = new ComputeCommandQueue(context, context.Devices[0], ComputeCommandQueueFlags.None);

                ICollection<ComputeEventBase> events = new Collection<ComputeEventBase>();

                // BUG: ATI Stream v2.2 crash if event list not null.
                commands.Execute(kernel, null, new long[] { count }, null, events);
                //commands.Execute(kernel, null, new long[] { count }, null, null);

                arrC = new float[count];
                GCHandle arrCHandle = GCHandle.Alloc(arrC, GCHandleType.Pinned);

                commands.Read(c, true, 0, count, arrCHandle.AddrOfPinnedObject(), events);

                arrCHandle.Free();

                for (int i = 0; i < count; i++)
                    log.WriteLine("{0} + {1} = {2}", arrA[i], arrB[i], arrC[i]);
            }
            catch (Exception e)
            {
                log.WriteLine(e.ToString());
            }

            EndTest(log, "Vector addition test");
        }
        ////////////////////////////////////////////////////////////////////////////////////////////////////
        /// <summary>   Initializes a new instance of the Cloo.ComputeKernel class. </summary>
        ///
        /// <param name="handle">   The handle of the <see cref="ComputeKernel"/>. </param>
        /// <param name="program">  Gets the <see cref="ComputeProgram"/> that the
        ///                         <see cref="ComputeKernel"/> belongs to. </param>
        ////////////////////////////////////////////////////////////////////////////////////////////////////

        internal ComputeKernel(CLKernelHandle handle, ComputeProgram program)
        {
            Handle = handle;
            SetID(Handle.Value);

            context      = program.Context;
            functionName = GetStringInfo <CLKernelHandle, ComputeKernelInfo>(Handle, ComputeKernelInfo.FunctionName, CL12.GetKernelInfo);
            this.program = program;

            Trace.WriteLine("Create " + this + " in Thread(" + Thread.CurrentThread.ManagedThreadId + ").", "Information");
        }
Beispiel #9
0
        ////////////////////////////////////////////////////////////////////////////////////////////////////
        /// <summary>   Initializes a new instance of the Cloo.ComputeKernel class. </summary>
        ///
        /// <param name="handle">   The handle of the <see cref="ComputeKernel"/>. </param>
        /// <param name="program">  Gets the <see cref="ComputeProgram"/> that the
        ///                         <see cref="ComputeKernel"/> belongs to. </param>
        ////////////////////////////////////////////////////////////////////////////////////////////////////

        internal ComputeKernel(CLKernelHandle handle, ComputeProgram program)
        {
            Handle = handle;
            SetID(Handle.Value);

            context      = program.Context;
            functionName = GetStringInfo <CLKernelHandle, ComputeKernelInfo>(Handle, ComputeKernelInfo.FunctionName, CL12.GetKernelInfo);
            this.program = program;

            RILogManager.Default?.SendTrace(string.Intern("Create ") + this + string.Intern(" in Thread(") + Thread.CurrentThread.ManagedThreadId + string.Intern(")."), string.Intern("Information"));
        }
Beispiel #10
0
        internal ComputeKernel(string functionName, ComputeProgram program)
        {
            ComputeErrorCode error = ComputeErrorCode.Success;

            Handle = CLInterface.CL12.CreateKernel(program.Handle, functionName, out error);
            ComputeException.ThrowOnError(error);

            SetID(Handle.Value);

            context           = program.Context;
            this.functionName = functionName;
            this.program      = program;
        }
Beispiel #11
0
        ////////////////////////////////////////////////////////////////////////////////////////////////////
        /// <summary>   Initializes a new instance of the Cloo.ComputeKernel class. </summary>
        ///
        /// <param name="functionName"> Gets the function name of the <see cref="ComputeKernel"/>. </param>
        /// <param name="program">      Gets the <see cref="ComputeProgram"/> that the
        ///                             <see cref="ComputeKernel"/> belongs to. </param>
        ////////////////////////////////////////////////////////////////////////////////////////////////////

        internal ComputeKernel(string functionName, ComputeProgram program)
        {
            Handle = CL12.CreateKernel(program.Handle, functionName, out var error);
            ComputeException.ThrowOnError(error);

            SetID(Handle.Value);

            context           = program.Context;
            this.functionName = functionName;
            this.program      = program;

            RILogManager.Default?.SendTrace(string.Intern("Create ") + this + string.Intern(" in Thread(") + Thread.CurrentThread.ManagedThreadId + string.Intern(")."), string.Intern("Information"));
        }
 public void Run(ComputeContext context, TextWriter log)
 {
     this.log = log;
     
     try
     {
         program = new ComputeProgram(context, clSource);
         program.Build(null, null, notify, IntPtr.Zero);
     }
     catch (Exception e)
     {
         log.WriteLine(e.ToString());
     }
 }
 public void Run(ComputeContext context, TextWriter log)
 {
     try
     {
         ComputeProgram program = new ComputeProgram(context, kernelSources);
         program.Build(null, null, null, IntPtr.Zero);
         log.WriteLine("Program successfully built.");                
         program.CreateAllKernels();
         log.WriteLine("Kernels successfully created.");
     }
     catch (Exception e)
     {
         log.WriteLine(e.ToString());
     }
 }
        ////////////////////////////////////////////////////////////////////////////////////////////////////
        /// <summary>   Initializes a new instance of the Cloo.ComputeKernel class. </summary>
        ///
        /// <param name="functionName"> Gets the function name of the <see cref="ComputeKernel"/>. </param>
        /// <param name="program">      Gets the <see cref="ComputeProgram"/> that the
        ///                             <see cref="ComputeKernel"/> belongs to. </param>
        ////////////////////////////////////////////////////////////////////////////////////////////////////

        internal ComputeKernel(string functionName, ComputeProgram program)
        {
            ComputeErrorCode error = ComputeErrorCode.Success;

            Handle = CL12.CreateKernel(program.Handle, functionName, out error);
            ComputeException.ThrowOnError(error);

            SetID(Handle.Value);

            context           = program.Context;
            this.functionName = functionName;
            this.program      = program;

            Trace.WriteLine("Create " + this + " in Thread(" + Thread.CurrentThread.ManagedThreadId + ").", "Information");
        }
Beispiel #15
0
        protected override void RunInternal()
        {
            int count = 10;
            float[] arrA = new float[count];
            float[] arrB = new float[count];
            float[] arrC = new float[count];

            Random rand = new Random();

            for (int i = 0; i < count; i++)
            {
                arrA[i] = (float)(rand.NextDouble() * 100);
                arrB[i] = (float)(rand.NextDouble() * 100);
            }

            ComputeBuffer<float> a = new ComputeBuffer<float>(context, ComputeMemoryFlags.ReadOnly | ComputeMemoryFlags.CopyHostPointer, arrA);
            ComputeBuffer<float> b = new ComputeBuffer<float>(context, ComputeMemoryFlags.ReadOnly | ComputeMemoryFlags.CopyHostPointer, arrB);
            ComputeBuffer<float> c = new ComputeBuffer<float>(context, ComputeMemoryFlags.WriteOnly, arrC.Length);

            ComputeProgram program = new ComputeProgram(context, new string[] { kernelSource });
            program.Build(null, null, null, IntPtr.Zero);

            ComputeKernel kernel = program.CreateKernel("VectorAdd");
            kernel.SetMemoryArgument(0, a);
            kernel.SetMemoryArgument(1, b);
            kernel.SetMemoryArgument(2, c);

            ComputeCommandQueue commands = new ComputeCommandQueue(context, context.Devices[0], ComputeCommandQueueFlags.None);

            ComputeEventList events = new ComputeEventList();

            commands.Execute(kernel, null, new long[] { count }, null, events);

            arrC = new float[count];
            GCHandle arrCHandle = GCHandle.Alloc(arrC, GCHandleType.Pinned);

            commands.Read(c, false, 0, count, arrCHandle.AddrOfPinnedObject(), events);
            commands.Finish();

            arrCHandle.Free();

            for (int i = 0; i < count; i++)
                Console.WriteLine("{0} + {1} = {2}", arrA[i], arrB[i], arrC[i]);
        }
		public OpenCLPasswordMatcher ()
		{
			if (ComputePlatform.Platforms.Count == 0) {
				Console.WriteLine ("Cound not find any OpenCL platforms");
				Environment.Exit (1);
			}

			var platform = ComputePlatform.Platforms [0];

			logger.Info ("Found {0} computing devices:", platform.Devices.Count);

			foreach (var d in platform.Devices) {
				logger.Info ("* {0}", d.Name);
			}

			Context = new ComputeContext (ComputeDeviceTypes.All,	
				new ComputeContextPropertyList (platform), null, IntPtr.Zero);

			Device = Context.Devices [0];

			logger.Info ("Using first device.");

			// load opencl source
			StreamReader streamReader = new StreamReader (MD5_OPENCL_FILE);
			string clSource = streamReader.ReadToEnd ();
			streamReader.Close ();

			// create program with opencl source
			ComputeProgram program = new ComputeProgram (Context, clSource);

			// compile opencl source
			try {
				program.Build (null, null, null, IntPtr.Zero);
			} catch (Exception e) {
				logger.Error ("Build log: " + program.GetBuildLog(Device));
				throw e;
			}

			// load chosen kernel from program
			Kernel = program.CreateKernel ("crackMD5");
		}
Beispiel #17
0
        public static void Run(TextWriter log, ComputeContext context)
        {
            StartTest(log, "Program test");

            ProgramTest.log = log;

            try
            {
                ComputeProgram program = new ComputeProgram(context, clSource);
                program.Build(null, null, notify, IntPtr.Zero);
                byte[] bytes = program.Binaries[0];
                log.WriteLine("Compiled program head:");
                log.WriteLine(BitConverter.ToString(bytes, 0, 16) + "...");
            }
            catch (Exception e)
            {
                log.WriteLine(e.ToString());
            }

            EndTest(log, "Program test");
        }
 public void Run(ComputeContext context, TextWriter log)
 {
     this.log = log;
             try
         {
             DateTime ExecutionStartTime; //Var will hold Execution Starting Time
             DateTime ExecutionStopTime;//Var will hold Execution Stopped Time
             TimeSpan ExecutionTime;//Var will count Total Execution Time-Our Main Hero
             ExecutionStartTime = DateTime.Now; //Gets the system Current date time expressed as local time
         
             program = new ComputeProgram(context, clSource);
             program.Build(null, null, notify, IntPtr.Zero);
             //program.Build(null, null, null , IntPtr.Zero);
         
             ExecutionStopTime = DateTime.Now;
             ExecutionTime = ExecutionStopTime - ExecutionStartTime;
             log.WriteLine("Use {0} ms", ExecutionTime.TotalMilliseconds.ToString());
         }
         catch (Exception e)
         {
             log.WriteLine(e.ToString());
         }
     
 }
Beispiel #19
0
        public void InitGPU(int platformIdx)
        {
            platform = ComputePlatform.Platforms[platformIdx];
            context = new ComputeContext(ComputeDeviceTypes.Gpu, new ComputeContextPropertyList(platform), null, IntPtr.Zero);
            StreamReader streamReader = new StreamReader("../../program.cl");
            string clSource = streamReader.ReadToEnd();
            streamReader.Close();
            ComputeProgram program = new ComputeProgram(context, clSource);
            program.Build(null, null, null, IntPtr.Zero);

            ComputeKernel kernelInit = program.CreateKernel("init");
            ComputeKernel kernelUpdate = program.CreateKernel("update");

            var flags = ComputeMemoryFlags.ReadWrite | ComputeMemoryFlags.UseHostPointer;

            int aantalPixels = screen.height * screen.width;

            rays = new GPURay[aantalPixels];
            pixels = new Vector3[aantalPixels];
            setGPUCameraToCamera();
            GPUCamera[] gpuCamArray = { gpuCamera };

            ComputeBuffer<GPURay> bufferRays = new ComputeBuffer<GPURay>(context, flags, rays);
            ComputeBuffer<Vector3> bufferPixels = new ComputeBuffer<Vector3>(context, flags, pixels);
            ComputeBuffer<GPUCamera> bufferCamera = new ComputeBuffer<GPUCamera>(context, flags, gpuCamArray);

            kernelUpdate.SetMemoryArgument(0, bufferRays);
            kernelUpdate.SetMemoryArgument(1, bufferPixels);
            kernelUpdate.SetMemoryArgument(2, bufferCamera);

            ComputeCommandQueue queue = new ComputeCommandQueue(context, context.Devices[0], 0);

        }
        /// <summary>
        /// OpenCL関係の準備をする
        /// </summary>
        static void InitializeOpenCL(Real[] result, Real[] left, Real[] right)
        {
            // プラットフォームを取得
            var platform = ComputePlatform.Platforms[0];
            Console.WriteLine("プラットフォーム:{0} ({1})", platform.Name, platform.Version);

            // コンテキストを作成
            var context = new ComputeContext(Cloo.ComputeDeviceTypes.Gpu, new ComputeContextPropertyList(platform), null, IntPtr.Zero);

            // 利用可能なデバイス群を取得
            var devices = context.Devices;
            Console.WriteLine("デバイス数:{0}", devices.Count);

            // 1デバイスで使う要素数を計算
            countPerDevice = (int)Math.Ceiling((double)COUNT / devices.Count);

            // キューの配列を作成
            queues = new ComputeCommandQueue[devices.Count];

            // 利用可能なデバイスすべてに対して
            for(int i = 0; i < devices.Count; i++)
            {
                var device = devices[i];

                // キューを作成
                queues[i] = new ComputeCommandQueue(context, device, ComputeCommandQueueFlags.None);

                // デバイス情報を表示
                Console.WriteLine("* {0} ({1})", device.Name, device.Vendor);
            }

            // プログラムを作成
            var program = new ComputeProgram(context, Properties.Resources.MultiGpu);

            // ビルドしてみて
            try
            {
                string realString = ((typeof(Real) == typeof(Double)) ? "double" : "float");

                program.Build(devices,
                    string.Format(" -D REAL={0} -D REALV={0}{1} -D VLOADN=vload{1} -D VSTOREN=vstore{1} -D COUNT_PER_WORKITEM={2} -Werror", realString, VECTOR_COUNT, COUNT_PER_WORKITEM),
                    null, IntPtr.Zero);
            }
            // 失敗したら
            catch(BuildProgramFailureComputeException ex)
            {
                // ログを表示して例外を投げる
                throw new ApplicationException(string.Format("{0}\n{1}", ex.Message, program.GetBuildLog(devices[0])), ex);
            }

            // カーネルを作成
            addOneElement = new ComputeKernel[devices.Count];
            for(int i = 0; i < devices.Count; i++)
            {
                addOneElement[i] = program.CreateKernel("AddOneElement");
            }

            // バッファーを作成
            bufferLeft = new ComputeBuffer<Real>(context, ComputeMemoryFlags.ReadOnly | ComputeMemoryFlags.UseHostPointer, left);
            bufferRight = new ComputeBuffer<Real>(context, ComputeMemoryFlags.ReadOnly | ComputeMemoryFlags.UseHostPointer, right);
            bufferResult = new ComputeBuffer<Real>(context, ComputeMemoryFlags.WriteOnly | ComputeMemoryFlags.UseHostPointer, result);

            buffersLeft = new ComputeSubBuffer<Real>[devices.Count];
            buffersRight = new ComputeSubBuffer<Real>[devices.Count];
            buffersResult = new ComputeSubBuffer<Real>[devices.Count];
            for(int i = 0; i < devices.Count; i++)
            {
                buffersLeft[i] = new ComputeSubBuffer<Real>(bufferLeft, ComputeMemoryFlags.ReadOnly, countPerDevice * i, countPerDevice);
                buffersRight[i] = new ComputeSubBuffer<Real>(bufferRight, ComputeMemoryFlags.ReadOnly, countPerDevice * i, countPerDevice);
                buffersResult[i] = new ComputeSubBuffer<Real>(bufferResult, ComputeMemoryFlags.WriteOnly, countPerDevice * i, countPerDevice);
            }
        }
Beispiel #21
0
        public static void InitializeOpenCL()
        {
            string source = File.ReadAllText("MonteCarloSimulate.cl");

            //Choose Device
            ComputePlatform platform = ComputePlatform.Platforms[0];

            openCLDevice = platform.QueryDevices()[0];

            ComputeContextPropertyList properties =
                new ComputeContextPropertyList(platform);

            //Setup of stuff on our side
            openCLContext = new ComputeContext(ComputeDeviceTypes.All,
                properties, null, IntPtr.Zero);

            //Build the program, which gets us the kernel
            openCLProgram = new ComputeProgram(openCLContext, source);
            openCLProgram.Build(null, null, null, IntPtr.Zero);
            //can use notify as the 3rd command... if you want this to be non-blocking

            openCLKernel = openCLProgram.CreateKernel("MonteCarloSimulate");


        }
Beispiel #22
0
        public static void Test()
        {
            string source = File.ReadAllText("MonteCarloSimulate.cl");

            //Choose Device
            ComputePlatform platform = ComputePlatform.Platforms[0];

            ComputeDevice device = platform.QueryDevices()[0];

            ComputeContextPropertyList properties =
                new ComputeContextPropertyList(platform);

            //Setup of stuff on our side
            ComputeContext context = new ComputeContext(ComputeDeviceTypes.All,
                properties, null, IntPtr.Zero);

            //Build the program, which gets us the kernel
            ComputeProgram program = new ComputeProgram(context, source);
            program.Build(null, null, null, IntPtr.Zero);
            //can use notify as the 3rd command... if you want this to be non-blocking

            ComputeKernel kernel = program.CreateKernel("MonteCarloSimulate");


            //Create arguments
            int sideSize = 4096;
            int[] inMatrixA = new int[sideSize * sideSize];
            int[] inMatrixB = new int[sideSize * sideSize];
            int[] outMatrixC = new int[sideSize * sideSize];
            Random random = new Random((int)DateTime.Now.Ticks);

            if (sideSize <= 32)
                for (int y = 0; y < sideSize; y++)
                    for (int x = 0; x < sideSize; x++)
                    {
                        inMatrixA[y * sideSize + x] = random.Next(3);
                        inMatrixB[y * sideSize + x] = random.Next(3);
                        outMatrixC[y * sideSize + x] = 0;
                    }


            ComputeBuffer<int> bufferMatrixA = new ComputeBuffer<int>(context,
                ComputeMemoryFlags.UseHostPointer, inMatrixA);

            ComputeBuffer<int> bufferMatrixB = new ComputeBuffer<int>(context,
                ComputeMemoryFlags.UseHostPointer, inMatrixB);

            ComputeBuffer<int> bufferMatrixC = new ComputeBuffer<int>(context,
                ComputeMemoryFlags.UseHostPointer, outMatrixC);

            long localWorkSize = Math.Min(device.MaxComputeUnits, sideSize);


            //Sets arguments
            kernel.SetMemoryArgument(0, bufferMatrixA);
            kernel.SetMemoryArgument(1, bufferMatrixB);
            kernel.SetMemoryArgument(2, bufferMatrixC);
            kernel.SetLocalArgument(3, sideSize * 2);
            kernel.SetValueArgument<int>(4, sideSize);
            //kernel.SetLocalArgument(1, localWorkSize);            

            string offset = " ";
            for (int x = 0; x < sideSize; x++)
                offset += "  ";

            if (sideSize <= 32)
                for (int y = 0; y < sideSize; y++)
                {
                    Console.Write(offset);
                    for (int x = 0; x < sideSize; x++)
                        Console.Write(inMatrixA[y * sideSize + x] + " ");
                    Console.WriteLine();
                }




            //Runs commands
            ComputeCommandQueue commands = new ComputeCommandQueue(context,
                context.Devices[0], ComputeCommandQueueFlags.None);

            long executionTime = DateTime.Now.Ticks;

            //Execute kernel
            //globalWorkSize in increments of localWorkSize (max of device.MaxComputeUnits or kernel.GetWorkGroupSize())
            commands.Execute(kernel, null,
                new long[] { Math.Min(sideSize, 16), Math.Min(sideSize, 16) },
                new long[] { localWorkSize, 1 }, null);

            //globalWorkSize can be any size
            //localWorkSize product much not be greater than device.MaxComputeUnits
            //and it must not be greater than kernel.GetWorkGroupSize()
            //ESSENTIALLY, the program iterates through globalWorkSize
            //in increments of localWorkSize. Both are multidimensional,
            //but this just saves us the time of doing that
            //(1 dimension can be put to multiple if the max dimension lengths
            //are known very easily with remainder).

            //Also, you should probably use this
            //kernel.GetPreferredWorkGroupSizeMultiple(device);

            commands.Finish();

            commands.ReadFromBuffer(bufferMatrixC, ref outMatrixC, true, null);

            commands.Finish();
            executionTime = DateTime.Now.Ticks - executionTime;


            GC.Collect();
            program.Dispose();

            Console.WriteLine();
            if (sideSize <= 32)
                for (int y = 0; y < sideSize; y++)
                {
                    for (int x = 0; x < sideSize; x++)
                        Console.Write(inMatrixB[y * sideSize + x] + " ");
                    Console.Write(" ");
                    for (int x = 0; x < sideSize; x++)
                        Console.Write(outMatrixC[y * sideSize + x] + " ");

                    Console.WriteLine();
                }

            int testY = random.Next(sideSize);
            int testX = random.Next(sideSize);

            int sum = 0;
            for (int q = 0; q < sideSize; q++)
                sum += inMatrixA[q * sideSize + testX] *
                    inMatrixB[testY * sideSize + q];

            Console.WriteLine(sum == outMatrixC[testY * sideSize + testX]);

            Console.WriteLine(executionTime / 10000.0);

        }
Beispiel #23
0
        public ComputeKernel CreateKernel(object kernelInstance)
        {
            string kernelName = kernelInstance.GetType().Name;

            if (HardwareAccelerationEnabled)
            {
                IKernel program = KernelManager.LoadKernel(kernelName);

                // Create and build the opencl program.
                var computeProgram = new ComputeProgram(_context, program.Code);
                computeProgram.Build(null, null, null, IntPtr.Zero);

                // Create the kernel function and set its arguments.
                ComputeKernel kernel = computeProgram.CreateKernel("Run");

                int index = 0;

                foreach (string key in _intComputeBuffers.Keys)
                {
                    kernel.SetMemoryArgument(index, _intComputeBuffers[key]);

                    index++;
                }

                foreach (string key in _floatComputeBuffers.Keys)
                {
                    kernel.SetMemoryArgument(index, _floatComputeBuffers[key]);

                    index++;
                }

                return kernel;
            }

            return null;
        }
Beispiel #24
0
        private void CalculateConvolution(ComputeContext computeContext)
        {
            Stopwatch stopwatch = new Stopwatch();
            stopwatch.Start();

            float dx;
            bool shiftXParse = float.TryParse(textBoxShiftX.Text, NumberStyles.Float, CultureInfo.InvariantCulture.NumberFormat, out dx);
            if (!shiftXParse)
                throw new SyntaxErrorException(", needs to be .");

            float dy;
            bool shiftYParse = float.TryParse(textBoxShiftX.Text, NumberStyles.Float, CultureInfo.InvariantCulture.NumberFormat, out dy);
            if (!shiftYParse)
                throw new SyntaxErrorException(", needs to be  .");

            float dz;
            bool shiftZParse = float.TryParse(textBoxShiftX.Text, NumberStyles.Float, CultureInfo.InvariantCulture.NumberFormat, out dz);
            if (!shiftZParse)
                throw new SyntaxErrorException(", needs to be  .");

            int pixelCount = _imageDimensionX*_imageDimensionY*_imageDimensionZ;

            Console.WriteLine("Computing...");
            Console.WriteLine("Reading kernel...");

            String kernelPath = Directory.GetParent(Directory.GetCurrentDirectory()).Parent.Parent.FullName;

            String kernelString;
            using (var sr = new StreamReader(kernelPath + "\\convolution.cl"))
                kernelString = sr.ReadToEnd();

            Console.WriteLine("Reading kernel... done");

            float[] selectedTransformation = Transformations.GetTransformation((TransformationType)comboBoxTransform.SelectedItem, 1.0f / float.Parse(textBoxPixelSize.Text), 1.0f / float.Parse(textBoxPixelSize.Text), 1.0f / float.Parse(textBoxPixelSize.Text), dx, dy, dz);

            //create openCL program
            ComputeProgram computeProgram = new ComputeProgram(computeContext, kernelString);

            computeProgram.Build(computeContext.Devices, null, null, IntPtr.Zero);

            ComputeProgramBuildStatus computeProgramBuildStatus = computeProgram.GetBuildStatus(_selectedComputeDevice);
            Console.WriteLine("computeProgramBuildStatus\n\t"+computeProgramBuildStatus);

            String buildLog = computeProgram.GetBuildLog(_selectedComputeDevice);
            Console.WriteLine("buildLog");
            if (buildLog.Equals("\n"))
                Console.WriteLine("\tbuildLog is empty...");
            else
                Console.WriteLine("\t" + buildLog);

            float[] fluorophores = CsvData.ReadFluorophores(_sourceFilename);

            /////////////////////////////////////////////
            // Create a Command Queue & Event List
            /////////////////////////////////////////////
            ComputeCommandQueue computeCommandQueue = new ComputeCommandQueue(computeContext, _selectedComputeDevice, ComputeCommandQueueFlags.None);

            ////////////////////////////////////////////////////////////////
            // Create Buffers Transform
            ////////////////////////////////////////////////////////////////
            ComputeBuffer<float> fluorophoresCoords = new ComputeBuffer<float>(computeContext, ComputeMemoryFlags.ReadWrite, fluorophores.LongLength);

            ComputeBuffer<float> transformationMatrix = new ComputeBuffer<float>(computeContext, ComputeMemoryFlags.ReadOnly, selectedTransformation.LongLength);

            /////////////////////////////////////////////
            // Create the transformFluorophoresKernel
            ///////////////////////////////////////////////////////////
            ComputeKernel transformFluorophoresKernel = computeProgram.CreateKernel("transform_fluorophores");

            /////////////////////////////////////////////
            // Set the transformFluorophoresKernel arguments
            /////////////////////////////////////////////
            transformFluorophoresKernel.SetMemoryArgument(0, fluorophoresCoords);
            transformFluorophoresKernel.SetMemoryArgument(1, transformationMatrix);

            /////////////////////////////////////////////
            // Configure the work-item structure
            /////////////////////////////////////////////
            long[] globalWorkOffsetTransformFluorophoresKernel = null;
            long[] globalWorkSizeTransformFluorophoresKernel = new long[]   { fluorophores.Length / 4 };
            long[] localWorkSizeTransformFluorophoresKernel = null;

            ////////////////////////////////////////////////////////
            // Enqueue the transformFluorophoresKernel for execution
            ////////////////////////////////////////////////////////

            computeCommandQueue.WriteToBuffer(fluorophores, fluorophoresCoords, true, null);
            computeCommandQueue.WriteToBuffer(selectedTransformation, transformationMatrix, true, null);

            computeCommandQueue.Execute(transformFluorophoresKernel, globalWorkOffsetTransformFluorophoresKernel, globalWorkSizeTransformFluorophoresKernel, localWorkSizeTransformFluorophoresKernel, null);
            //            computeCommandQueue.ExecuteTask(transformFluorophoresKernel, transformFluorophoresEvents);

            float[] transformedFluorophores = new float[fluorophores.Length];

            computeCommandQueue.ReadFromBuffer(fluorophoresCoords, ref transformedFluorophores, true, null);

            computeCommandQueue.Finish();

            //TODO remove, only for testing
            //            for (int i = 0; i < transformedFluorophores.Length; i++)
            //            {
            //                Console.WriteLine(transformedFluorophores[i]);
            //            }
            // /TODO remove, only for testing

            stopwatch.Stop();
            Console.WriteLine("Transform fluophores duration:\n\t" + stopwatch.Elapsed);
            stopwatch.Reset();
            stopwatch.Start();
            // fluorophoresCoords are now transformed (done in place)

            ////////////////////////////////////////////////////////////////
            // Create Buffers Convolve Fluorophores
            ////////////////////////////////////////////////////////////////

            const int convolve_kernel_lwgs = 16;
            int totalBuffer = (int) Math.Ceiling(pixelCount / (float)convolve_kernel_lwgs) * convolve_kernel_lwgs;

            ComputeBuffer<float> resultImage = new ComputeBuffer<float>(computeContext, ComputeMemoryFlags.WriteOnly, totalBuffer);

            /////////////////////////////////////////////
            // Create the transformFluorophoresKernel
            /////////////////////////////////////////////
            ComputeKernel convolveFluorophoresKernel = computeProgram.CreateKernel("convolve_fluorophores");

            /////////////////////////////////////////////
            // Set the convolveFluorophoresKernel arguments
            /////////////////////////////////////////////

            convolveFluorophoresKernel.SetMemoryArgument(0, resultImage);
            convolveFluorophoresKernel.SetValueArgument(1, _imageDimensionX);
            convolveFluorophoresKernel.SetValueArgument(2, _imageDimensionY);
            convolveFluorophoresKernel.SetMemoryArgument(3, fluorophoresCoords);
            convolveFluorophoresKernel.SetLocalArgument(4, convolve_kernel_lwgs);
            convolveFluorophoresKernel.SetValueArgument(5, fluorophores.Length / 4);

            /////////////////////////////////////////////
            // Configure the work-item structure
            /////////////////////////////////////////////
            long[] globalWorkOffsetTransformConvolveFluorophoresKernel = null;
            long[] globalWorkSizeTransformConvolveFluorophoresKernel = new long[] { pixelCount };
            long[] localWorkSizeTransformConvolveFluorophoresKernel = new long[] {convolve_kernel_lwgs};

            ////////////////////////////////////////////////////////
            // Enqueue the convolveFluorophoresKernel for execution
            ////////////////////////////////////////////////////////

            computeCommandQueue.Execute(convolveFluorophoresKernel, globalWorkOffsetTransformConvolveFluorophoresKernel, globalWorkSizeTransformConvolveFluorophoresKernel, localWorkSizeTransformConvolveFluorophoresKernel, null);

            float[] resultImageData = new float[totalBuffer];
            computeCommandQueue.ReadFromBuffer(resultImage, ref resultImageData, true, null);

            computeCommandQueue.Finish();

            for (int i = 0; i < pixelCount; i++)
            {
                Console.WriteLine(resultImageData[i]);
            }

            Console.WriteLine("Writing data to file...");
            //            CsvData.WriteToDisk("..\\..\\..\\output.csv", resultImageData);
            TiffData.WriteToDisk(resultImageData, _saveFilename, _imageDimensionX, _imageDimensionY);

            Bitmap bitmap = new Bitmap(_imageDimensionX, _imageDimensionY);

            float max = resultImageData.Max();

            float scale = 255/(float)max;

            //            for (int r = 0; r < _imageDimensionY; r++)
            //            {
            //                for (int c = 0; c < _imageDimensionX; c++)
            //                {
            //                    float value = resultImageData[c*(r + 1)];
            //                    Color newColor = Color.FromArgb((int)(value * scale), (int)(value * scale), (int)(value * scale));
            //                    bitmap.SetPixel(c,r, newColor);
            //                }
            //            }

            ushort[] ushortdata = new ushort[resultImageData.Length];

            for (int i = 0; i < resultImageData.Length; i++)
            {
                ushortdata[i] = (ushort)resultImageData[i];
            }

            uint[] convertGray16ToRgb = ConvertGray16ToRGB(ushortdata, 16);

            byte[] bytes = new byte[convertGray16ToRgb.Length * 4];
            //
            //            int[] resultImageData2 = new int[resultImageData.Length];
            //
            for (int index = 0; index < convertGray16ToRgb.Length; index++)
            {
            //                resultImageData2[index] = (int)(scale*resultImageData[index]);

                byte[] bytes1 = BitConverter.GetBytes(convertGray16ToRgb[index]);
                bytes[index] = bytes1[0];
                bytes[4 * index + 1] = bytes1[1];
                bytes[4 * index + 2] = bytes1[2];
                bytes[4 * index + 3] = bytes1[3];
            }
            //
            //            for (int r = 0; r < _imageDimensionY; r++)
            //            {
            //                for (int c = 0; c < _imageDimensionX; c++)
            //                {
            //                    float value = resultImageData2[c*(r + 1)];
            //                    Color newColor = Color.FromArgb((int)(value), (int)(value), (int)(value));
            //                    bitmap.SetPixel(c,r, newColor);
            //                }
            //            }
            //            bitmap.Save("c:\\temp.bmp");

            using (MemoryStream ms = new MemoryStream(bytes))
            {
                Image image = Bitmap.FromStream(ms);
                image.Save("c:\\temp.bmp");
            }

            Console.WriteLine("Writing data to file... done");

            stopwatch.Stop();
            Console.WriteLine("Convolve fluophores duration:\n\t" + stopwatch.Elapsed);
            Console.WriteLine("Computing... done");
        }
        public void Run(ComputeContext context, TextWriter log)
        {
            try
            {
                // Create the arrays and fill them with random data.
                int count = 640*480; // 
                float[] arrA = new float[count];
                float[] arrB = new float[count];
                float[] arrC = new float[count];

                Random rand = new Random();
                for (int i = 0; i < count; i++)
                {
                    arrA[i] = (float)(rand.NextDouble() * 100);
                    arrB[i] = (float)(rand.NextDouble() * 100);
                }

                
                // Create the input buffers and fill them with data from the arrays.
                // Access modifiers should match those in a kernel.
                // CopyHostPointer means the buffer should be filled with the data provided in the last argument.
                

                program = new ComputeProgram(context, clProgramSource);
                program.Build(null, null, null, IntPtr.Zero);

                ComputeBuffer<float> a = new ComputeBuffer<float>(context, ComputeMemoryFlags.ReadOnly | ComputeMemoryFlags.CopyHostPointer, arrA);
                //ComputeBuffer<float> b = new ComputeBuffer<float>(context, ComputeMemoryFlags.ReadOnly | ComputeMemoryFlags.CopyHostPointer, arrB);

                // The output buffer doesn't need any data from the host. Only its size is specified (arrC.Length).
                ComputeBuffer<float> c = new ComputeBuffer<float>(context, ComputeMemoryFlags.WriteOnly, arrC.Length);

                // Create and build the opencl program.
                
                // Create the kernel function and set its arguments.
                ComputeKernel kernel = program.CreateKernel("CompareGPUCPU");
                DateTime ExecutionStartTime; //Var will hold Execution Starting Time
                DateTime ExecutionStopTime;//Var will hold Execution Stopped Time
                TimeSpan ExecutionTime;//Var will count Total Execution Time-Our Main Hero                
                ComputeCommandQueue commands = new ComputeCommandQueue(context, context.Devices[0], ComputeCommandQueueFlags.None);
                
                ExecutionStartTime = DateTime.Now; //Gets the system Current date time expressed as local time
                int repeatTimes = 100;
                for (int repeatCounter = 0; repeatCounter < repeatTimes; repeatCounter++)
                {
                    kernel.SetMemoryArgument(0, a);
                    //kernel.SetMemoryArgument(1, b);
                    //kernel.SetMemoryArgument(2, c);
                    kernel.SetMemoryArgument(1, c);

                    // Create the event wait list. An event list is not really needed for this example but it is important to see how it works.
                    // Note that events (like everything else) consume OpenCL resources and creating a lot of them may slow down execution.
                    // For this reason their use should be avoided if possible.
                    //ComputeEventList eventList = new ComputeEventList();

                    // Create the command queue. This is used to control kernel execution and manage read/write/copy operations.
                  

                    // Execute the kernel "count" times. After this call returns, "eventList" will contain an event associated with this command.
                    // If eventList == null or typeof(eventList) == ReadOnlyCollection<ComputeEventBase>, a new event will not be created.
                    //commands.Execute(kernel, null, new long[] { count }, null, eventList);
                    commands.Execute(kernel, null, new long[] { count }, null, null);

                    // Read back the results. If the command-queue has out-of-order execution enabled (default is off), ReadFromBuffer 
                    // will not execute until any previous events in eventList (in our case only eventList[0]) are marked as complete 
                    // by OpenCL. By default the command-queue will execute the commands in the same order as they are issued from the host.
                    // eventList will contain two events after this method returns.
                    //commands.ReadFromBuffer(c, ref arrC, false, eventList);
                    commands.ReadFromBuffer(c, ref arrC, false, null);

                    // A blocking "ReadFromBuffer" (if 3rd argument is true) will wait for itself and any previous commands
                    // in the command queue or eventList to finish execution. Otherwise an explicit wait for all the opencl commands 
                    // to finish has to be issued before "arrC" can be used. 
                    // This explicit synchronization can be achieved in two ways:

                    // 1) Wait for the events in the list to finish,
                    //eventList.Wait();

                    // 2) Or simply use
                    commands.Finish();
                }
                ExecutionStopTime = DateTime.Now;
                ExecutionTime = ExecutionStopTime - ExecutionStartTime;
                double perTaskTime = ExecutionTime.TotalMilliseconds / repeatTimes;
                log.WriteLine("Use {0} ms using GPU", perTaskTime);
 
                // Do that using CPU
                /*
                ExecutionStartTime = DateTime.Now; //Gets the system Current date time expressed as local time
                for (int repeatCounter = 0; repeatCounter < repeatTimes; repeatCounter++)
                {
                    for (int i = 0; i < count; i++)
                    {
                        //arrC[i] = arrA[i] + arrB[i];
                        int j;
                        for (j = 0; j < 330 * 10; j++)
                            arrC[i] = arrA[i] + j;
                    }
                }
                ExecutionStopTime = DateTime.Now;
                ExecutionTime = ExecutionStopTime - ExecutionStartTime;
                perTaskTime = ExecutionTime.TotalMilliseconds / repeatTimes;
                log.WriteLine("Use {0} ms using CPU", ExecutionTime.TotalMilliseconds.ToString());
                 */
                log.WriteLine("arrA[0]:{0}, arrC[0]:{1}", arrA[0], arrC[0]);
            }
            catch (Exception e)
            {
                log.WriteLine(e.ToString());
            }
        }
        /// <summary>
        /// Compile the kernel with a map of preprocessor defines, a collection of
        /// name-value pairs.
        /// </summary>
        ///
        /// <param name="options">A map of preprocessor defines.</param>
        public void Compile(IDictionary<String, String> options)
        {
            // clear out any old program

            if (this.program != null)
            {
                this.program.Dispose();
                this.kernel.Dispose();
            }

            // Create the program from the source code

            this.program = new ComputeProgram(this.context, this.cl);

            if (options.Count > 0)
            {
                StringBuilder builder = new StringBuilder();
                /* foreach */
                foreach (KeyValuePair<String, String> obj in options)
                {
                    if (builder.Length > 0)
                    {
                        builder.Append(" ");
                    }
                    builder.Append("-D ");
                    builder.Append(obj.Key);
                    builder.Append("=");
                    builder.Append(obj.Value);
                }

                program.Build(null, builder.ToString(), null, IntPtr.Zero);
            }
            else
            {
                program.Build(null, null, null, IntPtr.Zero);
            }

            // Create the kernel
            this.kernel = Program.CreateKernel(this.kernelName);
        }
Beispiel #27
0
        /// <summary>
        /// Entry point for a standard work thread.
        /// </summary>
        private void WorkThread()
        {
            InitializeOpenCL();

            try
            {
                // continue working until canceled
                while (!cts.IsCancellationRequested)
                    Work(Context.GetWork(this, GetType().Name));
            }
            catch (OperationCanceledException)
            {
                // ignore
            }

            clQueue.Finish();

            clKernel.Dispose();
            clKernel = null;

            clBuffer0.Dispose();
            clBuffer0 = null;

            clBuffer1.Dispose();
            clBuffer1 = null;

            clQueue.Dispose();
            clQueue = null;

            clDevice = null;

            clProgram.Dispose();
            clProgram = null;

            clContext.Dispose();
            clContext = null;
        }
 public OpenCLCalculator(ComputeContext context, ComputeProgram prg, ComputeKernel krnl)
 {
     _context = context;
     _prg = prg;
     _krnl = krnl;
 }
Beispiel #29
0
        bool useGPU = true; // GPU code enabled (from commandline)

        #endregion Fields

        #region Methods

        // initialize renderer: takes in command line parameters passed by template code
        public void Init( int rt, bool gpu, int platformIdx )
        {
            // pass command line parameters
            runningTime = rt;
            useGPU = gpu;
            gpuPlatform = platformIdx;
            // initialize accumulator
            accumulator = new Vector3[screen.width * screen.height];
            ClearAccumulator();
            // setup scene
            scene = new Scene();
            // setup camera
            camera = new Camera( screen.width, screen.height );

            // Generate randoms
            Console.Write("Generating randoms....\t");

            randoms = new float[1000];
            Random r = RTTools.GetRNG();
            for (int i = 0; i < 1000; i++)
            randoms[i] = (float)r.NextDouble();

            int variable = r.Next();

            Console.WriteLine("Done!");

            // initialize required opencl things if gpu is used
            if (useGPU)
            {
            StreamReader streamReader = new StreamReader("../../kernel.cl");
            string clSource = streamReader.ReadToEnd();
            streamReader.Close();

            platform = ComputePlatform.Platforms[0];
            context = new ComputeContext(ComputeDeviceTypes.Gpu, new ComputeContextPropertyList(platform), null, IntPtr.Zero);
            queue = new ComputeCommandQueue(context, context.Devices[0], ComputeCommandQueueFlags.None);

            program = new ComputeProgram(context, clSource);
            try
            {
                program.Build(null, null, null, IntPtr.Zero);
                kernel = program.CreateKernel("Main");

                sceneBuffer = new ComputeBuffer<Vector4>(context, ComputeMemoryFlags.ReadOnly | ComputeMemoryFlags.UseHostPointer, scene.toCL());
                rndBuffer = new ComputeBuffer<float>(context, ComputeMemoryFlags.ReadOnly | ComputeMemoryFlags.UseHostPointer, randoms);
                cameraBuffer = new ComputeBuffer<Vector3>(context, ComputeMemoryFlags.ReadOnly | ComputeMemoryFlags.UseHostPointer, camera.toCL());
                outputBuffer = new ComputeBuffer<int>(context, ComputeMemoryFlags.WriteOnly | ComputeMemoryFlags.UseHostPointer, screen.pixels);
                skydome = new ComputeBuffer<float>(context, ComputeMemoryFlags.ReadOnly | ComputeMemoryFlags.UseHostPointer, scene.Skydome);

                kernel.SetMemoryArgument(0, outputBuffer);
                kernel.SetValueArgument(1, screen.width);
                kernel.SetValueArgument(2, screen.height);
                kernel.SetMemoryArgument(3, sceneBuffer);
                kernel.SetValueArgument(4, scene.toCL().Length);
                kernel.SetMemoryArgument(5, skydome);
                kernel.SetMemoryArgument(6, cameraBuffer);
                kernel.SetMemoryArgument(7, rndBuffer);

            }
            catch (ComputeException e) {
                Console.WriteLine("Error in kernel code: {0}", program.GetBuildLog(context.Devices[0]));
                Console.ReadLine();
                useGPU = false;
            }
            }
            else {
            return;
            }
        }
        /// <summary>
        /// Initializes local fields and the underlying compute context.
        /// </summary>
        public void Initialize()
        {
            if (this.context == null)
            {
                var devices = ComputePlatform.Platforms.SelectMany(a => a.Devices).Where(a => a.Extensions.Contains("cl_khr_fp64")).Take(1).ToArray();
                ComputeContextPropertyList list = new ComputeContextPropertyList(devices[0].Platform);
                this.context = new ComputeContext(devices, list, null, IntPtr.Zero);
            }

            this.program = new ComputeProgram(this.context, File.ReadAllText("Mandelbrot.cl"));

            this.program.Build(null, null, null, IntPtr.Zero);

            this.mandelbrot = this.program.CreateKernel("Mandelbrot");
            this.toBitmap = this.program.CreateKernel("ToBitmap");

            this.resultBuffer = new ComputeBuffer<int>(this.context, ComputeMemoryFlags.ReadWrite, this.ImageWidth * this.ImageHeight);
            this.bitmapBuffer = new ComputeBuffer<byte>(this.context, ComputeMemoryFlags.ReadWrite, this.ImageWidth * this.ImageHeight * 4);

            this.mandelbrot.SetMemoryArgument(7, this.resultBuffer);
            this.toBitmap.SetMemoryArgument(1, this.resultBuffer);
            this.toBitmap.SetMemoryArgument(2, this.bitmapBuffer);

            this.commandQueue = new ComputeCommandQueue(this.context, this.context.Devices.OrderBy(a => a.Type).Where(a => a.Extensions.Contains("cl_khr_fp64")).First(), ComputeCommandQueueFlags.None);
        }
 /// <summary>
 /// Release this kernel.
 /// </summary>
 ///
 public virtual void Release()
 {
     if (this.program != null)
     {
         this.program.Dispose();
         this.kernel.Dispose();
         this.program = null;
         this.kernel = null;
     }
 }
Beispiel #32
0
        /// <summary>
        /// Attempts to initialize OpenCL for the selected GPU.
        /// </summary>
        private void InitializeOpenCL()
        {
            // only initialize once
            if (clKernel != null)
                return;

            // select the device we've been instructed to use
            clDevice = ComputePlatform.Platforms
                .SelectMany(i => i.Devices)
                .SingleOrDefault(i => i.Handle.Value == Gpu.CLDeviceHandle.Value);

            // context we'll be working underneath
            clContext = new ComputeContext(new ComputeDevice[] { clDevice }, new ComputeContextPropertyList(clDevice.Platform), null, IntPtr.Zero);

            // queue to control device
            clQueue = new ComputeCommandQueue(clContext, clDevice, ComputeCommandQueueFlags.None);

            // buffers to store kernel output
            clBuffer0 = new ComputeBuffer<uint>(clContext, ComputeMemoryFlags.ReadOnly, 16);
            clBuffer1 = new ComputeBuffer<uint>(clContext, ComputeMemoryFlags.ReadOnly, 16);

            // kernel code
            string kernelCode;
            using (var rdr = new StreamReader(GetType().Assembly.GetManifestResourceStream("BitMaker.Miner.Gpu.DiabloMiner.cl")))
                kernelCode = rdr.ReadToEnd();

            clProgram = new ComputeProgram(clContext, kernelCode);

            try
            {
                // build kernel for device
                clProgram.Build(new ComputeDevice[] { clDevice }, "-D WORKSIZE=" + clDevice.MaxWorkGroupSize, null, IntPtr.Zero);
            }
            catch (ComputeException)
            {
                throw new Exception(clProgram.GetBuildLog(clDevice));
            }

            clKernel = clProgram.CreateKernel("search");
        }
Beispiel #33
0
        private void buildProgramMenuItem_Click(object sender, EventArgs e)
        {
            if (editorTextBox.Text.Length == 0)
            {
                logTextBox.Text = "No source.";
                return;
            }

            string[] logContent;

            ComputeContextPropertyList properties = new ComputeContextPropertyList(configForm.Platform);
            ComputeContext context = new ComputeContext(configForm.Devices, properties, null, IntPtr.Zero);
            ComputeProgram program = new ComputeProgram(context, editorTextBox.Text);
            try
            {
                program.Build(configForm.Devices, configForm.Options, null, IntPtr.Zero);
                logContent = new string[] { "Build succeeded." };
            }
            catch (Exception exception)
            {
                List<string> lineList = new List<string>();
                foreach (ComputeDevice device in context.Devices)
                {
                    string header = "PLATFORM: " + configForm.Platform.Name + ", DEVICE: " + device.Name;
                    lineList.Add(header);

                    StringReader reader = new StringReader(program.GetBuildLog(device));
                    string line = reader.ReadLine();
                    while (line != null)
                    {
                        lineList.Add(line);
                        line = reader.ReadLine();
                    }

                    lineList.Add("");
                    lineList.Add(exception.Message);
                }
                logContent = lineList.ToArray();
            }

            logTextBox.Lines = logContent;
        }
Beispiel #34
0
        public void Start(IMinerContext context)
        {
            string code;

            var kernelRes = Assembly.GetExecutingAssembly().GetManifestResourceStream("BitMaker.Miner.Cloo.Miner.cl");
            using (var rdr = new StreamReader(kernelRes))
                code = clProgramSource;

            var platform = ComputePlatform.Platforms[0];
            var properties = new ComputeContextPropertyList(platform);
            device = platform.Devices[0];
            ccontext = new ComputeContext(platform.Devices, properties, null, IntPtr.Zero);
            program = new ComputeProgram(ccontext, clProgramSource);
            program.Build(null, null, notify, IntPtr.Zero);
        }
        public TerrainGen()
        {
            #if CPU_DEBUG
            var platform = ComputePlatform.Platforms[1];
            #else
            var platform = ComputePlatform.Platforms[0];
            #endif
            _devices = new List<ComputeDevice>();
            _devices.Add(platform.Devices[0]);
            _properties = new ComputeContextPropertyList(platform);
            _context = new ComputeContext(_devices, _properties, null, IntPtr.Zero);
            _cmdQueue = new ComputeCommandQueue(_context, _devices[0], ComputeCommandQueueFlags.None);

            #region setup generator kernel
            bool loadFromSource = Gbl.HasRawHashChanged[Gbl.RawDir.Scripts];
            loadFromSource = true;
            _chunkWidthInBlocks = Gbl.LoadContent<int>("TGen_ChunkWidthInBlocks");
            _chunkWidthInVerts = _chunkWidthInBlocks + 1;
            _blockWidth = Gbl.LoadContent<int>("TGen_BlockWidthInMeters");
            float lacunarity = Gbl.LoadContent<float>("TGen_Lacunarity");
            float gain = Gbl.LoadContent<float>("TGen_Gain");
            int octaves = Gbl.LoadContent<int>("TGen_Octaves");
            float offset = Gbl.LoadContent<float>("TGen_Offset");
            float hScale = Gbl.LoadContent<float>("TGen_HScale");
            float vScale = Gbl.LoadContent<float>("TGen_VScale");

            _genConstants = new ComputeBuffer<float>(_context, ComputeMemoryFlags.ReadOnly, 8);
            var genArr = new[]{
                lacunarity,
                gain,
                offset,
                octaves,
                hScale,
                vScale,
                _blockWidth,
                _chunkWidthInBlocks
            };

            _cmdQueue.WriteToBuffer(genArr, _genConstants, false, null);
            if (loadFromSource){
                _generationPrgm = new ComputeProgram(_context, Gbl.LoadScript("TGen_Generator"));
            #if CPU_DEBUG
                _generationPrgm.Build(null, @"-g -s D:\Projects\Gondola\Scripts\GenTerrain.cl", null, IntPtr.Zero); //use option -I + scriptDir for header search
            #else
                _generationPrgm.Build(null, "", null, IntPtr.Zero);//use option -I + scriptDir for header search
            #endif
                Gbl.SaveBinary(_generationPrgm.Binaries, "TGen_Generator");
            }
            else{
                var binary = Gbl.LoadBinary("TGen_Generator");
                _generationPrgm = new ComputeProgram(_context, binary, _devices);
                _generationPrgm.Build(null, "", null, IntPtr.Zero);
            }
            //loadFromSource = false;

            _terrainGenKernel = _generationPrgm.CreateKernel("GenTerrain");
            _normalGenKernel = _generationPrgm.CreateKernel("GenNormals");

            //despite the script using float3 for these fields, we need to consider it to be float4 because the
            //implementation is basically a float4 wrapper that uses zero for the last variable
            _geometry = new ComputeBuffer<float>(_context, ComputeMemoryFlags.None, _chunkWidthInVerts*_chunkWidthInVerts*4);
            _normals = new ComputeBuffer<ushort>(_context, ComputeMemoryFlags.None, _chunkWidthInVerts * _chunkWidthInVerts * 4);
            _binormals = new ComputeBuffer<byte>(_context, ComputeMemoryFlags.None, _chunkWidthInVerts*_chunkWidthInVerts*4);
            _tangents = new ComputeBuffer<byte>(_context, ComputeMemoryFlags.None, _chunkWidthInVerts*_chunkWidthInVerts*4);
            _uvCoords = new ComputeBuffer<float>(_context, ComputeMemoryFlags.None, _chunkWidthInVerts*_chunkWidthInVerts*2);

            _terrainGenKernel.SetMemoryArgument(0, _genConstants);
            _terrainGenKernel.SetMemoryArgument(3, _geometry);
            _terrainGenKernel.SetMemoryArgument(4, _uvCoords);

            _normalGenKernel.SetMemoryArgument(0, _genConstants);
            _normalGenKernel.SetMemoryArgument(3, _geometry);
            _normalGenKernel.SetMemoryArgument(4, _normals);
            _normalGenKernel.SetMemoryArgument(5, _binormals);
            _normalGenKernel.SetMemoryArgument(6, _tangents);

            #endregion

            #region setup quadtree kernel

            if (loadFromSource){
                _qTreePrgm = new ComputeProgram(_context, Gbl.LoadScript("TGen_QTree"));
            #if CPU_DEBUG
                _qTreePrgm.Build(null, @"-g -s D:\Projects\Gondola\Scripts\Quadtree.cl", null, IntPtr.Zero);
            #else
                _qTreePrgm.Build(null, "", null, IntPtr.Zero);
            #endif
                Gbl.SaveBinary(_qTreePrgm.Binaries, "TGen_QTree");
            }
            else{
                var binary = Gbl.LoadBinary("TGen_QTree");
                _qTreePrgm = new ComputeProgram(_context, binary, _devices);
                _qTreePrgm.Build(null, "", null, IntPtr.Zero);
            }

            _qTreeKernel = _qTreePrgm.CreateKernel("QuadTree");
            _crossCullKernel = _qTreePrgm.CreateKernel("CrossCull");

            _activeVerts = new ComputeBuffer<byte>(_context, ComputeMemoryFlags.None, _chunkWidthInVerts*_chunkWidthInVerts);

            _dummy = new ComputeBuffer<int>(_context, ComputeMemoryFlags.None, 50);
            var rawNormals = new ushort[_chunkWidthInVerts * _chunkWidthInVerts * 4];
            _emptyVerts = new byte[_chunkWidthInVerts*_chunkWidthInVerts];
            for (int i = 0; i < _emptyVerts.Length; i++){
                _emptyVerts[i] = 1;
            }
            _cmdQueue.WriteToBuffer(rawNormals, _normals, true, null);
            _cmdQueue.WriteToBuffer(_emptyVerts, _activeVerts, true, null);

            _qTreeKernel.SetValueArgument(1, _chunkWidthInBlocks);
            _qTreeKernel.SetMemoryArgument(2, _normals);
            _qTreeKernel.SetMemoryArgument(3, _activeVerts);
            _qTreeKernel.SetMemoryArgument(4, _dummy);

            _crossCullKernel.SetValueArgument(1, _chunkWidthInBlocks);
            _crossCullKernel.SetMemoryArgument(2, _normals);
            _crossCullKernel.SetMemoryArgument(3, _activeVerts);
            _crossCullKernel.SetMemoryArgument(4, _dummy);

            #endregion

            #region setup winding kernel

            if (loadFromSource){
                _winderPrgm = new ComputeProgram(_context, Gbl.LoadScript("TGen_VertexWinder"));
            #if CPU_DEBUG
                _winderPrgm.Build(null, @"-g -s D:\Projects\Gondola\Scripts\VertexWinder.cl", null, IntPtr.Zero);
            #else
                _winderPrgm.Build(null, "", null, IntPtr.Zero);
            #endif
                Gbl.SaveBinary(_winderPrgm.Binaries, "TGen_VertexWinder");
            }
            else{
                var binary = Gbl.LoadBinary("TGen_VertexWinder");
                _winderPrgm = new ComputeProgram(_context, binary, _devices);
                _winderPrgm.Build(null, "", null, IntPtr.Zero);
            }

            _winderKernel = _winderPrgm.CreateKernel("VertexWinder");
            _indicies = new ComputeBuffer<int>(_context, ComputeMemoryFlags.None, (_chunkWidthInBlocks)*(_chunkWidthInBlocks)*8);

            _winderKernel.SetMemoryArgument(0, _activeVerts);
            _winderKernel.SetMemoryArgument(1, _indicies);

            _emptyIndices = new int[(_chunkWidthInBlocks)*(_chunkWidthInBlocks)*8];
            for (int i = 0; i < (_chunkWidthInBlocks)*(_chunkWidthInBlocks)*8; i++){
                _emptyIndices[i] = 0;
            }
            _cmdQueue.WriteToBuffer(_emptyIndices, _indicies, true, null);

            #endregion

            if (loadFromSource){
                Gbl.AllowMD5Refresh[Gbl.RawDir.Scripts] = true;
            }

            _cmdQueue.Finish();
        }
        public ICalculator GenFractalCalc(List<ProcessLayer> LayerData, FractalType fractaltype, string code, ProcessLayer deflayer)
        {
            string macros = @"
            #pragma OPENCL EXTENSION cl_amd_printf : enable

            inline float ABS(float a) {
              return a>0?a:-a;
            }

            inline float ARGC(float2 a) {
              return atan2(a.y,a.x);
            }

            inline float NORM(float2 a) {
              return a.x*a.x+a.y*a.y;
            }

            inline float ABSC(float2 a) {
              return sqrt(NORM(a));
            }

            inline float2 MULC(float2 a, float2 b) {
              return (float2)( a.x*b.x-a.y*b.y, a.y*b.x+a.x*b.y  );
            }

            inline float2 DIVC(float2 a, float2 b) {
              return (float2)( (a.x*b.x+a.y*b.y)/(b.x*b.x+b.y*b.y), (a.y*b.x-a.x*b.y)/(b.x*b.x+b.y*b.y)  );
            }

            inline float2 lnc(float2 c) {
              float r = ABSC(c);
              float a = ARGC(c);
              return (float2)(log(r),a);
            }

            inline float2 arctanc(float2 c) {
              float2 io = (float2)(0.0f,1.0f);
              float2 two = (float2)(2.0f,0.0f);
              float2 one = (float2)(1.0f,0.0f);

              return (float2)(MULC(DIVC(io,two),lnc(one - MULC(io,c))-lnc(one + MULC(io,c))));
            }

            inline float2 powc(float2 c, float p) {
              if (NORM(c)==0) {
            return (float2)(0.0f,0.0f);
              } else {
            float r = pow(ABSC(c),p);
            float a = ARGC(c)*p;
            return (float2)(r*cos(a),r*sin(a));
              }
            }

            struct ProcessLayer {
             float2 c_old2x;
             float2 c_oldx;
             float2 c_x;
             float2 c_resx;
             float c_calc;
             float c_cmean;
             float c_cvarsx;
             float c_cvariance;
             int c_active;
             int c_isin;
             int c_n;
             int c_resn;
            };

            kernel void FractalCalc (
            global  read_only float2* in_x,
            global  read_only float2* in_c,
            ";

              StringBuilder kernel = new StringBuilder(macros);

              for (int i=0; i< LayerData.Count; i++) {
            kernel.Append("    global write_only struct ProcessLayer* out_p" + i);
            kernel.Append(i+1==LayerData.Count ? "\n){" : ",\n");
              }

              bool hastriangle = false;
              bool fractdiv = true;
              SeqType modesused = 0;

              foreach (var it in LayerData)
              {
            if (it.c_checktype.HasFlag(SeqCheck.MPL_CHECK_TRIANGLE)) hastriangle = true;
            if (it.c_checktype.HasFlag(SeqCheck.MPL_CHECK_TRIANGLE_SMOOTH)) hastriangle = true;
            modesused |= it.c_seqtype;
              }

              if (modesused.HasFlag(SeqType.MPL_SEQ_STDDEV)) modesused |= SeqType.MPL_SEQ_VARIANCE;
              if (modesused.HasFlag(SeqType.MPL_SEQ_VARIANCE)) modesused |= SeqType.MPL_SEQ_VARSX;
              if (modesused.HasFlag(SeqType.MPL_SEQ_VARSX)) modesused |= SeqType.MPL_SEQ_MEAN;

              kernel.Append("float2 sumx = (float2)(0.0f,0.0f);");
              kernel.Append("float2 meanx = (float2)(0.0f,0.0f);");
              kernel.Append("float2 varsx = (float2)(0.0f,0.0f);");
              kernel.Append("float2 variacex = (float2)(0.0f,0.0f);");
              kernel.Append("float2 sdx = (float2)(0.0f,0.0f);");
              kernel.Append("float2 minx = (float2)(0.0f,0.0f);");
              kernel.Append("float2 maxx = (float2)(0.0f,0.0f);");
              kernel.Append("float2 deltax = (float2)(0.0f,0.0f);");
              kernel.Append("float2 deltac = (float2)(0.0f,0.0f);");

              kernel.Append("float delta = 0.0f;");
              kernel.Append("float newxnorm = 0.0f;");
              kernel.Append("float lowbound = 0.0f;");
              kernel.Append("float newd = 0.0f;");

              kernel.Append("int end = 0;");
              kernel.Append("int n = 0;");
              kernel.Append("float2 newx = (float2)(0.0f,0.0f);");

              kernel.Append("int index = get_global_id(0);");
              kernel.Append("float2 x = in_x[index];");
              kernel.Append("float2 c = in_c[index];");

              for (int i = 0; i < LayerData.Count; i++)
              {
            kernel.Append("struct ProcessLayer p"+i+";");
            kernel.Append("p"+i+".c_active = 1;");
            kernel.Append("p"+i+".c_isin = 0;");
            kernel.Append("p"+i+".c_x = x;");
            kernel.Append("p"+i+".c_oldx = x;");
            kernel.Append("p"+i+".c_old2x = x;");
            kernel.Append("p"+i+".c_calc = 0;");
            kernel.Append("p"+i+".c_cmean = 0;");
            kernel.Append("p"+i+".c_cvarsx = 0;");
            kernel.Append("p"+i+".c_cvariance = 0;");
              }

              kernel.Append("struct ProcessLayer* p = 0;");

              if (hastriangle)
              {
            if (fractaltype == FractalType.FRACTAL_TYPE_MANDEL)
            {
              kernel.Append("float trinorm = ABSC(c);");
              // trinorm = c.Magnitude;
            }
            else
            {
              kernel.Append("float trinorm = NORM(c);");
              // trinorm = c.Norm;
            }
              }

              kernel.Append("while (!end) {");
              // while (!end)
              kernel.Append("n++;");
              // n++;

              switch (fractaltype)
              {
            case FractalType.FRACTAL_TYPE_MANDEL:
              kernel.Append("newx = (float2)(x.x*x.x - x.y*x.y,2*x.x*x.y) + c;");
              //kernel.Append(@"printf(""%f %f - "",newx.x,newx.y);");
              //double sx = x.Real;
              //double sy = x.Imaginary;
              //return new Complex(sx * sx - sy * sy + c.Real, 2 * sx * sy + c.Imaginary);
              break;
            case FractalType.FRACTAL_TYPE_MANDEL_N:
              kernel.Append("newx = powc(x,pr) + c;");
              // return Complex.Pow(x, param) + c;
              break;
            case FractalType.FRACTAL_TYPE_BURNINGSHIP:
              kernel.Append("newx = (float2)(x.x*x.x-x.y*x.y,2*ABS(x.x*x.y)) + c;");
              //  double sx = x.Real;
              //  double sy = x.Imaginary;
              //  return new Complex(sx * sx - sy * sy + c.Real, 2 * absval(sx * sy) + c.Imaginary);
              break;
            case FractalType.FRACTAL_TYPE_BURNINGSHIP_N:
              kernel.Append("newx = powc((ABS(x.x),ABS(x.y)),pr) + c;");
              // return Complex.Pow(new Complex(absval(x.Real), absval(x.Imaginary)), n) + c;
              break;
            case FractalType.FRACTAL_TYPE_DIVERGENT:
              kernel.Append("newx = " + code + ";");
              //  newx = code.eval(x, c, n, param);
              break;
            case FractalType.FRACTAL_TYPE_CONVERGENT:
              kernel.Append("newx = " + code + ";");
              fractdiv = false;
              break;
            default:
              throw new NotSupportedException("Unknown FractalType");
              }
              if (modesused.HasFlag(SeqType.MPL_SEQ_SUM))
              {
            kernel.Append("sumx += newx;");
            //sumx+=newx;
              }
              if (modesused.HasFlag(SeqType.MPL_SEQ_MEAN))
              {
            kernel.Append("deltax = newx-meanx;");
            kernel.Append("meanx += deltax/(float)n;");
            /*Complex delta = newx-meanx;
            meanx = meanx+delta/(double)n;*/
            if (modesused.HasFlag(SeqType.MPL_SEQ_VARSX))
            {
              kernel.Append("varsx += MULC(deltax,(newx-meanx));");
              //varsx = varsx + delta*(newx-meanx);
              if (modesused.HasFlag(SeqType.MPL_SEQ_VARIANCE))
              {
            kernel.Append("if (n!=1) {");
            // if (n!=1) {
            kernel.Append("variacex = varsx / (float)((float)n-(float)1.0f);");
            //variacex = varsx/((double)n-(double)1);
            if (modesused.HasFlag(SeqType.MPL_SEQ_STDDEV))
            {
              kernel.Append("sdx = powc(variacex,0.5f);");
              //sdx = Complex.Sqrt(variacex);
            }
            kernel.Append("}");
              }
            }
              }
              if (modesused.HasFlag(SeqType.MPL_SEQ_MIN))
              {
            kernel.Append("if (n==1) minx = newx; else {");
            kernel.Append("if (NORM(newx)<NORM(minx)) { minx = newx; } }");
            //if (n==1) minx=newx; else if (Complex.Abs(newx)<Complex.Abs(minx)) minx=newx;
              }
              if (modesused.HasFlag(SeqType.MPL_SEQ_MAX))
              {
            kernel.Append("if (n==1) maxx = newx; else {");
            kernel.Append("if (NORM(newx)>NORM(maxx)) { maxx = newx; } }");
            //if (n==1) maxx=newx; else if (Complex.Abs(newx)>Complex.Abs(maxx)) maxx=newx;
              }
              if (modesused.HasFlag(SeqType.MPL_SEQ_DELTA))
              {
            kernel.Append("deltax = newx - x");
            //deltax = newx-x;
              }

              for (int i=0; i< LayerData.Count; i++)
              {
            var p = LayerData[i];
            kernel.Append("p = &p"+i+";");
            kernel.Append("if (p->c_active) {");
            //if (p.c_active) {
            kernel.Append("p->c_n = n;");
            //p.c_n = n;
            kernel.Append("p->c_old2x = p->c_oldx;");
            kernel.Append("p->c_oldx = p->c_x;");
            //p.c_old2x = p.c_oldx;
            //p.c_oldx = p.c_x;
            switch (p.c_seqtype)
            {
              case SeqType.MPL_SEQ_NORMAL: kernel.Append("p->c_x = newx;"); break; // p.c_x = newx; break;
              case SeqType.MPL_SEQ_SUM: kernel.Append("p->c_x = sumx;"); break; //  p.c_x = sumx; break;
              case SeqType.MPL_SEQ_MEAN: kernel.Append("p->c_x = meanx;"); break;// p.c_x = meanx; break;
              case SeqType.MPL_SEQ_VARSX: kernel.Append("p->c_x = varsx;"); break;
              case SeqType.MPL_SEQ_VARIANCE: kernel.Append("p->c_x = variacex;"); break; // p.c_x = variacex; break;
              case SeqType.MPL_SEQ_STDDEV: kernel.Append("p->c_x = sdx;"); break; // p.c_x = sdx; break;
              case SeqType.MPL_SEQ_MIN: kernel.Append("p->c_x = minx;"); break; //  p.c_x = minx; break;
              case SeqType.MPL_SEQ_MAX: kernel.Append("p->c_x = maxx;"); break; //  p.c_x = maxx; break;
              case SeqType.MPL_SEQ_DELTA: kernel.Append("p->c_x = deltax;"); break; //  p.c_x = deltax; break;
              default: kernel.Append("p->c_x = newx;"); break; // p.c_x = newx; break;
            }
            kernel.Append("newd = 0;");
            //double newd = 0;

            switch (p.c_checktype)
            {
              case SeqCheck.MPL_CHECK_SMOOTH:
            if (fractdiv)
            {
              kernel.Append("newd = exp(-ABSC(p->c_x));");
              //newd = Math.Exp(-Complex.Abs(p.c_x));
            }
            else
            {
              kernel.Append("newd = exp(-ABSC(p->c_x-p->c_oldx));");
              //newd = Math.Exp(-Complex.Abs(p.c_x-p.c_oldx));
            }
            break;
              case SeqCheck.MPL_CHECK_REAL:
            kernel.Append("newd = p->c_x.x;");
            //newd = p.c_x.Real;
            break;
              case SeqCheck.MPL_CHECK_IMAG:
            kernel.Append("newd = p->c_x.y;");
            //newd = p.c_x.Imaginary;
            break;
              case SeqCheck.MPL_CHECK_ARG:
            kernel.Append("newd = atan2(p->c_x.y,p->c_x.x);");
            //newd = p.c_x.Phase;
            break;
              case SeqCheck.MPL_CHECK_ABS:
            kernel.Append("newd = ABSC(p->c_x);");
            //newd = p.c_x.Magnitude;
            break;
              case SeqCheck.MPL_CHECK_CURVATURE:
            kernel.Append("if (isnotequal(p.c_oldx,p.c_old2x)) { newd = ABSC(atanc(DIVC(p->c_x-p->c_oldx,p->c_oldx-p->c_old2x))); } else newd = 0;");
            //if ((p.c_oldx!=p.c_old2x)) newd=Complex.Abs(Complex.Atan((p.c_x-p.c_oldx) / (p.c_oldx-p.c_old2x))); else newd=0; }
            break;
              case SeqCheck.MPL_CHECK_TRIANGLE:
            if (fractaltype == FractalType.FRACTAL_TYPE_MANDEL)
            {
              kernel.Append("newxnorm = NORM(p->c_oldx);");
              //double newxnorm = p.c_oldx.Norm();
              kernel.Append("lowbound = ABS(newxnorm-trinorm);");
              //double lowbound = absval(newxnorm-trinorm);
              kernel.Append("if ((newxnorm+trinorm-lowbound)==0) newd = 0; else newd = (ABSC(p->c_x)-lowbound)/(newxnorm+trinorm-lowbound);");
              //if ((newxnorm+trinorm-lowbound)==0) newd=0; else
              //  newd = (p.c_x.Magnitude-lowbound)/(newxnorm+trinorm-lowbound);
            }
            else
            {
              kernel.Append("newxnorm = ABSC(p->c_x);");
              //double newxnorm = p.c_x.Magnitude;
              kernel.Append("lowbound = ABS(newxnorm-trinorm);");
              //double lowbound = absval(newxnorm-trinorm);
              kernel.Append("if ((newxnorm+trinorm-lowbound)==0) newd = 0; else newd = (ABSC(p->c_x-c)-lowbound)/(newxnorm+trinorm-lowbound);");
              //if ((newxnorm+trinorm-lowbound)==0) newd=0; else
              //  newd = ((Complex.Abs(p.c_x-c)-lowbound)/(newxnorm+trinorm-lowbound));
            }
            break;
              case SeqCheck.MPL_CHECK_TRIANGLE_SMOOTH:
            if (fractaltype == FractalType.FRACTAL_TYPE_MANDEL)
            {
              kernel.Append("newxnorm = NORM(p->c_oldx);");
              //double newxnorm = p.c_oldx.Norm();
              kernel.Append("lowbound = ABS(newxnorm-trinorm);");
              //double lowbound = absval(newxnorm-trinorm);
              kernel.Append("if ((newxnorm+trinorm-lowbound)==0) newd = 0; else newd = (ABSC(p->c_x)-lowbound)/(newxnorm+trinorm-lowbound);");
              //if ((newxnorm+trinorm-lowbound)==0) newd=0; else
              //  newd = (p.c_x.Magnitude-lowbound)/(newxnorm+trinorm-lowbound);
            }
            else
            {
              kernel.Append("newxnorm = ABSC(p->c_x);");
              //double newxnorm = p.c_x.Magnitude;
              kernel.Append("lowbound = ABS(newxnorm-trinorm);");
              //double lowbound = absval(newxnorm-trinorm);
              kernel.Append("if ((newxnorm+trinorm-lowbound)==0) newd = 0; else newd = (ABSC(p->c_x-c)-lowbound)/(newxnorm+trinorm-lowbound);");
              //if ((newxnorm+trinorm-lowbound)==0) newd=0; else
              //  newd = ((Complex.Abs(p.c_x-c)-lowbound)/(newxnorm+trinorm-lowbound));
            }
            break;
              case SeqCheck.MPL_CHECK_ORBIT_TRAP:
            switch (p.c_orbittraptype)
            {
              case OrbitTrap.MPL_ORBIT_TRAP_POINT:
                kernel.Append("newd = ABSC(p->c_x - p->c_pointA);");
                //newd = Complex.Abs(p.c_x - p.c_pointA);
                break;
              case OrbitTrap.MPL_ORBIT_TRAP_LINE:
                if ((p.c_pointA.Real) == 1)
                {
                  kernel.Append("newd = ABS(p->c_x.x);");
                  //newd = Math.Abs(p.c_x.Real);
                }
                else
                {
                  kernel.Append("newd = ABS(p->c_x.y);");
                  //newd = Math.Abs(p.c_x.Imaginary);
                }
                break;
              case OrbitTrap.MPL_ORBIT_TRAP_GAUSS:
                {
                  kernel.Append("newd = ABSC((round(p->c_x.x),round(p->c_x.y)) - p->c_x);");
                  //Complex gauss = new Complex(Math.Round(p.c_x.Real),Math.Round(p.c_x.Imaginary));
                  //newd = Complex.Abs(gauss - p.c_x);
                }
                break;
            }
            break;
            }
            switch (p.c_checkseqtype)
            {
              case SeqType.MPL_SEQ_NORMAL: kernel.Append("p->c_calc = newd;"); break;
              case SeqType.MPL_SEQ_SUM: kernel.Append("p->c_calc += newd;"); break; // p.c_calc += newd; break;
              case SeqType.MPL_SEQ_MEAN: kernel.Append("p->c_calc += newd;"); break; // p.c_calc += newd; break;
              case SeqType.MPL_SEQ_VARSX:
            {
              kernel.Append("delta = newd - p->c_cmean;");
              //double delta = newd - p.c_cmean;
              kernel.Append("p->c_cmean = p->c_cmean + delta / p->c_n;");
              //p.c_cmean = p.c_cmean+delta/p.c_n;
              kernel.Append("p->c_calc += delta * (newd - p->c_cmean);");
              //p.c_calc += delta*(newd-p.c_cmean);
            }
            break;
              case SeqType.MPL_SEQ_VARIANCE:
            {
              kernel.Append("delta = newd - p->c_cmean;");
              //double delta = newd - p.c_cmean;
              kernel.Append("p->c_cmean = p->c_cmean + delta / p->c_n;");
              //p.c_cmean = p.c_cmean+delta/p.c_n;
              kernel.Append("p->c_cvarsx += delta * (newd - p->c_cmean);");
              //p.c_cvarsx = p.c_cvarsx + delta*(newd-p.c_cmean);
              kernel.Append("if (p->c_n!=1) { p->c_calc = p->c_cvarsx/(p->c_n-1.0f); }");
              /*if (p.c_n!=1) {
                p.c_calc = p.c_cvarsx/(p.c_n-1.0);
              }*/
            }
            break;
              case SeqType.MPL_SEQ_STDDEV:
            {
              kernel.Append("delta = newd - p->c_cmean;");
              //double delta = newd - p.c_cmean;
              kernel.Append("p->c_cmean = p->c_cmean + delta / p->c_n;");
              //p.c_cmean = p.c_cmean+delta/p.c_n;
              kernel.Append("p->c_cvarsx += delta * (newd - p->c_cmean);");
              //p.c_cvarsx = p.c_cvarsx + delta*(newd-p.c_cmean);
              kernel.Append("if (p->c_n!=1) { p->c_cvariance = p->c_cvarsx/((float)p->c_n-1.0f);");
              /*if (p.c_n!=1) {
                p.c_cvariance = p.c_cvarsx/(p.c_n-1.0);
              }*/
              kernel.Append("p->c_calc = sqrt(p->c_cvariance);");
              //p.c_calc = Math.Sqrt(p.c_cvariance);
              kernel.Append("}");
            }
            break;
              case SeqType.MPL_SEQ_MIN:
            kernel.Append("if (p->c_n==1) p->c_calc = newd; else if (p->c_calc>newd) { p->c_calc = newd; p->c_resx = p->c_x; p->c_resn = p->c_n; };");
            //if (p.c_n==1) p.c_calc=newd; else if (p.c_calc>newd) { p.c_calc = newd; p.c_resx = p.c_x; p.c_resn = p.c_n; }
            break;
              case SeqType.MPL_SEQ_MAX:
            kernel.Append("if (p->c_n==1) p->c_calc = newd; else if (p->c_calc<newd) { p->c_calc = newd; p->c_resx = p->c_x; p->c_resn = p->c_n; };");
            // if (p.c_n==1) p.c_calc=newd; else if (p.c_calc<newd) { p.c_calc = newd; p.c_resx = p.c_x; p.c_resn = p.c_n; }
            break;
              case SeqType.MPL_SEQ_DELTA:
            kernel.Append("p->c_calc = newd-p->c_calc;");
            //p.c_calc = newd-p.c_calc;
            break;
              default:
            kernel.Append("p->c_calc = newd;");
            //p.c_calc = newd;
            break;
            }

            if (p.c_convchktype == ConvCheck.MPL_CONVCHK_REAL)
            {
              kernel.AppendFormat(CultureInfo.InvariantCulture,"if (p->c_x.x*p->c_x.x " + (fractdiv ? ">" : "<") + " {0:E}f) p->c_active = 0;", p.c_bailout);
              /*double ddd = p.c_x.Real*p.c_x.Real;
              if ((fractdiv) && ( ddd>p.c_bailout)) p.c_active = false;
              if (!(fractdiv) && ( ddd<p.c_bailout)) p.c_active = false;*/
            }
            else if (p.c_convchktype == ConvCheck.MPL_CONVCHK_IMAG)
            {
              kernel.AppendFormat(CultureInfo.InvariantCulture, "if (p->c_x.y*p->c_x.y " + (fractdiv ? ">" : "<") + " {0:E}f) p->c_active = 0;", p.c_bailout);
              /*double ddd = p.c_x.Imaginary*p.c_x.Imaginary;
              if ((fractdiv) && ( ddd>p.c_bailout)) p.c_active = false;
              if (!(fractdiv) && ( ddd<p.c_bailout)) p.c_active = false;*/
            }
            else if (p.c_convchktype == ConvCheck.MPL_CONVCHK_OR)
            {
              kernel.AppendFormat(CultureInfo.InvariantCulture, "if ((p->c_x.y*p->c_x.y " + (fractdiv ? ">" : "<") + " {0:E}f) || (p->c_x.x*p->c_x.x " + (fractdiv ? ">" : "<") + " {0:E}f)) p->c_active = 0;", p.c_bailout);
              /*if ((fractdiv) && ((p.c_x.Real*p.c_x.Real>p.c_bailout) || (p.c_x.Imaginary*p.c_x.Imaginary>p.c_bailout))) p.c_active = false;
              if (!(fractdiv) && ((p.c_x.Real*p.c_x.Real<p.c_bailout) || (p.c_x.Imaginary*p.c_x.Imaginary<p.c_bailout))) p.c_active = false;*/
            }
            else if (p.c_convchktype == ConvCheck.MPL_CONVCHK_AND)
            {
              kernel.AppendFormat(CultureInfo.InvariantCulture, "if ((p->c_x.y*p->c_x.y " + (fractdiv ? ">" : "<") + " {0:E}f) && (p->c_x.x*p->c_x.x " + (fractdiv ? ">" : "<") + " {0:E}f)) p->c_active = 0;", p.c_bailout);
              /*if ((fractdiv) && ((p.c_x.Real*p.c_x.Real>p.c_bailout) && (p.c_x.Imaginary*p.c_x.Imaginary>p.c_bailout))) p.c_active = false;
              if (!(fractdiv) && ((p.c_x.Real*p.c_x.Real<p.c_bailout) && (p.c_x.Imaginary*p.c_x.Imaginary<p.c_bailout))) p.c_active = false;*/
            }
            else if (p.c_convchktype == ConvCheck.MPL_CONVCHK_MANH)
            {
              kernel.AppendFormat(CultureInfo.InvariantCulture, "if ( ((ABS(p->c_x.y)+ABS(p->c_x.x))*((ABS(p->c_x.y)+ABS(p->c_x.x))) " + (fractdiv ? ">" : "<") + " {0:G}f)) p->c_active = 0;", p.c_bailout);
              /*double ddd = (absval(p.c_x.Imaginary)+absval(p.c_x.Real))*(absval(p.c_x.Imaginary)+absval(p.c_x.Real));
               if ((fractdiv) && ( ddd>p.c_bailout)) p.c_active = false;
              if (!(fractdiv) && ( ddd<p.c_bailout)) p.c_active = false;*/
            }
            else if (p.c_convchktype == ConvCheck.MPL_CONVCHK_MANR)
            {
              kernel.AppendFormat(CultureInfo.InvariantCulture, "if ( ((p->c_x.y+p->c_x.x)*(p->c_x.y+p->c_x.x)) " + (fractdiv ? ">" : "<") + " {0:E}f)) p->c_active = 0;", p.c_bailout);
              /*double ddd = (p.c_x.Real+p.c_x.Imaginary)*(p.c_x.Real+p.c_x.Imaginary);
               if ((fractdiv) && ( ddd>p.c_bailout)) p.c_active = false;
              if (!(fractdiv) && ( ddd<p.c_bailout)) p.c_active = false; */
            }
            else
            {
              kernel.AppendFormat(CultureInfo.InvariantCulture, "if (NORM(p->c_x) " + (fractdiv ? ">" : "<") + " {0:E}f) p->c_active = 0;", p.c_bailout);
              /*double ddd = p.c_x.Norm();
               if ((fractdiv) && ( ddd>p.c_bailout)) p.c_active = false;
              if (!(fractdiv) && ( ddd<p.c_bailout)) p.c_active = false;*/
            }
            kernel.AppendFormat(CultureInfo.InvariantCulture, "if (p->c_n>{0}) {{ p->c_active = 0; p->c_isin = 1; }}", p.c_nlimit);
            //if (p.c_n>p.c_nlimit) { p.c_active = false; p.c_isin = true; }
            if (p.c_checktype == SeqCheck.MPL_CHECK_TRIANGLE_SMOOTH)
            {
              throw new NotImplementedException("Smooth triangle algorithm is unavailable in this CalculatorFactory");
              /*if (p.c_active == false)
            if (!p.c_isin) {
              p.c_oldx = p.c_x;
              p.c_x = Fractal_Mandel(p.c_x,c);
              p.c_n++;
              double newxnorm = p.c_oldx.Norm();
              double lowbound = absval(newxnorm-trinorm);
              if ((newxnorm+trinorm-lowbound)==0) newd=0; else
                newd = (p.c_x.Magnitude-lowbound)/(newxnorm+trinorm-lowbound);
              p.c_calc += newd;
              double oldsum = p.c_calc/(p.c_n+1);
              double il2=1/Math.Log(2);
              double lp=Math.Log(Math.Log(p.c_bailout));
              double f=il2*lp-il2*Math.Log(Math.Log(Complex.Abs(p.c_x)))+2;
              double az2 = p.c_x.Norm();
              p.c_oldx = p.c_x;
              p.c_x = Fractal_Mandel(p.c_oldx,c);
              lowbound = absval(az2-trinorm);
              if ((az2+trinorm-lowbound)!=0) p.c_calc+=(Complex.Abs(p.c_x)-lowbound)/(az2+trinorm-lowbound);
              p.c_n++;
              p.c_calc = p.c_calc/(p.c_n+1);
              p.c_calc = oldsum+(p.c_calc-oldsum)*(f-1);
            } else {
              p.c_calc /= p.c_n+1;
            }*/
            }
            else if (p.c_checkseqtype == SeqType.MPL_SEQ_MEAN)
            {
              kernel.Append("if (p->c_active == 0) p->c_calc /= (float)p->c_n+1.0f;");
              //if (p.c_active == false) p.c_calc /= p.c_n+1;
            }
            if (p == deflayer)
            {
              kernel.Append("if (p->c_active == 0) end = 1;");
              /*if (!deflayer.c_active) end = true; */
            }
            kernel.Append("}");

              }
              kernel.Append("x = newx; }");
              for (int i = 0; i < LayerData.Count; i++)
              {
            kernel.Append("out_p"+i+"[index] = p"+i+";");
            //kernel.Append("out_p" + i + "[index].c_calc = 52.0f;");
              }
              kernel.Append("}");

              //System.Console.WriteLine(kernel.Replace(";", ";\n").Replace("}","}\n"));
              //kernel.Clear();
              //kernel.Append(@"kernel void VectorAdd(global  read_only float* a,global  read_only float* b,global write_only float* c ){int index = get_global_id(0);c[index] = a[index] + b[index];}");

              ComputeProgram prg = new ComputeProgram(_context, kernel.Replace(";", ";\n").Replace("}","}\n").ToString());
              try
              {
            prg.Build(null, null, null, IntPtr.Zero);
              }
              catch (ComputeException e)
              {
            throw new Exception("Error while building: " + prg.GetBuildLog(_context.Devices[0]), e);
              }
              ComputeKernel krnl = prg.CreateKernel("FractalCalc");

              return new OpenCLCalculator(_context,prg,krnl);
        }