Exemple #1
0
        public static void _M_Pow(Index2 size, ArrayView2D <float> m, int p)
        {
            var x = size.X;
            var y = size.Y;

            m[x, y] = GPUMath.Pow(m[x, y], p);
        }
        public static void CosineSimilarityKernel(
            Index index,
            ArrayView2D <int> dataset,
            ArrayView2D <double> distances)
        {
            int rows = dataset.Rows;
            int i    = index / rows;
            int j    = index % rows;

            if (i < j)
            {
                return;
            }

            double dotProduct   = 0;
            double magnitudeOne = 0;
            double magnitudeTwo = 0;

            for (int k = 0; k < dataset.Columns; k++)
            {
                dotProduct   += (dataset[i, k] * dataset[j, k]);
                magnitudeOne += (dataset[i, k] * dataset[i, k]);
                magnitudeTwo += (dataset[j, k] * dataset[j, k]);
            }
            double distance = double.NaN;
            double divisor  = GPUMath.Sqrt(magnitudeOne * magnitudeTwo);

            if (divisor != 0)
            {
                distance = GPUMath.Max(0, 1 - (dotProduct / divisor));
            }
            distances[i, j] = distance;
            distances[j, i] = distance;
        }
Exemple #3
0
        public static void _M_Sqrt(Index2 size, ArrayView2D <float> output, ArrayView2D <float> m)
        {
            var x = size.X;
            var y = size.Y;

            output[x, y] = GPUMath.Sqrt(m[x, y]);
        }
Exemple #4
0
 /// <summary>
 /// Clamps the given index value according to Max(Min(clamp, max), min).
 /// </summary>
 /// <param name="value">The value to clamp.</param>
 /// <param name="min">The first argument.</param>
 /// <param name="max">The second argument.</param>
 /// <returns>The clamped value in the interval [min, max].</returns>
 public static Index3 Clamp(Index3 value, Index3 min, Index3 max)
 {
     return(new Index3(
                GPUMath.Clamp(value.X, min.X, max.X),
                GPUMath.Clamp(value.Y, min.Y, max.Y),
                GPUMath.Clamp(value.Z, min.Z, max.Z)));
 }
Exemple #5
0
 /// <summary>
 /// Computes max(first, second).
 /// </summary>
 /// <param name="first">The first argument.</param>
 /// <param name="second">The second argument.</param>
 /// <returns>The maximum of first and second value.</returns>
 public static Index3 Max(Index3 first, Index3 second)
 {
     return(new Index3(
                GPUMath.Max(first.X, second.X),
                GPUMath.Max(first.Y, second.Y),
                GPUMath.Max(first.Z, second.Z)));
 }
Exemple #6
0
        public static void _M_euclidian_distance(Index2 size, ArrayView2D <float> output, Index2 position)
        {
            var x = size.X;
            var y = size.Y;

            output[x, y] = GPUMath.Sqrt(GPUMath.Pow(x - position.X, 2) + GPUMath.Pow(y - position.Y, 2));
        }
Exemple #7
0
        public static void kernel_m_Sqrt(Index2 pos, ArrayView2D <float> output, ArrayView2D <float> arr)
        {
            int x = pos.X;
            int y = pos.Y;

            output[x, y] = GPUMath.Sqrt(arr[x, y]);
        }
Exemple #8
0
 /// <summary>
 /// A simple 1D kernel using math functions.
 /// The GPUMath class contains intrinsic math functions that -
 /// in contrast to the default .Net Math class -
 /// work on both floats and doubles.
 /// Note that both classes are supported on all
 /// accelerators. The CompileUnitFlags.FastMath flag can be used during the creation of the
 /// compile unit to enable fast math intrinsics.
 /// </summary>
 /// <param name="index">The current thread index.</param>
 /// <param name="dataView">The view pointing to our memory buffer.</param>
 /// <param name="constant">A uniform constant.</param>
 static void MathKernel(
     Index index,                    // The global thread index (1D in this case)
     ArrayView <float> singleView,   // A view of floats to store float results from GPUMath
     ArrayView <double> doubleView,  // A view of doubles to store double results from GPUMath
     ArrayView <double> doubleView2) // A view of doubles to store double results from .Net Math
 {
     // Note the different returns type of GPUMath.Sqrt and Math.Sqrt.
     singleView[index]  = GPUMath.Sqrt(index);
     doubleView[index]  = GPUMath.Sqrt((double)index);
     doubleView2[index] = Math.Sqrt(index);
 }
