MCPcopy Create free account
hub / github.com/DeepRec-AI/DeepRec / HandleReduce

Method HandleReduce

tensorflow/compiler/xla/service/gpu/ir_emitter.cc:715–822  ·  view source on GitHub ↗

Source from the content-addressed store, hash-verified

713}
714
715Status IrEmitter::HandleReduce(HloInstruction* instr) {
716 const HloReduceInstruction* reduce = Cast<HloReduceInstruction>(instr);
717 const Shape& out_shape = reduce->shape();
718 bool returns_tuple = !out_shape.IsArray();
719 int accumulators_count = 1;
720 if (returns_tuple) {
721 CHECK(out_shape.IsTuple());
722 accumulators_count = out_shape.tuple_shapes_size();
723 }
724
725 auto arg = reduce->operand(0);
726 absl::Span<const int64> dimensions(reduce->dimensions());
727 HloComputation* function = reduce->to_apply();
728 return EmitTargetElementLoop(
729 *reduce,
730 [=](const llvm_ir::IrArray::Index& index) -> StatusOr<llvm::Value*> {
731 std::vector<llvm::Value*> accumulator_addrs;
732 std::vector<llvm::Type*> accumulator_types;
733
734 // Initialize accumulators with initial values.
735 for (int i = 0; i < accumulators_count; i++) {
736 auto init_value = reduce->init_values()[i];
737 const Shape& element_shape =
738 returns_tuple ? out_shape.tuple_shapes(i) : out_shape;
739 PrimitiveType accumulator_type = element_shape.element_type();
740 llvm::Type* accumulator_llvm_type =
741 llvm_ir::PrimitiveTypeToIrType(accumulator_type, module_);
742 llvm::AllocaInst* accumulator_addr = Alloca(accumulator_llvm_type);
743 Store(Load(GetBasePointer(*init_value)), accumulator_addr);
744 accumulator_addrs.push_back(accumulator_addr);
745 accumulator_types.push_back(accumulator_llvm_type);
746 }
747
748 // The enclosing loops go over all the target elements. Now we have to
749 // compute the actual target element. For this, we build a new loop nest
750 // to iterate over all the reduction dimensions in the argument.
751 // AddLoopsForShapeOnDimensions will return an Index where induction
752 // Value*s are placed for each dimension in dimensions, and all the rest
753 // are nullptrs.
754 llvm_ir::ForLoopNest loops(IrName(reduce, "inner"), &b_);
755 std::vector<llvm::Value*> input_multi_index =
756 loops.AddLoopsForShapeOnDimensions(arg->shape(), dimensions,
757 "reduction_dim");
758
759 SetToFirstInsertPoint(loops.GetInnerLoopBodyBasicBlock(), &b_);
760
761 // Build a full index for the input argument, using reduced_dims_index
762 // as the base. In reduced_dims_index only the reduction dimensions are
763 // filled in. We fill in the rest of the dimensions with induction
764 // Value*s taken from 'index' which iterates over the target array.
765 // See the high-level description in the XLA documentation for details.
766 llvm_ir::IrArray::Index::const_iterator it = index.begin();
767
768 for (auto& i : input_multi_index) {
769 if (i == nullptr) {
770 i = *it++;
771 }
772 }

Callers

nothing calls this directly

Calls 15

PrimitiveTypeToIrTypeFunction · 0.85
LoadFunction · 0.85
IrNameFunction · 0.85
SetToFirstInsertPointFunction · 0.85
ShapeToIrTypeFunction · 0.85
EmitTupleFunction · 0.85
tuple_shapes_sizeMethod · 0.80
to_applyMethod · 0.80
init_valuesMethod · 0.80

Tested by

no test coverage detected