#include "fp_streamops.cpp"
#include <stdlib.h>
#include <stdio.h>
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
#include <math.h>
#define ARRAYSIZE 32

void  bitonic(float  idx1[], float  input[ARRAYSIZE], float  output[], float  stageWidth, float  offset, float  twoOffset, int  idx1_brcc_stream_size_0, int  output_brcc_stream_size_0) {

for (int brcc_iterator_0=0; brcc_iterator_0 < output_brcc_stream_size_0; brcc_iterator_0++) {
float  idx2;
float  sign;
float  dir;
float  min;
float  max;

sign=((fmod( idx1[(idx1_brcc_stream_size_0 == 1) ? 0 : (brcc_iterator_0%idx1_brcc_stream_size_0)], twoOffset)) <(offset)) ? (1.000000f) : (-1.000000f);

dir=((fmod(floor(( idx1[(idx1_brcc_stream_size_0 == 1) ? 0 : (brcc_iterator_0%idx1_brcc_stream_size_0)]) /(stageWidth)), 2)) ==(0)) ? (1.000000f) : (-1.000000f);

idx2=( idx1[(idx1_brcc_stream_size_0 == 1) ? 0 : (brcc_iterator_0%idx1_brcc_stream_size_0)]) +((sign) *(offset));

min=((input[(int)( idx1[(idx1_brcc_stream_size_0 == 1) ? 0 : (brcc_iterator_0%idx1_brcc_stream_size_0)])]) <(input[(int)(idx2)])) ? (input[(int)( idx1[(idx1_brcc_stream_size_0 == 1) ? 0 : (brcc_iterator_0%idx1_brcc_stream_size_0)])]) : (input[(int)(idx2)]);

max=((input[(int)( idx1[(idx1_brcc_stream_size_0 == 1) ? 0 : (brcc_iterator_0%idx1_brcc_stream_size_0)])]) >(input[(int)(idx2)])) ? (input[(int)( idx1[(idx1_brcc_stream_size_0 == 1) ? 0 : (brcc_iterator_0%idx1_brcc_stream_size_0)])]) : (input[(int)(idx2)]);
	output[brcc_iterator_0]=((sign) ==(dir)) ? (min) : (max);

}
}

template <int idx1_brcc_stream_size_0, int idx1_brcc_stream_size_1, int output_brcc_stream_size_0, int output_brcc_stream_size_1>
void  bitonic(float  idx1[idx1_brcc_stream_size_0][idx1_brcc_stream_size_1], float  input[ARRAYSIZE], float  output[output_brcc_stream_size_0][output_brcc_stream_size_1], float  stageWidth, float  offset, float  twoOffset) {

for (int brcc_iterator_0=0; brcc_iterator_0 < output_brcc_stream_size_0; brcc_iterator_0++) {
for (int brcc_iterator_1=0; brcc_iterator_1 < output_brcc_stream_size_1; brcc_iterator_1++) {
float  idx2;
float  sign;
float  dir;
float  min;
float  max;

sign=((fmod(((idx1_brcc_stream_size_0 == 1) ?
	((idx1_brcc_stream_size_1 == 1) ? idx1[0][0] : idx1[0][brcc_iterator_1%idx1_brcc_stream_size_1]) :
	((idx1_brcc_stream_size_1 == 1) ? idx1[brcc_iterator_0%idx1_brcc_stream_size_0][0] : idx1[brcc_iterator_0%idx1_brcc_stream_size_0][brcc_iterator_1%idx1_brcc_stream_size_1])), twoOffset)) <(offset)) ? (1.000000f) : (-1.000000f);

dir=((fmod(floor((((idx1_brcc_stream_size_0 == 1) ?
	((idx1_brcc_stream_size_1 == 1) ? idx1[0][0] : idx1[0][brcc_iterator_1%idx1_brcc_stream_size_1]) :
	((idx1_brcc_stream_size_1 == 1) ? idx1[brcc_iterator_0%idx1_brcc_stream_size_0][0] : idx1[brcc_iterator_0%idx1_brcc_stream_size_0][brcc_iterator_1%idx1_brcc_stream_size_1]))) /(stageWidth)), 2)) ==(0)) ? (1.000000f) : (-1.000000f);

idx2=(((idx1_brcc_stream_size_0 == 1) ?
	((idx1_brcc_stream_size_1 == 1) ? idx1[0][0] : idx1[0][brcc_iterator_1%idx1_brcc_stream_size_1]) :
	((idx1_brcc_stream_size_1 == 1) ? idx1[brcc_iterator_0%idx1_brcc_stream_size_0][0] : idx1[brcc_iterator_0%idx1_brcc_stream_size_0][brcc_iterator_1%idx1_brcc_stream_size_1]))) +((sign) *(offset));

min=((input[(int)(((idx1_brcc_stream_size_0 == 1) ?
	((idx1_brcc_stream_size_1 == 1) ? idx1[0][0] : idx1[0][brcc_iterator_1%idx1_brcc_stream_size_1]) :
	((idx1_brcc_stream_size_1 == 1) ? idx1[brcc_iterator_0%idx1_brcc_stream_size_0][0] : idx1[brcc_iterator_0%idx1_brcc_stream_size_0][brcc_iterator_1%idx1_brcc_stream_size_1])))]) <(input[(int)(idx2)])) ? (input[(int)(((idx1_brcc_stream_size_0 == 1) ?
	((idx1_brcc_stream_size_1 == 1) ? idx1[0][0] : idx1[0][brcc_iterator_1%idx1_brcc_stream_size_1]) :
	((idx1_brcc_stream_size_1 == 1) ? idx1[brcc_iterator_0%idx1_brcc_stream_size_0][0] : idx1[brcc_iterator_0%idx1_brcc_stream_size_0][brcc_iterator_1%idx1_brcc_stream_size_1])))]) : (input[(int)(idx2)]);

max=((input[(int)(((idx1_brcc_stream_size_0 == 1) ?
	((idx1_brcc_stream_size_1 == 1) ? idx1[0][0] : idx1[0][brcc_iterator_1%idx1_brcc_stream_size_1]) :
	((idx1_brcc_stream_size_1 == 1) ? idx1[brcc_iterator_0%idx1_brcc_stream_size_0][0] : idx1[brcc_iterator_0%idx1_brcc_stream_size_0][brcc_iterator_1%idx1_brcc_stream_size_1])))]) >(input[(int)(idx2)])) ? (input[(int)(((idx1_brcc_stream_size_0 == 1) ?
	((idx1_brcc_stream_size_1 == 1) ? idx1[0][0] : idx1[0][brcc_iterator_1%idx1_brcc_stream_size_1]) :
	((idx1_brcc_stream_size_1 == 1) ? idx1[brcc_iterator_0%idx1_brcc_stream_size_0][0] : idx1[brcc_iterator_0%idx1_brcc_stream_size_0][brcc_iterator_1%idx1_brcc_stream_size_1])))]) : (input[(int)(idx2)]);
	output[brcc_iterator_0][brcc_iterator_1]=((sign) ==(dir)) ? (min) : (max);

}
}}