Exemple #9
0
        public float hit(float ox1, float oy1, ref float n1)
        {
            float dx = ox1 - x;
            float dy = oy1 - y;

            if (dx * dx + dy * dy < radius * radius)
            {
                float dz = GPUMath.Sqrt(radius * radius - dx * dx - dy * dy);
                n1 = dz / GPUMath.Sqrt(radius * radius);
                return(dz + z);
            }
            return(-2e10f);
        }
Exemple #10
0
        public static void kernel_V_Pow(Index pos, ArrayView <float> output, ArrayView <float> arr, float exp)
        {
            int x = pos.X;

            output[x] = GPUMath.Pow(arr[x], exp);
        }
Exemple #11
0
 public static void MathKernel(Index2 index, ArrayView2D<float> singleView)
 {
     singleView[index.X, index.Y] = GPUMath.Sqrt(index.X * index.Y);
 }
Exemple #12
0
 /// <summary>
 /// Computes max(first, second).
 /// </summary>
 /// <param name="first">The first argument.</param>
 /// <param name="second">The second argument.</param>
 /// <returns>The maximum of first and second value.</returns>
 public static Index2 Max(Index2 first, Index2 second)
 {
     return(new Index2(
                GPUMath.Max(first.X, second.X),
                GPUMath.Max(first.Y, second.Y)));
 }
