summaryrefslogtreecommitdiffstatshomepage
path: root/3rdparty/bimg/3rdparty/astc/astc_weight_align.cpp
diff options
context:
space:
mode:
Diffstat (limited to '3rdparty/bimg/3rdparty/astc/astc_weight_align.cpp')
-rw-r--r--3rdparty/bimg/3rdparty/astc/astc_weight_align.cpp600
1 files changed, 0 insertions, 600 deletions
diff --git a/3rdparty/bimg/3rdparty/astc/astc_weight_align.cpp b/3rdparty/bimg/3rdparty/astc/astc_weight_align.cpp
deleted file mode 100644
index 789438fd137..00000000000
--- a/3rdparty/bimg/3rdparty/astc/astc_weight_align.cpp
+++ /dev/null
@@ -1,600 +0,0 @@
-/*----------------------------------------------------------------------------*/
-/**
- * This confidential and proprietary software may be used only as
- * authorised by a licensing agreement from ARM Limited
- * (C) COPYRIGHT 2011-2012 ARM Limited
- * ALL RIGHTS RESERVED
- *
- * The entire notice above must be reproduced on all authorised
- * copies and copies may only be made to the extent permitted
- * by a licensing agreement from ARM Limited.
- *
- * @brief Angular-sum algorithm for weight alignment.
- *
- * This algorithm works as follows:
- * * we compute a complex number P as (cos s*i, sin s*i) for each
- * weight, where i is the input value and s is a scaling factor
- * based on the spacing between the weights.
- * * we then add together complex numbers for all the weights.
- * * we then compute the length and angle of the resulting sum.
- *
- * This should produce the following results:
- * * perfect alignment results in a vector whose length is equal to
- * the sum of lengths of all inputs
- * * even distribution results in a vector of length 0.
- * * all samples identical results in perfect alignment for every
- * scaling.
- *
- * For each scaling factor within a given set, we compute an alignment
- * factor from 0 to 1. This should then result in some scalings standing
- * out as having particularly good alignment factors; we can use this to
- * produce a set of candidate scale/shift values for various quantization
- * levels; we should then actually try them and see what happens.
- *
- * Assuming N quantization steps, the scaling factor becomes s=2*PI*(N-1);
- * we should probably have about 1 scaling factor for every 1/4
- * quantization step (perhaps 1/8 for low levels of quantization)
- */
-/*----------------------------------------------------------------------------*/
-
-#define _USE_MATH_DEFINES // for M_PI on windows
-
-#include <math.h>
-#include "astc_codec_internals.h"
-
-#ifdef DEBUG_PRINT_DIAGNOSTICS
- #include <stdio.h>
-#endif
-
-static const float angular_steppings[] = {
- 1.0, 1.125,
- 1.25, 1.375,
- 1.5, 1.625,
- 1.75, 1.875,
-
- 2.0, 2.25, 2.5, 2.75,
- 3.0, 3.25, 3.5, 3.75,
- 4.0, 4.25, 4.5, 4.75,
- 5.0, 5.25, 5.5, 5.75,
- 6.0, 6.25, 6.5, 6.75,
- 7.0, 7.25, 7.5, 7.75,
-
- 8.0, 8.5,
- 9.0, 9.5,
- 10.0, 10.5,
- 11.0, 11.5,
- 12.0, 12.5,
- 13.0, 13.5,
- 14.0, 14.5,
- 15.0, 15.5,
- 16.0, 16.5,
- 17.0, 17.5,
- 18.0, 18.5,
- 19.0, 19.5,
- 20.0, 20.5,
- 21.0, 21.5,
- 22.0, 22.5,
- 23.0, 23.5,
- 24.0, 24.5,
- 25.0, 25.5,
- 26.0, 26.5,
- 27.0, 27.5,
- 28.0, 28.5,
- 29.0, 29.5,
- 30.0, 30.5,
- 31.0, 31.5,
- 32.0, 32.5,
- 33.0, 33.5,
- 34.0, 34.5,
- 35.0, 35.5,
-};
-
-#define ANGULAR_STEPS ((int)(sizeof(angular_steppings)/sizeof(angular_steppings[0])))
-
-static float stepsizes[ANGULAR_STEPS];
-static float stepsizes_sqr[ANGULAR_STEPS];
-
-static int max_angular_steps_needed_for_quant_level[13];
-
-// we store sine/cosine values for 64 possible weight values; this causes
-// slight quality loss compared to using sin() and cos() directly.
-
-#define SINCOS_STEPS 64
-
-static float sin_table[SINCOS_STEPS][ANGULAR_STEPS];
-static float cos_table[SINCOS_STEPS][ANGULAR_STEPS];
-
-void prepare_angular_tables(void)
-{
- int i, j;
- int max_angular_steps_needed_for_quant_steps[40];
- for (i = 0; i < ANGULAR_STEPS; i++)
- {
- stepsizes[i] = 1.0f / angular_steppings[i];
- stepsizes_sqr[i] = stepsizes[i] * stepsizes[i];
-
- for (j = 0; j < SINCOS_STEPS; j++)
- {
- sin_table[j][i] = static_cast < float >(sin((2.0f * M_PI / (SINCOS_STEPS - 1.0f)) * angular_steppings[i] * j));
- cos_table[j][i] = static_cast < float >(cos((2.0f * M_PI / (SINCOS_STEPS - 1.0f)) * angular_steppings[i] * j));
- }
-
- int p = static_cast < int >(floor(angular_steppings[i])) + 1;
- max_angular_steps_needed_for_quant_steps[p] = MIN(i + 1, ANGULAR_STEPS - 1);
- }
-
-
- // yes, the next-to-last entry is supposed to have the value 33. This because under
- // ASTC, the 32-weight mode leaves a double-sized hole in the middle of the
- // weight space, so we are better off matching 33 weights than 32.
- static const int steps_of_level[] = { 2, 3, 4, 5, 6, 8, 10, 12, 16, 20, 24, 33, 36 };
-
- for (i = 0; i < 13; i++)
- max_angular_steps_needed_for_quant_level[i] = max_angular_steps_needed_for_quant_steps[steps_of_level[i]];
-
-}
-
-
-union if32
-{
- float f;
- int32_t s;
- uint32_t u;
-};
-
-
-// function to compute angular sums; then, from the
-// angular sums, compute alignment factor and offset.
-
-/* static inline */
-void compute_angular_offsets(int samplecount, const float *samples, const float *sample_weights, int max_angular_steps, float *offsets)
-{
- int i, j;
-
- float anglesum_x[ANGULAR_STEPS];
- float anglesum_y[ANGULAR_STEPS];
-
- for (i = 0; i < max_angular_steps; i++)
- {
- anglesum_x[i] = 0;
- anglesum_y[i] = 0;
- }
-
-
- // compute the angle-sums.
- for (i = 0; i < samplecount; i++)
- {
- float sample = samples[i];
- float sample_weight = sample_weights[i];
- if32 p;
- p.f = (sample * (SINCOS_STEPS - 1.0f)) + 12582912.0f;
- unsigned int isample = p.u & 0x3F;
-
- const float *sinptr = sin_table[isample];
- const float *cosptr = cos_table[isample];
-
- for (j = 0; j < max_angular_steps; j++)
- {
- float cp = cosptr[j];
- float sp = sinptr[j];
-
- anglesum_x[j] += cp * sample_weight;
- anglesum_y[j] += sp * sample_weight;
- }
- }
-
- // post-process the angle-sums
- for (i = 0; i < max_angular_steps; i++)
- {
- float angle = atan2(anglesum_y[i], anglesum_x[i]); // positive angle -> positive offset
- offsets[i] = angle * (stepsizes[i] * (1.0f / (2.0f * (float)M_PI)));
- }
-}
-
-
-
-// for a given step-size and a given offset, compute the
-// lowest and highest weight that results from quantizing using the stepsize & offset.
-// also, compute the resulting error.
-
-
-/* static inline */
-void compute_lowest_and_highest_weight(int samplecount, const float *samples, const float *sample_weights,
- int max_angular_steps, const float *offsets,
- int8_t * lowest_weight, int8_t * highest_weight,
- float *error, float *cut_low_weight_error, float *cut_high_weight_error)
-{
- int i;
-
- int sp;
-
- float error_from_forcing_weight_down[60];
- float error_from_forcing_weight_either_way[60];
- for (i = 0; i < 60; i++)
- {
- error_from_forcing_weight_down[i] = 0;
- error_from_forcing_weight_either_way[i] = 0;
- }
-
- // weight + 12
- static const unsigned int idxtab[256] = {
-
- 12, 13, 14, 15, 16, 17, 18, 19,
- 20, 21, 22, 23, 24, 25, 26, 27,
- 28, 29, 30, 31, 32, 33, 34, 35,
- 36, 37, 38, 39, 40, 41, 42, 43,
- 44, 45, 46, 47, 48, 49, 50, 51,
- 52, 53, 54, 55, 55, 55, 55, 55,
- 55, 55, 55, 55, 55, 55, 55, 55,
- 55, 55, 55, 55, 55, 55, 55, 55,
- 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 1, 2, 3,
- 4, 5, 6, 7, 8, 9, 10, 11,
-
- 12, 13, 14, 15, 16, 17, 18, 19,
- 20, 21, 22, 23, 24, 25, 26, 27,
- 28, 29, 30, 31, 32, 33, 34, 35,
- 36, 37, 38, 39, 40, 41, 42, 43,
- 44, 45, 46, 47, 48, 49, 50, 51,
- 52, 53, 54, 55, 55, 55, 55, 55,
- 55, 55, 55, 55, 55, 55, 55, 55,
- 55, 55, 55, 55, 55, 55, 55, 55,
- 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 1, 2, 3,
- 4, 5, 6, 7, 8, 9, 10, 11
- };
-
-
-
- for (sp = 0; sp < max_angular_steps; sp++)
- {
- unsigned int minidx_bias12 = 55;
- unsigned int maxidx_bias12 = 0;
-
- float errval = 0.0f;
-
- float rcp_stepsize = angular_steppings[sp];
- float offset = offsets[sp];
-
- float scaled_offset = rcp_stepsize * offset;
-
-
- for (i = 0; i < samplecount - 1; i += 2)
- {
- float wt1 = sample_weights[i];
- float wt2 = sample_weights[i + 1];
- if32 p1, p2;
- float sval1 = (samples[i] * rcp_stepsize) - scaled_offset;
- float sval2 = (samples[i + 1] * rcp_stepsize) - scaled_offset;
- p1.f = sval1 + 12582912.0f; // FP representation abuse to avoid floor() and float->int conversion
- p2.f = sval2 + 12582912.0f; // FP representation abuse to avoid floor() and float->int conversion
- float isval1 = p1.f - 12582912.0f;
- float isval2 = p2.f - 12582912.0f;
- float dif1 = sval1 - isval1;
- float dif2 = sval2 - isval2;
-
- errval += (dif1 * wt1) * dif1;
- errval += (dif2 * wt2) * dif2;
-
- // table lookups that really perform a minmax function.
- unsigned int idx1_bias12 = idxtab[p1.u & 0xFF];
- unsigned int idx2_bias12 = idxtab[p2.u & 0xFF];
-
- if (idx1_bias12 < minidx_bias12)
- minidx_bias12 = idx1_bias12;
- if (idx1_bias12 > maxidx_bias12)
- maxidx_bias12 = idx1_bias12;
- if (idx2_bias12 < minidx_bias12)
- minidx_bias12 = idx2_bias12;
- if (idx2_bias12 > maxidx_bias12)
- maxidx_bias12 = idx2_bias12;
-
- error_from_forcing_weight_either_way[idx1_bias12] += wt1;
- error_from_forcing_weight_down[idx1_bias12] += (dif1 * wt1);
-
- error_from_forcing_weight_either_way[idx2_bias12] += wt2;
- error_from_forcing_weight_down[idx2_bias12] += (dif2 * wt2);
- }
-
- if (samplecount & 1)
- {
- i = samplecount - 1;
- float wt = sample_weights[i];
- if32 p;
- float sval = (samples[i] * rcp_stepsize) - scaled_offset;
- p.f = sval + 12582912.0f; // FP representation abuse to avoid floor() and float->int conversion
- float isval = p.f - 12582912.0f;
- float dif = sval - isval;
-
- errval += (dif * wt) * dif;
-
- unsigned int idx_bias12 = idxtab[p.u & 0xFF];
-
- if (idx_bias12 < minidx_bias12)
- minidx_bias12 = idx_bias12;
- if (idx_bias12 > maxidx_bias12)
- maxidx_bias12 = idx_bias12;
-
- error_from_forcing_weight_either_way[idx_bias12] += wt;
- error_from_forcing_weight_down[idx_bias12] += dif * wt;
- }
-
-
- lowest_weight[sp] = (int)minidx_bias12 - 12;
- highest_weight[sp] = (int)maxidx_bias12 - 12;
- error[sp] = errval;
-
- // the cut_(lowest/highest)_weight_error indicate the error that results from
- // forcing samples that should have had the (lowest/highest) weight value
- // one step (up/down).
- cut_low_weight_error[sp] = error_from_forcing_weight_either_way[minidx_bias12] - 2.0f * error_from_forcing_weight_down[minidx_bias12];
- cut_high_weight_error[sp] = error_from_forcing_weight_either_way[maxidx_bias12] + 2.0f * error_from_forcing_weight_down[maxidx_bias12];
-
- // clear out the error-from-forcing values we actually used in this pass
- // so that these are clean for the next pass.
- unsigned int ui;
- for (ui = minidx_bias12 & ~0x3; ui <= maxidx_bias12; ui += 4)
- {
- error_from_forcing_weight_either_way[ui] = 0;
- error_from_forcing_weight_down[ui] = 0;
- error_from_forcing_weight_either_way[ui + 1] = 0;
- error_from_forcing_weight_down[ui + 1] = 0;
- error_from_forcing_weight_either_way[ui + 2] = 0;
- error_from_forcing_weight_down[ui + 2] = 0;
- error_from_forcing_weight_either_way[ui + 3] = 0;
- error_from_forcing_weight_down[ui + 3] = 0;
- }
- }
-
-
- for (sp = 0; sp < max_angular_steps; sp++)
- {
- float errscale = stepsizes_sqr[sp];
- error[sp] *= errscale;
- cut_low_weight_error[sp] *= errscale;
- cut_high_weight_error[sp] *= errscale;
- }
-}
-
-
-
-// main function for running the angular algorithm.
-
-
-void compute_angular_endpoints_for_quantization_levels(int samplecount, const float *samples, const float *sample_weights, int max_quantization_level, float low_value[12], float high_value[12])
-{
- int i;
-
-
- max_quantization_level++; // Temporarily increase level - needs refinement
-
- static const int quantization_steps_for_level[13] = { 2, 3, 4, 5, 6, 8, 10, 12, 16, 20, 24, 33, 36 };
- int max_quantization_steps = quantization_steps_for_level[max_quantization_level];
-
- float offsets[ANGULAR_STEPS];
-
- int max_angular_steps = max_angular_steps_needed_for_quant_level[max_quantization_level];
-
- compute_angular_offsets(samplecount, samples, sample_weights, max_angular_steps, offsets);
-
-
- // the +4 offsets are to allow for vectorization within compute_lowest_and_highest_weight().
- int8_t lowest_weight[ANGULAR_STEPS + 4];
- int8_t highest_weight[ANGULAR_STEPS + 4];
- float error[ANGULAR_STEPS + 4];
-
- float cut_low_weight_error[ANGULAR_STEPS + 4];
- float cut_high_weight_error[ANGULAR_STEPS + 4];
-
- compute_lowest_and_highest_weight(samplecount, samples, sample_weights, max_angular_steps, offsets, lowest_weight, highest_weight, error, cut_low_weight_error, cut_high_weight_error);
-
-
- #ifdef DEBUG_PRINT_DIAGNOSTICS
- if (print_diagnostics)
- {
- printf("%s : max-angular-steps=%d \n", __func__, max_angular_steps);
- printf("Samplecount=%d, max_quantization_level=%d\n", samplecount, max_quantization_level);
- for (i = 0; i < samplecount; i++)
- printf("Sample %d : %f (weight %f)\n", i, samples[i], sample_weights[i]);
-
- for (i = 0; i < max_angular_steps; i++)
- {
- printf("%d: offset=%f error=%f lowest=%d highest=%d cl=%f ch=%f\n", i, offsets[i], error[i], lowest_weight[i], highest_weight[i], cut_low_weight_error[i], cut_high_weight_error[i]);
- }
- printf("\n");
- }
- #endif
-
- // for each quantization level, find the best error terms.
- float best_errors[40];
- int best_scale[40];
- uint8_t cut_low_weight[40];
-
- for (i = 0; i < (max_quantization_steps + 4); i++)
- {
- best_errors[i] = 1e30f;
- best_scale[i] = -1; // Indicates no solution found
- cut_low_weight[i] = 0;
- }
-
-
-
- for (i = 0; i < max_angular_steps; i++)
- {
- int samplecount = highest_weight[i] - lowest_weight[i] + 1;
- if (samplecount >= (max_quantization_steps + 4))
- {
- continue;
- }
- if (samplecount < 2)
- samplecount = 2;
-
- if (best_errors[samplecount] > error[i])
- {
- best_errors[samplecount] = error[i];
- best_scale[samplecount] = i;
- cut_low_weight[samplecount] = 0;
- }
-
- float error_cut_low = error[i] + cut_low_weight_error[i];
- float error_cut_high = error[i] + cut_high_weight_error[i];
- float error_cut_low_high = error[i] + cut_low_weight_error[i] + cut_high_weight_error[i];
-
- if (best_errors[samplecount - 1] > error_cut_low)
- {
- best_errors[samplecount - 1] = error_cut_low;
- best_scale[samplecount - 1] = i;
- cut_low_weight[samplecount - 1] = 1;
- }
-
- if (best_errors[samplecount - 1] > error_cut_high)
- {
- best_errors[samplecount - 1] = error_cut_high;
- best_scale[samplecount - 1] = i;
- cut_low_weight[samplecount - 1] = 0;
- }
-
- if (best_errors[samplecount - 2] > error_cut_low_high)
- {
- best_errors[samplecount - 2] = error_cut_low_high;
- best_scale[samplecount - 2] = i;
- cut_low_weight[samplecount - 2] = 1;
- }
-
- }
-
- // if we got a better error-value for a low sample count than for a high one,
- // use the low sample count error value for the higher sample count as well.
- for (i = 3; i <= max_quantization_steps; i++)
- {
- if (best_errors[i] > best_errors[i - 1])
- {
- best_errors[i] = best_errors[i - 1];
- best_scale[i] = best_scale[i - 1];
- cut_low_weight[i] = cut_low_weight[i - 1];
- }
- }
-
-
- max_quantization_level--; // Decrease level again (see corresponding ++, above)
-
- static const int ql_weights[12] = { 2, 3, 4, 5, 6, 8, 10, 12, 16, 20, 24, 33 };
- for (i = 0; i <= max_quantization_level; i++)
- {
- int q = ql_weights[i];
- int bsi = best_scale[q];
-
- // Did we find anything?
- if(bsi < 0)
- {
- printf("ERROR: Unable to find an encoding within the specified error limits. Please revise the error limit values and try again.\n");
- exit(1);
- }
-
- float stepsize = stepsizes[bsi];
- int lwi = lowest_weight[bsi] + cut_low_weight[q];
- int hwi = lwi + q - 1;
- float offset = offsets[bsi];
-
- low_value[i] = offset + lwi * stepsize;
- high_value[i] = offset + hwi * stepsize;
- }
-
-}
-
-
-// helper functions that will compute ideal angular-endpoints
-// for a given set of weights and a given block size descriptors
-
-void compute_angular_endpoints_1plane(float mode_cutoff, const block_size_descriptor * bsd,
- const float *decimated_quantized_weights, const float *decimated_weights,
- float low_value[MAX_WEIGHT_MODES], float high_value[MAX_WEIGHT_MODES])
-{
- int i;
- float low_values[MAX_DECIMATION_MODES][12];
- float high_values[MAX_DECIMATION_MODES][12];
-
- for (i = 0; i < MAX_DECIMATION_MODES; i++)
- {
- int samplecount = bsd->decimation_mode_samples[i];
- int quant_mode = bsd->decimation_mode_maxprec_1plane[i];
- float percentile = bsd->decimation_mode_percentile[i];
- int permit_encode = bsd->permit_encode[i];
- if (permit_encode == 0 || samplecount < 1 || quant_mode < 0 || percentile > mode_cutoff)
- continue;
-
-
- compute_angular_endpoints_for_quantization_levels(samplecount,
- decimated_quantized_weights + i * MAX_WEIGHTS_PER_BLOCK,
- decimated_weights + i * MAX_WEIGHTS_PER_BLOCK, quant_mode, low_values[i], high_values[i]);
- }
-
- for (i = 0; i < MAX_WEIGHT_MODES; i++)
- {
- if (bsd->block_modes[i].is_dual_plane != 0 || bsd->block_modes[i].percentile > mode_cutoff)
- continue;
- int quant_mode = bsd->block_modes[i].quantization_mode;
- int decim_mode = bsd->block_modes[i].decimation_mode;
-
- low_value[i] = low_values[decim_mode][quant_mode];
- high_value[i] = high_values[decim_mode][quant_mode];
- }
-
-}
-
-
-
-void compute_angular_endpoints_2planes(float mode_cutoff,
- const block_size_descriptor * bsd,
- const float *decimated_quantized_weights,
- const float *decimated_weights,
- float low_value1[MAX_WEIGHT_MODES], float high_value1[MAX_WEIGHT_MODES], float low_value2[MAX_WEIGHT_MODES], float high_value2[MAX_WEIGHT_MODES])
-{
- int i;
- float low_values1[MAX_DECIMATION_MODES][12];
- float high_values1[MAX_DECIMATION_MODES][12];
- float low_values2[MAX_DECIMATION_MODES][12];
- float high_values2[MAX_DECIMATION_MODES][12];
-
- for (i = 0; i < MAX_DECIMATION_MODES; i++)
- {
- int samplecount = bsd->decimation_mode_samples[i];
- int quant_mode = bsd->decimation_mode_maxprec_2planes[i];
- float percentile = bsd->decimation_mode_percentile[i];
- int permit_encode = bsd->permit_encode[i];
- if (permit_encode == 0 || samplecount < 1 || quant_mode < 0 || percentile > mode_cutoff)
- continue;
-
- compute_angular_endpoints_for_quantization_levels(samplecount,
- decimated_quantized_weights + 2 * i * MAX_WEIGHTS_PER_BLOCK,
- decimated_weights + 2 * i * MAX_WEIGHTS_PER_BLOCK, quant_mode, low_values1[i], high_values1[i]);
-
- compute_angular_endpoints_for_quantization_levels(samplecount,
- decimated_quantized_weights + (2 * i + 1) * MAX_WEIGHTS_PER_BLOCK,
- decimated_weights + (2 * i + 1) * MAX_WEIGHTS_PER_BLOCK, quant_mode, low_values2[i], high_values2[i]);
-
- }
-
- for (i = 0; i < MAX_WEIGHT_MODES; i++)
- {
- if (bsd->block_modes[i].is_dual_plane != 1 || bsd->block_modes[i].percentile > mode_cutoff)
- continue;
- int quant_mode = bsd->block_modes[i].quantization_mode;
- int decim_mode = bsd->block_modes[i].decimation_mode;
-
- low_value1[i] = low_values1[decim_mode][quant_mode];
- high_value1[i] = high_values1[decim_mode][quant_mode];
- low_value2[i] = low_values2[decim_mode][quant_mode];
- high_value2[i] = high_values2[decim_mode][quant_mode];
- }
-}