Skip to content

Commit

Permalink
Override the default isExecutable() method in StringTensorPack-15 (
Browse files Browse the repository at this point in the history
…openvinotoolkit#28376)

### Details:
 - Override the default `isExecutable()` method in `StringTensorPack-15`
- This fixes incorrect packing of empty strings (see reproducer in the
ticket)

### Tickets:
 - CVS-159636

---------

Signed-off-by: p-wysocki <przemyslaw.wysocki@intel.com>
  • Loading branch information
p-wysocki authored Jan 13, 2025
1 parent 8eb1deb commit ab749ce
Show file tree
Hide file tree
Showing 4 changed files with 41 additions and 12 deletions.
4 changes: 4 additions & 0 deletions src/plugins/intel_cpu/src/nodes/string_tensor_pack.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -81,6 +81,10 @@ struct StringTensorPack::StringTensorPackExecute {
}
};

bool StringTensorPack::isExecutable() const {
return !(isInputTensorAtPortEmpty(0) || isInputTensorAtPortEmpty(1));
}

void StringTensorPack::execute(dnnl::stream strm) {
auto indicesPrecision = getParentEdgeAt(0)->getMemory().getDesc().getPrecision();
StringTensorPackContext ctx = {*this};
Expand Down
1 change: 1 addition & 0 deletions src/plugins/intel_cpu/src/nodes/string_tensor_pack.h
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ class StringTensorPack : public Node {
static bool isSupportedOperation(const std::shared_ptr<const ov::Node>& op, std::string& errorMessage) noexcept;
void getSupportedDescriptors() override;
void initSupportedPrimitiveDescriptors() override;
bool isExecutable() const override;
void execute(dnnl::stream strm) override;
bool created() const override;
bool needPrepareParams() const override;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -52,19 +52,30 @@ void StringTensorPackLayerCPUTest::generate_inputs(const std::vector<ov::Shape>&
const auto indicesType = funcInputs[0].get_element_type();
const auto& indicesShape = targetInputStaticShapes[0];
const auto& symbolsShape = targetInputStaticShapes[2];

const ov::Tensor beginsTensor = ov::test::utils::create_and_fill_tensor_consistently(indicesType, indicesShape, symbolsShape[0], 0, 3);
const ov::Tensor endsTensor = ov::test::utils::create_and_fill_tensor_consistently(indicesType, indicesShape, symbolsShape[0], 3, 3);
inputs.insert({ funcInputs[0].get_node_shared_ptr(), beginsTensor });
inputs.insert({ funcInputs[1].get_node_shared_ptr(), endsTensor });

ov::Tensor beginsTensor;
ov::Tensor endsTensor;
ov::Tensor symbolsTensor;
ov::test::utils::InputGenerateData in_symbol_data;
in_symbol_data.start_from = 0;
in_symbol_data.range = 10;
symbolsTensor = ov::test::utils::create_and_fill_tensor(ov::element::u8, symbolsShape, in_symbol_data);
inputs.insert({ funcInputs[2].get_node_shared_ptr(), symbolsTensor });
}
if (shape_size(symbolsShape) == 0) {
symbolsTensor = ov::Tensor(ov::element::u8, symbolsShape);
beginsTensor = ov::Tensor(indicesType, indicesShape);
endsTensor = ov::Tensor(indicesType, indicesShape);
beginsTensor = ov::test::utils::create_and_fill_tensor_consistently(indicesType, indicesShape, 0, 0, 0);
endsTensor = ov::test::utils::create_and_fill_tensor_consistently(indicesType, indicesShape, 0, 0, 0);
} else {
ov::test::utils::InputGenerateData in_symbol_data;
in_symbol_data.start_from = 0;
in_symbol_data.range = 10;
symbolsTensor = ov::test::utils::create_and_fill_tensor(ov::element::u8, symbolsShape, in_symbol_data);
beginsTensor =
ov::test::utils::create_and_fill_tensor_consistently(indicesType, indicesShape, symbolsShape[0], 0, 3);
endsTensor =
ov::test::utils::create_and_fill_tensor_consistently(indicesType, indicesShape, symbolsShape[0], 3, 3);
}

inputs.insert({funcInputs[0].get_node_shared_ptr(), beginsTensor});
inputs.insert({funcInputs[1].get_node_shared_ptr(), endsTensor});
inputs.insert({funcInputs[2].get_node_shared_ptr(), symbolsTensor});
}

void StringTensorPackLayerCPUTest::SetUp() {
StringTensorPackLayerTestParams basicParamsSet;
Expand Down Expand Up @@ -120,6 +131,14 @@ const std::vector<StringTensorPackSpecificParams> StringTensorPackParamsVector =
InputShape{{-1, {1, 4}, {1, 4}}, {{1, 1, 4}, {1, 4, 1}}}, // begins/ends shape
InputShape{{{50, 100}}, {{50}, {75}, {100}}}, // utf-8 encoded symbols shape
},
StringTensorPackSpecificParams{
InputShape{{}, {{1, 1, 4}}}, // begins/ends shape
InputShape{{}, {{0}}}, // utf-8 encoded symbols shape
},
StringTensorPackSpecificParams{
InputShape{{-1, -1, -1}, {{1, 1, 3}, {1, 1, 4}, {1, 3, 4}, {1, 3, 4}}}, // begins/ends shape
InputShape{{-1}, {{9}, {0}, {108}, {0}}}, // utf-8 encoded symbols shape
},
};

} // namespace StringTensorPack
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -155,6 +155,11 @@ std::vector<StringTensorPackParams> generateStringTensorPackParams() {
ov::element::u8,
std::vector<uint8_t>{0x49, 0x6e, 0x74, 0x65, 0x6c, 0x4f, 0x70, 0x65, 0x6e, 0x56, 0x49, 0x4e, 0x4f}),
Tensor({1, 3}, ov::element::string, std::vector<std::string>{"Intel", "OpenVINO", ""})),
// empty bytes input
StringTensorPackParams(Tensor({1, 3}, T_idx, std::vector<T_I>{0, 0, 0}),
Tensor({1, 3}, T_idx, std::vector<T_I>{0, 0, 0}),
Tensor({0}, ov::element::u8, std::vector<uint8_t>{}),
Tensor({1, 3}, ov::element::string, std::vector<std::string>{"", "", ""})),
};
return StringTensorPackParamsList;
}
Expand Down

0 comments on commit ab749ce

Please sign in to comment.