aten/src/ATen/native/sparse/SparseTensor.cpp
// NB: Got rid of the sizes == NULL case
Got rid of the sizes == NULL case
Got rid of the sizes == NULL case
SparseTensor new_with_tensor_and_size_sparse(const LongTensor& indices, const Tensor& values_, ArrayRef<int64_t> sizes) {
  Tensor values;
  if (values_.dim() == 0) {
    values = values_.expand({1});
  } else {
    values = values_;
  }
  const SparseType& dtype = values.type().toSparse();
  if (indices.numel() == 0 && values.numel() == 0) {
    return new_with_size_sparse(dtype, sizes);
  }
  int64_t sparseDims = indices.size(0);
  int64_t denseDims = values.dim() - 1;
  AT_CHECK(sizes.size() == sparseDims + denseDims, "number of dimensions must be sparseDims (", sparseDims, ") + denseDims (", denseDims, "), but got ", sizes);
  LongTensor max_indices = std::get< 0>(indices.max( 1,  false));
  LongTensor cpu_max_indices;
  if (max_indices.is_cuda()) {
    cpu_max_indices = at::CPU(kLong).copy(max_indices);
  } else {
    cpu_max_indices = max_indices;
  }
  auto cpu_max_indices_accessor = cpu_max_indices.accessor<int64_t, 1>();
  for (int64_t d = 0; d < sparseDims; d++) {
    int64_t max_index_in_dim = cpu_max_indices_accessor[d];
    int64_t dim_size = sizes[static_cast<size_t>(d)];
    AT_CHECK(max_index_in_dim < dim_size,
             "sizes is inconsistent with indices: for dim ", d, ", size is ", dim_size, " but found index ", max_index_in_dim);
  }
  for (int64_t d = 0; d < denseDims; d++) {
    int64_t values_size = values.size(d+1);
    int64_t specified_size = sizes[static_cast<size_t>(sparseDims + d)];
    AT_CHECK(values_size <= specified_size,
             "values and sizes are inconsistent: sizes[", d + sparseDims, "] is ", specified_size,
             " but values.size(", d + 1, ") is ", values_size);
  }
  return _new_with_dims_and_tensor_sparse(dtype, sparseDims, denseDims, sizes, indices, values);
}
SparseTensor new_with_tensor_and_size_sparse ( const LongTensor & indices , const Tensor & values_ , ArrayRef < int64_t > sizes ) { Tensor values ; if ( values_ . dim ( ) == 0 ) { values = values_ . expand ( { 1 } ) ; } else { values = values_ ; } const SparseType & dtype = values . type ( ) . toSparse ( ) ; if ( indices . numel ( ) == 0 && values . numel ( ) == 0 ) { return new_with_size_sparse ( dtype , sizes ) ; } int64_t sparseDims = indices . size ( 0 ) ; int64_t denseDims = values . dim ( ) - 1 ; AT_CHECK ( sizes . size ( ) == sparseDims + denseDims , " " , sparseDims , " " , denseDims , " " , sizes ) ; LongTensor max_indices = std :: get < 0 > ( indices . max ( 1 , false ) ) ; LongTensor cpu_max_indices ; if ( max_indices . is_cuda ( ) ) { cpu_max_indices = at :: CPU ( kLong ) . copy ( max_indices ) ; } else { cpu_max_indices = max_indices ; } auto cpu_max_indices_accessor = cpu_max_indices . accessor < int64_t , 1 > ( ) ; for ( int64_t d = 0 ; d < sparseDims ; d ++ ) { int64_t max_index_in_dim = cpu_max_indices_accessor [ d ] ; int64_t dim_size = sizes [ static_cast < size_t > ( d ) ] ; AT_CHECK ( max_index_in_dim < dim_size , " " , d , " " , dim_size , " " , max_index_in_dim ) ; } for ( int64_t d = 0 ; d < denseDims ; d ++ ) { int64_t values_size = values . size ( d + 1 ) ; int64_t specified_size = sizes [ static_cast < size_t > ( sparseDims + d ) ] ; AT_CHECK ( values_size <= specified_size , " " , d + sparseDims , " " , specified_size , " " , d + 1 , " " , values_size ) ; } return _new_with_dims_and_tensor_sparse ( dtype , sparseDims , denseDims , sizes , indices , values ) ; }
NB: Got rid of the sizes == NULL case
NB : Got rid of the sizes == NULL case
// Mimic Numpy behavior here and treat it as a 1D tensor // NB: This used to be dims, but mumble TH handling zero-sized tensors // incorrectly /* values */ /* dim */ /* keepdim */ // NB: This used to sync ndim times to access each entry; now we copy // everything to CPU first and then access it.