예제 #1
0
파일: GPUManager.cs 프로젝트: Wowo51/Sym
        public void Initialize(Context context, AcceleratorId acceleratorId, double[,] independents, double[] dependants)
        {
            AcceleratorId = acceleratorId;
            AcceleratorType acceleratorType = AcceleratorId.AcceleratorType;

            if (acceleratorType == AcceleratorType.CPU)
            {
                Accelerator = Accelerator.Create(context, AcceleratorId);
            }
            else if (acceleratorType == AcceleratorType.OpenCL)
            {
                Accelerator = CLAccelerator.Create(context, AcceleratorId);
            }
            else if (acceleratorType == AcceleratorType.Cuda)
            {
                Accelerator = CudaAccelerator.Create(context, AcceleratorId);
            }
            EvaluationKernel      = Accelerator.LoadAutoGroupedStreamKernel <Index2, ArrayView2D <double>, ArrayView <double>, ArrayView <NodeGPU>, ArrayView <int>, ArrayView2D <double> >(EvaluationKernelFunction);
            ProcessResultsKernel  = Accelerator.LoadAutoGroupedStreamKernel <Index1, ArrayView2D <double>, ArrayView <double> >(ProcessResultsKernelFunction);
            IndependentsTableSize = new Index2(independents.GetUpperBound(0) + 1, independents.GetUpperBound(1) + 1);
            Independents          = Accelerator.Allocate <double>(IndependentsTableSize);
            Independents.CopyFrom(independents, new Index2(), new Index2(), IndependentsTableSize);
            Dependants = Accelerator.Allocate <double>(dependants.Length);
            Dependants.CopyFrom(dependants, 0, 0, dependants.Length);
        }
예제 #2
0
        public void GenerateHeightField(TerrainPatch patch)
        {
            using (var context = new Context())
            {
                AcceleratorId aid = Accelerator.Accelerators.Where(id => id.AcceleratorType == AcceleratorType.Cuda).FirstOrDefault();
                if (aid.AcceleratorType != AcceleratorType.Cuda)
                {
                    Console.WriteLine(@"There is no CUDA accelerator present.  Doing nothing.");
                    return;
                }
                using (var accelerator = Accelerator.Create(context, aid))
                    using (var gpu_dem = accelerator.Allocate <short>(ViperEnvironment.Terrain.Data.Length))
                        using (var gpu_range = accelerator.Allocate <float>(cpu_range.Length))
                            using (var gpu_slope = accelerator.Allocate <float>(cpu_slope.Length))
                                using (var gpu_rise = accelerator.Allocate <short>(TerrainPatch.DefaultSize * TerrainPatch.DefaultSize))
                                {
                                    gpu_dem.CopyFrom(ViperEnvironment.Terrain.Data, 0, 0, ViperEnvironment.Terrain.Data.Length);
                                    gpu_range.CopyFrom(cpu_range, 0, 0, cpu_range.Length);

                                    var launchDimension = new Index2(TerrainPatch.DefaultSize, TerrainPatch.DefaultSize);

                                    var kernel1 = accelerator.LoadStreamKernel <Index2, ArrayView <short>, ArrayView <float>, ArrayView <short>, int, int>(RiseKernel1);
                                }
            }
        }
예제 #3
0
 bool GetAccelerator(AcceleratorType t, out AcceleratorId aid)
 {
     aid = Accelerator.Accelerators.Where(id => id.AcceleratorType == t).FirstOrDefault();
     if (aid.AcceleratorType != t)
     {
         Console.WriteLine(@"There is accelerator present of the desired type.  Doing nothing.");
     }
     return(aid.AcceleratorType == t);
 }
