aten/src/ATen/native/EmbeddingBag.cpp
// Assumes all input tensors except for `weight` are contiguous.
// See NOTE [ embedding_bag Native Functions ] in native_functions.yaml for details
Assumes all input tensors except for `weight` are contiguous.
See NOTE [ embedding_bag Native Functions ] in native_functions.yaml for details
Assumes all input tensors except for ` weight ` are contiguous . See NOTE [ embedding_bag Native Functions ] in native_functions . yaml for details
std::tuple<Tensor, Tensor, Tensor, Tensor>
_embedding_bag_cpu(const Tensor &weight, const Tensor &indices,
                  const Tensor &offsets, const bool scale_grad_by_freq,
                  const int64_t mode, bool sparse) {
  auto indices_arg = TensorArg(indices, "indices", 1);
  checkScalarType("embedding_bag", indices_arg, kLong);
  auto offsets_arg = TensorArg(offsets, "offsets", 1);
  checkScalarType("embedding_bag", indices_arg, kLong);
  auto weight_arg = TensorArg(weight, "weight", 1);
  checkScalarTypes("embedding_bag", weight_arg, {kFloat, kDouble});
  auto bag_size = at::zeros(offsets.sizes(), indices.type());
  make_bag_size(offsets, indices, mode, bag_size);
  auto offset2bag = at::zeros(
     {indices.sizes()[0] + 1}, indices.options()); 
  make_offset2bag(offsets, indices, offset2bag);
  offset2bag.resize_({indices.sizes()[0]});
  auto output = at::zeros({offsets.size(0), weight.size(1)}, weight.options());
  if (mode == MODE_MEAN || mode == MODE_SUM) {
    if (weight.type().scalarType() == kFloat) {
      index_select_add<float>(indices, offset2bag, weight, output);
    } else if (weight.type().scalarType() == kDouble) {
      index_select_add<double>(indices, offset2bag, weight, output);
    }
    auto ret = apply_bag_size(offsets, indices, mode, output, bag_size);
    return std::tuple<Tensor, Tensor, Tensor, Tensor>(ret, offset2bag, bag_size, bag_size);
  } else { 
    return AT_DISPATCH_FLOATING_TYPES_AND_HALF(
      weight.type(), "embedding_bag_cpu_max", [&]() {
        return embedding_bag_cpu_max<scalar_t>(weight, indices, offset2bag, output, bag_size, offsets);
      }
    );
  }
}
std :: tuple < Tensor , Tensor , Tensor , Tensor > _embedding_bag_cpu ( const Tensor & weight , const Tensor & indices , const Tensor & offsets , const bool scale_grad_by_freq , const int64_t mode , bool sparse ) { auto indices_arg = TensorArg ( indices , " " , 1 ) ; checkScalarType ( " " , indices_arg , kLong ) ; auto offsets_arg = TensorArg ( offsets , " " , 1 ) ; checkScalarType ( " " , indices_arg , kLong ) ; auto weight_arg = TensorArg ( weight , " " , 1 ) ; checkScalarTypes ( " " , weight_arg , { kFloat , kDouble } ) ; auto bag_size = at :: zeros ( offsets . sizes ( ) , indices . type ( ) ) ; make_bag_size ( offsets , indices , mode , bag_size ) ; auto offset2bag = at :: zeros ( { indices . sizes ( ) [ 0 ] + 1 } , indices . options ( ) ) ; make_offset2bag ( offsets , indices , offset2bag ) ; offset2bag . resize_ ( { indices . sizes ( ) [ 0 ] } ) ; auto output = at :: zeros ( { offsets . size ( 0 ) , weight . size ( 1 ) } , weight . options ( ) ) ; if ( mode == MODE_MEAN || mode == MODE_SUM ) { if ( weight . type ( ) . scalarType ( ) == kFloat ) { index_select_add < float > ( indices , offset2bag , weight , output ) ; } else if ( weight . type ( ) . scalarType ( ) == kDouble ) { index_select_add < double > ( indices , offset2bag , weight , output ) ; } auto ret = apply_bag_size ( offsets , indices , mode , output , bag_size ) ; return std :: tuple < Tensor , Tensor , Tensor , Tensor > ( ret , offset2bag , bag_size , bag_size ) ; } else { return AT_DISPATCH_FLOATING_TYPES_AND_HALF ( weight . type ( ) , " " , [ & ] ( ) { return embedding_bag_cpu_max < scalar_t > ( weight , indices , offset2bag , output , bag_size , offsets ) ; } ) ; } }
Assumes all input tensors except for `weight` are contiguous.
Assumes all input tensors except for ` weight ` are contiguous .
// If the last entries are empty, that the last offsets are irrelevant as they // won't change anything in the assignment of ID -> bag, but index_add would // throw out of bounds error. So to keep it simple we just add one more // entry to the end then get rid of it after make_offset2bag. // offset2bag = [0 0 0 0 0] // MODE_MAX