| 658 | |
| 659 | template <typename T, typename Context> |
| 660 | void EinsumKernelImpl(const Context& dev_ctx, |
| 661 | const std::vector<char>& forward_all_labels, |
| 662 | const LabelMap& forward_label_shape, |
| 663 | const std::vector<const DenseTensor*>& inputs, |
| 664 | const std::string& equation, |
| 665 | DenseTensor* out, |
| 666 | std::vector<DenseTensor*> cache, |
| 667 | bool is_forward = true) { |
| 668 | VLOG(5) << "Start EinsumKernelImpl with inputs(" << inputs.size() << "): "; |
| 669 | for (auto& i : inputs) { |
| 670 | VLOG(5) << " inputs [ " << i << " ].shape=" << i->dims(); |
| 671 | } |
| 672 | ValidationCheck(equation); |
| 673 | // collect the following information to prepare einsum. |
| 674 | LabelMap labelshape(0); |
| 675 | LabelMap labeltype(LabelType::Reduction); |
| 676 | std::vector<LabelMap> label2perms(inputs.size(), LabelMap(-1)); |
| 677 | std::vector<char> all_labels; // order: ABO, AO, BO, AB, Reduce |
| 678 | std::vector<std::vector<int64_t>> broadcast_shapes(2); |
| 679 | std::vector<int64_t> output_dims; |
| 680 | |
| 681 | std::vector<DDim> input_dims; |
| 682 | for (auto& i : inputs) { |
| 683 | input_dims.push_back(i->dims()); |
| 684 | } |
| 685 | std::vector<std::string> input_strs; |
| 686 | std::string right; |
| 687 | if (!is_forward) { |
| 688 | all_labels = forward_all_labels; |
| 689 | labelshape = forward_label_shape; |
| 690 | } |
| 691 | ParseEinsumEquation(equation, |
| 692 | input_dims, |
| 693 | &labelshape, |
| 694 | &labeltype, |
| 695 | &all_labels, |
| 696 | &label2perms, |
| 697 | &broadcast_shapes, |
| 698 | &output_dims, |
| 699 | &right, |
| 700 | &input_strs); |
| 701 | if (inputs.size() > 2) { |
| 702 | PADDLE_THROW(common::errors::InvalidArgument( |
| 703 | "EinsumOp kernel only support len(operands) between (0, 2]. Use " |
| 704 | "opt_einsum first to convert multi-variable to binary-variable.")); |
| 705 | } |
| 706 | auto after_contraction = PerformContraction<T, Context>(dev_ctx, |
| 707 | inputs, |
| 708 | input_strs, |
| 709 | label2perms, |
| 710 | all_labels, |
| 711 | labeltype, |
| 712 | labelshape, |
| 713 | broadcast_shapes, |
| 714 | cache, |
| 715 | !is_forward); |
| 716 | *out = TransposeToOutput<T, Context>( |
| 717 | dev_ctx, after_contraction, unique_labels(right), all_labels); |
nothing calls this directly
no test coverage detected