예제 #4
0
        public Image<Rgba32> AddFilter(IImageFilter filter)
        {
            using (var context = new Context())
            {
                AcceleratorId acceleratorId = new AcceleratorId();
                if (Accelerator.Accelerators.Where(a => a.AcceleratorType == AcceleratorType.Cuda).Count() != 0)
                {
                    acceleratorId = Accelerator.Accelerators.Where(a =>
                    a.AcceleratorType == AcceleratorType.Cuda)
                        .FirstOrDefault();
                }
                else
                {
                    acceleratorId = Accelerator.Accelerators.Where(a => a.AcceleratorType == AcceleratorType.CPU).FirstOrDefault();
                }

                using (var accelerator = Accelerator.Create(context, acceleratorId))
                {
                    return filter.PerformFilter(accelerator);
                }
            }
        }
예제 #5
0
        static float EncodingToSlope(int encoding) => 4f * encoding / 1000000f;  // Haven't looked at the numerics closely to see whether these are exact inverses.  Don't care enough yet.

        /// <summary>
        /// Generate the near horizon for the patch, overwriting what was there.
        /// The horizons will be in slope format, not angles
        /// </summary>
        /// <param name="target"></param>
        public void AddNearHorizon(TerrainPatch target)
        {
            Debug.Assert(Terrain != null);
            Debug.Assert(target != null);
            if (target.Horizons == null)
            {
                target.InitializeHorizons();
            }
            using (var context = new Context())
            {
                AcceleratorId aid = Accelerator.Accelerators.Where(id => id.AcceleratorType == AcceleratorType.Cuda).FirstOrDefault();
                //AcceleratorId aid = Accelerator.Accelerators.Where(id => id.AcceleratorType == AcceleratorType.CPU).FirstOrDefault();
                if (aid.AcceleratorType != AcceleratorType.Cuda)
                {
                    Console.WriteLine(@"There is no CUDA accelerator present.  Doing nothing.");
                    return;
                }
                using (var accelerator = Accelerator.Create(context, aid))
                {
                    target.Matrices = null;  // Be sure!!
                    target.FillPoints(Terrain);
                    target.FillMatricesRelativeToPoint(Terrain, target.Points[0][0]);

                    // Matrices
                    var cpu_matrices_size = target.Height * target.Width * 12;
                    var basePoint         = target.Points[0][0];
                    var cpu_matrices      = MakeCPUMatrices(target);

                    // Horizon (load from target)
                    var cpu_horizon_size = target.Height * target.Width * Horizon.HorizonSamples;
                    var cpu_horizon      = new float[cpu_horizon_size];

                    // Initialize to float.MinValue.  Maintain horizon as slope
                    for (var i = 0; i < cpu_horizon_size; i++)
                    {
                        cpu_horizon[i] = float.MinValue;
                    }

                    // Caster array
                    const int dem_size    = TerrainPatch.DEM_size;
                    const int patch_size  = TerrainPatch.DefaultSize;
                    var       maxDistance = (float)TerrainPatch.MaximumLocalDistance;
                    var       border      = 2 + (int)Math.Ceiling(maxDistance); // the 2 is margin for the bilinear interpolation

                    var line_min    = Math.Max(0, target.Line - border);
                    var line_max    = Math.Min(dem_size - 1, target.Line + patch_size + border); // 1 more than the highest index
                    var line_size   = line_max - line_min;
                    var line_offset = target.Line - line_min;

                    var sample_min    = Math.Max(0, target.Sample - border);
                    var sample_max    = Math.Min(dem_size - 1, target.Sample + patch_size + border); // 1 more than the highest index
                    var sample_size   = sample_max - sample_min;
                    var sample_offset = target.Sample - sample_min;

                    var cpu_caster_points_size = line_size * sample_size * 3;
                    var cpu_caster_points      = new float[cpu_caster_points_size];
                    FillNearCasterArray(cpu_caster_points, target.Points[0][0], line_min, line_max, sample_min, sample_max);

                    //DumpNearFieldTestCsv(cpu_caster_points, cpu_matrices);

                    var test_floats_size = Horizon.HorizonSamples * TerrainPatch.NearHorizonOversample;
                    var test_floats      = new float[test_floats_size];

                    using (var gpu_matrices = accelerator.Allocate <float>(cpu_matrices_size))
                        using (var gpu_horizon = accelerator.Allocate <float>(cpu_horizon_size))
                            using (var gpu_caster_points = accelerator.Allocate <float>(cpu_caster_points_size))
                                using (var gpu_test_floats = accelerator.Allocate <float>(test_floats_size))
                                {
                                    gpu_matrices.CopyFrom(cpu_matrices, 0, 0, cpu_matrices_size);
                                    gpu_horizon.CopyFrom(cpu_horizon, 0, 0, cpu_horizon_size);
                                    gpu_caster_points.CopyFrom(cpu_caster_points, 0, 0, cpu_caster_points_size);
                                    gpu_test_floats.CopyFrom(test_floats, 0, 0, test_floats_size);

                                    var   groupSize       = accelerator.MaxNumThreadsPerGroup;
                                    Index launchDimension = Horizon.HorizonSamples * TerrainPatch.NearHorizonOversample;

                                    const float d_min  = 1f;
                                    var         d_max  = (float)TerrainPatch.MaximumLocalDistance;
                                    const float d_step = TerrainPatch.LocalStep;

                                    var kernel1 = accelerator.LoadAutoGroupedStreamKernel <Index, int, int, int, int, int, int, float, float, float, ArrayView <float>, ArrayView <float>, ArrayView <float>, ArrayView <float> >(NearHorizonKernel1);

                                    Console.WriteLine(@"Launching near horizon kernels ... ");
                                    if (true)
                                    {
                                        for (var target_line = 0; target_line < TerrainPatch.DefaultSize; target_line++)
                                        {
                                            for (var target_sample = 0; target_sample < TerrainPatch.DefaultSize; target_sample++)
                                            {
                                                kernel1(launchDimension, target_line, target_sample, line_offset, sample_offset, line_size, sample_size, d_min, d_max, d_step, gpu_caster_points, gpu_matrices, gpu_horizon, gpu_test_floats);
                                            }
                                        }
                                    }
                                    else
                                    {
                                        kernel1(launchDimension, 0, 0, line_offset, sample_offset, line_size, sample_size, d_min, d_max, d_step, gpu_caster_points, gpu_matrices, gpu_horizon, gpu_test_floats);
                                    }

                                    gpu_horizon.CopyTo(cpu_horizon, 0, 0, cpu_horizon_size);
                                    gpu_test_floats.CopyTo(test_floats, 0, 0, test_floats_size);

                                    // Update the horizons
                                    for (var line = 0; line < TerrainPatch.DefaultSize; line++)
                                    {
                                        for (var sample = 0; sample < TerrainPatch.DefaultSize; sample++)
                                        {
                                            var offset = (line * TerrainPatch.DefaultSize + sample) * Horizon.HorizonSamples;
                                            var buffer = target.Horizons[line][sample].Buffer;
                                            for (var i = 0; i < Horizon.HorizonSamples; i++)
                                            {
                                                buffer[i] = cpu_horizon[i + offset];
                                            }
                                        }
                                    }
                                }
                }
            }
        }
