public RtRaster <double> RunCpuInterpolation(YieldReportData dataPoints, IGeometry dataBoundary)
        {
            var bounds = new RTBounds(dataBoundary).ToMeters();
            var xMax   = bounds.MaxX;
            var xMin   = bounds.MinX;
            var yMax   = bounds.MaxY;
            var yMin   = bounds.MinY;

            CollectionStats yld   = dataPoints.YieldData.Yield;
            Stopwatch       timer = new Stopwatch();

            timer.Start();
            var ip     = new Interpolator();
            var raster = ip.OldInterpolate(yld.data.Select(v => new RtPointZ(v.X, v.Y, (float)v.Z)).ToList(), xMin, xMax, yMin, yMax, 0.0f, 4, 1, 1.0f, 1.0f);

            //var raster = CommonServices.CreateHeatMap(yld.data.Select(v => new RtPointZ(v.X,v.Y,(float)v.Z)).ToList(), xMin,yMin,xMax,yMax);
            timer.Stop();
            var elapsed = timer.ElapsedTicks;

            Console.WriteLine("Cpu Interpolation took {0} ms", elapsed / (Stopwatch.Frequency / 1000));

            RtRaster <double> rasterDbl = new RtRaster <double>(raster.NumCols, raster.NumRows, raster.Xll, raster.Yll, 1.0, 1);

            rasterDbl.SetRasterBand(0, raster.Bands[0].TransformDataBand(v => (double)v));
            return(rasterDbl);
        }
        public RtRaster <double> RunGpuInterpolation(YieldReportData dataPoints, IGeometry dataBoundary)
        {
            try
            {
                int cellSize = 1;
                var bounds   = new RTBounds(dataBoundary).ToMeters();
                var xMax     = bounds.MaxX;
                var xMin     = bounds.MinX;
                var yMax     = bounds.MaxY;
                var yMin     = bounds.MinY;
                var xDist    = (int)(xMax - xMin + 1);
                var yDist    = (int)(yMax - yMin + 1);
                //var cost = (xDist * yDist * dataPoints.Count) / (Environment.ProcessorCount * cellSize * cellSize);
                var nCols = xDist / cellSize;
                var nRows = yDist / cellSize;

                CollectionStats yld = dataPoints.YieldData.Yield;
                //create host side arrays for input data and boundary and output data
                double[] h_datax = yld.DataPoints.Select(pt => RtPoint <double> .LatLonToMeters(pt)).Select(ptz => ptz.X).ToArray();
                double[] h_datay = yld.DataPoints.Select(pt => RtPoint <double> .LatLonToMeters(pt)).Select(ptz => ptz.Y).ToArray();
                double[] h_dataz = yld.DataPoints.Select(pt => RtPoint <double> .LatLonToMeters(pt)).Select(ptz => ptz.Z).ToArray();

                var dataSize = sizeof(double) * h_datax.Length;
                Console.WriteLine("Performing interpolation on {0} data points of {1} bytes", h_datax.Length, dataSize);
                var      cols      = Enumerable.Range(0, nCols - 1).ToArray();
                var      coords    = Enumerable.Range(0, nRows).SelectMany(row => cols.Select(col => Tuple.Create(row, col))).ToArray();
                double[] h_outputx = coords.Select(coord => xMin + (coord.Item2 * cellSize)).ToArray();
                double[] h_outputy = coords.Select(coord => yMin + (coord.Item1 * cellSize)).ToArray();
                double[] h_outputz = coords.Select(coord => 0.0).ToArray();

                var outputSize = sizeof(double) * h_outputx.Length;
                Console.WriteLine("Output Raster has {0} raster points of {1} bytes", h_outputx.Length, outputSize);
                double2[] h_boundCoords = dataBoundary.Coordinates.Select(coord => new double2(coord.X, coord.Y)).ToArray();
                using (CudaDeviceVariable <double> d_datax = h_datax)
                    using (CudaDeviceVariable <double> d_datay = h_datay)
                        using (CudaDeviceVariable <double> d_dataz = h_dataz)
                            using (CudaDeviceVariable <double> d_outputx = h_outputx)
                                using (CudaDeviceVariable <double> d_outputy = h_outputy)
                                    using (CudaDeviceVariable <double> d_outputz = h_outputz)
                                    {
                                        const int ThreadsPerBlock = 512;
                                        InterpolateKernel.BlockDimensions = ThreadsPerBlock;
                                        InterpolateKernel.GridDimensions  = (h_outputx.Length + ThreadsPerBlock - 1) / ThreadsPerBlock;
                                        Console.WriteLine("Invoke Kernel with Grid Dimensions = {0}", InterpolateKernel.GridDimensions);

                                        Stopwatch timer = new Stopwatch();
                                        timer.Start();
                                        InterpolateKernel.Run(d_datax.DevicePointer, d_datay.DevicePointer, d_dataz.DevicePointer,
                                                              d_outputx.DevicePointer, d_outputy.DevicePointer, d_outputz.DevicePointer,
                                                              h_outputx.Length, h_datax.Length);
                                        timer.Stop();
                                        var elapsed = timer.ElapsedTicks;
                                        Console.WriteLine("Gpu Interpolation took {0} ms", elapsed / (Stopwatch.Frequency / 1000));
                                        h_outputz = d_outputz;
                                    }

                if (h_outputz.All(pt => pt != 0.0))
                {
                    Console.WriteLine("Kernel succeeded");
                }
                else
                {
                    Console.WriteLine("Kernel failed");
                }

                var raster      = new RtRaster <double>(nCols, nRows, xMin, yMin, cellSize * 2);
                var noDataValue = 0.0f;
                var rasterBand  = RtRasterBand <double> .CreateRasterBand(typeof(double), nCols, nRows, noDataValue, h_outputz);

                raster.SetRasterBand(0, rasterBand);

                return(raster);
            }


            catch (Exception ex)
            {
                ctx.Dispose();

                Console.WriteLine(ex.Message + "\nStackTrace: " + ex.StackTrace);
                //+
                //    ex.InnerException == null ? "" :
                //    String.Format("\n\t{0}\n\tStackTrace: {1}", ex.InnerException.Message,
                //    ex.InnerException.StackTrace)

                return(null);
            }
        }