diff --git a/src/plugins/intel_cpu/src/nodes/scatter_update.cpp b/src/plugins/intel_cpu/src/nodes/scatter_update.cpp index 68376724612d4a..3934f4f5bc0120 100644 --- a/src/plugins/intel_cpu/src/nodes/scatter_update.cpp +++ b/src/plugins/intel_cpu/src/nodes/scatter_update.cpp @@ -981,6 +981,7 @@ void ScatterUpdate::scatterNDUpdate(const MemoryPtr& mem_data, uint8_t* update = mem_updates->getDataAs(); uint8_t* dstData = mem_data->getDataAs(); const auto& srcDataDim = getParentEdgeAt(DATA_ID)->getMemory().getStaticDims(); + const auto elementsCount = getParentEdgeAt(DATA_ID)->getMemory().getShape().getElementsCount(); const auto& indicesDim = getParentEdgeAt(INDICES_ID)->getMemory().getStaticDims(); size_t indicesRank = indicesDim.size(); @@ -1004,8 +1005,14 @@ void ScatterUpdate::scatterNDUpdate(const MemoryPtr& mem_data, } dstOffset += idxValue * srcBlockND[i + 1]; } + + // Exception must be thrown according to the specification + CPU_NODE_ASSERT(dstOffset < elementsCount, + " indices contain values that points to non-existing data tensor element"); + dstOffset *= dataSize; size_t updateOffset = tupleIdx * sizeToUpdate; + cpu_memcpy(dstData + dstOffset, update + updateOffset, sizeToUpdate); }); } @@ -1020,6 +1027,7 @@ void ScatterUpdate::scatterNDUpdate(const MemoryPtr& mem_data, DataType* update = mem_updates->getDataAs(); DataType* dstData = mem_data->getDataAs(); const auto& srcDataDim = getParentEdgeAt(DATA_ID)->getMemory().getStaticDims(); + const auto elementsCount = getParentEdgeAt(DATA_ID)->getMemory().getShape().getElementsCount(); const auto& indicesDim = getParentEdgeAt(INDICES_ID)->getMemory().getStaticDims(); const auto indicesRank = indicesDim.size(); @@ -1041,6 +1049,11 @@ void ScatterUpdate::scatterNDUpdate(const MemoryPtr& mem_data, } dstOffset += idxValue * srcBlockND[i + 1]; } + + // Exception must be thrown according to the specification + CPU_NODE_ASSERT(dstOffset < elementsCount, + " indices contain values that points to non-existing data tensor element"); + const auto updateOffset = tupleIdx * sizeToUpdate; DataType* dstDataWithOffset = dstData + dstOffset; const DataType* updateWithOffset = update + updateOffset; diff --git a/src/plugins/intel_cpu/tests/functional/custom/single_layer_tests/scatter_ND_update.cpp b/src/plugins/intel_cpu/tests/functional/custom/single_layer_tests/scatter_ND_update.cpp index 4ffa9a58486344..27f0540dc7dbd7 100644 --- a/src/plugins/intel_cpu/tests/functional/custom/single_layer_tests/scatter_ND_update.cpp +++ b/src/plugins/intel_cpu/tests/functional/custom/single_layer_tests/scatter_ND_update.cpp @@ -15,6 +15,7 @@ using IndicesValues = std::vector; struct ScatterNDUpdateLayerParams { ScatterNDUpdateShapes inputShapes; IndicesValues indicesValues; + bool exceptionExpected; }; using scatterUpdateParams = std::tuple scatterParams = { {{2, 2, 1}, {{2, 2, 1}, {2, 2, 1}, {2, 2, 1}}}, {{-1, -1, -1, -1, -1, -1}, {{2, 2, 9, 10, 9, 10}, {2, 2, 1, 11, 2, 5}, {2, 2, 15, 8, 1, 7}}}, }, - IndicesValues{5, 6, 2, 8}}, - ScatterNDUpdateLayerParams{ScatterNDUpdateShapes{{{-1, -1, -1, -1}, {{10, 9, 9, 11}, {7, 5, 3, 12}, {3, 4, 9, 8}}}, - {{2, 3}, {{2, 3}, {2, 3}, {2, 3}}}, - {{-1, -1}, {{2, 11}, {2, 12}, {2, 8}}}}, - IndicesValues{0, 1, 1, 2, 2, 2}}, + IndicesValues{5, 6, 2, 8} + }, ScatterNDUpdateLayerParams{ - ScatterNDUpdateShapes{{{{3, 10}, -1, {3, 9}, -1}, {{10, 9, 9, 11}, {7, 5, 3, 12}, {3, 4, 9, 8}}}, - {{2, 3}, {{2, 3}, {2, 3}, {2, 3}}}, - {{{2, 4}, -1}, {{2, 11}, {2, 12}, {2, 8}}}}, + ScatterNDUpdateShapes{ + {{-1, -1, -1, -1}, {{10, 9, 9, 11}, {7, 5, 3, 12}, {3, 4, 9, 8}}}, + {{2, 3}, {{2, 3}, {2, 3}, {2, 3}}}, + {{-1, -1}, {{2, 11}, {2, 12}, {2, 8}}} + }, + IndicesValues{0, 1, 1, 2, 2, 2} + }, + ScatterNDUpdateLayerParams{ + ScatterNDUpdateShapes{ + {{{3, 10}, -1, {3, 9}, -1}, {{10, 9, 9, 11}, {7, 5, 3, 12}, {3, 4, 9, 8}}}, + {{2, 3}, {{2, 3}, {2, 3}, {2, 3}}}, + {{{2, 4}, -1}, {{2, 11}, {2, 12}, {2, 8}}} + }, IndicesValues{0, 1, 1, 2, 2, 2}}, ScatterNDUpdateLayerParams{ - ScatterNDUpdateShapes{{{{3, 10}, {4, 11}, {3, 9}, {8, 15}}, {{10, 9, 9, 11}, {7, 5, 3, 12}, {3, 4, 9, 8}}}, - {{2, 3}, {{2, 3}, {2, 3}, {2, 3}}}, - {{{2, 4}, -1}, {{2, 11}, {2, 12}, {2, 8}}}}, + ScatterNDUpdateShapes{ + {{{3, 10}, {4, 11}, {3, 9}, {8, 15}}, {{10, 9, 9, 11}, {7, 5, 3, 12}, {3, 4, 9, 8}}}, + {{2, 3}, {{2, 3}, {2, 3}, {2, 3}}}, + {{{2, 4}, -1}, {{2, 11}, {2, 12}, {2, 8}}} + }, IndicesValues{0, 1, 1, 2, 2, 2}}, ScatterNDUpdateLayerParams{ - ScatterNDUpdateShapes{{{{3, 10}, {4, 11}, {3, 9}, {8, 15}}, {{10, 9, 9, 11}, {7, 5, 3, 12}, {3, 4, 9, 8}}}, - {{2, 3}, {{2, 3}, {2, 3}, {2, 3}}}, - {{{2, 4}, -1}, {{2, 11}, {2, 12}, {2, 8}}}}, + ScatterNDUpdateShapes{ + {{{3, 10}, {4, 11}, {3, 9}, {8, 15}}, {{10, 9, 9, 11}, {7, 5, 3, 12}, {3, 4, 9, 8}}}, + {{2, 3}, {{2, 3}, {2, 3}, {2, 3}}}, + {{{2, 4}, -1}, {{2, 11}, {2, 12}, {2, 8}}}}, IndicesValues{-1, -1, -1, -2, -2, -2}}, + // out of bounds indices + ScatterNDUpdateLayerParams{ + ScatterNDUpdateShapes{ + {{}, {{4, 8, 64, 1}}}, + {{}, {{1}}}, + {{}, {{8, 64, 1}}} + }, + IndicesValues{4}, // index is out of bounds + true + }, }; const std::vector inputPrecisions = {