forked from jiuyuan/InfiniTensor
Merge branch 'Conv_NHWC' of github.com:InfiniTensor/InfiniTensor into Conv_NHWC
This commit is contained in:
commit
259c4b8240
|
@ -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
|
||||
|
|
|
@ -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];
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -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):
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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();
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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(
|
||||
|
|
|
@ -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));
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue