mirror of
https://github.com/saymrwulf/onnxruntime.git
synced 2026-07-29 20:14:01 +00:00
Fix slice.
This commit is contained in:
parent
13dabd97b6
commit
ccb840ac99
5 changed files with 124 additions and 117 deletions
|
|
@ -13,49 +13,36 @@ public:
|
|||
: DmlOperator(kernelInfo),
|
||||
SliceHelperBase(kernelInfo, kernelInfo.GetTensorShapeDescription(), opsetVersion)
|
||||
{
|
||||
uint32_t minInputCount = (opsetVersion < 10) ? 1 : 3;
|
||||
ML_CHECK_VALID_ARGUMENT(kernelInfo.GetInputCount() >= minInputCount);
|
||||
const uint32_t inputCount = kernelInfo.GetInputCount();
|
||||
ML_CHECK_VALID_ARGUMENT((opsetVersion < 10 && inputCount == 1)
|
||||
|| (opsetVersion == 10 && inputCount >= 3 && inputCount <= 5));
|
||||
ML_CHECK_VALID_ARGUMENT(kernelInfo.GetOutputCount() == 1);
|
||||
|
||||
// TODO (23108599): Slice V10 introduces an optional "Steps" input which the kernel does not yet support.
|
||||
THROW_HR_IF(E_NOTIMPL, kernelInfo.GetInputCount() > 4);
|
||||
|
||||
std::vector<std::optional<uint32_t>> kernelInputIndices = { 0 };
|
||||
std::vector<std::optional<uint32_t>> kernelInputIndices = { 0 }; // Only bind GPU to first 'data' tensor.
|
||||
DmlOperator::Initialize(kernelInfo, kernelInputIndices);
|
||||
|
||||
assert(m_inputTensorDescs[0].GetDimensionCount() >= gsl::narrow_cast<uint32_t>(m_offsets.size()));
|
||||
assert(m_inputTensorDescs[0].GetDimensionCount() >= gsl::narrow_cast<uint32_t>(m_sizes.size()));
|
||||
assert(m_inputTensorDescs[0].GetDimensionCount() >= gsl::narrow_cast<uint32_t>(m_strides.size()));
|
||||
const uint32_t inputTensorRank = m_inputTensorDescs[0].GetDimensionCount();
|
||||
assert(inputTensorRank >= gsl::narrow_cast<uint32_t>(m_offsets.size()));
|
||||
assert(inputTensorRank >= gsl::narrow_cast<uint32_t>(m_sizes.size()));
|
||||
assert(inputTensorRank >= gsl::narrow_cast<uint32_t>(m_strides.size()));
|
||||
|
||||
// Pad the parameters to respect DML's requirements
|
||||
m_offsets.insert(
|
||||
m_offsets.begin(),
|
||||
m_inputTensorDescs[0].GetDimensionCount() - gsl::narrow_cast<uint32_t>(m_offsets.size()),
|
||||
0);
|
||||
|
||||
m_sizes.insert(
|
||||
m_sizes.begin(),
|
||||
m_inputTensorDescs[0].GetDimensionCount() - gsl::narrow_cast<uint32_t>(m_sizes.size()),
|
||||
1);
|
||||
|
||||
m_strides.insert(
|
||||
m_strides.begin(),
|
||||
m_inputTensorDescs[0].GetDimensionCount() - gsl::narrow_cast<uint32_t>(m_strides.size()),
|
||||
1);
|
||||
FillWithLeadingValues(/*inout*/ m_offsets, m_inputTensorDescs[0].GetDimensionCount(), 0u);
|
||||
FillWithLeadingValues(/*inout*/ m_sizes, m_inputTensorDescs[0].GetDimensionCount(), 1u);
|
||||
FillWithLeadingValues(/*inout*/ m_strides, m_inputTensorDescs[0].GetDimensionCount(), 1);
|
||||
|
||||
std::vector<DML_TENSOR_DESC> inputDescs = GetDmlInputDescs();
|
||||
std::vector<DML_TENSOR_DESC> outputDescs = GetDmlOutputDescs();
|
||||
|
||||
DML_SLICE_OPERATOR_DESC sliceDesc = {};
|
||||
DML_SLICE1_OPERATOR_DESC sliceDesc = {};
|
||||
sliceDesc.InputTensor = inputDescs.data();
|
||||
sliceDesc.OutputTensor = outputDescs.data();
|
||||
sliceDesc.DimensionCount = gsl::narrow_cast<uint32_t>(m_offsets.size());
|
||||
sliceDesc.Offsets = m_offsets.data();
|
||||
sliceDesc.Sizes = m_sizes.data();
|
||||
sliceDesc.Strides = m_strides.data();
|
||||
sliceDesc.InputWindowOffsets = m_offsets.data();
|
||||
sliceDesc.InputWindowSizes = m_sizes.data();
|
||||
sliceDesc.InputWindowStrides = m_strides.data();
|
||||
|
||||
DML_OPERATOR_DESC opDesc = { DML_OPERATOR_SLICE, &sliceDesc };
|
||||
|
||||
DML_OPERATOR_DESC opDesc = { DML_OPERATOR_SLICE1, &sliceDesc };
|
||||
SetDmlOperatorDesc(opDesc, kernelInfo);
|
||||
}
|
||||
};
|
||||
|
|
@ -73,9 +60,10 @@ public:
|
|||
|
||||
void CALLBACK QuerySlice(IMLOperatorSupportQueryContextPrivate* context, bool *isSupported)
|
||||
{
|
||||
*isSupported = (context->GetInputCount() <= 4);
|
||||
*isSupported = (context->GetInputCount() <= 5);
|
||||
}
|
||||
|
||||
DML_OP_DEFINE_CREATION_FUNCTION(Slice7, DmlOperatorSliceTemplate<7>);
|
||||
DML_OP_DEFINE_CREATION_FUNCTION(Slice10, DmlOperatorSliceTemplate<10>);
|
||||
DML_OP_DEFINE_CREATION_FUNCTION(Slice11, DmlOperatorSliceTemplate<10>);
|
||||
} // namespace Dml
|
||||
|
|
|
|||
|
|
@ -101,6 +101,7 @@ DML_OP_EXTERN_CREATION_FUNCTION(Tile);
|
|||
DML_OP_EXTERN_CREATION_FUNCTION(Concat);
|
||||
DML_OP_EXTERN_CREATION_FUNCTION(Slice7);
|
||||
DML_OP_EXTERN_CREATION_FUNCTION(Slice10);
|
||||
DML_OP_EXTERN_CREATION_FUNCTION(Slice11);
|
||||
DML_OP_EXTERN_CREATION_FUNCTION(Pad);
|
||||
DML_OP_EXTERN_CREATION_FUNCTION(SpaceToDepth);
|
||||
DML_OP_EXTERN_CREATION_FUNCTION(DepthToSpace);
|
||||
|
|
@ -214,6 +215,7 @@ const static char* const typeNameListCast[2] = { "T1", "T2" };
|
|||
const static char* const typeNameListIsNan[2] = { "T1", "T2" };
|
||||
const static char* const typeNameListConstantOfShape[2] = { "T1", "T2" };
|
||||
const static char* const typeNameListScatterGather[2] = { "T", "Tind" };
|
||||
const static char* const typeNameListSlice10[2] = { "T", "Tind" };
|
||||
const static char* const typeNameListQuantize[2] = { "T1", "T2" };
|
||||
const static char* const typeNameListWhere[2] = { "B", "T" };
|
||||
const static char* const typeNameListOneHot[3] = { "T1", "T2", "T3" };
|
||||
|
|
@ -228,6 +230,7 @@ const static SupportedTensorDataTypes supportedTypeListTopK[2] = {SupportedTenso
|
|||
const static SupportedTensorDataTypes supportedTypeListIndices[1] = { SupportedTensorDataTypes::Int32|SupportedTensorDataTypes::Int64 };
|
||||
const static SupportedTensorDataTypes supportedTypeListCast[2] = { SupportedTensorDataTypes::AllScalars, SupportedTensorDataTypes::Scalars8to32 };
|
||||
const static SupportedTensorDataTypes supportedTypeListScatterGather[2] = { SupportedTensorDataTypes::NumericDefault, SupportedTensorDataTypes::Int32 | SupportedTensorDataTypes::Int64 };
|
||||
const static SupportedTensorDataTypes supportedTypeListSlice10[2] = { SupportedTensorDataTypes::NumericDefault, SupportedTensorDataTypes::Int32 | SupportedTensorDataTypes::Int64 };
|
||||
const static SupportedTensorDataTypes supportedTypeListQuantizeLinear[2] = { SupportedTensorDataTypes::Float32 | SupportedTensorDataTypes::Int32, SupportedTensorDataTypes::UInt8 | SupportedTensorDataTypes::Int8 };
|
||||
const static SupportedTensorDataTypes supportedTypeListDequantizeLinear[2] = { SupportedTensorDataTypes::Float32, SupportedTensorDataTypes::UInt8 | SupportedTensorDataTypes::Int8 | SupportedTensorDataTypes::Int32 };
|
||||
const static SupportedTensorDataTypes supportedTypeListQuantize[2] = { SupportedTensorDataTypes::Float32, SupportedTensorDataTypes::UInt8 };
|
||||
|
|
@ -297,7 +300,8 @@ const static OperatorRegistrationInformation operatorRegistrationInformationTabl
|
|||
{REG_INFO( 7, Transpose, typeNameListDefault, supportedTypeListFloat16to32, DmGraphSupport::Supported)},
|
||||
{REG_INFO( 7, Concat, typeNameListDefault, supportedTypeListNumericDefault, DmGraphSupport::Supported)},
|
||||
{REG_INFO_VER( 7, Slice, typeNameListDefault, supportedTypeListNumericDefault, DmGraphSupport::Supported)},
|
||||
{REG_INFO_VER( 10, Slice, typeNameListDefault, supportedTypeListNumericDefault, DmGraphSupport::Supported, {1, 2, 3}, std::nullopt, QuerySlice)},
|
||||
{REG_INFO_VER( 10, Slice, typeNameListSlice10, supportedTypeListSlice10, DmGraphSupport::Supported, {1, 2, 3, 4}, std::nullopt, QuerySlice)},
|
||||
{REG_INFO_VER( 11, Slice, typeNameListSlice10, supportedTypeListSlice10, DmGraphSupport::Supported, {1, 2, 3, 4}, std::nullopt, QuerySlice)},
|
||||
{REG_INFO( 7, Pad, typeNameListDefault, supportedTypeListFloat16to32, DmGraphSupport::Supported)},
|
||||
{REG_INFO( 7, SpaceToDepth, typeNameListDefault, supportedTypeListFloat16to32, DmGraphSupport::Supported)},
|
||||
{REG_INFO( 7, DepthToSpace, typeNameListDefault, supportedTypeListFloat16to32, DmGraphSupport::Supported)},
|
||||
|
|
@ -473,7 +477,6 @@ const static OperatorRegistrationInformation operatorRegistrationInformationTabl
|
|||
{REG_INFO( 11, Scan, typeNameListDefault, supportedTypeListFloat16to32, DmGraphSupport::Supported)},
|
||||
{REG_INFO( 11, ScatterElements, typeNameListDefault, supportedTypeListFloat16to32, DmGraphSupport::Supported)},
|
||||
{REG_INFO( 11, ScatterND, typeNameListDefault, supportedTypeListFloat16to32, DmGraphSupport::Supported)},
|
||||
{REG_INFO( 11, Slice, typeNameListDefault, supportedTypeListFloat16to32, DmGraphSupport::Supported)},
|
||||
{REG_INFO( 11, Softmax, typeNameListDefault, supportedTypeListFloat16to32, DmGraphSupport::Supported)},
|
||||
{REG_INFO( 11, Split, typeNameListDefault, supportedTypeListFloat16to32, DmGraphSupport::Supported)},
|
||||
{REG_INFO( 11, Squeeze, typeNameListDefault, supportedTypeListFloat16to32, DmGraphSupport::Supported)},
|
||||
|
|
|
|||
|
|
@ -563,6 +563,20 @@ public:
|
|||
return m_impl->GetOutputCount();
|
||||
}
|
||||
|
||||
// Returns true if an input to the operator is valid.
|
||||
// This returns false for optional omitted inputs and invalid indices.
|
||||
bool IsInputValid(uint32_t inputIndex) const noexcept
|
||||
{
|
||||
return m_impl->IsInputValid(inputIndex);
|
||||
}
|
||||
|
||||
// Returns true if an output to the operator is valid.
|
||||
// This returns false for optional omitted inputs and invalid indices.
|
||||
bool IsOutputValid(uint32_t inputIndex) const noexcept
|
||||
{
|
||||
return m_impl->IsOutputValid(inputIndex);
|
||||
}
|
||||
|
||||
MLOperatorEdgeDescription GetInputEdgeDescription(uint32_t inputIndex) const
|
||||
{
|
||||
MLOperatorEdgeDescription ret;
|
||||
|
|
|
|||
|
|
@ -32,21 +32,51 @@ void HandleNegativeAxes(gsl::span<int32_t> onnxAxes, uint32_t dimCount)
|
|||
}
|
||||
}
|
||||
|
||||
void FillWithLeadingValues(/*inout*/ std::vector<uint32_t>& values, uint32_t minimumElementCount, uint32_t fillValue)
|
||||
void ReadCpuLocalTensorIntoInt32(
|
||||
const MLOperatorTensor& tensor,
|
||||
std::vector<int32_t>& result
|
||||
)
|
||||
{
|
||||
// e.g.
|
||||
// input = [6,7]
|
||||
// elementCount = 4
|
||||
// fillValue = 1
|
||||
// output = [1,1,6,7]
|
||||
result.clear();
|
||||
ML_CHECK_VALID_ARGUMENT(tensor.IsCpuData(), "Tensor must be CPU Tensor.");
|
||||
|
||||
const size_t oldElementCount = values.size();
|
||||
const size_t newElementCount = std::max(size_t(minimumElementCount), oldElementCount);
|
||||
const size_t fillCount = newElementCount - oldElementCount;
|
||||
const std::vector<uint32_t>& tensorDimensions = tensor.GetShape();
|
||||
const uint32_t elementCount = ComputeElementCountFromDimensions(tensorDimensions);
|
||||
|
||||
values.resize(newElementCount);
|
||||
std::copy_backward(values.data(), values.data() + oldElementCount, values.data() + fillCount);
|
||||
std::fill_n(values.data(), fillCount, fillValue);
|
||||
switch (tensor.GetTensorDataType())
|
||||
{
|
||||
case MLOperatorTensorDataType::Int32:
|
||||
{
|
||||
const int32_t* data = tensor.GetData<int32_t>();
|
||||
result.assign(data, data + elementCount);
|
||||
}
|
||||
break;
|
||||
|
||||
case MLOperatorTensorDataType::Int64:
|
||||
{
|
||||
const int64_t* data = tensor.GetData<int64_t>();
|
||||
for (auto d : gsl::make_span(data, data + elementCount))
|
||||
{
|
||||
result.push_back(gsl::narrow_cast<int32_t>(d));
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
ML_INVALID_ARGUMENT("Expecting CPU local tensor of type int32 or int64.");
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void DowncastDimensions(gsl::span<const int64_t> inputDimensions, std::vector<DimensionType>& outputDimensions)
|
||||
{
|
||||
outputDimensions.reserve(inputDimensions.size());
|
||||
outputDimensions.clear();
|
||||
|
||||
for (int64_t dim : inputDimensions)
|
||||
{
|
||||
outputDimensions.push_back(gsl::narrow_cast<uint32_t>(std::clamp<int64_t>(dim, INT32_MIN, INT32_MAX)));
|
||||
}
|
||||
}
|
||||
|
||||
int64_t ReadAsInt64(MLOperatorTensorDataType tensorDataType, const void* p)
|
||||
|
|
@ -1070,10 +1100,7 @@ int64_t ReadAsInt64(MLOperatorTensorDataType tensorDataType, const void* p)
|
|||
|
||||
// First element of shape tensor is how many dims to expand to.
|
||||
std::vector<uint32_t> desiredTensorShape;
|
||||
for (int64_t dim : gsl::make_span(shapeData, dimCount))
|
||||
{
|
||||
desiredTensorShape.push_back(gsl::narrow_cast<uint32_t>(dim));
|
||||
}
|
||||
DowncastDimensions(gsl::make_span(shapeData, dimCount), /*out*/ desiredTensorShape);
|
||||
|
||||
// Determine the broadcasted input shape.
|
||||
outputDimensions = OperatorHelper::BroadcastTensorShape(actualInputTensorShape, desiredTensorShape);
|
||||
|
|
@ -1098,10 +1125,7 @@ int64_t ReadAsInt64(MLOperatorTensorDataType tensorDataType, const void* p)
|
|||
|
||||
// First element of shape tensor is how many dims to expand to.
|
||||
std::vector<uint32_t> desiredTensorShape;
|
||||
for (int64_t dim : gsl::make_span(shapeData, dimCount))
|
||||
{
|
||||
desiredTensorShape.push_back(gsl::narrow_cast<uint32_t>(dim));
|
||||
}
|
||||
DowncastDimensions(gsl::make_span(shapeData, dimCount), /*out*/ desiredTensorShape);
|
||||
|
||||
return { std::move(EdgeShapes(desiredTensorShape)) };
|
||||
}
|
||||
|
|
|
|||
|
|
@ -75,10 +75,28 @@ void RemoveValuesByIndex(gsl::span<const uint32_t> indices, bool keepOneValue, /
|
|||
values.resize(newValuesCount);
|
||||
}
|
||||
|
||||
void FillWithLeadingValues(/*inout*/ std::vector<uint32_t>& values, uint32_t minimumElementCount, uint32_t fillValue);
|
||||
template <typename T>
|
||||
void FillWithLeadingValues(/*inout*/ std::vector<T>& values, uint32_t minimumElementCount, T fillValue)
|
||||
{
|
||||
// e.g.
|
||||
// input = [6,7]
|
||||
// elementCount = 4
|
||||
// fillValue = 1
|
||||
// output = [1,1,6,7]
|
||||
|
||||
const size_t oldElementCount = values.size();
|
||||
const size_t newElementCount = std::max(size_t(minimumElementCount), oldElementCount);
|
||||
const size_t fillCount = newElementCount - oldElementCount;
|
||||
|
||||
values.resize(newElementCount);
|
||||
std::copy_backward(values.data(), values.data() + oldElementCount, values.data() + fillCount);
|
||||
std::fill_n(values.data(), fillCount, fillValue);
|
||||
}
|
||||
|
||||
int64_t ReadAsInt64(MLOperatorTensorDataType tensorDataType, const void* p);
|
||||
|
||||
void ReadCpuLocalTensorIntoInt32(const MLOperatorTensor& tensor, std::vector<int32_t>& result);
|
||||
|
||||
class EdgeShapes {
|
||||
public:
|
||||
EdgeShapes() = default;
|
||||
|
|
@ -503,56 +521,25 @@ class SplitHelper {
|
|||
class SliceHelperBase
|
||||
{
|
||||
public:
|
||||
template<typename Info_t, typename Index_t>
|
||||
template<typename Info_t>
|
||||
void ReadIndexTensors(
|
||||
const Info_t& operatorInfo,
|
||||
std::vector<int32_t>& starts,
|
||||
std::vector<int32_t>& ends,
|
||||
std::vector<int32_t>& axes,
|
||||
std::vector<int32_t>& steps
|
||||
)
|
||||
/*out*/ std::vector<int32_t>& starts,
|
||||
/*out*/ std::vector<int32_t>& ends,
|
||||
/*out*/ std::vector<int32_t>& axes,
|
||||
/*out*/ std::vector<int32_t>& steps
|
||||
)
|
||||
{
|
||||
// Get starts, ends, optional axes and optional steps from constant inputs.
|
||||
MLOperatorTensor startsTensor = operatorInfo.GetConstantInputTensor(1);
|
||||
const std::vector<uint32_t>& startsTensorDimensions = startsTensor.GetShape();
|
||||
size_t dimCount = startsTensorDimensions[0];
|
||||
const Index_t* startsData = startsTensor.GetData<Index_t>();
|
||||
for (size_t i = 0; i < dimCount; ++i)
|
||||
// Get starts, ends, optional axes, and optional steps from constant inputs.
|
||||
ReadCpuLocalTensorIntoInt32(operatorInfo.GetConstantInputTensor(1), /*out*/ starts);
|
||||
ReadCpuLocalTensorIntoInt32(operatorInfo.GetConstantInputTensor(2), /*out*/ ends);
|
||||
if (operatorInfo.IsInputValid(3))
|
||||
{
|
||||
starts.push_back(gsl::narrow_cast<int32_t>(startsData[i]));
|
||||
ReadCpuLocalTensorIntoInt32(operatorInfo.GetConstantInputTensor(3), /*out*/ axes);
|
||||
}
|
||||
|
||||
MLOperatorTensor endsTensor = operatorInfo.GetConstantInputTensor(2);
|
||||
const std::vector<uint32_t>& endsTensorDimensions = endsTensor.GetShape();
|
||||
dimCount = endsTensorDimensions[0];
|
||||
const Index_t* endsData = endsTensor.GetData<Index_t>();
|
||||
for (size_t i = 0; i < dimCount; ++i)
|
||||
if (operatorInfo.IsInputValid(4))
|
||||
{
|
||||
ends.push_back(gsl::narrow_cast<int32_t>(endsData[i]));
|
||||
}
|
||||
uint32_t inputCount = operatorInfo.GetInputCount();
|
||||
if (inputCount > 3)
|
||||
{
|
||||
MLOperatorTensor axesTensor = operatorInfo.GetConstantInputTensor(3);
|
||||
const std::vector<uint32_t>& axesTensorDimensions = axesTensor.GetShape();
|
||||
dimCount = axesTensorDimensions[0];
|
||||
const Index_t* axesData = axesTensor.GetData<Index_t>();
|
||||
for (size_t i = 0; i < dimCount; ++i)
|
||||
{
|
||||
axes.push_back(gsl::narrow_cast<int32_t>(axesData[i]));
|
||||
}
|
||||
}
|
||||
|
||||
if (inputCount > 4)
|
||||
{
|
||||
MLOperatorTensor stepsTensor = operatorInfo.GetConstantInputTensor(4);
|
||||
const std::vector<uint32_t>& stepsTensorDimensions = stepsTensor.GetShape();
|
||||
dimCount = stepsTensorDimensions[0];
|
||||
const Index_t* stepsData = stepsTensor.GetData<Index_t>();
|
||||
for (size_t i = 0; i < dimCount; ++i)
|
||||
{
|
||||
steps.push_back(gsl::narrow_cast<int32_t>(stepsData[i]));
|
||||
}
|
||||
ReadCpuLocalTensorIntoInt32(operatorInfo.GetConstantInputTensor(4), /*out*/ steps);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -567,29 +554,23 @@ public:
|
|||
std::vector<int32_t> ends;
|
||||
std::vector<int32_t> axes;
|
||||
std::vector<int32_t> steps;
|
||||
|
||||
if (opsetVersion == 7)
|
||||
{
|
||||
// Get starts, ends and axes from attributes
|
||||
// Read starts, ends, and axes from attributes.
|
||||
starts = operatorInfo.GetOptionalAttributeVectorInt32(AttrName::Starts);
|
||||
ends = operatorInfo.GetOptionalAttributeVectorInt32(AttrName::Ends);
|
||||
axes = operatorInfo.GetOptionalAttributeVectorInt32(AttrName::Axes);
|
||||
}
|
||||
else if (opsetVersion == 10)
|
||||
{
|
||||
if (operatorInfo.GetConstantInputTensor(1).GetTensorDataType() == MLOperatorTensorDataType::Int32)
|
||||
{
|
||||
ReadIndexTensors<Info_t, int32_t>(operatorInfo, starts, ends, axes, steps);
|
||||
}
|
||||
else
|
||||
{
|
||||
THROW_HR_IF(E_INVALIDARG, operatorInfo.GetConstantInputTensor(1).GetTensorDataType() != MLOperatorTensorDataType::Int64);
|
||||
ReadIndexTensors<Info_t, int64_t>(operatorInfo, starts, ends, axes, steps);
|
||||
}
|
||||
// Read starts, ends, and axes from tensors.
|
||||
ReadIndexTensors(operatorInfo, /*out*/ starts, /*out*/ ends, /*out*/ axes, /*out*/ steps);
|
||||
}
|
||||
|
||||
const uint32_t dimCount = gsl::narrow_cast<int32_t>(inputDimensions.size());
|
||||
HandleNegativeAxes(/*inout*/ axes, dimCount);
|
||||
|
||||
const uint32_t inputDimensionCount = gsl::narrow_cast<int32_t>(inputDimensions.size());
|
||||
HandleNegativeAxes(/*inout*/ axes, inputDimensionCount);
|
||||
|
||||
ML_CHECK_VALID_ARGUMENT(starts.size() == ends.size(), "'starts' must equal 'ends' in size.");
|
||||
ML_CHECK_VALID_ARGUMENT(axes.empty() || starts.size() == axes.size(), "'axes' must equal 'starts' in size, or 'axes' must be empty.");
|
||||
|
||||
|
|
@ -604,18 +585,14 @@ public:
|
|||
// Clamp selected dimensions to given 'starts' and 'ends'.
|
||||
for (int i = 0, ci = gsl::narrow_cast<int>(starts.size()); i < ci; ++i)
|
||||
{
|
||||
int dimIndex = i;
|
||||
if (!axes.empty())
|
||||
{
|
||||
dimIndex = axes[i];
|
||||
}
|
||||
int dimIndex = axes.empty() ? i : axes[i];
|
||||
ML_CHECK_VALID_ARGUMENT(dimIndex < inputDimensions.size(), "'axes' must be valid with within actual input dimensions.");
|
||||
|
||||
// Positive values are offsets from 0.
|
||||
// Negative values are offsets from the dimension's size.
|
||||
int dim = gsl::narrow_cast<int>(inputDimensions[dimIndex]);
|
||||
int start = (starts[i] < 0) ? (starts[i] + dim) : starts[i];
|
||||
int end = (ends[i] < 0) ? (ends[i] + dim) : ends[i];
|
||||
int start = (starts[i] < 0 && starts[i] > INT_MIN) ? (starts[i] + dim) : starts[i];
|
||||
int end = (ends[i] < 0 && ends[i] < INT_MAX) ? (ends[i] + dim) : ends[i];
|
||||
|
||||
// Clamp the dimensions to the slice extents.
|
||||
// Clamp negative numbers to 0, per case test_slice_start_out_of_bounds.
|
||||
|
|
@ -1195,6 +1172,7 @@ using ShapeInferenceHelper_Transpose = TransposeHelper;
|
|||
using ShapeInferenceHelper_Concat = ConcatHelper;
|
||||
using ShapeInferenceHelper_Slice7 = SliceHelper;
|
||||
using ShapeInferenceHelper_Slice10 = Slice10Helper;
|
||||
using ShapeInferenceHelper_Slice11 = Slice10Helper; // No functional change from 10.
|
||||
using ShapeInferenceHelper_Pad = PaddingHelper;
|
||||
using ShapeInferenceHelper_SpaceToDepth = SpaceToDepthHelper;
|
||||
using ShapeInferenceHelper_DepthToSpace = DepthToSpaceHelper;
|
||||
|
|
|
|||
Loading…
Reference in a new issue