forked from sld-columbia/esp
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
add MRI-Q accelerator designed with the Stratus HLS flow (sld-columbi…
- Loading branch information
Showing
40 changed files
with
3,492 additions
and
2 deletions.
There are no files selected for viewing
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
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -7,7 +7,6 @@ vivado_src | |
solver.* | ||
*final.xml | ||
cgraph.graphml | ||
data | ||
inout | ||
*.o | ||
*.opp | ||
|
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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,57 @@ | ||
### Directory introduction: | ||
|
||
* `hw/` | ||
|
||
* `mriq.xml` | ||
|
||
* `memlist.txt` | ||
|
||
* `hls/` | ||
|
||
* `sim/` | ||
|
||
* `tb/` | ||
|
||
* `src/` | ||
|
||
* `inc/` | ||
|
||
* `data/` | ||
* 32\_32\_32\_dataset.bin: | ||
* It comes from Parboil benchmark, with numX as 32768, numK as 3072. We use this file to generate test data with smaller sizes. | ||
* genData.c : | ||
* generate a smaller dataset from 32\_32\_32\_dataset.bin. It needs two arguments: numX and numK. It writes new data into an input file with name test\_32\_x<numX>\_k<numK>.bin and a golden output file test\_32\_x<numX>\_k<numK>.bin with the same data layout. So we can use the two programs provided by Parboil benchmark to read data into pointer variables. | ||
* wrt_bmData.c | ||
* This program is used to generate test data for baremetal application. We need to provide six arguments: 1, numX, 2. numK, 3. batch\_size\_k, 4. num\_batch\_k, 5. batch\_size\_x, 6. num\_batch\_x. | ||
* Makefile | ||
* compile genData.c and wrt_bmData.c | ||
|
||
|
||
* `sw/` | ||
|
||
* `baremetal` | ||
|
||
* `linux` | ||
|
||
* `common/` | ||
* helper.h | ||
* Contains functions reading data from input file and golden output file. It is included by init_buff.h file | ||
* init_buff.h | ||
* Generate input data and golden output data. It is used in hw/tb/system.cpp and sw/linux/app/mriq.c. | ||
* sw_exec.h | ||
* It is only used in sw/linux/app/mriq.c. sw_exec() measures executing time of software computation. | ||
* utils.h | ||
* Has two functions: init\_parameters() and validate\_buffer(). They are used by hw/tb/system.cpp, sw/baremetal/mriq.c, sw/linux/app/mriq.c | ||
|
||
### Testing Instructions: | ||
#### Testing with testbench | ||
The file path and name are specified in hls/project.tcl. We hardcoded the test file names and path in hls/project.tcl as hw/data/test\_small.bin and hw/data/test\_small.out. Its configuration parameters are [batch\_size\_x, num\_batch\_x, batch\_size\_k, num\_batch\_k] = [4, 1, 16, 1]. If you want to use other paramters, you can firstly specify them in tb/system.hpp file, then use the same parameters to generate the corresponding testing data with programs in hw/data. You can rename the testing file in project.tcl or use the same name "test\_small" | ||
#### Testing with baremetal app | ||
We can generate the corresponding test data with the two programs under hw/data/ folder. The instructions of how to generate test data are in the README file of hw/data/. We then set the configuration parameters in sw/baremetal/mriq.c and include the file in init\_buf() function. | ||
|
||
#### Testing with Linux app | ||
|
||
There are three arguments of linux app: name-of-input-file, name-of-golden-outputfile, and the answer to "do you want to run software program of this accelerator?". For example: | ||
> ./mriq_stratus.exe test_small.bin test_small.out 0 | ||
The 3rd argment tells the linux app whether you want to run the software code of computation and measure its execution time on FPGA. "0" means "No" and "1" is "Yes". Files should be transfered to the ~/applications/test/ folder on Linux. |
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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,158 @@ | ||
/*************************************************************************** | ||
*cr | ||
*cr (C) Copyright 2007 The Board of Trustees of the | ||
*cr University of Illinois | ||
*cr All Rights Reserved | ||
*cr | ||
***************************************************************************/ | ||
|
||
#include <endian.h> | ||
#include <stdlib.h> | ||
#include <malloc.h> | ||
#include <stdio.h> | ||
#include <inttypes.h> | ||
#include <math.h> | ||
|
||
|
||
#include <string.h> | ||
|
||
|
||
#define Pix2 6.2831853071795864769252867665590058f | ||
|
||
#ifdef __cplusplus | ||
extern "C" { | ||
#endif | ||
|
||
|
||
void inputData(const char* fName, int* _numK, int* _numX, | ||
float** kx, float** ky, float** kz, | ||
float** x, float** y, float** z, | ||
float** phiR, float** phiI); | ||
|
||
void outputData(const char* fName, float** outR, float** outI, int* numX); | ||
|
||
void ComputeQ(int numK, int numX, | ||
float *plm_kx, float *plm_ky, float *plm_kz, | ||
float* plm_x, float* plm_y, float* plm_z, | ||
float *plm_phiR, float *plm_phiI, | ||
float *plm_Qr, float *plm_Qi); | ||
void createDataStructsforCompute(int numX, float** Qr, float** Qi); | ||
|
||
|
||
#ifdef __cplusplus | ||
} | ||
#endif | ||
|
||
void inputData(const char* fName, int * _numK, int* _numX, | ||
float** kx, float** ky, float** kz, | ||
float** x, float** y, float** z, | ||
float** phiR, float** phiI) | ||
{ | ||
|
||
|
||
FILE* fid = fopen(fName, "r"); | ||
int numK, numX; | ||
|
||
if (fid == NULL) | ||
{ | ||
fprintf(stderr, "Cannot open input file\n"); | ||
exit(-1); | ||
} | ||
fread (&numK, sizeof (int), 1, fid); | ||
*_numK = numK; | ||
|
||
fread (&numX, sizeof (int), 1, fid); | ||
*_numX = numX; | ||
|
||
|
||
*kx = (float *) memalign(16, numK * sizeof (float)); | ||
fread (*kx, sizeof (float), numK, fid); | ||
*ky = (float *) memalign(16, numK * sizeof (float)); | ||
fread (*ky, sizeof (float), numK, fid); | ||
*kz = (float *) memalign(16, numK * sizeof (float)); | ||
fread (*kz, sizeof (float), numK, fid); | ||
*x = (float *) memalign(16, numX * sizeof (float)); | ||
fread (*x, sizeof (float), numX, fid); | ||
*y = (float *) memalign(16, numX * sizeof (float)); | ||
fread (*y, sizeof (float), numX, fid); | ||
*z = (float *) memalign(16, numX * sizeof (float)); | ||
fread (*z, sizeof (float), numX, fid); | ||
*phiR = (float *) memalign(16, numK * sizeof (float)); | ||
fread (*phiR, sizeof (float), numK, fid); | ||
*phiI = (float *) memalign(16, numK * sizeof (float)); | ||
fread (*phiI, sizeof (float), numK, fid); | ||
fclose (fid); | ||
|
||
|
||
} | ||
|
||
|
||
|
||
|
||
|
||
void outputData(const char* fName, float** outR, float** outI, int* _numX) | ||
{ | ||
int numX; | ||
FILE* fid = fopen(fName, "r"); | ||
|
||
if (fid == NULL) | ||
{ | ||
fprintf(stderr, "Cannot open output file\n"); | ||
exit(-1); | ||
} | ||
|
||
|
||
fread(&numX, sizeof(int), 1, fid); | ||
*_numX = numX; | ||
|
||
|
||
*outR = (float *) memalign(16, numX * sizeof (float)); | ||
fread(*outR, sizeof(float), numX, fid); | ||
|
||
*outI = (float *) memalign(16, numX * sizeof (float)); | ||
fread(*outI, sizeof(float), numX, fid); | ||
fclose (fid); | ||
} | ||
|
||
|
||
void ComputeQ(int numK, int numX, | ||
float *plm_kx, float *plm_ky, float *plm_kz, | ||
float* plm_x, float* plm_y, float* plm_z, | ||
float *plm_phiR, float *plm_phiI, | ||
float *plm_Qr, float *plm_Qi) { | ||
float expArg; | ||
float cosArg; | ||
float sinArg; | ||
float phiMag; | ||
int indexK, indexX; | ||
for (indexX = 0; indexX < numX; indexX++) { | ||
// Sum the contributions to this point over all frequencies | ||
float Qracc = 0.0f; | ||
float Qiacc = 0.0f; | ||
for (indexK = 0; indexK < numK; indexK++) { | ||
phiMag = plm_phiR[indexK]*plm_phiR[indexK] + plm_phiI[indexK]*plm_phiI[indexK]; | ||
|
||
|
||
expArg = Pix2 * (plm_kx[indexK] * plm_x[indexX] + | ||
plm_ky[indexK] * plm_y[indexX] + | ||
plm_kz[indexK] * plm_z[indexX]); | ||
cosArg = cosf(expArg); | ||
sinArg = sinf(expArg); | ||
|
||
Qracc += phiMag * cosArg; | ||
Qiacc += phiMag * sinArg; | ||
} | ||
plm_Qr[indexX] = Qracc; | ||
plm_Qi[indexX] = Qiacc; | ||
} | ||
} | ||
|
||
|
||
void createDataStructsforCompute(int numX, float** Qr, float** Qi) | ||
{ | ||
|
||
*Qr = (float*) memalign(16, numX * sizeof (float)); | ||
memset((void *)*Qr, 0, numX * sizeof(float)); | ||
*Qi = (float*) memalign(16, numX * sizeof (float)); | ||
memset((void *)*Qi, 0, numX * sizeof(float)); | ||
} |
116 changes: 116 additions & 0 deletions
116
accelerators/stratus_hls/mriq_stratus/common/init_buff.h
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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,116 @@ | ||
#include "helper.h" | ||
|
||
// init_buffer function can't be used in baremetal app | ||
|
||
|
||
|
||
|
||
void init_buffer(float *in, float *gold, | ||
const char* inputFile, | ||
const char* goldFile, | ||
int32_t batch_size_x, int32_t num_batch_x, | ||
int32_t batch_size_k, int32_t num_batch_k) | ||
{ | ||
|
||
int numX_bm, numK_bm; | ||
float *kx, *ky, *kz, *x, *y, *z, *phiR, *phiI; | ||
|
||
inputData(inputFile, | ||
&numK_bm, | ||
&numX_bm, | ||
&kx, &ky, &kz, | ||
&x, &y, &z, | ||
&phiR, &phiI); | ||
|
||
|
||
int i, j; | ||
int offset_idx = 0; | ||
int idx_single; | ||
|
||
|
||
for(i=0; i < num_batch_k; i++) { | ||
|
||
idx_single = i * batch_size_k; | ||
|
||
|
||
for(j=0; j < batch_size_k; j++) | ||
in[offset_idx + j] = kx[idx_single + j]; | ||
|
||
offset_idx += batch_size_k; // 1 | ||
|
||
for(j=0; j < batch_size_k; j++) | ||
in[offset_idx + j] = ky[idx_single + j]; | ||
|
||
offset_idx += batch_size_k; // 2 | ||
|
||
for(j=0; j < batch_size_k; j++) | ||
in[offset_idx + j] = kz[idx_single + j]; | ||
|
||
offset_idx += batch_size_k; // 3 | ||
|
||
for(j=0; j < batch_size_k; j++) | ||
in[offset_idx + j] = phiR[idx_single + j]; | ||
|
||
offset_idx += batch_size_k; // 4 | ||
|
||
for(j=0; j < batch_size_k; j++) | ||
in[offset_idx + j] = phiI[idx_single + j]; | ||
|
||
offset_idx += batch_size_k; // 5 | ||
} | ||
|
||
|
||
for(i = 0; i < num_batch_x; i++) { | ||
idx_single = i * batch_size_x; | ||
|
||
for(j=0; j < batch_size_x; j++) | ||
in[offset_idx + j] = x[idx_single + j]; | ||
|
||
offset_idx += batch_size_x; // 1 | ||
|
||
for(j=0; j < batch_size_x; j++) | ||
in[offset_idx + j] = y[idx_single + j]; | ||
|
||
offset_idx += batch_size_x; // 2 | ||
|
||
for(j=0; j < batch_size_x; j++) | ||
in[offset_idx + j] = z[idx_single + j]; | ||
|
||
offset_idx += batch_size_x; // 3 | ||
} | ||
|
||
|
||
// read golden output from files and store to gold buf | ||
|
||
float *Qr, *Qi; | ||
outputData(goldFile, &Qr, &Qi, &numX_bm); | ||
|
||
for (int b = 0; b < num_batch_x; b++) { | ||
unsigned base_in = 2 * b * batch_size_x; | ||
|
||
unsigned base = b * batch_size_x; | ||
|
||
for (int i = 0; i < batch_size_x; i++) | ||
gold[base_in + i] = Qr[base + i]; | ||
|
||
base_in += batch_size_x; | ||
|
||
for (int i = 0; i < batch_size_x; i++) | ||
gold[base_in + i] = Qi[base + i]; | ||
|
||
} | ||
|
||
|
||
free(x); | ||
free(y); | ||
free(z); | ||
free(kx); | ||
free(ky); | ||
free(kz); | ||
free(phiR); | ||
free(phiI); | ||
|
||
free(Qr); | ||
free(Qi); | ||
|
||
} |
Oops, something went wrong.