8 #include "sn_network.h"
10 sn_network_t *sn_network_create (int inputs_num)
14 n = (sn_network_t *) malloc (sizeof (sn_network_t));
17 memset (n, '\0', sizeof (sn_network_t));
19 n->inputs_num = inputs_num;
22 } /* sn_network_t *sn_network_create */
24 void sn_network_destroy (sn_network_t *n)
29 if (n->stages != NULL)
32 for (i = 0; i < n->stages_num; i++)
34 sn_stage_destroy (n->stages[i]);
42 } /* void sn_network_destroy */
44 int sn_network_stage_add (sn_network_t *n, sn_stage_t *s)
48 temp = (sn_stage_t **) realloc (n->stages, (n->stages_num + 1)
49 * sizeof (sn_stage_t *));
54 SN_STAGE_DEPTH (s) = n->stages_num;
55 n->stages[n->stages_num] = s;
59 } /* int sn_network_stage_add */
61 int sn_network_stage_remove (sn_network_t *n, int s_num)
63 int nmemb = n->stages_num - (s_num + 1);
66 assert (s_num < n->stages_num);
68 sn_stage_destroy (n->stages[s_num]);
69 n->stages[s_num] = NULL;
73 memmove (n->stages + s_num, n->stages + (s_num + 1),
74 nmemb * sizeof (sn_stage_t *));
75 n->stages[n->stages_num - 1] = NULL;
79 /* Free the unused memory */
80 if (n->stages_num == 0)
87 temp = (sn_stage_t **) realloc (n->stages,
88 n->stages_num * sizeof (sn_stage_t *));
95 } /* int sn_network_stage_remove */
97 sn_network_t *sn_network_clone (const sn_network_t *n)
102 n_copy = sn_network_create (n->inputs_num);
106 for (i = 0; i < n->stages_num; i++)
111 s = sn_stage_clone (n->stages[i]);
115 status = sn_network_stage_add (n_copy, s);
120 if (i < n->stages_num)
122 sn_network_destroy (n_copy);
127 } /* sn_network_t *sn_network_clone */
129 int sn_network_show (sn_network_t *n)
133 for (i = 0; i < n->stages_num; i++)
134 sn_stage_show (n->stages[i]);
137 } /* int sn_network_show */
139 int sn_network_invert (sn_network_t *n)
143 for (i = 0; i < n->stages_num; i++)
144 sn_stage_invert (n->stages[i]);
147 } /* int sn_network_invert */
149 int sn_network_compress (sn_network_t *n)
155 for (i = 1; i < n->stages_num; i++)
161 for (j = 0; j < SN_STAGE_COMP_NUM (s); j++)
163 sn_comparator_t *c = SN_STAGE_COMP_GET (s, j);
166 for (k = i - 1; k >= 0; k--)
170 conflict = sn_stage_comparator_check_conflict (n->stages[k], c);
185 sn_stage_comparator_add (n->stages[move_to], c);
186 sn_stage_comparator_remove (s, j);
192 while ((n->stages_num > 0)
193 && (SN_STAGE_COMP_NUM (n->stages[n->stages_num - 1]) == 0))
194 sn_network_stage_remove (n, n->stages_num - 1);
197 } /* int sn_network_compress */
199 int sn_network_cut_at (sn_network_t *n, int input, enum sn_network_cut_dir_e dir)
202 int position = input;
204 for (i = 0; i < n->stages_num; i++)
210 new_position = sn_stage_cut_at (s, position, dir);
212 if (position != new_position)
216 for (j = 0; j < i; j++)
217 sn_stage_swap (n->stages[j], position, new_position);
220 position = new_position;
223 assert (((dir == DIR_MIN) && (position == 0))
224 || ((dir == DIR_MAX) && (position == (n->inputs_num - 1))));
226 for (i = 0; i < n->stages_num; i++)
227 sn_stage_remove_input (n->stages[i], position);
232 } /* int sn_network_cut_at */
234 static int sn_network_add_bitonic_merger_recursive (sn_network_t *n,
244 s = sn_stage_create (n->stages_num);
250 for (i = low; i < (low + m); i++)
257 sn_stage_comparator_add (s, &c);
260 sn_network_stage_add (n, s);
262 sn_network_add_bitonic_merger_recursive (n, low, m);
263 sn_network_add_bitonic_merger_recursive (n, low + m, m);
266 } /* int sn_network_add_bitonic_merger_recursive */
268 static int sn_network_add_bitonic_merger (sn_network_t *n)
274 s = sn_stage_create (n->stages_num);
278 m = n->inputs_num / 2;
280 for (i = 0; i < m; i++)
285 c.max = n->inputs_num - (i + 1);
287 sn_stage_comparator_add (s, &c);
290 sn_network_stage_add (n, s);
292 sn_network_add_bitonic_merger_recursive (n, 0, m);
293 sn_network_add_bitonic_merger_recursive (n, m, m);
296 } /* int sn_network_add_bitonic_merger */
298 sn_network_t *sn_network_combine (sn_network_t *n0, sn_network_t *n1)
305 stages_num = (n0->stages_num > n1->stages_num)
309 n = sn_network_create (n0->inputs_num + n1->inputs_num);
313 for (i = 0; i < stages_num; i++)
315 sn_stage_t *s = sn_stage_create (i);
317 if (i < n0->stages_num)
318 for (j = 0; j < SN_STAGE_COMP_NUM (n0->stages[i]); j++)
320 sn_comparator_t *c = SN_STAGE_COMP_GET (n0->stages[i], j);
321 sn_stage_comparator_add (s, c);
324 if (i < n1->stages_num)
325 for (j = 0; j < SN_STAGE_COMP_NUM (n1->stages[i]); j++)
327 sn_comparator_t *c_orig = SN_STAGE_COMP_GET (n1->stages[i], j);
328 sn_comparator_t c_copy;
330 SN_COMP_MIN(&c_copy) = SN_COMP_MIN(c_orig) + n0->inputs_num;
331 SN_COMP_MAX(&c_copy) = SN_COMP_MAX(c_orig) + n0->inputs_num;
333 sn_stage_comparator_add (s, &c_copy);
336 sn_network_stage_add (n, s);
339 sn_network_add_bitonic_merger (n);
340 sn_network_compress (n);
343 } /* sn_network_t *sn_network_combine */
345 sn_network_t *sn_network_read (FILE *fh)
352 while (fgets (buffer, sizeof (buffer), fh) != NULL)
354 char *str_key = buffer;
355 char *str_value = NULL;
356 int buffer_len = strlen (buffer);
358 while ((buffer_len > 0) && ((buffer[buffer_len - 1] == '\n')
359 || (buffer[buffer_len - 1] == '\r')))
362 buffer[buffer_len] = '\0';
367 str_value = strchr (buffer, ':');
368 if (str_value == NULL)
370 printf ("Cannot parse line: %s\n", buffer);
374 *str_value = '\0'; str_value++;
375 while ((*str_value != '\0') && (isspace (*str_value) != 0))
378 if (strcasecmp ("Inputs", str_key) == 0)
379 opt_inputs = atoi (str_value);
381 printf ("Unknown key: %s\n", str_key);
382 } /* while (fgets) */
387 n = sn_network_create (opt_inputs);
393 s = sn_stage_read (fh);
397 sn_network_stage_add (n, s);
400 if (SN_NETWORK_STAGE_NUM (n) < 1)
402 sn_network_destroy (n);
407 } /* sn_network_t *sn_network_read */
409 sn_network_t *sn_network_read_file (const char *file)
414 fh = fopen (file, "r");
418 n = sn_network_read (fh);
423 } /* sn_network_t *sn_network_read_file */
425 int sn_network_write (sn_network_t *n, FILE *fh)
429 fprintf (fh, "Inputs: %i\n", n->inputs_num);
432 for (i = 0; i < n->stages_num; i++)
433 sn_stage_write (n->stages[i], fh);
436 } /* int sn_network_write */
438 int sn_network_write_file (sn_network_t *n, const char *file)
443 fh = fopen (file, "w");
447 status = sn_network_write (n, fh);
452 } /* int sn_network_write_file */
454 /* vim: set shiftwidth=2 softtabstop=2 : */