annotate src/fftw-3.3.8/support/addchain.c @ 168:ceec0dd9ec9c

Replace these with versions built using an older toolset (so as to avoid ABI compatibilities when linking on Ubuntu 14.04 for packaging purposes)
author Chris Cannam <cannam@all-day-breakfast.com>
date Fri, 07 Feb 2020 11:51:13 +0000
parents bd3cc4d1df30
children
rev   line source
cannam@167 1 /* addition-chain optimizer */
cannam@167 2 #include <stdio.h>
cannam@167 3 #include <stdlib.h>
cannam@167 4 #include <unistd.h>
cannam@167 5
cannam@167 6 static int verbose;
cannam@167 7 static int mulcost = 18;
cannam@167 8 static int ldcost = 2;
cannam@167 9 static int sqcost = 10;
cannam@167 10 static int reflcost = 8;
cannam@167 11 #define INFTY 100000
cannam@167 12
cannam@167 13 static int *answer;
cannam@167 14 static int best_so_far;
cannam@167 15
cannam@167 16 static void print_answer(int n, int t)
cannam@167 17 {
cannam@167 18 int i;
cannam@167 19 printf("| (%d, %d) -> [", n, t);
cannam@167 20 for (i = 0; i < t; ++i)
cannam@167 21 printf("%d;", answer[i]);
cannam@167 22 printf("] (* %d *)\n", best_so_far);
cannam@167 23 }
cannam@167 24
cannam@167 25 #define DO(i, j, k, cst) \
cannam@167 26 if (k < n) { \
cannam@167 27 int c = A[i] + A[j] + cst; \
cannam@167 28 if (c < A[k]) { \
cannam@167 29 A[k] = c; \
cannam@167 30 changed = 1; \
cannam@167 31 } \
cannam@167 32 }
cannam@167 33
cannam@167 34 #define DO3(i, j, l, k, cst) \
cannam@167 35 if (k < n) { \
cannam@167 36 int c = A[i] + A[j] + A[l] + cst; \
cannam@167 37 if (c < A[k]) { \
cannam@167 38 A[k] = c; \
cannam@167 39 changed = 1; \
cannam@167 40 } \
cannam@167 41 }
cannam@167 42
cannam@167 43 static int optimize(int n, int *A)
cannam@167 44 {
cannam@167 45 int i, j, k, changed, cst, cstmax;
cannam@167 46
cannam@167 47 do {
cannam@167 48 changed = 0;
cannam@167 49 for (i = 0; i < n; ++i) {
cannam@167 50 k = i + i;
cannam@167 51 DO(i, i, k, sqcost);
cannam@167 52 }
cannam@167 53
cannam@167 54 for (i = 0; i < n; ++i) {
cannam@167 55 for (j = 0; j <= i; ++j) {
cannam@167 56 k = i + j;
cannam@167 57 DO(i, j, k, mulcost);
cannam@167 58 k = i - j;
cannam@167 59 DO(i, j, k, mulcost);
cannam@167 60
cannam@167 61 k = i + j;
cannam@167 62 DO3(i, j, i - j, k, reflcost);
cannam@167 63 }
cannam@167 64 }
cannam@167 65
cannam@167 66 } while (changed);
cannam@167 67
cannam@167 68 cst = cstmax = 0;
cannam@167 69 for (i = 0; i < n; ++i) {
cannam@167 70 cst += A[i];
cannam@167 71 if (A[i] > cstmax) cstmax = A[i];
cannam@167 72 }
cannam@167 73 /* return cstmax; */
cannam@167 74 return cst;
cannam@167 75 }
cannam@167 76
cannam@167 77 static void search(int n, int t, int *A, int *B, int depth)
cannam@167 78 {
cannam@167 79 if (depth == 0) {
cannam@167 80 int i, tc;
cannam@167 81 for (i = 0; i < n; ++i)
cannam@167 82 A[i] = INFTY;
cannam@167 83 A[0] = 0; /* always free */
cannam@167 84 for (i = 1; i <= t; ++i)
cannam@167 85 A[B[-i]] = ldcost;
cannam@167 86
cannam@167 87 tc = optimize(n, A);
cannam@167 88 if (tc < best_so_far) {
cannam@167 89 best_so_far = tc;
cannam@167 90 for (i = 1; i <= t; ++i)
cannam@167 91 answer[t - i] = B[-i];
cannam@167 92 if (verbose)
cannam@167 93 print_answer(n, t);
cannam@167 94 }
cannam@167 95 } else {
cannam@167 96 for (B[0] = B[-1] + 1; B[0] < n; ++B[0])
cannam@167 97 search(n, t, A, B + 1, depth - 1);
cannam@167 98 }
cannam@167 99 }
cannam@167 100
cannam@167 101 static void doit(int n, int t)
cannam@167 102 {
cannam@167 103 int *A;
cannam@167 104 int *B;
cannam@167 105
cannam@167 106 A = malloc(n * sizeof(int));
cannam@167 107 B = malloc((t + 1) * sizeof(int));
cannam@167 108 answer = malloc(t * sizeof(int));
cannam@167 109
cannam@167 110 B[0] = 0;
cannam@167 111 best_so_far = INFTY;
cannam@167 112 search(n, t, A, B + 1, t);
cannam@167 113
cannam@167 114 print_answer(n, t);
cannam@167 115
cannam@167 116 free(A); free(B); free(answer);
cannam@167 117 }
cannam@167 118
cannam@167 119 int main(int argc, char *argv[])
cannam@167 120 {
cannam@167 121 int n = 32;
cannam@167 122 int t = 3;
cannam@167 123 int all;
cannam@167 124 int ch;
cannam@167 125
cannam@167 126 verbose = 0;
cannam@167 127 all = 0;
cannam@167 128 while ((ch = getopt(argc, argv, "n:t:m:l:r:s:va")) != -1) {
cannam@167 129 switch (ch) {
cannam@167 130 case 'n':
cannam@167 131 n = atoi(optarg);
cannam@167 132 break;
cannam@167 133 case 't':
cannam@167 134 t = atoi(optarg);
cannam@167 135 break;
cannam@167 136 case 'm':
cannam@167 137 mulcost = atoi(optarg);
cannam@167 138 break;
cannam@167 139 case 'l':
cannam@167 140 ldcost = atoi(optarg);
cannam@167 141 break;
cannam@167 142 case 's':
cannam@167 143 sqcost = atoi(optarg);
cannam@167 144 break;
cannam@167 145 case 'r':
cannam@167 146 reflcost = atoi(optarg);
cannam@167 147 break;
cannam@167 148 case 'v':
cannam@167 149 ++verbose;
cannam@167 150 break;
cannam@167 151 case 'a':
cannam@167 152 ++all;
cannam@167 153 break;
cannam@167 154 case '?':
cannam@167 155 fprintf(stderr, "use the source\n");
cannam@167 156 exit(1);
cannam@167 157 }
cannam@167 158 }
cannam@167 159
cannam@167 160 if (all) {
cannam@167 161 for (n = 4; n <= 64; n *= 2) {
cannam@167 162 int n1 = n - 1; if (n1 > 7) n1 = 7;
cannam@167 163 for (t = 1; t <= n1; ++t)
cannam@167 164 doit(n, t);
cannam@167 165 }
cannam@167 166 } else {
cannam@167 167 doit(n, t);
cannam@167 168 }
cannam@167 169
cannam@167 170 return 0;
cannam@167 171 }