tiny.simd.CostDistribution
Defined in autotune.
API (16)
Actions
Public operations.
Types and contracts
Public types and contracts.
Fields and members
Public fields and members.
Source
Source: lib/simd/src/autotune.zig:3
zig
pub const CostDistribution = struct { num_values: usize = 0, pointer_padding: [8 - @sizeOf(usize)]u8 = @splat(0), online_n: f64 = 0, values: [max_values]f64 = @splat(0), pub const max_values: usize = 14; const m1_index: usize = 0; const m2_index: usize = 1; const mean_index: usize = 2; const standard_deviation_index: usize = 3; const lower_index: usize = 4; const upper_index: usize = 5; pub fn notify(self: *@This(), value: f64) void { if (value < 0) return; if (self.isOnline()) { self.onlineNotify(value); return; } std.debug.assert(self.num_values < max_values); self.values[self.num_values] = value; self.num_values += 1; if (self.num_values == max_values) self.warmUpOnline(); } pub fn estimateCost(self: *@This()) f64 { std.debug.assert(self.num_values != 0); if (!self.isOnline()) self.warmUpOnline(); return self.mean(); } pub fn isOnline(self: *const @This()) bool { return self.online_n > 0; } pub fn bufferedCount(self: *const @This()) usize { return self.num_values; } pub fn onlineCount(self: *const @This()) f64 { return self.online_n; } pub fn m1(self: *const @This()) f64 { return self.values[m1_index]; } pub fn m2(self: *const @This()) f64 { return self.values[m2_index]; } pub fn mean(self: *const @This()) f64 { return self.values[mean_index]; } pub fn standardDeviation(self: *const @This()) f64 { return self.values[standard_deviation_index]; } pub fn lower(self: *const @This()) f64 { return self.values[lower_index]; } pub fn upper(self: *const @This()) f64 { return self.values[upper_index]; } fn median(to_sort: []f64) f64 { std.debug.assert(to_sort.len >= 2); std.mem.sort(f64, to_sort, {}, std.sort.asc(f64)); const middle = to_sort.len / 2; if (to_sort.len % 2 != 0) return to_sort[middle]; return (to_sort[middle] + to_sort[middle - 1]) * 0.5; } fn medianAbsoluteDeviation(values: []const f64, median_value: f64) f64 { var deviations: [max_values]f64 = undefined; for (values, deviations[0..values.len]) |value, *deviation| { deviation.* = @abs(value - median_value); } return median(deviations[0..values.len]); } fn removeOutliers(self: *@This()) void { if (self.num_values < 3) return; std.debug.assert(self.num_values <= max_values); const active = self.values[0..self.num_values]; const median_value = median(active); const mad = medianAbsoluteDeviation(active, median_value); if (mad == 0) { const skewness = (active[active.len - 1] - median_value) - (median_value - active[0]); const trim = @max(self.num_values / 2, 2); const left = @max(if (skewness < 0) trim * 3 / 4 else trim / 4, 1); self.num_values -= trim; std.debug.assert(self.num_values >= 1); std.mem.copyForwards( f64, self.values[0..self.num_values], self.values[left .. left + self.num_values], ); return; } const upper_bound = median_value + 5 * mad; const lower_bound = median_value - 5 * mad; var right = self.num_values - 1; while (self.values[right] > upper_bound) right -= 1; std.debug.assert(right >= self.num_values / 2); var left: usize = 0; while (left < right and self.values[left] < lower_bound) left += 1; std.debug.assert(left <= self.num_values / 2); self.num_values = right - left + 1; std.mem.copyForwards( f64, self.values[0..self.num_values], self.values[left .. left + self.num_values], ); } fn sampleMean(self: *const @This()) f64 { std.debug.assert(!self.isOnline()); std.debug.assert(self.num_values != 0); std.debug.assert(self.num_values <= max_values); var sum: f64 = 0; for (self.values[0..self.num_values]) |value| sum += value; return sum / @as(f64, @floatFromInt(self.num_values)); } fn sampleVariance(self: *const @This(), sample_mean: f64) f64 { std.debug.assert(sample_mean >= 0); std.debug.assert(!self.isOnline()); std.debug.assert(self.num_values != 0); std.debug.assert(self.num_values <= max_values); if (self.num_values == 1) return 0; var squared_sum: f64 = 0; for (self.values[0..self.num_values]) |value| { const difference = value - sample_mean; squared_sum += difference * difference; } return squared_sum / @as(f64, @floatFromInt(self.num_values - 1)); } fn onlineNotify(self: *@This(), unbounded_value: f64) void { const value = @min(@max(self.lower(), unbounded_value), self.upper()); const n_minus_one = self.online_n; self.online_n += 1; const difference = value - self.values[m1_index]; const difference_div_n = difference / self.online_n; self.values[m1_index] += difference_div_n; std.debug.assert(self.values[m1_index] >= self.lower()); self.values[m2_index] += difference * n_minus_one * difference_div_n; const standard_deviation = @sqrt(self.values[m2_index] / @max(1, n_minus_one)); self.values[mean_index] = self.values[m1_index] * 0.2 + self.values[mean_index] * 0.8; self.values[standard_deviation_index] = standard_deviation * 0.2 + self.values[standard_deviation_index] * 0.8; self.values[lower_index] = self.values[mean_index] - 3.5 * self.values[standard_deviation_index]; self.values[upper_index] = self.values[mean_index] + 3.5 * self.values[standard_deviation_index]; } fn warmUpOnline(self: *@This()) void { self.removeOutliers(); const sample_mean = self.sampleMean(); const sample_variance = self.sampleVariance(sample_mean); var copy: [max_values]f64 = undefined; @memcpy(copy[0..self.num_values], self.values[0..self.num_values]); self.values[m1_index] = 0; self.values[m2_index] = 0; self.values[mean_index] = sample_mean; self.values[standard_deviation_index] = @sqrt(sample_variance); if (self.values[standard_deviation_index] == 0) { self.values[standard_deviation_index] = self.values[mean_index] / 2; } self.values[lower_index] = self.values[mean_index] - 4 * self.values[standard_deviation_index]; self.values[upper_index] = self.values[mean_index] + 4 * self.values[standard_deviation_index]; for (copy[0..self.num_values]) |value| self.onlineNotify(value); std.debug.assert(self.isOnline()); }};Source: lib/simd/src/root.zig:561
zig
pub const CostDistribution = autotune.CostDistribution;Audit
| Definitions | 13 |
|---|---|
| Public names | 26 |
| Members | 4 |
| Version | 26.7.0 |
| Revision | daab053ee433 |