Sat. Dec 9th, 2023

# Linear Regression in HLS

Feb 10, 2017

Linear regression tries to fit a line, in the form of $y = a_0 x+a_1$, to a given data set. In a simple form assume that a data set consists of $(y_i, x_i)$. For example: ${(1, 3), (2, 5), (3, 7), (4, 9), (5, 11)}$ shows such a data set.

The following code calculates $a_0$ and $a_1$ for a given data set.

[code language=”c”]
void lr(
DATA_TYPE *memory_0
, DATA_TYPE *memory_1
, u32 in_X
, u32 in_Y
, DATA_TYPE *a0
, DATA_TYPE *a1
, u32 n) {
#pragma HLS INTERFACE s_axilite port=return bundle=control_bus
#pragma HLS INTERFACE s_axilite port=in_X bundle=control_bus
#pragma HLS INTERFACE s_axilite port=in_Y bundle=control_bus
#pragma HLS INTERFACE s_axilite port=a0 bundle=control_bus
#pragma HLS INTERFACE s_axilite port=a1 bundle=control_bus
#pragma HLS INTERFACE s_axilite port=n bundle=control_bus
#pragma HLS INTERFACE m_axi port=memory_0
#pragma HLS INTERFACE m_axi port=memory_1

DATA_TYPE SumX = 0;
DATA_TYPE SumY = 0;
DATA_TYPE SumXX = 0;
DATA_TYPE SumXY = 0;

#pragma HLS DATAFLOW

DATA_TYPE t, y;
hls::stream<DATA_TYPE> input_X_fifo;
hls::stream<DATA_TYPE> input_Y_fifo;

for (int i = 0; i < n; i++) {
#pragma HLS PIPELINE
input_X_fifo << *(memory_0 + in_X + i);
input_Y_fifo << *(memory_1 + in_Y + i);
}

//computation
for (int i = 0; i < n/(B); i++) {
#pragma HLS PIPELINE
DATA_TYPE X[B];
DATA_TYPE Y[B];
for (int j = 0; j < B; j++) {
#pragma HLS UNROLL
}
DATA_TYPE SumX_tmp = 0;
DATA_TYPE SumY_tmp = 0;
DATA_TYPE SumXX_tmp = 0;
DATA_TYPE SumXY_tmp = 0;
int j = 0;
for (j = 0; j < B; j++) {
#pragma HLS UNROLL
SumX_tmp += X[j];
SumY_tmp += Y[j];
SumXX_tmp += X[j]*X[j];
SumXY_tmp += X[j]*Y[j];
}

SumX += SumX_tmp;
SumY += SumY_tmp;
SumXX += SumXX_tmp;
SumXY += SumXY_tmp;

}

//write back data
*a0 = (SumY*SumXX – SumX*SumXY)/(n*SumXX-SumX*SumX);
*a1 = (n*SumXY-SumX*SumY)/(n*SumXX-SumX*SumX);
}
[/code]