Merge branch 'Conv_NHWC' of github.com:InfiniTensor/InfiniTensor into Conv_NHWC

This commit is contained in:
wanghailu 2023-06-28 09:11:40 +08:00
commit 259c4b8240
9 changed files with 61 additions and 82 deletions

View File

@ -45,8 +45,8 @@ class GraphHandlerObj {
inline OpVec operators() { return g->getOperators(); }
Tensor conv(Tensor input, Tensor weight, Tensor output, int ph, int pw,
int sh, int sw, int dh, int dw);
Tensor conv(Tensor input, Tensor weight, Tensor bias, Tensor output, int ph,
int pw, int sh, int sw, int dh, int dw);
Tensor convTransposed2d(Tensor input, Tensor weight, Tensor output, int ph,
int pw, int sh, int sw, int dh, int dw, int oph,
int opw);
@ -109,7 +109,7 @@ class GraphHandlerObj {
inline void data_malloc() { g->dataMalloc(); }
inline void run() { g->getRuntime()->run(g); }
inline void run() { g->getRuntime()->run(g, true); }
};
} // namespace infini

View File

@ -111,7 +111,7 @@ class ConvBaseObj : public OperatorObj {
auto getNCHWFRS() const { return tuple(n, c, h, w, f, r, s); }
auto getPadStrideDilation() const { return tuple(ph, pw, sh, sw, dh, dw); }
int getChannelPerGroup() const {
if (type == OpType::ConvTransNHWC) {
if (type == OpType::ConvNHWC || type == OpType::ConvTransNHWC) {
return inputs[1]->getDims()[3];
} else {
return inputs[1]->getDims()[1];

View File

@ -84,50 +84,18 @@ class OnnxStub:
else:
adapt = node.input[0]
if len(node.input) > 2:
bias = "{}-bias".format(node.output[0])
reshape = "{}-reshape".format(node.output[0])
tensors[bias] = self.handler.conv(
tensors[adapt],
tensors[node.input[1]],
None,
p[0],
p[1],
s[0],
s[1],
d[0],
d[1],
)
tensors[reshape] = self.handler.reshape(
tensors[node.input[2]],
None,
[
1,
reduce(
lambda acc, x: acc * x,
_search_shape(model, node.input[2]),
),
1,
1,
],
)
tensors[node.output[0]] = self.handler.add(
tensors[bias],
tensors[reshape],
tensors.get(node.output[0]),
)
else:
tensors[node.output[0]] = self.handler.conv(
tensors[adapt],
tensors[node.input[1]],
tensors.get(node.output[0]),
p[0],
p[1],
s[0],
s[1],
d[0],
d[1],
)
tensors[node.output[0]] = self.handler.conv(
tensors[adapt],
tensors[node.input[1]],
tensors[node.input[2]] if len(node.input) > 2 else None,
tensors.get(node.output[0]),
p[0],
p[1],
s[0],
s[1],
d[0],
d[1],
)
elif node.op_type == "ConvTranspose":
attributes = _parse_attribute(
node,

View File

@ -43,6 +43,8 @@ class TestStringMethods(unittest.TestCase):
model = OnnxStub(onnx.load(model_file), backend.cpu_runtime()).to_onnx(
"new"
)
# with open("modified.onnx", "wb") as f:
# f.write(model.SerializeToString())
model = infer_shapes(model)
def test_tensor(self):

View File

@ -3,10 +3,12 @@
#include "nnet/dbg.h"
#include "operators/concat.h"
#include "operators/conv.h"
#include "operators/element_wise.h"
#include "operators/matmul.h"
#include "operators/pooling.h"
#include "operators/reshape.h"
#include "operators/transpose.h"
#include "operators/unary.h"
#ifdef USE_BANG
#include "bang/bang_runtime.h"
@ -57,7 +59,6 @@ Graph convertNCHWtoNHWCModel(Graph inG) {
if (inTensor->hasData()) {
tensors[uid] =
g->addTensor(runWeightComputation(rt, inTensor));
} else {
Shape s = inTensor->getDims();
tensors[uid] = g->addTensor(vector{s[0], s[2], s[3], s[1]},
@ -92,15 +93,6 @@ Graph convertNCHWtoNHWCModel(Graph inG) {
g->addOpWithOutputs<ConvTransposed2dNHWCObj>(
inputs[0], inputs[1], outputs[0], ph, pw, sh, sw, dh, dw, oph,
opw, group, bias, cOp->getAct());
} else if (const auto &pOp = as<PoolingObj>(op)) {
auto t = g->addOp<TransposeObj>(inputs[0], nullptr,
vector<int>{0, 2, 3, 1})
->getOutput();
auto tt = g->addTensor(op->getOutput()->getDims(),
op->getOutput()->getDType());
g->cloneOperator(op, {t}, {tt});
g->addOpWithOutputs<TransposeObj>(tt, outputs[0],
vector<int>{0, 3, 1, 2});
} else if (const auto &ccOp = as<ConcatObj>(op)) {
int axis = ccOp->getDim();
axis = vector<int>{0, 3, 1, 2}[axis];
@ -115,6 +107,10 @@ Graph convertNCHWtoNHWCModel(Graph inG) {
outputs[0]->getDims());
} else if (const auto &mmOp = as<MatmulObj>(op)) {
g->cloneOperator(mmOp, inputs, outputs);
} else if (const auto &uOp = as<UnaryObj>(op)) {
g->cloneOperator(uOp, inputs, outputs);
} else if (const auto &eOp = as<ElementWiseObj>(op)) {
g->cloneOperator(eOp, inputs, outputs);
} else {
dbg(op);
for (auto &t : inputs) {
@ -125,14 +121,17 @@ Graph convertNCHWtoNHWCModel(Graph inG) {
if (t->getDims().size() != 4)
IT_TODO_HALT();
}
// FIXME: the weights for these operators should not be processed
auto t = g->addOp<TransposeObj>(inputs[0], nullptr,
vector<int>{0, 2, 3, 1})
vector<int>{0, 3, 1, 2})
->getOutput();
auto tt = g->addTensor(op->getOutput()->getDims(),
op->getOutput()->getDType());
t->dataMalloc();
auto s = op->getOutput()->getDims();
auto tt = g->addTensor(s, op->getOutput()->getDType());
tt->dataMalloc();
g->cloneOperator(op, {t}, {tt});
g->addOpWithOutputs<TransposeObj>(tt, outputs[0],
vector<int>{0, 3, 1, 2});
vector<int>{0, 2, 3, 1});
}
}
return g;

View File

@ -23,16 +23,18 @@ Tensor GraphHandlerObj::tensor(Shape dims, int dtype) {
return g->addTensor(std::move(dims), dtype_repr_convert(dtype));
}
Tensor GraphHandlerObj::conv(Tensor input, Tensor weight, Tensor output, int ph,
int pw, int sh, int sw, int dh, int dw) {
Tensor GraphHandlerObj::conv(Tensor input, Tensor weight, Tensor bias,
Tensor output, int ph, int pw, int sh, int sw,
int dh, int dw) {
if (output) {
g->addOpWithOutputs<ConvObj>(std::move(input), std::move(weight),
output, ph, pw, sh, sw, dh, dw);
output, ph, pw, sh, sw, dh, dw, bias,
ActType::None);
return output;
} else {
return g
->addOp<ConvObj>(std::move(input), std::move(weight), output, ph,
pw, sh, sw, dh, dw)
pw, sh, sw, dh, dw, bias, ActType::None)
->getOutput();
}
}

View File

@ -84,12 +84,18 @@ HashType OperatorObj::hash() const {
bool OperatorObj::checkValid(GraphObj *graph) {
auto optShapes = inferShape();
if (!optShapes) // shape inference failed
if (!optShapes) { // shape inference failed
std::cout << "CheckValid: Shape inference failed." << std::endl;
std::cout << toString() << std::endl;
return false;
}
const vector<Shape> &shapes = *optShapes;
if (shapes.size() != outputs.size())
if (shapes.size() != outputs.size()) {
std::cout << "CheckValid: Shape inference result is not consistant with outputs number." << std::endl;
std::cout << toString() << std::endl;
return false;
}
if (graph) { // if graph != nullptr, outputs should be created
auto dataTypes = inferDataType();
for (size_t i = 0; i < outputs.size(); i++) {
@ -98,8 +104,11 @@ bool OperatorObj::checkValid(GraphObj *graph) {
}
} else { // if outputs have been created, check their shapes
for (size_t i = 0; i < shapes.size(); ++i) {
if (shapes[i] != outputs[i]->getDims())
if (shapes[i] != outputs[i]->getDims()) {
std::cout << "CheckValid: Shape inference result is not consistant with outputs[" << i << "]." << std::endl;
std::cout << toString() << std::endl;
return false;
}
}
}
return true;

View File

@ -31,8 +31,9 @@ class ConvCnnl : public BangKernelWithoutConfig {
int inputs0Array[4] = {n, h, w, c};
int inputs1[4] = {f, c, r, s};
int inputs1Array[4] = {f, r, s, c};
int output[4] = {n, c, h, w};
int outputArray[4] = {n, h, w, c};
auto oShape = op->getOutput()->getDims();
int output[4] = {oShape[0], oShape[1], oShape[2], oShape[3]};
int outputArray[4] = {output[0], output[3], output[1], output[2]};
if (op->getOpType() == OpType::Conv) {
cnnlTensorDescriptor_t aInDesc, aDesc, bInDesc, bDesc, cInDesc,
@ -146,7 +147,7 @@ class ConvCnnl : public BangKernelWithoutConfig {
checkCnnlError(cnnlCreateTensorDescriptor(&cDesc));
checkCnnlError(cnnlSetTensorDescriptor(
cDesc, CNNL_LAYOUT_NCHW, CNNL_DTYPE_FLOAT, 4, outputArray));
cDesc, CNNL_LAYOUT_NHWC, CNNL_DTYPE_FLOAT, 4, output));
cnnlConvolutionForwardAlgo_t algo;
cnnlGetConvolutionForwardAlgorithm(

View File

@ -64,10 +64,10 @@ void ConvObj::setAuxilaryAttributes(PaddingMode mode) {
ConvObj::ConvObj(GraphObj *graph, Tensor input, Tensor weight, Tensor output,
int ph, int pw, int sh, int sw, int dh, int dw, Tensor bias,
ActType act)
: ConvBaseObj(OpType::Conv, {input, weight}, output, ph, pw, sh, sw, dh, dw,
input, weight, act) {
if (bias)
IT_TODO_HALT();
: ConvBaseObj(OpType::Conv,
bias ? TensorVec{input, weight, bias}
: TensorVec{input, weight},
output, ph, pw, sh, sw, dh, dw, input, weight, act) {
setAuxilaryAttributes(PaddingMode::Other);
IT_ASSERT(checkValid(graph));
}
@ -75,10 +75,10 @@ ConvObj::ConvObj(GraphObj *graph, Tensor input, Tensor weight, Tensor output,
ConvObj::ConvObj(GraphObj *graph, Tensor input, Tensor weight, Tensor output,
PaddingMode mode, int sh, int sw, int dh, int dw, Tensor bias,
ActType act)
: ConvBaseObj(OpType::Conv, {input, weight}, output, mode, sh, sw, dh, dw,
input, weight, act) {
if (bias)
IT_TODO_HALT();
: ConvBaseObj(OpType::Conv,
bias ? TensorVec{input, weight, bias}
: TensorVec{input, weight},
output, mode, sh, sw, dh, dw, input, weight, act) {
setAuxilaryAttributes(mode);
IT_ASSERT(checkValid(graph));
}
@ -135,8 +135,6 @@ ConvNHWCObj::ConvNHWCObj(GraphObj *graph, Tensor input, Tensor weight,
int dw, Tensor bias, ActType act)
: ConvBaseObj(OpType::ConvNHWC, {input, weight}, output, ph, pw, sh, sw, dh,
dw, input, weight, act) {
if (bias)
IT_TODO_HALT();
setAuxilaryAttributes(PaddingMode::Other);
IT_ASSERT(checkValid(graph));
}