Skip to content

Instantly share code, notes, and snippets.

@thesps
Created March 11, 2021 11:27
Show Gist options
  • Save thesps/d87efc2558235e6b0244ee9b0cd41e06 to your computer and use it in GitHub Desktop.
Save thesps/d87efc2558235e6b0244ee9b0cd41e06 to your computer and use it in GitHub Desktop.
PR302-test
#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