| 128 | |
| 129 | template <typename T, typename Context> |
| 130 | void EinsumGradKernel(const Context& dev_ctx, |
| 131 | const std::vector<const DenseTensor*>& x, |
| 132 | const std::vector<const DenseTensor*>& inner_cache, |
| 133 | const DenseTensor& out_grad, |
| 134 | const std::string& equation, |
| 135 | std::vector<DenseTensor*> x_grad) { |
| 136 | VLOG(5) << "Start EinsumGradKernel:"; |
| 137 | bool has_zero_size_tensor = out_grad.numel() == 0; |
| 138 | for (auto& i : x_grad) { |
| 139 | if (i != nullptr) { |
| 140 | if (i->numel() == 0) { |
| 141 | has_zero_size_tensor = true; |
| 142 | } |
| 143 | Full<T, Context>(dev_ctx, i->dims(), 0, i); |
| 144 | } |
| 145 | } |
| 146 | if (has_zero_size_tensor) return; |
| 147 | LabelMap labelshape(0); |
| 148 | LabelMap labeltype(LabelType::Reduction); |
| 149 | std::vector<LabelMap> label2perms(x.size(), LabelMap(-1)); |
| 150 | std::vector<char> all_labels; // order: ABO, AO, BO, AB, Reduce |
| 151 | std::vector<std::vector<int64_t>> broadcast_shapes(2); |
| 152 | std::vector<int64_t> output_dims; |
| 153 | |
| 154 | std::vector<DDim> input_dims; |
| 155 | for (auto& i : x) { |
| 156 | input_dims.push_back(i->dims()); |
| 157 | } |
| 158 | std::vector<std::string> input_strs; |
| 159 | std::string right; |
| 160 | ParseEinsumEquation(equation, |
| 161 | input_dims, |
| 162 | &labelshape, |
| 163 | &labeltype, |
| 164 | &all_labels, |
| 165 | &label2perms, |
| 166 | &broadcast_shapes, |
| 167 | &output_dims, |
| 168 | &right, |
| 169 | &input_strs); |
| 170 | |
| 171 | VLOG(4) << "After grad parse einsum equation."; |
| 172 | |
| 173 | auto gather_labels_except_reduction = [&labeltype](std::string all) { |
| 174 | std::string res(""); |
| 175 | for (auto c : all) |
| 176 | if (labeltype[static_cast<int>(c)] != LabelType::Reduction) res += c; |
| 177 | auto tmp_unique = unique_labels(res); |
| 178 | return std::string(tmp_unique.begin(), tmp_unique.end()); |
| 179 | }; |
| 180 | if (x.size() == 1) { // Unary |
| 181 | auto splits = paddle::string::split_string(equation, "->"); |
| 182 | auto left = splits[0]; |
| 183 | right = splits[1]; |
| 184 | auto new_equation = right + "->" + gather_labels_except_reduction(left); |
| 185 | auto new_operands = std::vector<const DenseTensor*>(); |
| 186 | new_operands.push_back(&out_grad); |
| 187 | DenseTensor before_tile; |
nothing calls this directly
no test coverage detected