Cecilia/fix/slice decrease axis (#8342)
* 1. fix for CVS-69011 2.add more test cases for slice w/ decrease_axis * add test case simulating the last reshape2 of ocrnet which accepts slice (with decrease_axes in all dims) as its parents. * exportModel as a helper function. * fix: rank get_length type
This commit is contained in:
parent
51b9dff1bc
commit
d587fb2844
@ -77,9 +77,24 @@ NamedOutputs slice(const NodeContext& node) {
|
||||
auto decrease_axis = node.get_attribute<std::vector<int32_t>>("decrease_axis");
|
||||
|
||||
if (decrease_axis.size() > 0) {
|
||||
auto squeeze_index_node = Constant::create(element::i32, {}, decrease_axis);
|
||||
// according to paddle slice_op, when all axes are decreased, output shape is [1], instead of scalar.
|
||||
// Ref: paddle/fluid/operators/slice_op.h
|
||||
PartialShape input_shape = data.get_partial_shape();
|
||||
PDPD_OP_VALIDATION_CHECK(node,
|
||||
input_shape.rank().is_static(),
|
||||
"input rank of slice must be static when decrease_axis is set.");
|
||||
|
||||
auto squeeze_index_node = Constant::create(element::i32, {decrease_axis.size()}, decrease_axis);
|
||||
auto decreased_node = std::make_shared<Squeeze>(stride_slice_node, squeeze_index_node);
|
||||
|
||||
auto input_rank = input_shape.rank().get_length();
|
||||
if (input_rank == decrease_axis.size()) {
|
||||
auto restore_node = std::make_shared<Reshape>(decreased_node,
|
||||
std::make_shared<Constant>(element::i64, Shape{1}, 1),
|
||||
false); // restore to shape (1,)
|
||||
return node.default_single_output_mapping({restore_node}, {"Out"});
|
||||
}
|
||||
|
||||
return node.default_single_output_mapping({decreased_node}, {"Out"});
|
||||
}
|
||||
|
||||
|
@ -202,6 +202,9 @@ static const std::vector<std::string> models{std::string("argmax"),
|
||||
std::string("sigmoid"),
|
||||
std::string("slice"),
|
||||
std::string("slice_1d"),
|
||||
std::string("slice_decrease_axis/slice_decrease_axis.pdmodel"),
|
||||
std::string("slice_decrease_axis_all/slice_decrease_axis_all.pdmodel"),
|
||||
std::string("slice_reshape/slice_reshape.pdmodel"),
|
||||
std::string("softmax"),
|
||||
std::string("softmax_minus"),
|
||||
std::string("split_test1"),
|
||||
|
@ -1,10 +1,14 @@
|
||||
#
|
||||
# slice paddle model generator
|
||||
#
|
||||
import numpy as np
|
||||
from save_model import saveModel
|
||||
import paddle as pdpd
|
||||
import sys
|
||||
import os
|
||||
|
||||
import numpy as np
|
||||
import paddle as pdpd
|
||||
|
||||
from save_model import exportModel
|
||||
from save_model import saveModel
|
||||
|
||||
data_type = 'float32'
|
||||
|
||||
@ -28,6 +32,59 @@ def slice(name : str, x, axes : list, start : list, end : list):
|
||||
|
||||
return outs[0]
|
||||
|
||||
|
||||
def slice_dyn(test_shape=[2,8,10,10]):
|
||||
pdpd.disable_static()
|
||||
|
||||
data = pdpd.rand(shape=test_shape, dtype='float32')
|
||||
|
||||
'''
|
||||
slice w/ decrease_axis
|
||||
'''
|
||||
@pdpd.jit.to_static
|
||||
def test_slice_decrease_axis(x):
|
||||
return x[0, 1:3, :, 5]
|
||||
exportModel('slice_decrease_axis', test_slice_decrease_axis, [data], target_dir=sys.argv[1]) # output shape (2, 10)
|
||||
|
||||
'''
|
||||
slice w/o decrease_axis
|
||||
'''
|
||||
@pdpd.jit.to_static
|
||||
def test_slice(x):
|
||||
return pdpd.slice(x, axes=[0,1,3], starts=[0,1,5], ends=[1,3,6])
|
||||
# exportModel('slice_dyn', test_slice, [data], target_dir=sys.argv[1]) # output shape (1, 2, 10, 1) # disable it by default as this kind of test model already there. It's for comparsion only.
|
||||
|
||||
'''
|
||||
slice w/ decrease_axis of all dims
|
||||
'''
|
||||
@pdpd.jit.to_static
|
||||
def test_slice_decrease_axis_all(x):
|
||||
return x[0, 0, 0, 0]
|
||||
exportModel('slice_decrease_axis_all', test_slice_decrease_axis_all, [data], target_dir=sys.argv[1]) # output shape (1,)
|
||||
|
||||
'''
|
||||
slice w/o decrease_axis of all dims
|
||||
'''
|
||||
@pdpd.jit.to_static
|
||||
def test_slice_alldim(x):
|
||||
return pdpd.slice(x, axes=[0,1,2,3], starts=[0,0,0,0], ends=[1,1,1,1])
|
||||
# exportModel('slice_alldim', test_slice_alldim, [data], target_dir=sys.argv[1]) # output shape (1, 1, 1, 1) # disable it by default as this kind of test model already there. It's for comparsion only.
|
||||
|
||||
'''
|
||||
a test case simulating the last reshape2 of ocrnet which accepts slice (with decrease_axes in all dims) as its parents.
|
||||
'''
|
||||
def slice_reshape(B=1, C=256, H=16, W=32):
|
||||
pdpd.disable_static()
|
||||
|
||||
data = pdpd.rand(shape=[B, C, H*W], dtype='float32')
|
||||
|
||||
@pdpd.jit.to_static
|
||||
def test_model(x):
|
||||
x2 = pdpd.assign([-1, -1, 16, 32]).astype('int32')
|
||||
node_reshape = pdpd.reshape(x, [0, 256, x2[2], x2[3]])
|
||||
return node_reshape
|
||||
exportModel('slice_reshape', test_model, [data], target_dir=sys.argv[1])
|
||||
|
||||
def main():
|
||||
x = np.linspace(1, 60, num = 60, dtype=np.int32).reshape(4, 3, 5).astype(data_type)
|
||||
slice("slice", x, axes=[1, 2], start=(0, 1), end=(-1, 3))
|
||||
@ -36,4 +93,6 @@ def main():
|
||||
slice("slice_1d", x, axes=[0], start=[0], end=[1])
|
||||
|
||||
if __name__ == "__main__":
|
||||
main()
|
||||
main()
|
||||
slice_dyn()
|
||||
slice_reshape()
|
@ -1,4 +1,5 @@
|
||||
import os
|
||||
import sys
|
||||
import numpy as np
|
||||
import paddle as pdpd
|
||||
|
||||
@ -55,6 +56,42 @@ def saveModel(name, exe, feedkeys:list, fetchlist:list, inputs:list, outputs:lis
|
||||
pdpd.fluid.io.save_inference_model(model_dir, feedkeys, fetchlist, exe, model_filename=name+".pdmodel", params_filename=name+".pdiparams")
|
||||
|
||||
|
||||
'''
|
||||
export dyn model, along with input and output for reference.
|
||||
input_data: list of all inputs
|
||||
'''
|
||||
def exportModel(name, dyn_func, input_data:list, target_dir:str):
|
||||
model_dir = os.path.join(target_dir, name)
|
||||
if not os.path.exists(model_dir):
|
||||
os.makedirs(model_dir)
|
||||
save_path = '{}/{}'.format(model_dir, name)
|
||||
|
||||
input_specs = []
|
||||
for idx, data in enumerate(input_data):
|
||||
input_name = 'input{}'.format(idx)
|
||||
input_specs.append(
|
||||
pdpd.static.InputSpec(shape=data.shape, dtype=data.dtype, name=input_name)
|
||||
)
|
||||
|
||||
# dump input
|
||||
np.save(os.path.join(model_dir, "input{}".format(idx)), data)
|
||||
|
||||
pdpd.jit.save(dyn_func, save_path, input_specs)
|
||||
print('saved exported model to {}'.format(save_path))
|
||||
|
||||
# infer
|
||||
model = pdpd.jit.load(save_path)
|
||||
|
||||
result = model(*[input[:] for input in input_data])
|
||||
|
||||
# dump output for reference
|
||||
if isinstance(result, (tuple, list)):
|
||||
for idx, out in enumerate(result):
|
||||
np.save(os.path.join(model_dir, "output{}".format(idx)), out.numpy())
|
||||
else:
|
||||
np.save(os.path.join(model_dir, "output{}".format(0)), result.numpy())
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
np.set_printoptions(precision=2)
|
||||
np.set_printoptions(suppress=True)
|
||||
|
Loading…
Reference in New Issue
Block a user