Exemple #13
0
 /// <summary>
 /// Clamps the given index value according to Max(Min(clamp, max), min).
 /// </summary>
 /// <param name="value">The value to clamp.</param>
 /// <param name="min">The first argument.</param>
 /// <param name="max">The second argument.</param>
 /// <returns>The clamped value in the interval [min, max].</returns>
 public static Index2 Clamp(Index2 value, Index2 min, Index2 max)
 {
     return(new Index2(
                GPUMath.Clamp(value.X, min.X, max.X),
                GPUMath.Clamp(value.Y, min.Y, max.Y)));
 }
        static void NearHorizonKernel1(
            Index index,       // Horizon angle as integer
            int target_line,   // row within the 128 x 128 target patch
            int target_sample, // column
            int line_offset,
            int sample_offset,
            int points_rows,
            int points_columns,
            float d_min,
            float d_max,
            float d_step,
            ArrayView <float> points,
            ArrayView <float> matrices,
            ArrayView <float> horizon,
            ArrayView <float> test_floats)
        {
            //if (index == 0)
            //{
            //    var delme = 1;
            //}

            // Copy the matrix into registers
            var pos = (target_line * TerrainPatch.DefaultSize + target_sample) * 12;

            var row0x = matrices[pos++];
            var row1x = matrices[pos++];
            var row2x = matrices[pos++];
            var row3x = matrices[pos++];

            var row0y = matrices[pos++];
            var row1y = matrices[pos++];
            var row2y = matrices[pos++];
            var row3y = matrices[pos++];

            var row0z = matrices[pos++];
            var row1z = matrices[pos++];
            var row2z = matrices[pos++];
            var row3z = matrices[pos];

            // Work out the location of the central point in the point array
            float center_line   = target_line + line_offset;
            float center_sample = target_sample + sample_offset;

            var caster_line_max   = (float)points_rows - 1;
            var caster_sample_max = (float)points_columns - 1;

            // Work out the direction vector
            var ray_angle = 3.141592653589f * 2f * index / (TerrainPatch.NearHorizonOversample * Horizon.HorizonSamples);
            var ray_cos   = GPUMath.Cos(ray_angle);
            var ray_sin   = GPUMath.Sin(ray_angle);

            // Work out the direction in horizon space (the horizon offset).  This duplicates the calculation of the first point.
            // I'm duplicating code rather than refactoring, because there would be a lot of values to pass
            float azimuth_rad;
            {
                var d             = 1f;
                var caster_line   = center_line + ray_sin * d;
                var caster_sample = center_sample + ray_cos * d;

                var x1 = (int)caster_sample;  // Calculate the caster point by interpolating between four points from the points array
                var y1 = (int)caster_line;
                int x2 = x1 + 1;
                int y2 = y1 + 1;

                var q11_offset = 3 * (y1 * points_columns + x1);  // (y1, x1);
                var q11        = new Vector3(points[q11_offset], points[q11_offset + 1], points[q11_offset + 2]);

                var q12_offset = 3 * (y2 * points_columns + x1);  // (y2, x1);
                var q12        = new Vector3(points[q12_offset], points[q12_offset + 1], points[q12_offset + 2]);

                // First interpolation across rows (line)
                var q1_line = q11 + (caster_line - y1) * (q12 - q11);

                var q21_offset = 3 * (y1 * points_columns + x2);  // (y1, x2);
                var q21        = new Vector3(points[q21_offset], points[q21_offset + 1], points[q21_offset + 2]);

                var q22_offset = 3 * (y2 * points_columns + x2);  // (y2, x2);
                var q22        = new Vector3(points[q22_offset], points[q22_offset + 1], points[q22_offset + 2]);

                // Second interpolation across rows
                var q2_line = q21 + (caster_line - y1) * (q22 - q21);

                // Interpolate across samples
                var caster = q1_line + (caster_sample - x1) * (q2_line - q1_line);

                // Break out the coordinates
                var x_patch = caster.X;
                var y_patch = caster.Y;
                var z_patch = caster.Z;

                // Transform the point to the local frame
                var x = x_patch * row0x + y_patch * row1x + z_patch * row2x + row3x;
                var y = x_patch * row0y + y_patch * row1y + z_patch * row2y + row3y;
                var z = x_patch * row0z + y_patch * row1z + z_patch * row2z + row3z;

                // Adjust for solar array height (this is temporary, and I'm not sure we want this in the final version)
                z -= ObserverHeight;                            // meters

                azimuth_rad = GPUMath.Atan2(y, x) + GPUMath.PI; // [0,2PI]
            }

            var normalized_azimuth = (Horizon.HorizonSamples - 1) * azimuth_rad / (2d * Math.PI);  // range [0,1)
            var horizon_offset     = (int)(0.5d + normalized_azimuth);

            Debug.Assert(horizon_offset >= 0 && horizon_offset < Horizon.HorizonSamples);

            // index is which direction in [target_line,target_sample]'s horizon we're working on, but could be oversamples
            var horizon_index = (target_line * TerrainPatch.DefaultSize + target_sample) * Horizon.HorizonSamples + horizon_offset;
            var highest_slope = horizon[horizon_index];

            //test_floats[index] = ray_sin;

            for (var d = d_min; d <= d_max; d += d_step)
            {
                // Generate the location of the caster point in the points array
                var caster_line   = center_line + ray_sin * d;
                var caster_sample = center_sample + ray_cos * d;

                test_floats[index] = caster_sample;

                /*{
                 *  var idx = index == 2160 ? 7 : 11;
                 *  test_floats[idx] = d;
                 *  test_floats[idx + 1] = ray_angle;
                 *  test_floats[idx + 2] = caster_line - line_offset;
                 *  test_floats[idx + 3] = caster_sample - sample_offset;
                 * }*/

                if (caster_line < 1f || caster_line > caster_line_max || caster_sample < 1f || caster_sample > caster_sample_max)
                {
                    break;
                }

                // Calculate the caster point by interpolating between four points from the points array
                var x1 = (int)caster_sample;
                var y1 = (int)caster_line;
                int x2 = x1 + 1;
                int y2 = y1 + 1;

                var q11_offset = 3 * (y1 * points_columns + x1);  // (y1, x1);
                var q11        = new Vector3(points[q11_offset], points[q11_offset + 1], points[q11_offset + 2]);

                var q12_offset = 3 * (y2 * points_columns + x1);  // (y2, x1);
                var q12        = new Vector3(points[q12_offset], points[q12_offset + 1], points[q12_offset + 2]);

                // First interpolation across rows (line)
                var q1_line = q11 + (caster_line - y1) * (q12 - q11);

                var q21_offset = 3 * (y1 * points_columns + x2);  // (y1, x2);
                var q21        = new Vector3(points[q21_offset], points[q21_offset + 1], points[q21_offset + 2]);

                var q22_offset = 3 * (y2 * points_columns + x2);  // (y2, x2);
                var q22        = new Vector3(points[q22_offset], points[q22_offset + 1], points[q22_offset + 2]);

                // Second interpolation across rows
                var q2_line = q21 + (caster_line - y1) * (q22 - q21);

                // Interpolate across samples
                var caster = q1_line + (caster_sample - x1) * (q2_line - q1_line);

                // Break out the coordinates
                var x_patch = caster.X;
                var y_patch = caster.Y;
                var z_patch = caster.Z;

                // Transform the point to the local frame
                var x = x_patch * row0x + y_patch * row1x + z_patch * row2x + row3x;
                var y = x_patch * row0y + y_patch * row1y + z_patch * row2y + row3y;
                var z = x_patch * row0z + y_patch * row1z + z_patch * row2z + row3z;

                var alen  = GPUMath.Sqrt(x * x + y * y);
                var slope = z / alen;

                if (slope > highest_slope)
                {
                    highest_slope = slope;
                }

                /*if (target_line==0 && target_sample==0 && index == 0)
                 * {
                 *  test_floats[0] = slope;
                 *  test_floats[1] = x_patch;
                 *  test_floats[2] = y_patch;
                 *  test_floats[3] = z_patch;
                 *  test_floats[4] = x;
                 *  test_floats[5] = y;
                 *  test_floats[6] = z;
                 * }*/
            }

            horizon[horizon_index] = highest_slope;
        }
