Skip to content

Commit 7e1933c

Browse files
committed
feat[shared_library]: Can load test data from python to the host code
1 parent 84c3f3a commit 7e1933c

File tree

4 files changed

+72
-3
lines changed

4 files changed

+72
-3
lines changed

hls4ml/templates/vitis_accelerator/Makefile

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -118,6 +118,10 @@ INCLUDES += -I$(PWD)/libs/ -I$(PWD)/firmware/ -I$(PWD)/firmware/nnet_utils/
118118
host: $(KERNEL_NAME)_host_cl.cpp libs/xcl2.cpp $(wildcard libs/*.hpp)
119119
$(CXX) $(CXXFLAGS) $(KERNEL_NAME)_host_cl.cpp libs/xcl2.cpp -o $@ $(INCLUDES) $(LDFLAGS)
120120

121+
# Host shared library compilation #################################################
122+
host_shared: $(KERNEL_NAME)_host_cl.cpp libs/xcl2.cpp $(wildcard libs/*.hpp)
123+
$(CXX) -shared -fPIC $(CXXFLAGS) $(KERNEL_NAME)_host_cl.cpp libs/xcl2.cpp -o lib_host.so $(INCLUDES) $(LDFLAGS)
124+
121125
# Execute program #############################################################
122126

123127
run: ./host $(BUILD_DIR)/$(WRAPPER_NAME).xclbin

hls4ml/templates/vitis_accelerator/libs/DataBatcher.hpp

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -70,6 +70,34 @@ template <class T, class U> class DataBatcher {
7070
}
7171
}
7272

73+
/**
74+
* \brief Read in data from a shared buffer.
75+
* \param data Pointer to the shared buffer containing input data
76+
* \param size Size of the shared buffer in bytes
77+
*/
78+
void readSharedData(const double* data, uint64_t size)
79+
{
80+
if (size == 0) {
81+
throw std::runtime_error("No data to load");
82+
}
83+
84+
std::cout << "Loading data from memory buffer" << std::endl;
85+
originalSampleCount = size / _sampleInputSize;
86+
inputData.resize(size);
87+
for (uint64_t i = 0; i < size; i++) {
88+
inputData[i] = static_cast<T>(data[i]);
89+
}
90+
91+
// Zero-pad
92+
numBatches = std::ceil(static_cast<double>(originalSampleCount) / _batchsize);
93+
size_t finalSampleCount = numBatches * _batchsize;
94+
if (finalSampleCount > originalSampleCount) {
95+
std::cout << "Padding with " << (finalSampleCount - originalSampleCount) << " empty samples for a total of "
96+
<< numBatches << " batches of " << _batchsize << " samples" << std::endl;
97+
inputData.resize(finalSampleCount * _sampleInputSize, (T)0);
98+
}
99+
}
100+
73101
bool readReference(const std::string &filename) {
74102

75103
std::ifstream fref(filename);

hls4ml/templates/vitis_accelerator/libs/FpgaObj.hpp

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -142,6 +142,29 @@ template <class T, class U> class FpgaObj {
142142
db->batch(batchedData);
143143
}
144144

145+
/**
146+
* \brief Loads data from a shared buffer into batches and distribute evenly
147+
* amongst Workers.
148+
* \param data Pointer to the shared buffer containing input data
149+
* \param size Size of the shared buffer in bytes
150+
* \param profilingDataRepeat Additional number of times the given data is iterated
151+
* over. Profiling is enabled if this is greater than 0.
152+
*/
153+
void loadSharedData(const double* data, uint64_t size, int profilingDataRepeat = 0) {
154+
// Set-up containers for each Worker's batches/workload
155+
batchedData.reserve(_numCU * _workersPerCU * _numDevice);
156+
for (int i = 0; i < _numCU * _workersPerCU * _numDevice; i++) {
157+
batchedData.emplace_back();
158+
}
159+
160+
// Batch and distribute data
161+
db = new DataBatcher<T, U>(_batchsize, _sampleInputSize, _sampleOutputSize, _numCU * _workersPerCU * _numDevice,
162+
profilingDataRepeat);
163+
db->readSharedData(data, size);
164+
db->createResultBuffers();
165+
db->batch(batchedData);
166+
}
167+
145168
/**
146169
* \brief Workers evaluate all loaded data. Each worker uses a separate thread.
147170
*/

hls4ml/templates/vitis_accelerator/myproject_host_cl.cpp

Lines changed: 17 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -6,10 +6,24 @@
66
#include "kernel_wrapper.h"
77
#include "xcl2.hpp"
88

9-
void predict(double *input, uint64_t input_size, double *output, uint64_t output_size) {
10-
// TODO : Modify the databatcher so it can take those arrays instead of reading and writing files.
9+
extern "C" void predict(double *input, uint64_t input_size, double *output, uint64_t output_size) {
1110

12-
return;
11+
int argc = 2;
12+
char *argv[] = {const_cast<char *>("host"), const_cast<char *>("myproject.xclbin")};
13+
14+
Params params(argc, argv);
15+
16+
FpgaObj<in_buffer_t, out_buffer_t> fpga(params);
17+
18+
fpga.createWorkers(params.numWorker);
19+
20+
fpga.loadSharedData(input, input_size);
21+
22+
fpga.evaluateAll();
23+
24+
fpga.checkResults(params.referenceFilename);
25+
26+
fpga.saveResults(params.outputFilename);
1327
}
1428

1529
int main(int argc, char **argv) {

0 commit comments

Comments
 (0)