| 423 | class GeometryTensorArrayConcat : public GeometryComputer { |
| 424 | public: |
| 425 | virtual bool onCompute(const Op* op, const std::vector<Tensor*>& inputs, const std::vector<Tensor*>& outputs, |
| 426 | Context& context, CommandBuffer& res) const override { |
| 427 | auto output = outputs[0]; |
| 428 | auto outDes = TensorUtils::getDescribe(output); |
| 429 | outDes->memoryType = Tensor::InsideDescribe::MEMORY_VIRTUAL; |
| 430 | outDes->regions.clear(); |
| 431 | auto attr = TensorUtils::getDescribe(inputs[1])->tensorArrayAttr; |
| 432 | auto tpParam = op->main_as_TensorArray(); |
| 433 | int concatAxis = tpParam->axis(), newAxis = tpParam->new_axis(); |
| 434 | int outputDimensions = output->dimensions(); |
| 435 | concatAxis = (concatAxis + outputDimensions) % outputDimensions; |
| 436 | int outside = 1; |
| 437 | int inside = 1; |
| 438 | for (int i=0; i<concatAxis; ++i) { |
| 439 | outside *= output->length(i); |
| 440 | } |
| 441 | for (int i=concatAxis+1; i<output->dimensions(); ++i) { |
| 442 | inside *= output->length(i); |
| 443 | } |
| 444 | int concatFinal = output->length(concatAxis); |
| 445 | for (int i = 0, concatSum = 0, concatLast = -1; i < attr->arraySize; ++i) { |
| 446 | int shapeIndex = i; |
| 447 | if (attr->isIdenticalShape) { |
| 448 | shapeIndex = 0; |
| 449 | } |
| 450 | int concatLen = 1; |
| 451 | if (newAxis == 0) { |
| 452 | concatLen = attr->elemShape[shapeIndex][concatAxis]; |
| 453 | } |
| 454 | if (1 == outside && outDes->regions.size() > 0) { |
| 455 | // If outside is 1, fuse to one region |
| 456 | outDes->regions[outDes->regions.size() - 1].size[2] += inside * concatLen; |
| 457 | concatSum += concatLen; |
| 458 | continue; |
| 459 | } |
| 460 | if (concatLast == concatLen) { |
| 461 | // Fuse to last region |
| 462 | outDes->regions[outDes->regions.size() - 1].size[0] += 1; |
| 463 | concatSum += concatLen; |
| 464 | continue; |
| 465 | } |
| 466 | Tensor::InsideDescribe::Region reg; |
| 467 | reg.origin = inputs[1]; |
| 468 | reg.src.offset = inside * outside * concatSum; |
| 469 | reg.src.stride[0] = outside * inside * concatLen; |
| 470 | reg.src.stride[1] = inside * concatLen; |
| 471 | reg.dst.offset = inside * concatSum; |
| 472 | reg.dst.stride[0] = inside * concatLen; |
| 473 | reg.dst.stride[1] = inside * concatFinal; |
| 474 | reg.size[1] = outside; |
| 475 | reg.size[2] = inside * concatLen; |
| 476 | outDes->regions.push_back(reg); |
| 477 | concatSum += concatLen; |
| 478 | concatLast = concatLen; |
| 479 | } |
| 480 | return true; |
| 481 | } |
| 482 | }; |
nothing calls this directly
no test coverage detected