78 if (model.CheckIfTensorAlreadyExist(
fNData) ==
false){
79 throw std::runtime_error(
"TMVA Slice Op Input Tensor is not found in model");
82 std::vector<std::vector<Dim>> shapes;
86 std::vector<std::vector<IType>> itensors(4);
90 for (
size_t i = 0; i < 4; ++i) {
92 if (model.IsInitializedTensor(
fNames[i])) {
93 auto dptr = model.GetInitializedTensorData(
fNames[i]);
94 auto tensor =
static_cast<IType *
>(dptr.get());
95 auto vec = model.GetTensorShape(
fNames[i]);
96 assert(
vec.size() == 1);
97 itensors[i] = std::vector<IType>(tensor, tensor +
vec[0]);
99 }
else if (model.IsShapeTensor(
fNames[i])) {
110 auto shape = model.GetTensorShape(
fNames[i]);
112 for (
size_t k = 0; k < s; k++) {
142 if (itensors[2].empty()) {
147 for (
size_t i = 0; i <
fAxes.size(); i++) {
150 if (
fAxes[i] < 0 ||
fAxes[i] >=
static_cast<IType
>(dim))
151 throw std::runtime_error(
"TMVA Slice Op : invalid axis value " + std::to_string(
fAxes[i]) +
152 " for " + std::to_string(i));
156 for (
size_t i = 0; i <
fAxes.size(); i++) {
157 if (!itensors[0].empty() )
158 fStartDims.push_back(
Dim{
static_cast<size_t>(itensors[0][i])});
160 throw std::runtime_error(
"TMVA Slice Op : Missing start input tensor");
162 if (!itensors[1].empty())
163 fEndDims.push_back(
Dim{
static_cast<size_t>(itensors[1][i])});
165 throw std::runtime_error(
"TMVA Slice Op : Missing end input tensor");
167 if (!itensors[3].empty()) {
168 fStepDims.push_back(
Dim{
static_cast<size_t>(itensors[3][i])});
178 istart =
static_cast<IType
>(
fStartDims[i].dim);
179 if (istart < 0) istart = iAxisDim + istart;
181 IType iend =
static_cast<IType
>(iAxisDim);
183 iend =
static_cast<IType
>(
fEndDims[i].dim);
184 if (iend < 0) iend = iAxisDim + iend;
189 istep =
static_cast<IType
>(
fStepDims[i].dim);
191 throw std::runtime_error(
"TMVA Slice Op : parametric step inputs are not supported");
196 if (istart < 0) istart = 0;
198 if (istart >
static_cast<IType
>(iAxisDim)) istart =
static_cast<IType
>(iAxisDim);
199 if (iend < 0) iend = 0;
200 if (iend >
static_cast<IType
>(iAxisDim)) iend =
static_cast<IType
>(iAxisDim);
201 }
else if (istep < 0) {
202 if (istart >
static_cast<IType
>(iAxisDim)-1) istart =
static_cast<IType
>(iAxisDim) -1;
203 if (iend < -1) iend = -1;
204 if (iend >
static_cast<IType
>(iAxisDim)-1) iend =
static_cast<IType
>(iAxisDim) -1;
206 throw std::runtime_error(
"TMVA Slice Op : invalid step value " + std::to_string(istep) +
207 " for " + std::to_string(i));
224 IType istart =
static_cast<IType
>(
fStartDims[i].dim);
226 std::string sstart = std::string(
"(") +
fShapeInput[
fAxes[i]].param +
"-" + std::to_string(-istart) +
")";
235 IType iend =
static_cast<IType
>(
fEndDims[i].dim);
237 std::string send = std::string(
"(") +
fShapeInput[
fAxes[i]].param +
"-" + std::to_string(-iend) +
")";
239 }
else if (iend == std::numeric_limits<IType>::max()){
254 for (
size_t i = 0; i < dim; i++) {
256 int64_t istart =
static_cast<int64_t
>(
fStart[i].dim);
257 int64_t iend =
static_cast<int64_t
>(
fEnd[i].dim);
258 int64_t istep=
static_cast<int64_t
>(
fSteps[i].dim);
259 int64_t s = (iend-istart)/istep;
263 if (
fStart[i].GetVal() !=
"0")
264 s =
"(" +
fEnd[i].GetVal() +
"-" +
fStart[i].GetVal() +
")";
266 s =
fEnd[i].GetVal();
267 if (
fSteps[i].GetVal() !=
"1") {
269 s +=
")/" +
fSteps[i].GetVal() +
")";
274 if (
fEnd[i].isParam &&
fEnd[i].dim !=
size_t(-1))
275 model.AddShapeParam(
fEnd[i].param,
fEnd[i].dim );
286 auto inputData =
static_cast<int64_t*
>(model.GetInitializedTensorData(
fNData).get());
288 std::vector<int64_t> outputData(outputSize);
290 for (
size_t ii = 0; ii<
fStart.size(); ii++)
291 std::cout <<
fStart[ii] <<
" " <<
fEnd[ii] <<
" " <<
fSteps[ii] << std::endl;
293 auto sliceRecursive = [&](
size_t iaxis,
size_t & outIdx,
size_t & inOffset) {
294 auto slice_impl = [&](
size_t iax,
size_t & outputIdx,
size_t & inputOffset,
auto & sliceRecImpl) {
296 throw std::runtime_error(
"TMVA Slice Op : cannot have parametric values when input is constant");
298 std::vector<IType> indices;
299 for (IType i = (IType)
fStart[iax].dim; (IType(
fSteps[iax].dim) > 0) ? i < IType(
fEnd[iax].dim) : i > IType(
fEnd[iax].dim); i += IType(
fSteps[iax].dim) )
300 indices.push_back(i);
302 for (
size_t i = 0; i < indices.size(); i++) {
303 std::cout << outputIdx <<
" , " << indices[i] <<
" " << inputOffset <<
" ; ";
304 outputData[outputIdx] = inputData[inputOffset + indices[i]];
309 for (
size_t i = 0; i < indices.size(); i++) {
310 std::cout << inputStride[iax] <<
" , " << indices[i] <<
" " << inputOffset <<
" ";
311 size_t offset = inputOffset + inputStride[iax]*indices[i];
312 sliceRecImpl(iax+1, outputIdx, offset,sliceRecImpl);
316 slice_impl(iaxis, outIdx, inOffset,slice_impl);
320 sliceRecursive(0, idx, offset);
323 if (model.Verbose()) {
334 for (
size_t idim = 0; idim < ndim; idim++) {
344 if (model.Verbose()) {
347 if (
fIdentitySlice) std::cout <<
" (using alias tensor since slice is an identity) ";
348 std::cout << std::endl;