1 // Copyright (C) 2019 Intel Corporation
2 // SPDX-License-Identifier: Apache-2.0
12 #include <ie_layers.h>
13 #include <ie_memcpy.h>
14 #include "ie_const_infer_impl.hpp"
16 namespace InferenceEngine {
17 namespace ShapeInfer {
20 *@brief Implementation of Const inference for Fill layer
22 class FillConstInfer : public ConstInferImpl {
24 explicit FillConstInfer(const std::string& type) : ConstInferImpl(type) {}
26 void inferImpl(const std::vector<Blob::CPtr>& inData,
27 const std::map<std::string, std::string>& params,
28 const std::map<std::string, Blob::Ptr>& blobs,
29 std::vector<Blob::Ptr>& outData) override {
30 const size_t FILL_DIMS = 0;
31 const size_t FILL_VALUE = 1;
32 if (inData.empty() || outData.empty())
33 THROW_IE_EXCEPTION << " Incorrect number of input/output edges!";
35 if (inData.size() != 2)
36 THROW_IE_EXCEPTION << " Incorrect number of input edges!";
38 SizeVector dims = inData[FILL_DIMS]->getTensorDesc().getDims();
40 THROW_IE_EXCEPTION << " Fill dimensions vector should be 1 dimension";
42 if (inData[FILL_DIMS]->getTensorDesc().getPrecision() != Precision::I32)
43 THROW_IE_EXCEPTION << " Fill dimensions vector should be I32!";
45 SizeVector value_dims = inData[FILL_VALUE]->getTensorDesc().getDims();
46 if (value_dims.size() > 1)
47 THROW_IE_EXCEPTION << " Value scalar should have 1 dimension";
49 if (!(inData[FILL_VALUE]->getTensorDesc().getPrecision() == Precision::I32 &&
50 outData[0]->getTensorDesc().getPrecision() == Precision::I32) &&
51 !(inData[FILL_VALUE]->getTensorDesc().getPrecision() == Precision::FP32 &&
52 outData[0]->getTensorDesc().getPrecision() == Precision::FP32)) {
54 " 'Value' input scalars and output tensor should have same precision and only FP32 and I32 are supported!";
57 int32_t* fill_dims = inData[FILL_DIMS]->cbuffer().as<int32_t*>() +
58 inData[FILL_DIMS]->getTensorDesc().getBlockingDesc().getOffsetPadding();
59 size_t fill_size = inData[FILL_DIMS]->getTensorDesc().getDims()[0];
60 SizeVector dst_dims = outData[0]->getTensorDesc().getDims();
62 if (dst_dims.size() != fill_size) {
63 THROW_IE_EXCEPTION << "Output tensor dimension mismatch";
66 size_t work_amount_dst = 1;
67 for (size_t i = 0; i < dst_dims.size(); i++) {
68 work_amount_dst *= fill_dims[i];
69 if (static_cast<int>(dst_dims[i]) != fill_dims[i]) {
70 THROW_IE_EXCEPTION << "Output tensor dimension size mismatch";
74 switch (outData[0]->precision()) {
75 case Precision::FP32: {
76 float* dst_data = outData[0]->cbuffer().as<float*>() +
77 outData[0]->getTensorDesc().getBlockingDesc().getOffsetPadding();
78 float value = (inData[FILL_VALUE]->cbuffer().as<float*>() +
79 inData[FILL_VALUE]->getTensorDesc().getBlockingDesc().getOffsetPadding())[0];
81 parallel_nt(0, [&](const int ithr, const int nthr) {
82 size_t start = 0, end = 0;
83 splitter(work_amount_dst, nthr, ithr, start, end);
84 std::fill_n(dst_data + start, end - start, value);
88 case Precision::I32: {
89 int32_t* dst_data = outData[0]->cbuffer().as<int32_t*>() +
90 outData[0]->getTensorDesc().getBlockingDesc().getOffsetPadding();
91 int32_t value = (inData[FILL_VALUE]->cbuffer().as<int32_t*>() +
92 inData[FILL_VALUE]->getTensorDesc().getBlockingDesc().getOffsetPadding())[0];
94 parallel_nt(0, [&](const int ithr, const int nthr) {
95 size_t start = 0, end = 0;
96 splitter(work_amount_dst, nthr, ithr, start, end);
97 std::fill_n(dst_data + start, end - start, value);
102 THROW_IE_EXCEPTION << "Incorrect output precision. Only FP32 and I32 are supported!";
107 } // namespace ShapeInfer
108 } // namespace InferenceEngine