예제 #6
0
        /// <summary>
        /// Update the horizons of a patch based on a list of shadow casters.
        /// The horizons will be in slope, not angle, format
        /// </summary>
        /// <param name="target"></param>
        /// <param name="casters"></param>
        public void UpdateHorizons(TerrainPatch target, List <TerrainPatch> casters)
        {
            Debug.Assert(Terrain != null);
            if (casters.Count < 1)
            {
                return;
            }
            using (var context = new Context())
            {
                AcceleratorId aid = Accelerator.Accelerators.Where(id => id.AcceleratorType == AcceleratorType.Cuda).FirstOrDefault();
                if (aid.AcceleratorType != AcceleratorType.Cuda)
                {
                    Console.WriteLine(@"There is no CUDA accelerator present.  Doing nothing.");
                    return;
                }
                using (var accelerator = Accelerator.Create(context, aid))
                {
                    target.FillPoints(Terrain);
                    target.FillMatricesRelativeToPoint(Terrain, target.Points[0][0]);

                    // Matrices
                    var cpu_matrices_size = target.Height * target.Width * 12;
                    var basePoint         = target.Points[0][0];
                    var cpu_matrices      = MakeCPUMatrices(target);

                    // Horizon (load from target)
                    var cpu_horizon_size = target.Height * target.Width * Horizon.HorizonSamples;
                    var cpu_horizon      = new int[cpu_horizon_size];
                    for (var line = 0; line < TerrainPatch.DefaultSize; line++)
                    {
                        for (var sample = 0; sample < TerrainPatch.DefaultSize; sample++)
                        {
                            var offset = (line * TerrainPatch.DefaultSize + sample) * Horizon.HorizonSamples;
                            var buffer = target.Horizons[line][sample].Buffer;
                            for (var i = 0; i < Horizon.HorizonSamples; i++)
                            {
                                cpu_horizon[i + offset] = SlopeToEncoding(buffer[i]);
                            }
                        }
                    }

                    // Caster points
                    var cpu_caster_points_size = casters[0].Width * casters[0].Height * 3;
                    var cpu_caster_points      = new float[cpu_caster_points_size];

                    // test array
                    var cpu_test_array = new float[20];

                    using (var gpu_matrices = accelerator.Allocate <float>(cpu_matrices_size))
                        using (var gpu_horizon = accelerator.Allocate <int>(cpu_horizon_size))
                            using (var gpu_caster_points = accelerator.Allocate <float>(cpu_caster_points_size))
                                using (var gpu_test_array = accelerator.Allocate <float>(cpu_test_array.Length))
                                {
                                    gpu_matrices.CopyFrom(cpu_matrices, 0, 0, cpu_matrices_size);
                                    gpu_horizon.CopyFrom(cpu_horizon, 0, 0, cpu_horizon_size);

                                    var groupSize       = accelerator.MaxNumThreadsPerGroup;
                                    var launchDimension = new GroupedIndex2(
                                        new Index2(128, 128), // (data.Length + groupSize - 1) / groupSize,  // Compute the number of groups (round up)
                                        new Index2(1, 128));

                                    var kernel1 = accelerator.LoadSharedMemoryStreamKernel1 <GroupedIndex2, ArrayView <float>, ArrayView <float>, ArrayView <int>, ArrayView <float>, ArrayView <int> >(ShadowKernel1);

                                    //var stopwatch = new Stopwatch();
                                    //stopwatch.Start();

                                    foreach (var caster in casters)
                                    {
                                        caster.FillPoints(Terrain);
                                        CopyPointsToCpuArray(caster, basePoint, cpu_caster_points);
                                        gpu_caster_points.CopyFrom(cpu_caster_points, 0, 0, cpu_caster_points_size);

                                        kernel1(launchDimension, gpu_caster_points, gpu_matrices, gpu_horizon, gpu_test_array);

                                        accelerator.Synchronize();
                                    }

                                    // Copy out data
                                    gpu_horizon.CopyTo(cpu_horizon, 0, 0, cpu_horizon_size);
                                    gpu_test_array.CopyTo(cpu_test_array, 0, 0, cpu_test_array.Length);

                                    //stopwatch.Stop();
                                    //Console.WriteLine($"kernel time={stopwatch.Elapsed} cpu_horizon.Max()={cpu_horizon.Max()} cpu_horizon[0]={cpu_horizon[0]}");

                                    // Update the horizons
                                    for (var line = 0; line < TerrainPatch.DefaultSize; line++)
                                    {
                                        for (var sample = 0; sample < TerrainPatch.DefaultSize; sample++)
                                        {
                                            var offset = (line * TerrainPatch.DefaultSize + sample) * Horizon.HorizonSamples;
                                            var buffer = target.Horizons[line][sample].Buffer;
                                            for (var i = 0; i < Horizon.HorizonSamples; i++)
                                            {
                                                buffer[i] = EncodingToSlope(cpu_horizon[i + offset]);
                                            }
                                        }
                                    }

                                    //Console.WriteLine($"  max slope={cpu_horizon.Select(EncodingToSlope).Max()}");
                                }
                }
            }
        }