int  main()
 {
int  i;
int  lg_arraySize;
int  flip = 0;
int  stage;
int  step;
float  segWidth;
float  offset;
float  *array;
float  sorted1Strm[ARRAYSIZE];
float  sorted2Strm[ARRAYSIZE];
float  rangeEnd = ARRAYSIZE;
float  idxStrm[ARRAYSIZE];
for (int brcc_iter_iterator_0=0; brcc_iter_iterator_0<(ARRAYSIZE); brcc_iter_iterator_0++) {
	idxStrm[brcc_iter_iterator_0] = 0.000000f + brcc_iter_iterator_0*((ARRAYSIZE)-(0.000000f))/ARRAYSIZE;
}

array=(float *) (malloc((sizeof(float ) ) *(ARRAYSIZE)));

lg_arraySize=0;
for (i = ARRAYSIZE >> 1; i; lg_arraySize++)

i=(i) >>(1);
srand(time(NULL));
for (i = 0; i < ARRAYSIZE; i++)
array[i] = (float ) (rand() % 100);printf("N = %d  (requires lg_N=%d stages)\n",ARRAYSIZE,lg_arraySize);
printf("Original list:\n");
for (i = 0; i < ARRAYSIZE; i++)
printf("%3.2f ",array[i]);
printf("\n\n");
streamRead<float , ARRAYSIZE>(sorted1Strm,array);
for (stage = 1; stage <= lg_arraySize; stage++)
 {

segWidth=(float ) (pow(2.000000f, stage));
for (step = 1; step <= stage; step++)
 {

offset=(float ) (pow(2.000000f, (stage) -(step)));
if (!flip) {
bitonic(idxStrm,sorted1Strm,sorted2Strm,segWidth,offset,2 * offset,ARRAYSIZE,ARRAYSIZE);
} else {
bitonic(idxStrm,sorted2Strm,sorted1Strm,segWidth,offset,2 * offset,ARRAYSIZE,ARRAYSIZE);
}

flip=(flip) ? (0) : (1);

}

}
if (flip) {
streamWrite<float , ARRAYSIZE>(sorted2Strm,array);
} else {
streamWrite<float , ARRAYSIZE>(sorted1Strm,array);
}
printf("Sorted list:\n");
for (i = 0; i < ARRAYSIZE; i++)
printf("%3.2f ",array[i]);
printf("\n");
free(array);
return 0;


}
