Commit 486f0336 authored by Nicolas Peslerbe's avatar Nicolas Peslerbe

Fully tested and functional numpy sw tpu

parent f7cbc131
......@@ -49,7 +49,7 @@ public:
}
unsigned short shape(const int shape) const{
return SHAPE(_shape, shape);
return getShape(_shape, shape);
}
array<int, 3> shape(){
......@@ -77,14 +77,14 @@ public:
template <size_t NB_EL>
unsigned char reshape( array<int, NB_EL>& arr, bool force=false){
unsigned short shape[3];
unsigned short newShape[3];
for(unsigned short i = 0; i < 3; i++){
if (i < arr.size())
shape[i] = arr[i];
newShape[i] = arr[i];
else
shape[i] = 1;
newShape[i] = 1;
}
_reshape(NEW_SHAPE(shape[0], shape[1], shape[2]), force);
_reshape(NEW_SHAPE(newShape[0], newShape[1], newShape[2]), force);
}
......@@ -94,18 +94,18 @@ public:
**/
unsigned int _expand_dim(unsigned short axis){
assert(SHAPE(2) == 1);
short shape[3];
assert(shape(2) == 1);
short newShape[3];
int pointer = 0;
for(int i=0; i < 3; i++){
if(axis == i){
shape[pointer] = 1;
newShape[pointer] = 1;
pointer++;
}
shape[pointer] = SHAPE(i);
newShape[pointer] = shape(i);
pointer++;
}
return NEW_SHAPE(shape[0], shape[1], shape[2]);
return NEW_SHAPE(newShape[0], newShape[1], newShape[2]);
}
void expand_dim(unsigned short axis){
_reshape(_expand_dim(axis));
......@@ -116,11 +116,11 @@ public:
**/
T get(unsigned short i, unsigned short j=0, unsigned short k=0) const{
return getDataPointer()[i * SHAPE(1) * SHAPE(2) + j * SHAPE(2) + k];
return getDataPointer()[i * shape(1) * shape(2) + j * shape(2) + k];
}
void set(T value, unsigned short i, unsigned short j=0, unsigned short k=0){
getDataPointer()[i * SHAPE(1) * SHAPE(2) + j * SHAPE(2) + k] = value;
getDataPointer()[i * shape(1) * shape(2) + j * shape(2) + k] = value;
}
void setFlat(T value, unsigned int i){
......@@ -156,8 +156,8 @@ public:
#else
_tensorData = new T[SIZE(newShape)];
#endif
shape = newShape;
//cout << "Tensor of size: " << SHAPE(0) << "," << SHAPE(1) << "," << SHAPE(2) << " initialized. Alloc: " << SIZE(newShape) << endl;
_shape = newShape;
//cout << "Tensor of size: " << shape(0) << "," << shape(1) << "," << shape(2) << " initialized. Alloc: " << SIZE(newShape) << endl;
}
......@@ -186,9 +186,9 @@ public:
std::unique_ptr<TensorObj<T> > operator-(std::unique_ptr<TensorObj<T> >& second) {
assert(this->size() == second->size());
std::unique_ptr<TensorObj<T> > out = TensorObj<T>::init(this->getPackedShape());
std::unique_ptr<TensorObj<T> > out = TensorObj<T>::init(this->packedShape());
for (int i=0; i < this->size(); i++){
out->setLin(this->getLin(i) - second->getLin(i), i);
out->setFlat(this->getFlat(i) - second->getFlat(i), i);
}
return out;
......@@ -198,8 +198,8 @@ public:
int counter=0;
for (int i=0; i < this->size(); i++){
if((this->getLin(i) - second->getLin(i)) > 0.0025){
if(counter > 20 || ((this->getLin(i) - second->getLin(i) != 0x7FFFFFFF) && !large))
if((this->getFlat(i) - second->getFlat(i)) > 0.0025){
if(counter > 20 || ((this->getFlat(i) - second->getFlat(i) != 0x7FFFFFFF) && !large))
return false;
else
counter++;
......
This source diff could not be displayed because it is too large. You can view the blob instead.
#ifndef __NUMPY_DRIVERS__
#define __NUMPY_DRIVERS__
#include "Tensor.hpp"
#include <array>
#include <iostream>
using namespace std;
#ifdef PETALINUX
#else
#include "../../../numpy/c/inc/numpy.hpp"
#endif
#define R_DIM(s, inDim) (((axis >> s) & 0b1) ? 1 : GET_DIM(s, inDim))
#define REDUCE_FCT(s, op) \
template <size_t NB_EL> \
Tensor<float> reduce_##s (Tensor<float>& a, array<unsigned char, NB_EL> axis, bool keepdims=false){ \
unsigned char axisBool = axisarrayToAxisBool(axis); \
unsigned int newSize = computeReduceSize(a.getPackedShape(), axisBool, keepdims); \
Tensor<float> out(newSize); \
/*numpyTop(SET_INSTRUCTION(op, OP_WITH_BUFFER, FLOAT32), out.getHwTensor(), NULL, out.getPackedShape(), \
a.getHwTensor(), NULL, a.getPackedShape(), \
NULL, NULL, 0, \
NULL, 0, \
0., 0., 0, 0, axisBool, 0); */ \
return out; \
} \
template <size_t NB_EL> \
Tensor<int> reduce_##s (Tensor<int>& a, array<unsigned char, NB_EL> axis, bool keepdims=false){ \
unsigned char axisBool = axisarrayToAxisBool(axis); \
unsigned int newSize = computeReduceSize(a.getPackedShape(), axisBool, keepdims); \
Tensor<int> out(newSize); \
/*numpyTop(SET_INSTRUCTION(op, OP_WITH_BUFFER, INT32), out.getHwTensor(), NULL, out.getPackedShape(), \
a.getHwTensor(), NULL, a.getPackedShape(), \
NULL, NULL, 0, \
NULL, 0, \
0., 0., 0, 0, axisBool, 0); */ \
return out; \
} \
template <typename T>\
Tensor<T> reduce_##s (Tensor<T>& a, unsigned char axis=255, bool keepdims=false){ \
\
if(axis == 255){\
return reduce_##s (a, array<unsigned char,3>{0, 1, 2}, keepdims);\
} else{\
return reduce_##s (a, array<unsigned char,1>{axis}, keepdims); \
}\
} \
class Numpy{
public:
vector<unsigned char> allAxis{0, 1, 2};
unsigned int computeReduceSize(unsigned int inSize, unsigned char axis, bool keepdims){
cout << "New size: " <<(unsigned int)axis << endl;
if(keepdims) return NEW_SHAPE(R_DIM(0, inSize), R_DIM(1, inSize), R_DIM(2, inSize));
unsigned char i = 0;
unsigned short newDims[3] = {1, 1, 1};
if(R_DIM(0, inSize) != 1){newDims[i] = R_DIM(0, inSize);i++;}
if(R_DIM(1, inSize) != 1){newDims[i] = R_DIM(1, inSize);i++;}
if(R_DIM(2, inSize) != 1){newDims[i] = R_DIM(2, inSize);}
return NEW_SHAPE(newDims[0], newDims[1], newDims[2]);
}
template <size_t NB_EL>
unsigned char axisarrayToAxisBool( array<unsigned char, NB_EL>& arr){
unsigned char out = 0;
for(unsigned short i = 0; i < arr.size(); i++){
out |= 0b1 << arr.at(i);
cout << "New at: " <<(unsigned int)arr.at(i) << endl;
}
return out;
}
Numpy(){
// init numpy drivers here
}
REDUCE_FCT(max, MAX)
REDUCE_FCT(min, MIN)
REDUCE_FCT(mean, MEAN)
REDUCE_FCT(sum, SUM)
REDUCE_FCT(prod, PROD)
REDUCE_FCT(any, ANY)
REDUCE_FCT(all, ALL)
~Numpy(){}
};
#endif
......@@ -10,7 +10,7 @@
#define SHAPE(i, s) SHAPE##i (s)
unsigned short getShape(const unsigned int fullShape, const unsigned short axis){
static unsigned short getShape(const unsigned int fullShape, const unsigned short axis){
switch(axis){
case 0:
return SHAPE0(fullShape);
......
......@@ -85,6 +85,7 @@ def getFunction(f):
out += line
out = out.replace("#TYPE#", key)
out = out.replace("#TYPE_CONST#", value)
out = out.replace("#TYPE_SHORT#", value[0].lower())
out = out.replace("#NAME#", f["name"])
if "op_name" in f:
out = out.replace("#OP_NAME#", f["op_name"])
......@@ -171,11 +172,13 @@ def getTb(f):
numberT = {key: numberT[key] for key in f["only"]}
for key, value in numberT.items():
out = ""
if "tb_template" in f:
f["template"] = f["tb_template"]
for t in f["template"]:
if t in templatetb:
if "tb" in f and "no" in f["tb"]:
continue
addSizeMem(t, key)
#addSizeMem(t, key)
out = ""
for line in templatetb[t]:
......@@ -186,6 +189,7 @@ def getTb(f):
out = out.replace("#TOLERANCE#", "")
out = out.replace("#TYPE#", key)
out = out.replace("#TYPE_CONST#", value.lower())
out = out.replace("#TYPE_SHORT#", value[0].lower())
out = out.replace("#NAME#", f["name"])
complete += out
return complete
......@@ -344,7 +348,13 @@ functions = [{
},
{
"name": "sort",
"template": ["sort"]
"template": ["sort"],
"tb_template": ["Mt_Mt"]
},
{
"name": "argsort",
"template": ["argsort"],
"tb_template": ["Mt_Mi"]
},
{
"name": "extract",
......@@ -352,19 +362,23 @@ functions = [{
},
{
"name": "transpose",
"template": ["transpose"]
"template": ["transpose"],
"tb_template": ["Mt_Mt"]
},
{
"name": "matmul",
"template": ["matmul"]
"template": ["matmul"],
"tb_template": ["2Mt_Mt"]
},
{
"name": "range",
"template": ["range"]
"template": ["range"],
"op_name":"IN_RANGE"
},
{
"name": "boolean_mask",
"template": ["boolean_mask"]
"template": ["boolean_mask"],
"tb_template": ["MtMi_Mt"]
},
{
"name": "broadcast_to",
......@@ -373,7 +387,8 @@ functions = [{
},
{
"name": "gather",
"template": ["gather"]
"template": ["gather"],
"tb_template": ["MtMi_Mt"]
}]
destF.write("// Auto generated interface driver for hardware numpy\n")
......
This diff is collapsed.
......@@ -8,11 +8,11 @@ using namespace std;
template <typename T>
void printm(const Tensor <T>& tensor){
cout << "Print matrix of sizes: " << tensor->getDim(0) << "," << tensor->getDim(1) << "," << tensor->getDim(2) << endl;
for(int i = 0; i < tensor->getDim(0); i++){
for(int j = 0; j < tensor->getDim(1); j++){
cout << "Print matrix of sizes: " << tensor->shape(0) << "," << tensor->shape(1) << "," << tensor->shape(2) << endl;
for(int i = 0; i < tensor->shape(0); i++){
for(int j = 0; j < tensor->shape(1); j++){
cout << " [";
for(int k = 0; k < tensor->getDim(2); k++){
for(int k = 0; k < tensor->shape(2); k++){
cout << tensor->get(i, j, k) << " ";
}
cout << "] ";
......@@ -48,6 +48,21 @@ int main (int argc, char** argv) {
}
#SEC "Mt_Mi"
{
Tensor<#TYPE#> matrix1 = parse2DCsvFile<#TYPE#>("#TYPE_CONST#_#NAME#/original_0.txt");
Tensor<int> matrixOut = np.#NAME#(matrix1);
Tensor<int> matrix_test = parse2DCsvFile<int>("#TYPE_CONST#_#NAME#/out_{}.txt");
if(matrixOut->assertWith(matrix_test#TOLERANCE#))
cout << "Function #NAME# with type: #TYPE# is working!" << endl;
else{
printm((*matrixOut)-matrix_test);
cout << "!!!!!!!!!! Function #NAME# with type: #TYPE# is not working!" << endl;
return 1;
}
}
#SEC "Mt_Mt"
{
Tensor<#TYPE#> matrix1 = parse2DCsvFile<#TYPE#>("#TYPE_CONST#_#NAME#/original_0.txt");
......@@ -131,11 +146,11 @@ int main (int argc, char** argv) {
#SEC "where"
{
Tensor <int> matrix1 = parse2DCsvFile<int>("#TYPE_CONST#_#NAME#_v2/original_0.txt");
Tensor <#TYPE#> matrix2 = parse2DCsvFile<#TYPE#>("#TYPE_CONST#_#NAME#_v2/original_1.txt");
Tensor <#TYPE#> matrix3 = parse2DCsvFile<#TYPE#>("#TYPE_CONST#_#NAME#_v2/original_2.txt");
Tensor <int> matrix1 = parse2DCsvFile<int>("#TYPE_CONST#_#NAME#/original_0.txt");
Tensor <#TYPE#> matrix2 = parse2DCsvFile<#TYPE#>("#TYPE_CONST#_#NAME#/original_1.txt");
Tensor <#TYPE#> matrix3 = parse2DCsvFile<#TYPE#>("#TYPE_CONST#_#NAME#/original_2.txt");
Tensor <#TYPE#> matrixOut = np.#NAME#(matrix1, matrix2, matrix3);
Tensor <#TYPE#> matrix_test = parse2DCsvFile<#TYPE#>("#TYPE_CONST#_#NAME#_v2/out_{}.txt");
Tensor <#TYPE#> matrix_test = parse2DCsvFile<#TYPE#>("#TYPE_CONST#_#NAME#/out_{}.txt");
if(matrixOut->assertWith(matrix_test))
cout << "Function #NAME# with type: #TYPE# is working!" << endl;
else{
......@@ -160,3 +175,145 @@ int main (int argc, char** argv) {
}
}
#SEC "concatenate"
{
Tensor <#TYPE#> matrix1 = parse2DCsvFile<#TYPE#>("#TYPE_CONST#_concat/original_0.txt");
Tensor <#TYPE#> matrix2 = parse2DCsvFile<#TYPE#>("#TYPE_CONST#_concat/original_1.txt");
Tensor <#TYPE#> matrixOut = np.#NAME#(matrix1, matrix2, 0);
Tensor <#TYPE#> matrix_test = parse2DCsvFile<#TYPE#>("#TYPE_CONST#_concat/out_{'axis': 0}.txt");
if(matrixOut->assertWith(matrix_test))
cout << "Function #NAME# with type: #TYPE# is working!" << endl;
else{
printm((*matrixOut)-matrix_test);
cout << "!!!!!!!!!! Function #NAME# with type: #TYPE# is not working!" << endl;
return 1;
}
}
{
Tensor <#TYPE#> matrix1 = parse2DCsvFile<#TYPE#>("#TYPE_CONST#_concat/original_0.txt");
Tensor <#TYPE#> matrix2 = parse2DCsvFile<#TYPE#>("#TYPE_CONST#_concat/original_1.txt");
Tensor <#TYPE#> matrixOut = np.#NAME#(matrix1, matrix2, 1);
Tensor <#TYPE#> matrix_test = parse2DCsvFile<#TYPE#>("#TYPE_CONST#_concat/out_{'axis': 1}.txt");
if(matrixOut->assertWith(matrix_test))
cout << "Function #NAME# with type: #TYPE# is working!" << endl;
else{
printm((*matrixOut)-matrix_test);
cout << "!!!!!!!!!! Function #NAME# with type: #TYPE# is not working!" << endl;
return 1;
}
}
{
Tensor <#TYPE#> matrix1 = parse2DCsvFile<#TYPE#>("#TYPE_CONST#_stack/original_0.txt");
Tensor <#TYPE#> matrix2 = parse2DCsvFile<#TYPE#>("#TYPE_CONST#_stack/original_1.txt");
Tensor <#TYPE#> matrixOut = np.stack(matrix1, matrix2, 0);
Tensor <#TYPE#> matrix_test = parse2DCsvFile<#TYPE#>("#TYPE_CONST#_stack/out_{'axis': 0}.txt");
if(matrixOut->assertWith(matrix_test))
cout << "Function stack with type: #TYPE# is working!" << endl;
else{
printm((*matrixOut)-matrix_test);
cout << "!!!!!!!!!! Function stack with type: #TYPE# is not working!" << endl;
return 1;
}
}
{
Tensor <#TYPE#> matrix1 = parse2DCsvFile<#TYPE#>("#TYPE_CONST#_stack/original_0.txt");
Tensor <#TYPE#> matrix2 = parse2DCsvFile<#TYPE#>("#TYPE_CONST#_stack/original_1.txt");
Tensor <#TYPE#> matrixOut = np.stack(matrix1, matrix2, 1);
Tensor <#TYPE#> matrix_test = parse2DCsvFile<#TYPE#>("#TYPE_CONST#_stack/out_{'axis': 1}.txt");
if(matrixOut->assertWith(matrix_test))
cout << "Function stack with type: #TYPE# is working!" << endl;
else{
printm((*matrixOut)-matrix_test);
cout << "!!!!!!!!!! Function stack with type: #TYPE# is not working!" << endl;
return 1;
}
}
#SEC "range"
{
Tensor <#TYPE#> matrixOut = np.#NAME#_#TYPE_SHORT#(50, 0, 2);
Tensor <#TYPE#> matrix_test = parse2DCsvFile<#TYPE#>("#TYPE_CONST#_#NAME#/out_{'start': 0, 'limit': 50, 'delta': 2}.txt");
if(matrixOut->assertWith(matrix_test))
cout << "Function #NAME# with type: #TYPE# is working!" << endl;
else{
printm((*matrixOut)-matrix_test);
cout << "!!!!!!!!!! Function #NAME# with type: #TYPE# is not working!" << endl;
return 1;
}
}
{
Tensor <#TYPE#> matrixOut = np.#NAME#_#TYPE_SHORT#(60, 0);
Tensor <#TYPE#> matrix_test = parse2DCsvFile<#TYPE#>("#TYPE_CONST#_#NAME#/out_{'start': 0, 'limit': 60}.txt");
if(matrixOut->assertWith(matrix_test))
cout << "Function #NAME# with type: #TYPE# is working!" << endl;
else{
printm((*matrixOut)-matrix_test);
cout << "!!!!!!!!!! Function #NAME# with type: #TYPE# is not working!" << endl;
return 1;
}
}
{
Tensor <#TYPE#> matrixOut = np.#NAME#_#TYPE_SHORT#(60, 10);
Tensor <#TYPE#> matrix_test = parse2DCsvFile<#TYPE#>("#TYPE_CONST#_#NAME#/out_{'start': 10, 'limit': 60}.txt");
if(matrixOut->assertWith(matrix_test))
cout << "Function #NAME# with type: #TYPE# is working!" << endl;
else{
printm((*matrixOut)-matrix_test);
cout << "!!!!!!!!!! Function #NAME# with type: #TYPE# is not working!" << endl;
return 1;
}
}
#SEC "broadcast_to"
{
Tensor<#TYPE#> matrix1 = parse2DCsvFile<#TYPE#>("#TYPE_CONST#_#NAME#/original_0.txt");
Tensor<#TYPE#> matrixOut = np.#NAME#(matrix1, D(50,60));
Tensor<#TYPE#> matrix_test = parse2DCsvFile<#TYPE#>("#TYPE_CONST#_#NAME#/out_{'shape': [50, 60]}.txt");
if(matrixOut->assertWith(matrix_test#TOLERANCE#))
cout << "Function #NAME# with type: #TYPE# is working!" << endl;
else{
printm((*matrixOut)-matrix_test);
cout << "!!!!!!!!!! Function #NAME# with type: #TYPE# is not working!" << endl;
return 1;
}
}
#SEC "extract"
{
Tensor<#TYPE#> matrix1 = parse2DCsvFile<#TYPE#>("#TYPE_CONST#_slice/original_0.txt");
Tensor<#TYPE#> matrixOut = np.#NAME#(matrix1, SH(RANGE(4,20), RANGE(10,30)));
Tensor<#TYPE#> matrix_test = parse2DCsvFile<#TYPE#>("#TYPE_CONST#_slice/out_{}.txt");
if(matrixOut->assertWith(matrix_test#TOLERANCE#))
cout << "Function #NAME# with type: #TYPE# is working!" << endl;
else{
printm((*matrixOut)-matrix_test);
cout << "!!!!!!!!!! Function #NAME# with type: #TYPE# is not working!" << endl;
return 1;
}
}
#SEC "MtMi_Mt"
{
Tensor <#TYPE#> matrix1 = parse2DCsvFile<#TYPE#>("#TYPE_CONST#_#NAME#/original_0.txt");
Tensor <int> matrix2 = parse2DCsvFile<int>("#TYPE_CONST#_#NAME#/original_1.txt");
Tensor <#TYPE#> matrixOut = np.#NAME#(matrix1, matrix2);
Tensor <#TYPE#> matrix_test = parse2DCsvFile<#TYPE#>("#TYPE_CONST#_#NAME#/out_{}.txt");
if(matrixOut->assertWith(matrix_test))
cout << "Function #NAME# with type: #TYPE# is working!" << endl;
else{
printm((*matrixOut)-matrix_test);
cout << "!!!!!!!!!! Function #NAME# with type: #TYPE# is not working!" << endl;
return 1;
}
}
......@@ -73,7 +73,7 @@
// Type 2 operations
#define CONCAT 0x0
#define RANGE 0x1
#define IN_RANGE 0x1
#define GATHER 0x3
#define SORT 0x4
#define ARGSORT 0x5
......
......@@ -161,7 +161,7 @@ UNIT_INT_T type2_op_flow( ap_uint<6> instructionReg,
switch(instructionReg){
case CONCAT:
{
unsigned short axis = param0 && 0x3;
unsigned short axis = param0 & 0x3;
int totalL = SIZE(src1_sz) + SIZE(src2_sz);
int id0 = 0, id1 = 0;
for(int i=0; i < totalL; i++){
......@@ -201,9 +201,11 @@ UNIT_INT_T type2_op_flow( ap_uint<6> instructionReg,
buffer_int[d+1] = swap_int;
}
}
if (instructionReg == ARGSORT) dst_int_mem[totalL - c - 1] = buffer_int[totalL - c - 1];
else dst_mem[totalL - c - 1] = buffer[totalL - c - 1];
if (instructionReg == ARGSORT) dst_int_mem[totalL - c -1] = buffer_int[totalL - c -1];
else dst_mem[totalL - c -1] = buffer[totalL - c -1];
}
if (instructionReg == ARGSORT) dst_int_mem[0] = buffer_int[0];
else dst_mem[0] = buffer[0];
}
break;
case EXTRACT:
......@@ -224,8 +226,7 @@ UNIT_INT_T type2_op_flow( ap_uint<6> instructionReg,
break;
case TRANSPOSE:
{
unsigned short axis = param0 && 0x0b111;
unsigned short axis = param0 & 0b111;
int rdPtr= 0;
for(int i = 0; i < SHAPE0(src1_sz); i++){
......@@ -268,7 +269,7 @@ UNIT_INT_T type2_op_flow( ap_uint<6> instructionReg,
T temp = 0;
for (int k = 0; k < SHAPE1(src1_sz); ++k) {
#pragma HLS pipeline
temp += src1_mem[k + SHAPE1(src1_sz) * j] * src2_mem[j + SHAPE1(src2_sz) * k];
temp += src1_mem[k + SHAPE1(src1_sz) * i] * src2_mem[j + SHAPE1(src2_sz) * k];
}
dst_mem[wrPtr++] = temp;
......@@ -277,10 +278,10 @@ UNIT_INT_T type2_op_flow( ap_uint<6> instructionReg,
}
break;