Exemple #15
0
        public static void _V_euclidian_distance(Index size, ArrayView <float> output, Index position)
        {
            var x = size.X;

            output[x] = GPUMath.Sqrt(GPUMath.Pow(x - position.X, 2));
        }
        public static void _V_Max(Index size, ArrayView <float> output, ArrayView <float> v, ArrayView <float> v1)
        {
            int x = size.X;

            output[x] = GPUMath.Max(v[x], v1[x]);
        }
        public static void _V_Exp(Index size, ArrayView <float> output, ArrayView <float> v)
        {
            int x = size.X;

            output[x] = GPUMath.Exp(v[x]);
        }
Exemple #18
0
 /// <summary>
 /// Computes max(first, second).
 /// </summary>
 /// <param name="first">The first argument.</param>
 /// <param name="second">The second argument.</param>
 /// <returns>The maximum of first and second value.</returns>
 public static Index Max(Index first, Index second)
 {
     return(new Index(GPUMath.Max(first.X, second.X)));
 }
Exemple #19
0
        public static void kernel_V_Sin(Index pos, ArrayView <float> output, ArrayView <float> arr)
        {
            int x = pos.X;

            output[x] = GPUMath.Sin(arr[x]);
        }
Exemple #20
0
        public static void _V_Pow(Index size, ArrayView <float> output, ArrayView <float> v, int p)
        {
            var x = size.X;

            output[x] = GPUMath.Pow(v[x], p);
        }
Exemple #21
0
        public static void V_Cos(Index pos, ArrayView <float> output, ArrayView <float> arr)
        {
            int x = pos.X;

            output[x] = GPUMath.Cos(arr[x]);
        }
Exemple #22
0
        public static void _V_Log(Index size, ArrayView <float> output, ArrayView <float> v)
        {
            var x = size.X;

            output[x] = GPUMath.Log(v[x]);
        }
