Created
March 11, 2021 11:27
-
-
Save thesps/d87efc2558235e6b0244ee9b0cd41e06 to your computer and use it in GitHub Desktop.
PR302-test
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#include "ap_fixed.h" | |
#include <stdlib.h> | |
#include <iostream> | |
template<class T> | |
class Op_add{ | |
public: | |
T operator()(T a, T b){ | |
return a + b; | |
} | |
}; | |
constexpr int floorlog2(int x){ | |
return (x < 2) ? 0 : 1 + floorlog2(x / 2); | |
} | |
constexpr int pow2(int x){ | |
return x == 0 ? 1 : 2 * pow2(x - 1); | |
} | |
template<class T, int N, class Op> | |
T reduce_old(T* x, Op op){ | |
static constexpr int leftN = pow2(floorlog2(N - 1)) > 0 ? pow2(floorlog2(N - 1)) : 0; | |
static constexpr int rightN = N - leftN > 0 ? N - leftN : 0; | |
if(N == 1){ | |
return x[0]; | |
}else if(N == 2){ | |
return op(x[0],x[1]); | |
}else{ | |
T left[leftN]; | |
T right[rightN]; | |
#pragma HLS array_partition variable=left complete | |
#pragma HLS array_partition variable=right complete | |
ReduceLeft: for(int i = 0; i < leftN; i++){ | |
left[i] = x[i]; | |
} | |
ReduceRight: for(int i = 0; i < rightN; i++){ | |
right[i] = x[i+leftN]; | |
} | |
return op(reduce_old<T,leftN,Op>(left, op), reduce_old<T,rightN,Op>(right, op)); | |
} | |
} | |
template<class T, int N, class Op> | |
T reduce_new(const T* x, Op op) | |
{ | |
static constexpr int leftN = pow2(floorlog2(N - 1)) > 0 ? pow2(floorlog2(N - 1)) : 0; | |
static constexpr int rightN = N - leftN > 0 ? N - leftN : 0; | |
if (N == 1){ | |
return x[0]; | |
} | |
if (N == 2){ | |
return op(x[0],x[1]); | |
} | |
return op(reduce_new<T,leftN,Op>(x, op), reduce_new<T,rightN,Op>(x+leftN, op)); | |
} | |
typedef ap_fixed<16,6> T16; | |
#define N 16 | |
#define NTest 1000 | |
void test(T16 x[N], T16 y[3]){ | |
#pragma HLS array_partition variable=x complete | |
#pragma HLS array_partition variable=y complete | |
#pragma HLS pipeline | |
Op_add<T16> op_add; | |
y[0] = reduce_old<T16,N,Op_add<T16>>(x, op_add); | |
y[1] = reduce_new<T16,N,Op_add<T16>>(x, op_add); | |
y[2] = 0; | |
for(int i = 0; i < N; i++){ | |
y[2] += x[i]; | |
} | |
} | |
int main(){ | |
srand(314); | |
for(int i = 0; i < NTest; i++){ | |
T16 x[N]; | |
T16 y[3]; | |
for(int j = 0; j < N; j++){ | |
x[j] = T16(float(rand() % pow2(T16::width)) / pow2(T16::width-T16::iwidth)); | |
} | |
test(x, y); | |
bool match = y[0] == y[2] && y[1] == y[2]; | |
if(!match){ | |
for(int j = 0; j < N; j++){ | |
std::cout << float(x[j]) << ", "; | |
} | |
std::cout << std::endl; | |
for(int j = 0; j < 3; j++){ | |
std::cout << float(y[j]) << ", "; | |
} | |
std::cout << std::endl; | |
} | |
} | |
return 0; | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment