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; }
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]); }
/// <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))); }
/// <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))); }
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)); }
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]); }
/// <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); }
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); }
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); }
public static void MathKernel(Index2 index, ArrayView2D<float> singleView) { singleView[index.X, index.Y] = GPUMath.Sqrt(index.X * index.Y); }
/// <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))); }
/// <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; }
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]); }
/// <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))); }
public static void kernel_V_Sin(Index pos, ArrayView <float> output, ArrayView <float> arr) { int x = pos.X; output[x] = GPUMath.Sin(arr[x]); }
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); }
public static void V_Cos(Index pos, ArrayView <float> output, ArrayView <float> arr) { int x = pos.X; output[x] = GPUMath.Cos(arr[x]); }
public static void _V_Log(Index size, ArrayView <float> output, ArrayView <float> v) { var x = size.X; output[x] = GPUMath.Log(v[x]); }
/// <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]; } } } }