if (n_small == NULL)
return (NULL);
- n = sn_network_combine_bitonic (n_small, n_small);
+ n = sn_network_combine_bitonic_merge (n_small, n_small);
if (n == NULL)
{
sn_network_destroy (n_small);
- fprintf (stderr, "create_batcher_sort: sn_network_combine_bitonic "
+ fprintf (stderr, "create_batcher_sort: sn_network_combine_bitonic_merge "
"failed.\n");
return (NULL);
}
assert (p1 != NULL);
/* combine the two parents */
- n = sn_network_combine (p0, p1, inputs_num_is_power_of_two);
+ n = sn_network_combine (p0, p1);
sn_network_destroy (p0);
sn_network_destroy (p1);
* Florian octo Forster <ff at octo.it>
**/
-#ifndef _ISOC99_SOURCE
-# define _ISOC99_SOURCE
-#endif
-#ifndef _POSIX_C_SOURCE
-# define _POSIX_C_SOURCE 200112L
-#endif
+#include "config.h"
#include <stdlib.h>
#include <stdio.h>
+#include <string.h>
+#include <unistd.h>
#include "sn_network.h"
-void exit_usage (const char *name)
+static _Bool use_bitonic = 0;
+static const char *file0 = NULL;
+static const char *file1 = NULL;
+
+static void exit_usage (void) /* {{{ */
+{
+ printf ("sn-merge [options] <file0> <file1>\n"
+ "\n"
+ "Options:\n"
+ " -b Use the bitonic merger.\n"
+ " -o Use the odd-even merger. (default)\n"
+ " -h Display this help and exit.\n"
+ "\n");
+ exit (EXIT_FAILURE);
+} /* }}} void exit_usage */
+
+static int read_options (int argc, char **argv) /* {{{ */
{
- printf ("%s <file0> <file1>\n", name);
- exit (1);
-} /* void exit_usage */
+ int option;
+
+ while ((option = getopt (argc, argv, "boh")) != -1)
+ {
+ switch (option)
+ {
+ case 'b':
+ use_bitonic = 1;
+ break;
+
+ case 'o':
+ use_bitonic = 0;
+ break;
+
+ case 'h':
+ default:
+ exit_usage ();
+ }
+ }
+
+ if ((argc - optind) != 2)
+ exit_usage ();
+
+ file0 = argv[optind];
+ file1 = argv[optind + 1];
+
+ if ((file0 == NULL) || (file1 == NULL))
+ exit_usage ();
+
+ return (0);
+} /* }}} int read_options */
+
+static _Bool is_power_of_two (int n)
+{
+ if (n < 1)
+ return (0);
+ else if ((n == 1) || (n == 2))
+ return (1);
+ else if ((n % 2) != 0)
+ return (0);
+ else
+ return (is_power_of_two (n >> 1));
+} /* _Bool is_power_of_two */
int main (int argc, char **argv)
{
sn_network_t *n1;
sn_network_t *n;
- if (argc != 3)
- exit_usage (argv[0]);
+ read_options (argc, argv);
- n0 = sn_network_read_file (argv[1]);
+ if (strcmp ("-", file0) == 0)
+ n0 = sn_network_read (stdin);
+ else
+ n0 = sn_network_read_file (file0);
if (n0 == NULL)
{
- printf ("n0 == NULL\n");
- return (1);
+ fprintf (stderr, "Unable to read first network.\n");
+ exit (EXIT_FAILURE);
}
- n1 = sn_network_read_file (argv[2]);
+ if (strcmp ("-", file1) == 0)
+ {
+ if (strcmp ("-", file0) == 0)
+ n1 = sn_network_clone (n0);
+ else
+ n1 = sn_network_read (stdin);
+ }
+ else
+ n1 = sn_network_read_file (file1);
if (n1 == NULL)
{
- printf ("n1 == NULL\n");
- return (1);
+ fprintf (stderr, "Unable to read second network.\n");
+ exit (EXIT_FAILURE);
+ }
+
+ if (use_bitonic
+ && ((SN_NETWORK_INPUT_NUM (n0) != SN_NETWORK_INPUT_NUM (n1))
+ || !is_power_of_two (SN_NETWORK_INPUT_NUM (n0))))
+ {
+ fprintf (stderr, "Using the bitonic merge is currently only possible "
+ "if the number of inputs of both networks is identical and a "
+ "power of two\n");
+ exit (EXIT_FAILURE);
+ }
+
+ if (use_bitonic)
+ n = sn_network_combine_bitonic_merge (n0, n1);
+ else
+ n = sn_network_combine_odd_even_merge (n0, n1);
+
+ if (n == NULL)
+ {
+ fprintf (stderr, "Combining the networks faild.\n");
+ exit (EXIT_FAILURE);
}
- n = sn_network_combine (n0, n1, /* is power of two = */ 0);
sn_network_destroy (n0);
sn_network_destroy (n1);
#include <strings.h>
#include <ctype.h>
#include <assert.h>
+#include <errno.h>
#include "sn_network.h"
#include "sn_random.h"
{
sn_stage_t **temp;
+ if ((n == NULL) || (s == NULL))
+ return (EINVAL);
+
temp = (sn_stage_t **) realloc (n->stages, (n->stages_num + 1)
* sizeof (sn_stage_t *));
if (temp == NULL)
int nmemb = n->stages_num - (s_num + 1);
sn_stage_t **temp;
- assert (s_num < n->stages_num);
+ if ((n == NULL) || (s_num >= n->stages_num))
+ return (EINVAL);
sn_stage_destroy (n->stages[s_num]);
n->stages[s_num] = NULL;
sn_stage_t *s;
if ((n == NULL) || (c == NULL))
- return (-1);
+ return (EINVAL);
if (n->stages_num > 0)
{
{
int i;
+ if (n == NULL)
+ return (EINVAL);
+
for (i = 0; i < n->stages_num; i++)
sn_stage_invert (n->stages[i]);
{
int i;
+ if ((n == NULL) || (sw < 0))
+ return (EINVAL);
+
+ if (sw == 0)
+ return (0);
+
for (i = 0; i < n->stages_num; i++)
sn_stage_shift (n->stages[i], sw, SN_NETWORK_INPUT_NUM (n));
return (n);
} /* }}} sn_network_t *sn_network_combine_bitonic_shift */
-sn_network_t *sn_network_combine_bitonic (sn_network_t *n0, /* {{{ */
+sn_network_t *sn_network_combine_bitonic_merge (sn_network_t *n0, /* {{{ */
sn_network_t *n1)
{
return (sn_network_combine_bitonic_shift (n0, n1, /* do_shift = */ 0));
-} /* }}} sn_network_t *sn_network_combine_bitonic */
+} /* }}} sn_network_t *sn_network_combine_bitonic_merge */
sn_network_t *sn_network_combine_odd_even_merge (sn_network_t *n0, /* {{{ */
sn_network_t *n1)
sn_network_compress (n);
return (n);
-} /* }}} sn_network_t *sn_network_combine */
+} /* }}} sn_network_t *sn_network_combine_odd_even_merge */
sn_network_t *sn_network_combine (sn_network_t *n0, /* {{{ */
- sn_network_t *n1, int is_power_of_two)
+ sn_network_t *n1)
{
- sn_network_t *n;
-
- if ((is_power_of_two != 0) && (sn_bounded_random (0, 9) == 0))
- {
- DPRINTF ("sn_network_combine: Using the bitonic merger.\n");
- n = sn_network_combine_bitonic_shift (n0, n1, /* do_shift = */ 1);
- }
- else
- {
- DPRINTF ("sn_network_combine: Using the odd-even merger.\n");
- n = sn_network_combine_odd_even_merge (n0, n1);
- }
-
- sn_network_compress (n);
-
- return (n);
+ return (sn_network_combine_odd_even_merge (n0, n1));
} /* }}} sn_network_t *sn_network_combine */
int sn_network_sort (sn_network_t *n, int *values) /* {{{ */
* \return Zero on success, non-zero on failure.
*/
int sn_network_cut_at (sn_network_t *n, int input, enum sn_network_cut_dir_e dir);
-sn_network_t *sn_network_combine (sn_network_t *n0, sn_network_t *n1,
- int is_power_of_two);
-sn_network_t *sn_network_combine_bitonic (sn_network_t *n0, sn_network_t *n1);
+
+/**
+ * An alias for sn_network_combine_odd_even_merge().
+ */
+sn_network_t *sn_network_combine (sn_network_t *n0, sn_network_t *n1);
/**
* Combines two comparator networks using a bitonic merger. The number of
* \return Newly allocated network with twice the number of inputs or NULL on
* error.
*/
+sn_network_t *sn_network_combine_bitonic_merge (sn_network_t *n0, sn_network_t *n1);
/**
* Combines two comparator networks using the odd-even-merger.