Exemple #23
0
 /// <summary>
 /// Clamps the given index value according to Max(Min(clamp, max), min).
 /// </summary>
 /// <param name="value">The value to clamp.</param>
 /// <param name="min">The first argument.</param>
 /// <param name="max">The second argument.</param>
 /// <returns>The clamped value in the interval [min, max].</returns>
 public static Index Clamp(Index value, Index min, Index max)
 {
     return(new Index(GPUMath.Clamp(value.X, min.X, max.X)));
 }
        static void ShadowKernel1(
            GroupedIndex2 index,
            ArrayView <float> points,
            ArrayView <float> matrices,
            ArrayView <int> horizon,
            ArrayView <float> test_array,

            [SharedMemory(1440)]
            ArrayView <int> horizon_shared)
        {
            var target_line   = index.GridIdx.Y;
            var target_sample = index.GridIdx.X;
            var caster_line   = index.GroupIdx.Y;

            Debug.Assert(index.GroupIdx.X == 1);

            // Copy horizon for a[target_line,target_sample] into shared memory
            {
                var dim    = Group.Dimension.Y;
                var len    = horizon_shared.Length;
                var passes = (len + (dim - 1)) / dim;
                var offset = (target_line * TerrainPatch.DefaultSize + target_sample) * len;
                for (var pass = 0; pass < passes; pass++)
                {
                    var ptr = pass * dim + caster_line;
                    if (ptr < len)  // divergence
                    {
                        horizon_shared[ptr] = horizon[ptr + offset];
                    }
                }
            }

            Group.Barrier();

            // Copy the matrix into registers
            var pos = (target_line * TerrainPatch.DefaultSize + target_sample) * 12;

            var row0x = matrices[pos++];
            var row1x = matrices[pos++];
            var row2x = matrices[pos++];
            var row3x = matrices[pos++];

            var row0y = matrices[pos++];
            var row1y = matrices[pos++];
            var row2y = matrices[pos++];
            var row3y = matrices[pos++];

            var row0z = matrices[pos++];
            var row1z = matrices[pos++];
            var row2z = matrices[pos++];
            var row3z = matrices[pos];

            for (var caster_sample = 0; caster_sample < TerrainPatch.DefaultSize; caster_sample++)
            {
                // Fetch the other point in local frame
                var points_offset = (caster_line * TerrainPatch.DefaultSize + caster_sample) * 3;
                var x_patch       = points[points_offset];
                var y_patch       = points[points_offset + 1];
                var z_patch       = points[points_offset + 2];

                // Transform the point to the local frame
                var x = x_patch * row0x + y_patch * row1x + z_patch * row2x + row3x;
                var y = x_patch * row0y + y_patch * row1y + z_patch * row2y + row3y;
                var z = x_patch * row0z + y_patch * row1z + z_patch * row2z + row3z;

                // Adjust for solar array height (this is temporary, and I'm not sure we want this in the final version)
                z -= ObserverHeight;                            // meters

                var azimuth = GPUMath.Atan2(y, x) + GPUMath.PI; // [0,2 PI]
                var alen    = GPUMath.Sqrt(x * x + y * y);
                var slope   = z / alen;

                var slopem = slope > 2f ? 2f : slope;
                slopem = slopem < -2f ? -2f : slopem;
                slopem = slopem / 4f;

                var slopei = (int)(slopem * 1000000);

                var horizon_index = (int)(0.5f + 1439 * (azimuth / (2f * GPUMath.PI)));
                Atomic.Max(horizon_shared.GetVariableView(horizon_index), slopei);

                if (caster_sample == 0 && caster_line == 0 && target_line == 0 && target_sample == 0)
                {
                    test_array[0]  = x_patch;
                    test_array[1]  = y_patch;
                    test_array[2]  = z_patch;
                    test_array[3]  = x;
                    test_array[4]  = y;
                    test_array[5]  = z;
                    test_array[6]  = slope;
                    test_array[7]  = slopem;
                    test_array[8]  = slopei;
                    test_array[9]  = row3x;
                    test_array[10] = row3y;
                    test_array[11] = row3z;
                }
            }

            Group.Barrier();

            {
                var dim    = Group.Dimension.Y;
                var len    = horizon_shared.Length;
                var passes = (len + (dim - 1)) / dim;
                var offset = (target_line * TerrainPatch.DefaultSize + target_sample) * len;
                for (var pass = 0; pass < passes; pass++)
                {
                    var ptr = pass * dim + caster_line;
                    if (ptr < len)  // divergence
                    {
                        horizon[ptr + offset] = horizon_shared[ptr];
                    }
                }
            }
        }