mirror of
				https://github.com/pytorch/pytorch.git
				synced 2025-11-04 08:00:58 +08:00 
			
		
		
		
	Compare commits
	
		
			23 Commits
		
	
	
		
			mtia/basic
			...
			v0.4.0
		
	
	| Author | SHA1 | Date | |
|---|---|---|---|
| 3749c581b7 | |||
| 200fb22b22 | |||
| 86b2165ab8 | |||
| 07091ad7dc | |||
| 92b137a9ed | |||
| ce0f350393 | |||
| 77e8c92ab9 | |||
| 46c534a14e | |||
| 58ed43d6e4 | |||
| 5f93a2b14c | |||
| 10175ed4f2 | |||
| 307db03fac | |||
| 98822f3753 | |||
| dd5a319055 | |||
| 9b90c66af8 | |||
| 7cba734a59 | |||
| 38aaa6354f | |||
| 8b767d2b0f | |||
| 068fb53fd2 | |||
| 06caf5d76f | |||
| 951cdc2b22 | |||
| eaba629943 | |||
| 33c2dc99cf | 
							
								
								
									
										2
									
								
								.gitmodules
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										2
									
								
								.gitmodules
									
									
									
									
										vendored
									
									
								
							@ -22,7 +22,7 @@
 | 
			
		||||
	url = https://github.com/NVlabs/cub.git
 | 
			
		||||
[submodule "third_party/eigen"]
 | 
			
		||||
	path = third_party/eigen
 | 
			
		||||
	url = https://github.com/RLovelett/eigen.git
 | 
			
		||||
	url = https://github.com/eigenteam/eigen-git-mirror.git
 | 
			
		||||
[submodule "third_party/googletest"]
 | 
			
		||||
	path = third_party/googletest
 | 
			
		||||
	url = https://github.com/google/googletest.git
 | 
			
		||||
 | 
			
		||||
@ -123,11 +123,6 @@ function(filter_list output input)
 | 
			
		||||
endfunction()
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
IF ($ENV{TH_BINARY_BUILD})
 | 
			
		||||
  MESSAGE(STATUS "TH_BINARY_BUILD detected. Statically linking libstdc++")
 | 
			
		||||
  SET(CMAKE_CXX_FLAGS "-static-libstdc++ ${CMAKE_CXX_FLAGS}")
 | 
			
		||||
ENDIF()
 | 
			
		||||
 | 
			
		||||
# Can be compiled standalone
 | 
			
		||||
IF(NOT AT_INSTALL_BIN_DIR OR NOT AT_INSTALL_LIB_DIR OR NOT AT_INSTALL_INCLUDE_DIR OR NOT AT_INSTALL_SHARE_DIR)
 | 
			
		||||
  SET(AT_INSTALL_BIN_DIR "bin" CACHE PATH "AT install binary subdirectory")
 | 
			
		||||
@ -332,12 +327,55 @@ ENDIF()
 | 
			
		||||
TARGET_LINK_LIBRARIES(ATen cpuinfo)
 | 
			
		||||
 | 
			
		||||
IF(CUDA_FOUND)
 | 
			
		||||
  TARGET_LINK_LIBRARIES(ATen
 | 
			
		||||
    ${CUDA_LIBRARIES}
 | 
			
		||||
    ${CUDA_cusparse_LIBRARY}
 | 
			
		||||
    ${CUDA_curand_LIBRARY})
 | 
			
		||||
  CUDA_ADD_CUBLAS_TO_TARGET(ATen)
 | 
			
		||||
  CUDA_ADD_CUFFT_TO_TARGET(ATen)
 | 
			
		||||
  IF ($ENV{ATEN_STATIC_CUDA})
 | 
			
		||||
    # CuFFT has a complicated static story (especially around CUDA < 9) because it has device callback support
 | 
			
		||||
    # we first have to build a fake lib that links with no device callbacks,
 | 
			
		||||
    # and then we link against this object file.
 | 
			
		||||
    # This was recommended by the CuFFT team at NVIDIA
 | 
			
		||||
 | 
			
		||||
    # build fake CuFFT lib in build dir
 | 
			
		||||
    EXECUTE_PROCESS(COMMAND touch ${CMAKE_CURRENT_BINARY_DIR}/empty_file.cc)
 | 
			
		||||
    if(${CUDA_VERSION_MAJOR} EQUAL "8")
 | 
			
		||||
      SET(CUFFT_FAKELINK_OPTIONS
 | 
			
		||||
	--generate-code arch=compute_35,code=sm_35
 | 
			
		||||
	--generate-code arch=compute_50,code=sm_50
 | 
			
		||||
	--generate-code arch=compute_60,code=sm_60)
 | 
			
		||||
    elseif(${CUDA_VERSION_MAJOR} EQUAL "9")
 | 
			
		||||
      SET(CUFFT_FAKELINK_OPTIONS
 | 
			
		||||
	--generate-code arch=compute_35,code=sm_35
 | 
			
		||||
	--generate-code arch=compute_50,code=sm_50
 | 
			
		||||
	--generate-code arch=compute_60,code=sm_60
 | 
			
		||||
	--generate-code arch=compute_70,code=sm_70)
 | 
			
		||||
    else()
 | 
			
		||||
      MESSAGE(FATAL_ERROR "Unhandled major cuda version ${CUDA_VERSION_MAJOR}")
 | 
			
		||||
    endif()
 | 
			
		||||
    ADD_CUSTOM_COMMAND(
 | 
			
		||||
      OUTPUT ${CMAKE_CURRENT_BINARY_DIR}/cufft_static_library.a
 | 
			
		||||
      COMMAND "${CUDA_TOOLKIT_ROOT_DIR}/bin/nvcc" -o ${CMAKE_CURRENT_BINARY_DIR}/cufft_static_library.a -Xcompiler -fPIC
 | 
			
		||||
      ${CUFFT_FAKELINK_OPTIONS}
 | 
			
		||||
      --device-link ${CMAKE_CURRENT_BINARY_DIR}/empty_file.cc -lcufft_static -lculibos
 | 
			
		||||
      )
 | 
			
		||||
    ADD_CUSTOM_TARGET(FAKELINKED_CUFFT_TARGET DEPENDS ${CMAKE_CURRENT_BINARY_DIR}/cufft_static_library.a)
 | 
			
		||||
    add_library(FAKELINKED_CUFFT STATIC IMPORTED GLOBAL)
 | 
			
		||||
    add_dependencies(FAKELINKED_CUFFT FAKELINKED_CUFFT_TARGET)
 | 
			
		||||
    set_target_properties(FAKELINKED_CUFFT PROPERTIES IMPORTED_LOCATION ${CMAKE_CURRENT_BINARY_DIR}/cufft_static_library.a)
 | 
			
		||||
 | 
			
		||||
    TARGET_LINK_LIBRARIES(ATen
 | 
			
		||||
      ${CUDA_LIBRARIES}
 | 
			
		||||
      ${CUDA_TOOLKIT_ROOT_DIR}/lib64/libcusparse_static.a
 | 
			
		||||
      ${CUDA_TOOLKIT_ROOT_DIR}/lib64/libcurand_static.a
 | 
			
		||||
      ${CUDA_TOOLKIT_ROOT_DIR}/lib64/libcublas_static.a
 | 
			
		||||
      FAKELINKED_CUFFT
 | 
			
		||||
      ${CUDA_TOOLKIT_ROOT_DIR}/lib64/libcufft_static.a
 | 
			
		||||
      )
 | 
			
		||||
  ELSE()
 | 
			
		||||
    TARGET_LINK_LIBRARIES(ATen
 | 
			
		||||
      ${CUDA_LIBRARIES}
 | 
			
		||||
      ${CUDA_cusparse_LIBRARY}
 | 
			
		||||
      ${CUDA_curand_LIBRARY})
 | 
			
		||||
    CUDA_ADD_CUBLAS_TO_TARGET(ATen)
 | 
			
		||||
    CUDA_ADD_CUFFT_TO_TARGET(ATen)
 | 
			
		||||
  ENDIF()
 | 
			
		||||
 | 
			
		||||
  if(CUDNN_FOUND)
 | 
			
		||||
    target_link_libraries(ATen ${CUDNN_LIBRARIES})
 | 
			
		||||
 | 
			
		||||
@ -3,7 +3,6 @@
 | 
			
		||||
#include "ATen/ExpandUtils.h"
 | 
			
		||||
#include "ATen/NativeFunctions.h"
 | 
			
		||||
#include "ATen/WrapDimUtils.h"
 | 
			
		||||
#include "cpu/ReduceOpsKernel.h"
 | 
			
		||||
 | 
			
		||||
#include <algorithm>
 | 
			
		||||
#include <functional>
 | 
			
		||||
@ -92,11 +91,6 @@ Tensor sum(const Tensor &self) {
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
Tensor _sum_cpu(const Tensor& self) {
 | 
			
		||||
  if (self.is_contiguous()) {
 | 
			
		||||
    Tensor result = self.type().tensor({});
 | 
			
		||||
    sum_kernel(result, self, at::nullopt);
 | 
			
		||||
    return result;
 | 
			
		||||
  }
 | 
			
		||||
  return self._sumall();
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@ -113,11 +107,6 @@ Tensor prod(const Tensor &self) {
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
Tensor _prod_cpu(const Tensor &self) {
 | 
			
		||||
  if (self.is_contiguous()) {
 | 
			
		||||
    Tensor result = self.type().tensor({});
 | 
			
		||||
    prod_kernel(result, self, at::nullopt);
 | 
			
		||||
    return result;
 | 
			
		||||
  }
 | 
			
		||||
  return self._prodall();
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@ -180,12 +169,6 @@ Tensor &_sum_out_cpu(Tensor &result, const Tensor &self, int64_t dim_,
 | 
			
		||||
  int64_t dim = maybe_wrap_dim(dim_, self.dim());
 | 
			
		||||
  if (_dimreduce_return_trivial(result, self, 0))
 | 
			
		||||
    return result;
 | 
			
		||||
  if (self.is_contiguous() && result.is_contiguous()) {
 | 
			
		||||
    _dimreduce_setup(result, self, dim);
 | 
			
		||||
    sum_kernel(result, self, dim);
 | 
			
		||||
    if (!keepdim) result.squeeze_(dim);
 | 
			
		||||
    return result;
 | 
			
		||||
  }
 | 
			
		||||
  return at::_th_sum_out(result, self, dim, keepdim);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@ -214,12 +197,6 @@ Tensor &_prod_out_cpu(Tensor &result, const Tensor &self, int64_t dim_,
 | 
			
		||||
  int64_t dim = maybe_wrap_dim(dim_, self.dim());
 | 
			
		||||
  if (_dimreduce_return_trivial(result, self, 1))
 | 
			
		||||
    return result;
 | 
			
		||||
  if (self.is_contiguous() && result.is_contiguous()) {
 | 
			
		||||
    _dimreduce_setup(result, self, dim);
 | 
			
		||||
    prod_kernel(result, self, dim);
 | 
			
		||||
    if (!keepdim) result.squeeze_(dim);
 | 
			
		||||
    return result;
 | 
			
		||||
  }
 | 
			
		||||
  return at::_th_prod_out(result, self, dim, keepdim);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@ -1,154 +0,0 @@
 | 
			
		||||
#include "ATen/native/cpu/ReduceOpsKernel.h"
 | 
			
		||||
 | 
			
		||||
#include <numeric>
 | 
			
		||||
 | 
			
		||||
#include "ATen/Dispatch.h"
 | 
			
		||||
#include "ATen/Parallel.h"
 | 
			
		||||
#include "ATen/optional.h"
 | 
			
		||||
#include "ATen/cpu/vec256/vec256.h"
 | 
			
		||||
 | 
			
		||||
namespace at { namespace native { namespace {
 | 
			
		||||
 | 
			
		||||
using namespace vec256;
 | 
			
		||||
 | 
			
		||||
static inline int64_t round_down(int64_t a, int64_t m) {
 | 
			
		||||
  return a - (a % m);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
template<typename F>
 | 
			
		||||
static void parallel_for(int64_t end, int64_t step, bool parallelize, F func) {
 | 
			
		||||
  if (parallelize) {
 | 
			
		||||
    tbb::parallel_for<int64_t>(0, end, step, func);
 | 
			
		||||
  } else {
 | 
			
		||||
    for (int64_t i = 0; i != end; i += step) {
 | 
			
		||||
      func(i);
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static tbb::affinity_partitioner ap;
 | 
			
		||||
 | 
			
		||||
// Vectorized reduction defined by reduce operation `Op` with identity `ident`.
 | 
			
		||||
// The reduction is built on top of reduce128, which reduces down a column
 | 
			
		||||
// 128 bytes wide (WIDTH scalar elements). The width of 128 bytes is chosen
 | 
			
		||||
// because of the "adjacent cache line prefetch" behavior on x86 CPUs.
 | 
			
		||||
template<typename scalar_t, template <class> class Op, int ident>
 | 
			
		||||
struct Reduction {
 | 
			
		||||
  // reduction width in number of scalar elements
 | 
			
		||||
  static constexpr int WIDTH = 128 / sizeof(scalar_t);
 | 
			
		||||
 | 
			
		||||
  using Vec = Vec256<scalar_t>;
 | 
			
		||||
  using Reduce = Op<Vec>;
 | 
			
		||||
  using ReduceScalar = Op<scalar_t>;
 | 
			
		||||
 | 
			
		||||
  static void apply(Tensor& res, const Tensor& self, at::optional<int64_t> dim) {
 | 
			
		||||
    internal::init_tbb_num_threads();
 | 
			
		||||
 | 
			
		||||
    auto out = res.data<scalar_t>();
 | 
			
		||||
    auto data = self.data<scalar_t>();
 | 
			
		||||
    auto numel = self.numel();
 | 
			
		||||
    if (!dim.has_value()) {
 | 
			
		||||
      *out = reduce_all(data, numel);
 | 
			
		||||
      return;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    int64_t n = self.size(*dim);
 | 
			
		||||
    int64_t stride = self.stride(*dim);
 | 
			
		||||
    int64_t batch = numel / (n * stride);
 | 
			
		||||
    bool paralellize = batch * n > internal::TBB_GRAIN_SIZE;
 | 
			
		||||
    parallel_for(batch, 1, paralellize, [=](int64_t b) {
 | 
			
		||||
      if (stride == 1) {
 | 
			
		||||
        out[b] = reduce_all(&data[b * n], n);
 | 
			
		||||
      } else {
 | 
			
		||||
        reduce2d(&data[b * n * stride], &out[b * stride], n, stride, stride);
 | 
			
		||||
      }
 | 
			
		||||
    });
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  static scalar_t reduce_all(const scalar_t* data, int64_t size) {
 | 
			
		||||
    int64_t k = size / WIDTH;
 | 
			
		||||
 | 
			
		||||
    scalar_t sum;
 | 
			
		||||
    if (size > internal::TBB_GRAIN_SIZE) {
 | 
			
		||||
      sum = tbb::parallel_reduce(
 | 
			
		||||
          tbb::blocked_range<int64_t>(0, k, internal::TBB_GRAIN_SIZE / WIDTH),
 | 
			
		||||
          scalar_t(ident),
 | 
			
		||||
          [=](const tbb::blocked_range<int64_t>& r, scalar_t init) {
 | 
			
		||||
            scalar_t buf[WIDTH];
 | 
			
		||||
            reduce128(&data[r.begin() * WIDTH], buf, r.end() - r.begin(), WIDTH);
 | 
			
		||||
            return std::accumulate(buf, buf + WIDTH, init, ReduceScalar());
 | 
			
		||||
          },
 | 
			
		||||
          ReduceScalar(),
 | 
			
		||||
          ap);
 | 
			
		||||
    } else {
 | 
			
		||||
      scalar_t buf[WIDTH];
 | 
			
		||||
      reduce128(data, buf, k, WIDTH);
 | 
			
		||||
      sum = std::accumulate(buf, buf + WIDTH, scalar_t(ident), ReduceScalar());
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    for (int i = k * WIDTH; i != size; i++) {
 | 
			
		||||
      sum = ReduceScalar()(sum, data[i]);
 | 
			
		||||
    }
 | 
			
		||||
    return sum;
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  // Reduce down a column of WIDTH elements (128 bytes) with the given number
 | 
			
		||||
  // of rows. Stores the results in out[0 ... WIDTH-1].
 | 
			
		||||
  static void reduce128(const scalar_t* data, scalar_t* out, int64_t rows, int64_t stride) {
 | 
			
		||||
    Vec acc[4] = {ident, ident, ident, ident};  // 128 bytes (two cache lines)
 | 
			
		||||
    static_assert(sizeof(acc) == 128, "accumulator should be 128 bytes");
 | 
			
		||||
    for (int64_t row = 0; row != rows; row++) {
 | 
			
		||||
      for (int j = 0; j != 4; j++) {
 | 
			
		||||
        auto val = Vec::s_load(&data[row * stride + j * Vec::size]);
 | 
			
		||||
        acc[j] = Reduce()(acc[j], val);
 | 
			
		||||
      }
 | 
			
		||||
    }
 | 
			
		||||
    for (int j = 0; j != 4; j++) {
 | 
			
		||||
      acc[j].store(&out[j * Vec::size]);
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  // Reduce a 2d matrix down each column. Stores the results in out[0 ... cols-1]
 | 
			
		||||
  static void reduce2d(const scalar_t* data, scalar_t* out, int64_t rows, int64_t cols, int64_t stride) {
 | 
			
		||||
    int64_t cols_rounded = round_down(cols, WIDTH);
 | 
			
		||||
    bool paralellize = cols * rows > internal::TBB_GRAIN_SIZE;
 | 
			
		||||
    parallel_for(cols_rounded, WIDTH, paralellize, [=](int64_t col) {
 | 
			
		||||
      reduce128(&data[col], &out[col], rows, stride);
 | 
			
		||||
    });
 | 
			
		||||
 | 
			
		||||
    if (cols_rounded != cols) {
 | 
			
		||||
      scalar_t buf[WIDTH];
 | 
			
		||||
      for (int64_t j = 0; j != cols - cols_rounded; j++) {
 | 
			
		||||
        buf[j] = ident;
 | 
			
		||||
      }
 | 
			
		||||
      for (int64_t row = 0; row != rows; row++) {
 | 
			
		||||
        for (int64_t j = 0; j != cols - cols_rounded; j++) {
 | 
			
		||||
          auto val = data[row * stride + j + cols_rounded];
 | 
			
		||||
          buf[j] = ReduceScalar()(buf[j], val);
 | 
			
		||||
        }
 | 
			
		||||
      }
 | 
			
		||||
      for (int64_t j = 0; j != cols - cols_rounded; j++) {
 | 
			
		||||
        out[j + cols_rounded] = buf[j];
 | 
			
		||||
      }
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
static void sum_kernel_impl(Tensor& result, const Tensor& self, at::optional<int64_t> dim) {
 | 
			
		||||
  AT_DISPATCH_ALL_TYPES(self.type(), "sum", [&] {
 | 
			
		||||
    Reduction<scalar_t, std::plus, 0>::apply(result, self, dim);
 | 
			
		||||
  });
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void prod_kernel_impl(Tensor& result, const Tensor& self, at::optional<int64_t> dim) {
 | 
			
		||||
  AT_DISPATCH_ALL_TYPES(self.type(), "prod", [&] {
 | 
			
		||||
    Reduction<scalar_t, std::multiplies, 1>::apply(result, self, dim);
 | 
			
		||||
  });
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
}  // anonymous namespace
 | 
			
		||||
 | 
			
		||||
REGISTER_DISPATCH(sum_kernel, &sum_kernel_impl);
 | 
			
		||||
REGISTER_DISPATCH(prod_kernel, &prod_kernel_impl);
 | 
			
		||||
 | 
			
		||||
}}  // namespace at::native
 | 
			
		||||
@ -1,16 +0,0 @@
 | 
			
		||||
#pragma once
 | 
			
		||||
 | 
			
		||||
#include <ATen/ATen.h>
 | 
			
		||||
#include <ATen/optional.h>
 | 
			
		||||
#include "CapabilityDispatch.h"
 | 
			
		||||
 | 
			
		||||
namespace at {
 | 
			
		||||
namespace native {
 | 
			
		||||
 | 
			
		||||
using reduce_fn = void(*)(Tensor &, const Tensor &, at::optional<int64_t>);
 | 
			
		||||
 | 
			
		||||
extern DispatchStub<reduce_fn> sum_kernel;
 | 
			
		||||
extern DispatchStub<reduce_fn> prod_kernel;
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
}
 | 
			
		||||
@ -392,6 +392,9 @@ THCTensor_(median)(THCState *state,
 | 
			
		||||
  THCTensor *newValues = THCTensor_(newNarrow)(state, sorted, dimension, k, 1);
 | 
			
		||||
  THCudaLongTensor *newIndices = THCudaLongTensor_newNarrow(state, sorted_indices, dimension, k, 1);
 | 
			
		||||
 | 
			
		||||
  THCTensor_(free)(state, sorted);
 | 
			
		||||
  THCudaLongTensor_free(state, sorted_indices);
 | 
			
		||||
 | 
			
		||||
  if (!keepdim) {
 | 
			
		||||
    THCTensor_(squeeze1d)(state, newValues, newValues, dimension);
 | 
			
		||||
    THCudaLongTensor_squeeze1d(state, newIndices, newIndices, dimension);
 | 
			
		||||
 | 
			
		||||
@ -11,6 +11,8 @@ Automatic differentiation package - torch.autograd
 | 
			
		||||
 | 
			
		||||
.. autofunction:: grad
 | 
			
		||||
 | 
			
		||||
.. _locally-disable-grad:
 | 
			
		||||
 | 
			
		||||
Locally disabling gradient computation
 | 
			
		||||
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@ -1,56 +0,0 @@
 | 
			
		||||
.. currentmodule:: torch
 | 
			
		||||
 | 
			
		||||
.. _device-doc:
 | 
			
		||||
 | 
			
		||||
torch.device
 | 
			
		||||
===================================
 | 
			
		||||
 | 
			
		||||
A :class:`torch.device` is an object representing the device on which a :class:`torch.Tensor` is
 | 
			
		||||
or will be allocated.
 | 
			
		||||
 | 
			
		||||
The :class:`torch.device` contains a device type (``'cpu'`` or ``'cuda'``) and optional device ordinal for the
 | 
			
		||||
device type.  If the device ordinal is not present, this represents the current device for the device type;
 | 
			
		||||
e.g. a :class:`torch.Tensor` constructed with device ``'cuda'`` is equivalent to ``'cuda:X'`` where X is the result of
 | 
			
		||||
:func:`torch.cuda.current_device()`.
 | 
			
		||||
 | 
			
		||||
A :class:`torch.Tensor`'s device can be accessed via the :attr:`Tensor.device` property.
 | 
			
		||||
 | 
			
		||||
A :class:`torch.device` can be constructed via a string or via a string and device ordinal
 | 
			
		||||
 | 
			
		||||
Via a string:
 | 
			
		||||
::
 | 
			
		||||
 | 
			
		||||
    >>> torch.device('cuda:0')
 | 
			
		||||
    device(type='cuda', index=0)
 | 
			
		||||
 | 
			
		||||
    >>> torch.device('cpu')
 | 
			
		||||
    device(type='cpu')
 | 
			
		||||
 | 
			
		||||
    >>> torch.device('cuda')  # current cuda device
 | 
			
		||||
    device(type='cuda')
 | 
			
		||||
 | 
			
		||||
Via a string and device ordinal:
 | 
			
		||||
 | 
			
		||||
::
 | 
			
		||||
 | 
			
		||||
    >>> torch.device('cuda', 0)
 | 
			
		||||
    device(type='cuda', index=0)
 | 
			
		||||
 | 
			
		||||
    >>> torch.device('cpu', 0)
 | 
			
		||||
    device(type='cpu', index=0)
 | 
			
		||||
 | 
			
		||||
.. note::
 | 
			
		||||
   For legacy reasons, a device can be constructed via a single device ordinal, which is treated
 | 
			
		||||
   as a cuda device.  This matches :meth:`Tensor.get_device`, which returns an ordinal for cuda
 | 
			
		||||
   tensors and is not supported for cpu tensors.
 | 
			
		||||
 | 
			
		||||
   >>> torch.device(1)
 | 
			
		||||
   device(type='cuda', index=1)
 | 
			
		||||
 | 
			
		||||
.. note::
 | 
			
		||||
   Methods which take a device will generally accept a (properly formatted) string
 | 
			
		||||
   or (legacy) integer device ordinal, i.e. the following are all equivalent:
 | 
			
		||||
 | 
			
		||||
   >>> torch.randn((2,3), device=torch.device('cuda:1'))
 | 
			
		||||
   >>> torch.randn((2,3), device='cuda:1')
 | 
			
		||||
   >>> torch.randn((2,3), device=1)  # legacy
 | 
			
		||||
@ -24,7 +24,9 @@ PyTorch is an optimized tensor library for deep learning using GPUs and CPUs.
 | 
			
		||||
 | 
			
		||||
   torch
 | 
			
		||||
   tensors
 | 
			
		||||
   tensor_attributes
 | 
			
		||||
   sparse
 | 
			
		||||
   cuda
 | 
			
		||||
   storage
 | 
			
		||||
   nn
 | 
			
		||||
   optim
 | 
			
		||||
@ -32,9 +34,6 @@ PyTorch is an optimized tensor library for deep learning using GPUs and CPUs.
 | 
			
		||||
   torch.distributions <distributions>
 | 
			
		||||
   torch.multiprocessing <multiprocessing>
 | 
			
		||||
   torch.distributed <distributed>
 | 
			
		||||
   torch.legacy <legacy>
 | 
			
		||||
   cuda
 | 
			
		||||
   device
 | 
			
		||||
   bottleneck
 | 
			
		||||
   checkpoint
 | 
			
		||||
   cpp_extension
 | 
			
		||||
@ -42,6 +41,7 @@ PyTorch is an optimized tensor library for deep learning using GPUs and CPUs.
 | 
			
		||||
   ffi
 | 
			
		||||
   model_zoo
 | 
			
		||||
   onnx
 | 
			
		||||
   torch.legacy <legacy>
 | 
			
		||||
 | 
			
		||||
.. toctree::
 | 
			
		||||
   :glob:
 | 
			
		||||
 | 
			
		||||
@ -19,17 +19,17 @@ Two tensors are "broadcastable" if the following rules hold:
 | 
			
		||||
 | 
			
		||||
For Example::
 | 
			
		||||
 | 
			
		||||
    >>> x=torch.FloatTensor(5,7,3)
 | 
			
		||||
    >>> y=torch.FloatTensor(5,7,3)
 | 
			
		||||
    >>> x=torch.empty(5,7,3)
 | 
			
		||||
    >>> y=torch.empty(5,7,3)
 | 
			
		||||
    # same shapes are always broadcastable (i.e. the above rules always hold)
 | 
			
		||||
 | 
			
		||||
    >>> x=torch.FloatTensor()
 | 
			
		||||
    >>> y=torch.FloatTensor(2,2)
 | 
			
		||||
    >>> x=torch.empty((0,))
 | 
			
		||||
    >>> y=torch.empty(2,2)
 | 
			
		||||
    # x and y are not broadcastable, because x does not have at least 1 dimension
 | 
			
		||||
 | 
			
		||||
    # can line up trailing dimensions
 | 
			
		||||
    >>> x=torch.FloatTensor(5,3,4,1)
 | 
			
		||||
    >>> y=torch.FloatTensor(  3,1,1)
 | 
			
		||||
    >>> x=torch.empty(5,3,4,1)
 | 
			
		||||
    >>> y=torch.empty(  3,1,1)
 | 
			
		||||
    # x and y are broadcastable.
 | 
			
		||||
    # 1st trailing dimension: both have size 1
 | 
			
		||||
    # 2nd trailing dimension: y has size 1
 | 
			
		||||
@ -37,8 +37,8 @@ For Example::
 | 
			
		||||
    # 4th trailing dimension: y dimension doesn't exist
 | 
			
		||||
 | 
			
		||||
    # but:
 | 
			
		||||
    >>> x=torch.FloatTensor(5,2,4,1)
 | 
			
		||||
    >>> y=torch.FloatTensor(  3,1,1)
 | 
			
		||||
    >>> x=torch.empty(5,2,4,1)
 | 
			
		||||
    >>> y=torch.empty(  3,1,1)
 | 
			
		||||
    # x and y are not broadcastable, because in the 3rd trailing dimension 2 != 3
 | 
			
		||||
 | 
			
		||||
If two tensors :attr:`x`, :attr:`y` are "broadcastable", the resulting tensor size
 | 
			
		||||
@ -52,19 +52,19 @@ is calculated as follows:
 | 
			
		||||
For Example::
 | 
			
		||||
 | 
			
		||||
    # can line up trailing dimensions to make reading easier
 | 
			
		||||
    >>> x=torch.FloatTensor(5,1,4,1)
 | 
			
		||||
    >>> y=torch.FloatTensor(  3,1,1)
 | 
			
		||||
    >>> x=torch.empty(5,1,4,1)
 | 
			
		||||
    >>> y=torch.empty(  3,1,1)
 | 
			
		||||
    >>> (x+y).size()
 | 
			
		||||
    torch.Size([5, 3, 4, 1])
 | 
			
		||||
 | 
			
		||||
    # but not necessary:
 | 
			
		||||
    >>> x=torch.FloatTensor(1)
 | 
			
		||||
    >>> y=torch.FloatTensor(3,1,7)
 | 
			
		||||
    >>> x=torch.empty(1)
 | 
			
		||||
    >>> y=torch.empty(3,1,7)
 | 
			
		||||
    >>> (x+y).size()
 | 
			
		||||
    torch.Size([3, 1, 7])
 | 
			
		||||
 | 
			
		||||
    >>> x=torch.FloatTensor(5,2,4,1)
 | 
			
		||||
    >>> y=torch.FloatTensor(3,1,1)
 | 
			
		||||
    >>> x=torch.empty(5,2,4,1)
 | 
			
		||||
    >>> y=torch.empty(3,1,1)
 | 
			
		||||
    >>> (x+y).size()
 | 
			
		||||
    RuntimeError: The size of tensor a (2) must match the size of tensor b (3) at non-singleton dimension 1
 | 
			
		||||
 | 
			
		||||
@ -75,14 +75,14 @@ as a result of the broadcast.
 | 
			
		||||
 | 
			
		||||
For Example::
 | 
			
		||||
 | 
			
		||||
    >>> x=torch.FloatTensor(5,3,4,1)
 | 
			
		||||
    >>> y=torch.FloatTensor(3,1,1)
 | 
			
		||||
    >>> x=torch.empty(5,3,4,1)
 | 
			
		||||
    >>> y=torch.empty(3,1,1)
 | 
			
		||||
    >>> (x.add_(y)).size()
 | 
			
		||||
    torch.Size([5, 3, 4, 1])
 | 
			
		||||
 | 
			
		||||
    # but:
 | 
			
		||||
    >>> x=torch.FloatTensor(1,3,1)
 | 
			
		||||
    >>> y=torch.FloatTensor(3,1,7)
 | 
			
		||||
    >>> x=torch.empty(1,3,1)
 | 
			
		||||
    >>> y=torch.empty(3,1,7)
 | 
			
		||||
    >>> (x.add_(y)).size()
 | 
			
		||||
    RuntimeError: The expanded size of the tensor (1) must match the existing size (7) at non-singleton dimension 2.
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@ -12,35 +12,47 @@ However, once a tensor is allocated, you can do operations on it irrespective
 | 
			
		||||
of the selected device, and the results will be always placed in on the same
 | 
			
		||||
device as the tensor.
 | 
			
		||||
 | 
			
		||||
Cross-GPU operations are not allowed by default, with the only exception of
 | 
			
		||||
:meth:`~torch.Tensor.copy_`. Unless you enable peer-to-peer memory access, any
 | 
			
		||||
attempts to launch ops on tensors spread across different devices will raise an
 | 
			
		||||
error.
 | 
			
		||||
Cross-GPU operations are not allowed by default, with the exception of
 | 
			
		||||
:meth:`~torch.Tensor.copy_` and other methods with copy-like functionality
 | 
			
		||||
such as :meth:`~torch.Tensor.to` and :meth:`~torch.Tensor.cuda`.
 | 
			
		||||
Unless you enable peer-to-peer memory access, any attempts to launch ops on
 | 
			
		||||
tensors spread across different devices will raise an error.
 | 
			
		||||
 | 
			
		||||
Below you can find a small example showcasing this::
 | 
			
		||||
 | 
			
		||||
    x = torch.cuda.FloatTensor(1)
 | 
			
		||||
    # x.get_device() == 0
 | 
			
		||||
    y = torch.FloatTensor(1).cuda()
 | 
			
		||||
    # y.get_device() == 0
 | 
			
		||||
    cuda = torch.device('cuda')     # Default CUDA device
 | 
			
		||||
    cuda0 = torch.device('cuda:0')
 | 
			
		||||
    cuda2 = torch.device('cuda:2')  # GPU 2 (these are 0-indexed)
 | 
			
		||||
 | 
			
		||||
    x = torch.tensor([1., 2.], device=cuda0)
 | 
			
		||||
    # x.device is device(type='cuda', index=0)
 | 
			
		||||
    y = torch.tensor([1., 2.]).cuda()
 | 
			
		||||
    # y.device is device(type='cuda', index=0)
 | 
			
		||||
 | 
			
		||||
    with torch.cuda.device(1):
 | 
			
		||||
        # allocates a tensor on GPU 1
 | 
			
		||||
        a = torch.cuda.FloatTensor(1)
 | 
			
		||||
        a = torch.tensor([1., 2.], device=cuda)
 | 
			
		||||
 | 
			
		||||
        # transfers a tensor from CPU to GPU 1
 | 
			
		||||
        b = torch.FloatTensor(1).cuda()
 | 
			
		||||
        # a.get_device() == b.get_device() == 1
 | 
			
		||||
        b = torch.tensor([1., 2.]).cuda()
 | 
			
		||||
        # a.device and b.device are device(type='cuda', index=1)
 | 
			
		||||
 | 
			
		||||
        # You can also use ``Tensor.to`` to transfer a tensor:
 | 
			
		||||
        b2 = torch.tensor([1., 2.]).to(device=cuda)
 | 
			
		||||
        # b.device and b2.device are device(type='cuda', index=1)
 | 
			
		||||
 | 
			
		||||
        c = a + b
 | 
			
		||||
        # c.get_device() == 1
 | 
			
		||||
        # c.device is device(type='cuda', index=1)
 | 
			
		||||
 | 
			
		||||
        z = x + y
 | 
			
		||||
        # z.get_device() == 0
 | 
			
		||||
        # z.device is device(type='cuda', index=0)
 | 
			
		||||
 | 
			
		||||
        # even within a context, you can give a GPU id to the .cuda call
 | 
			
		||||
        d = torch.randn(2).cuda(2)
 | 
			
		||||
        # d.get_device() == 2
 | 
			
		||||
        # even within a context, you can specify the device
 | 
			
		||||
        # (or give a GPU index to the .cuda call)
 | 
			
		||||
        d = torch.randn(2, device=cuda2)
 | 
			
		||||
        e = torch.randn(2).to(cuda2)
 | 
			
		||||
        f = torch.randn(2).cuda(cuda2)
 | 
			
		||||
        # d.device, e.device, and f.device are all device(type='cuda', index=2)
 | 
			
		||||
 | 
			
		||||
Asynchronous execution
 | 
			
		||||
----------------------
 | 
			
		||||
@ -79,8 +91,9 @@ relative order, unless explicit synchronization functions (such as
 | 
			
		||||
:meth:`~torch.cuda.synchronize` or :meth:`~torch.cuda.Stream.wait_stream`) are
 | 
			
		||||
used.  For example, the following code is incorrect::
 | 
			
		||||
 | 
			
		||||
    cuda = torch.device('cuda')
 | 
			
		||||
    s = torch.cuda.stream()  # Create a new stream.
 | 
			
		||||
    A = torch.cuda.FloatTensor(100, 100).normal_(0.0, 1.0)
 | 
			
		||||
    A = torch.empty((100, 100), device=cuda).normal_(0.0, 1.0)
 | 
			
		||||
    with torch.cuda.stream(s):
 | 
			
		||||
        # sum() may start execution before normal_() finishes!
 | 
			
		||||
        B = torch.sum(A)
 | 
			
		||||
@ -122,8 +135,10 @@ the initial hidden state of a recurrent neural network.
 | 
			
		||||
The first step is to determine whether the GPU should be used or not. A common
 | 
			
		||||
pattern is to use Python's ``argparse`` module to read in user arguments, and
 | 
			
		||||
have a flag that can be used to disable CUDA, in combination with
 | 
			
		||||
:meth:`~torch.cuda.is_available`. In the following, ``args.cuda`` results in a
 | 
			
		||||
flag that can be used to cast tensors and modules to CUDA if desired::
 | 
			
		||||
:meth:`~torch.cuda.is_available`. In the following, ``args.device`` results in a
 | 
			
		||||
:class:`torch.device` object that can be used to move tensors to CPU or CUDA.
 | 
			
		||||
 | 
			
		||||
::
 | 
			
		||||
 | 
			
		||||
    import argparse
 | 
			
		||||
    import torch
 | 
			
		||||
@ -132,29 +147,35 @@ flag that can be used to cast tensors and modules to CUDA if desired::
 | 
			
		||||
    parser.add_argument('--disable-cuda', action='store_true',
 | 
			
		||||
                        help='Disable CUDA')
 | 
			
		||||
    args = parser.parse_args()
 | 
			
		||||
    args.cuda = not args.disable_cuda and torch.cuda.is_available()
 | 
			
		||||
    args.device = None
 | 
			
		||||
    if not args.disable_cuda and torch.cuda.is_available():
 | 
			
		||||
        args.device = torch.device('cuda')
 | 
			
		||||
    else:
 | 
			
		||||
        args.device = torch.device('cpu')
 | 
			
		||||
 | 
			
		||||
If modules or tensors need to be sent to the GPU, ``args.cuda`` can be used as
 | 
			
		||||
follows::
 | 
			
		||||
Now that we have ``args.device``, we can use it to create a Tensor on the
 | 
			
		||||
desired device.
 | 
			
		||||
 | 
			
		||||
    x = torch.Tensor(8, 42)
 | 
			
		||||
    net = Network()
 | 
			
		||||
    if args.cuda:
 | 
			
		||||
      x = x.cuda()
 | 
			
		||||
      net.cuda()
 | 
			
		||||
::
 | 
			
		||||
 | 
			
		||||
When creating tensors, an alternative to the if statement is to have a default
 | 
			
		||||
datatype defined, and cast all tensors using that. An example when using a
 | 
			
		||||
dataloader would be as follows::
 | 
			
		||||
    x = torch.empty((8, 42), device=args.device)
 | 
			
		||||
    net = Network().to(device=args.device)
 | 
			
		||||
 | 
			
		||||
    dtype = torch.cuda.FloatTensor
 | 
			
		||||
This can be used in a number of cases to produce device agnostic code. Below
 | 
			
		||||
is an example when using a dataloader:
 | 
			
		||||
 | 
			
		||||
::
 | 
			
		||||
 | 
			
		||||
    cuda0 = torch.device('cuda:0')  # CUDA GPU 0
 | 
			
		||||
    for i, x in enumerate(train_loader):
 | 
			
		||||
        x = Variable(x.type(dtype))
 | 
			
		||||
        x = x.to(cuda0)
 | 
			
		||||
 | 
			
		||||
When working with multiple GPUs on a system, you can use the
 | 
			
		||||
``CUDA_VISIBLE_DEVICES`` environment flag to manage which GPUs are available to
 | 
			
		||||
PyTorch. As mentioned above, to manually control which GPU a tensor is created
 | 
			
		||||
on, the best practice is to use a :any:`torch.cuda.device` context manager::
 | 
			
		||||
on, the best practice is to use a :any:`torch.cuda.device` context manager.
 | 
			
		||||
 | 
			
		||||
::
 | 
			
		||||
 | 
			
		||||
    print("Outside device is 0")  # On device 0 (default in most scenarios)
 | 
			
		||||
    with torch.cuda.device(1):
 | 
			
		||||
@ -162,29 +183,52 @@ on, the best practice is to use a :any:`torch.cuda.device` context manager::
 | 
			
		||||
    print("Outside device is still 0")  # On device 0
 | 
			
		||||
 | 
			
		||||
If you have a tensor and would like to create a new tensor of the same type on
 | 
			
		||||
the same device, then you can use the :meth:`~torch.Tensor.new` method, which
 | 
			
		||||
acts the same as a normal tensor constructor. Whilst the previously mentioned
 | 
			
		||||
methods depend on the current GPU context, :meth:`~torch.Tensor.new` preserves
 | 
			
		||||
the device of the original tensor.
 | 
			
		||||
the same device, then you can use a ``torch.Tensor.new_*`` method
 | 
			
		||||
(see :class:`torch.Tensor`).
 | 
			
		||||
Whilst the previously mentioned ``torch.*`` factory functions
 | 
			
		||||
(:ref:`tensor-creation-ops`) depend on the current GPU context and
 | 
			
		||||
the attributes arguments you pass in, ``torch.Tensor.new_*`` methods preserve
 | 
			
		||||
the device and other attributes of the tensor.
 | 
			
		||||
 | 
			
		||||
This is the recommended practice when creating modules in which new
 | 
			
		||||
tensors/variables need to be created internally during the forward pass::
 | 
			
		||||
tensors need to be created internally during the forward pass.
 | 
			
		||||
 | 
			
		||||
    x_cpu = torch.FloatTensor(1)
 | 
			
		||||
    x_gpu = torch.cuda.FloatTensor(1)
 | 
			
		||||
    x_cpu_long = torch.LongTensor(1)
 | 
			
		||||
::
 | 
			
		||||
 | 
			
		||||
    cuda = torch.device('cuda')
 | 
			
		||||
    x_cpu = torch.empty(2)
 | 
			
		||||
    x_gpu = torch.empty(2, device=cuda)
 | 
			
		||||
    x_cpu_long = torch.empty(2, dtype=torch.int64)
 | 
			
		||||
 | 
			
		||||
    y_cpu = x_cpu.new_full([3, 2], fill_value=0.3)
 | 
			
		||||
    print(y_cpu)
 | 
			
		||||
 | 
			
		||||
        tensor([[ 0.3000,  0.3000],
 | 
			
		||||
                [ 0.3000,  0.3000],
 | 
			
		||||
                [ 0.3000,  0.3000]])
 | 
			
		||||
 | 
			
		||||
    y_gpu = x_gpu.new_full([3, 2], fill_value=-5)
 | 
			
		||||
    print(y_gpu)
 | 
			
		||||
 | 
			
		||||
        tensor([[-5.0000, -5.0000],
 | 
			
		||||
                [-5.0000, -5.0000],
 | 
			
		||||
                [-5.0000, -5.0000]], device='cuda:0')
 | 
			
		||||
 | 
			
		||||
    y_cpu_long = x_cpu_long.new_tensor([[1, 2, 3]])
 | 
			
		||||
    print(y_cpu_long)
 | 
			
		||||
 | 
			
		||||
        tensor([[ 1,  2,  3]])
 | 
			
		||||
 | 
			
		||||
    y_cpu = x_cpu.new(8, 10, 10).fill_(0.3)
 | 
			
		||||
    y_gpu = x_gpu.new(x_gpu.size()).fill_(-5)
 | 
			
		||||
    y_cpu_long = x_cpu_long.new([[1, 2, 3]])
 | 
			
		||||
 | 
			
		||||
If you want to create a tensor of the same type and size of another tensor, and
 | 
			
		||||
fill it with either ones or zeros, :meth:`~torch.ones_like` or
 | 
			
		||||
:meth:`~torch.zeros_like` are provided as convenient helper functions (which
 | 
			
		||||
also preserve device)::
 | 
			
		||||
also preserve :class:`torch.device` and :class:`torch.dtype` of a Tensor).
 | 
			
		||||
 | 
			
		||||
    x_cpu = torch.FloatTensor(1)
 | 
			
		||||
    x_gpu = torch.cuda.FloatTensor(1)
 | 
			
		||||
::
 | 
			
		||||
 | 
			
		||||
    x_cpu = torch.empty(2, 3)
 | 
			
		||||
    x_gpu = torch.empty(2, 3)
 | 
			
		||||
 | 
			
		||||
    y_cpu = torch.ones_like(x_cpu)
 | 
			
		||||
    y_gpu = torch.zeros_like(x_gpu)
 | 
			
		||||
@ -204,7 +248,7 @@ memory. CPU tensors and storages expose a :meth:`~torch.Tensor.pin_memory`
 | 
			
		||||
method, that returns a copy of the object, with data put in a pinned region.
 | 
			
		||||
 | 
			
		||||
Also, once you pin a tensor or storage, you can use asynchronous GPU copies.
 | 
			
		||||
Just pass an additional ``async=True`` argument to a :meth:`~torch.Tensor.cuda`
 | 
			
		||||
Just pass an additional ``non_blocking=True`` argument to a :meth:`~torch.Tensor.cuda`
 | 
			
		||||
call. This can be used to overlap data transfers with computation.
 | 
			
		||||
 | 
			
		||||
You can make the :class:`~torch.utils.data.DataLoader` return batches placed in
 | 
			
		||||
 | 
			
		||||
@ -9,8 +9,8 @@ memory and will only send a handle to another process.
 | 
			
		||||
 | 
			
		||||
.. note::
 | 
			
		||||
 | 
			
		||||
    When a :class:`~torch.autograd.Variable` is sent to another process, both
 | 
			
		||||
    the :attr:`Variable.data` and :attr:`Variable.grad.data` are going to be
 | 
			
		||||
    When a :class:`~torch.Tensor` is sent to another process, both
 | 
			
		||||
    the :attr:`~torch.Tensor` data and :attr:`torch.Tensor.grad` are going to be
 | 
			
		||||
    shared.
 | 
			
		||||
 | 
			
		||||
This allows to implement various training methods, like Hogwild, A3C, or any
 | 
			
		||||
 | 
			
		||||
							
								
								
									
										261
									
								
								docs/source/notes/windows.rst
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										261
									
								
								docs/source/notes/windows.rst
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,261 @@
 | 
			
		||||
Windows FAQ
 | 
			
		||||
==========================
 | 
			
		||||
 | 
			
		||||
Building from source
 | 
			
		||||
--------------------
 | 
			
		||||
 | 
			
		||||
Include optional components
 | 
			
		||||
^^^^^^^^^^^^^^^^^^^^^^^^^^^
 | 
			
		||||
 | 
			
		||||
There are two supported components for Windows PyTorch:
 | 
			
		||||
MKL and MAGMA. Here are the steps to build with them.
 | 
			
		||||
 | 
			
		||||
.. code-block:: bat
 | 
			
		||||
 | 
			
		||||
    REM Make sure you have 7z and curl installed.
 | 
			
		||||
 | 
			
		||||
    REM Download MKL files
 | 
			
		||||
    curl https://s3.amazonaws.com/ossci-windows/mkl_2018.2.185.7z -k -O
 | 
			
		||||
    7z x -aoa mkl_2018.2.185.7z -omkl
 | 
			
		||||
 | 
			
		||||
    REM Download MAGMA files
 | 
			
		||||
    REM cuda90/cuda91 is also available in the following line.
 | 
			
		||||
    set CUDA_PREFIX=cuda80 
 | 
			
		||||
    curl -k https://s3.amazonaws.com/ossci-windows/magma_%CUDA_PREFIX%_release_mkl_2018.2.185.7z -o magma.7z
 | 
			
		||||
    7z x -aoa magma.7z -omagma
 | 
			
		||||
    
 | 
			
		||||
    REM Setting essential environment variables
 | 
			
		||||
    set "CMAKE_INCLUDE_PATH=%cd%\\mkl\\include"
 | 
			
		||||
    set "LIB=%cd%\\mkl\\lib;%LIB%"
 | 
			
		||||
    set "MAGMA_HOME=%cd%\\magma"
 | 
			
		||||
 | 
			
		||||
Speeding CUDA build for Windows
 | 
			
		||||
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 | 
			
		||||
 | 
			
		||||
Visual Studio doesn't support parallel custom task currently.
 | 
			
		||||
As an alternative, we can use ``Ninja`` to parallelize CUDA
 | 
			
		||||
build tasks. It can be used by typing only a few lines of code.
 | 
			
		||||
 | 
			
		||||
.. code-block:: bat
 | 
			
		||||
    
 | 
			
		||||
    REM Let's install ninja first.
 | 
			
		||||
    pip install ninja
 | 
			
		||||
 | 
			
		||||
    REM Set it as the cmake generator
 | 
			
		||||
    set CMAKE_GENERATOR=Ninja
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
One key install script
 | 
			
		||||
^^^^^^^^^^^^^^^^^^^^^^
 | 
			
		||||
 | 
			
		||||
You can take a look at the script `here
 | 
			
		||||
<https://github.com/peterjc123/pytorch-scripts>`_. 
 | 
			
		||||
It will lead the way for you.
 | 
			
		||||
 | 
			
		||||
Extension
 | 
			
		||||
---------
 | 
			
		||||
 | 
			
		||||
CFFI Extension
 | 
			
		||||
^^^^^^^^^^^^^^
 | 
			
		||||
 | 
			
		||||
The support for CFFI Extension is very experimental. There're 
 | 
			
		||||
generally two steps to enable it under Windows.
 | 
			
		||||
 | 
			
		||||
First, specify additional ``libraries`` in ``Extension``
 | 
			
		||||
object to make it build on Windows.
 | 
			
		||||
 | 
			
		||||
.. code-block:: python
 | 
			
		||||
 | 
			
		||||
   ffi = create_extension(
 | 
			
		||||
       '_ext.my_lib',
 | 
			
		||||
       headers=headers,
 | 
			
		||||
       sources=sources,
 | 
			
		||||
       define_macros=defines,
 | 
			
		||||
       relative_to=__file__,
 | 
			
		||||
       with_cuda=with_cuda,
 | 
			
		||||
       extra_compile_args=["-std=c99"],
 | 
			
		||||
       libraries=['ATen', '_C'] # Append cuda libaries when necessary, like cudart
 | 
			
		||||
   )
 | 
			
		||||
 | 
			
		||||
Second, here is a workground for "unresolved external symbol 
 | 
			
		||||
state caused by ``extern THCState *state;``"
 | 
			
		||||
 | 
			
		||||
Change the source code from C to C++. An example is listed below.
 | 
			
		||||
 | 
			
		||||
.. code-block:: cpp
 | 
			
		||||
 | 
			
		||||
    #include <THC/THC.h>
 | 
			
		||||
    #include <ATen/ATen.h>
 | 
			
		||||
 | 
			
		||||
    THCState *state = at::globalContext().thc_state;
 | 
			
		||||
 | 
			
		||||
    extern "C" int my_lib_add_forward_cuda(THCudaTensor *input1, THCudaTensor *input2,
 | 
			
		||||
                                            THCudaTensor *output)
 | 
			
		||||
    {
 | 
			
		||||
        if (!THCudaTensor_isSameSizeAs(state, input1, input2))
 | 
			
		||||
        return 0;
 | 
			
		||||
        THCudaTensor_resizeAs(state, output, input1);
 | 
			
		||||
        THCudaTensor_cadd(state, output, input1, 1.0, input2);
 | 
			
		||||
        return 1;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    extern "C" int my_lib_add_backward_cuda(THCudaTensor *grad_output, THCudaTensor *grad_input)
 | 
			
		||||
    {
 | 
			
		||||
        THCudaTensor_resizeAs(state, grad_input, grad_output);
 | 
			
		||||
        THCudaTensor_fill(state, grad_input, 1);
 | 
			
		||||
        return 1;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
Cpp Extension
 | 
			
		||||
^^^^^^^^^^^^^
 | 
			
		||||
 | 
			
		||||
This type of extension has better support compared with
 | 
			
		||||
the previous one. However, it still needs some manual
 | 
			
		||||
configuration. First, you should open the
 | 
			
		||||
**x86_x64 Cross Tools Command Prompt for VS 2017**.
 | 
			
		||||
And then, you can open the Git-Bash in it. It is
 | 
			
		||||
usually located in ``C:\Program Files\Git\git-bash.exe``.
 | 
			
		||||
Finally, you can start your compiling process.
 | 
			
		||||
 | 
			
		||||
Installation
 | 
			
		||||
------------
 | 
			
		||||
 | 
			
		||||
Package not found in win-32 channel.
 | 
			
		||||
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 | 
			
		||||
 | 
			
		||||
.. code-block:: bat
 | 
			
		||||
 | 
			
		||||
    Solving environment: failed
 | 
			
		||||
 | 
			
		||||
    PackagesNotFoundError: The following packages are not available from current channels:
 | 
			
		||||
 | 
			
		||||
    - pytorch
 | 
			
		||||
 | 
			
		||||
    Current channels:
 | 
			
		||||
    - https://conda.anaconda.org/pytorch/win-32
 | 
			
		||||
    - https://conda.anaconda.org/pytorch/noarch
 | 
			
		||||
    - https://repo.continuum.io/pkgs/main/win-32
 | 
			
		||||
    - https://repo.continuum.io/pkgs/main/noarch
 | 
			
		||||
    - https://repo.continuum.io/pkgs/free/win-32
 | 
			
		||||
    - https://repo.continuum.io/pkgs/free/noarch
 | 
			
		||||
    - https://repo.continuum.io/pkgs/r/win-32
 | 
			
		||||
    - https://repo.continuum.io/pkgs/r/noarch
 | 
			
		||||
    - https://repo.continuum.io/pkgs/pro/win-32
 | 
			
		||||
    - https://repo.continuum.io/pkgs/pro/noarch
 | 
			
		||||
    - https://repo.continuum.io/pkgs/msys2/win-32
 | 
			
		||||
    - https://repo.continuum.io/pkgs/msys2/noarch
 | 
			
		||||
 | 
			
		||||
PyTorch doesn't work on 32-bit system. Please use Windows and
 | 
			
		||||
Python 64-bit version.
 | 
			
		||||
 | 
			
		||||
Why are there no Python 2 packages for Windows?
 | 
			
		||||
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 | 
			
		||||
 | 
			
		||||
Because it's not stable enough. There're some issues that need to
 | 
			
		||||
be solved before we officially release it. You can build it by yourself.
 | 
			
		||||
 | 
			
		||||
Import error
 | 
			
		||||
^^^^^^^^^^^^
 | 
			
		||||
 | 
			
		||||
.. code-block:: py3tb
 | 
			
		||||
 | 
			
		||||
    from torch._C import *
 | 
			
		||||
 | 
			
		||||
    ImportError: DLL load failed: The specified module could not be found.
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
The problem is caused by the missing of the essential files. Actually,
 | 
			
		||||
we include almost all the essential files that PyTorch need except VC2017
 | 
			
		||||
redistributable. You can resolve this by typing the following command.
 | 
			
		||||
 | 
			
		||||
.. code-block:: bat
 | 
			
		||||
 | 
			
		||||
    conda install -c peterjc123 vc vs2017_runtime
 | 
			
		||||
 | 
			
		||||
Another possible cause may be you are using GPU version without NVIDIA
 | 
			
		||||
graphics cards. Please replace your GPU package with the CPU one.
 | 
			
		||||
 | 
			
		||||
Usage (multiprocessing)
 | 
			
		||||
-------------------------------------------------------
 | 
			
		||||
 | 
			
		||||
Multiprocessing error without if-clause protection
 | 
			
		||||
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 | 
			
		||||
 | 
			
		||||
.. code-block:: py3tb
 | 
			
		||||
 | 
			
		||||
    RuntimeError:
 | 
			
		||||
   	An attempt has been made to start a new process before the
 | 
			
		||||
   	current process has finished its bootstrapping phase.
 | 
			
		||||
 | 
			
		||||
       This probably means that you are not using fork to start your
 | 
			
		||||
       child processes and you have forgotten to use the proper idiom
 | 
			
		||||
       in the main module:
 | 
			
		||||
 | 
			
		||||
           if __name__ == '__main__':
 | 
			
		||||
               freeze_support()
 | 
			
		||||
               ...
 | 
			
		||||
 | 
			
		||||
       The "freeze_support()" line can be omitted if the program
 | 
			
		||||
       is not going to be frozen to produce an executable.
 | 
			
		||||
 | 
			
		||||
The implementation of ``multiprocessing`` is different on Windows, which
 | 
			
		||||
uses ``spawn`` instead of ``fork``. So we have to wrap the code with an
 | 
			
		||||
if-clause to protect the code from executing multiple times. Refactor
 | 
			
		||||
your code into the following structure.
 | 
			
		||||
 | 
			
		||||
.. code-block:: python
 | 
			
		||||
 | 
			
		||||
    import torch
 | 
			
		||||
 | 
			
		||||
    def main()
 | 
			
		||||
        for i, data in enumerate(dataloader):
 | 
			
		||||
            # do something here
 | 
			
		||||
 | 
			
		||||
    if __name__ == '__main__':
 | 
			
		||||
        main()
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
Multiprocessing error "Broken pipe"
 | 
			
		||||
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 | 
			
		||||
 | 
			
		||||
.. code-block:: py3tb
 | 
			
		||||
 | 
			
		||||
    ForkingPickler(file, protocol).dump(obj)
 | 
			
		||||
 | 
			
		||||
    BrokenPipeError: [Errno 32] Broken pipe
 | 
			
		||||
 | 
			
		||||
This issue happens when the child process ends before the parent process
 | 
			
		||||
finishes sending data. There may be something wrong with your code. You
 | 
			
		||||
can debug your code by reducing the ``num_worker`` of 
 | 
			
		||||
:class:`~torch.utils.data.DataLoader` to zero and see if the issue persists.
 | 
			
		||||
 | 
			
		||||
Multiprocessing error "driver shut down"
 | 
			
		||||
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 | 
			
		||||
 | 
			
		||||
.. code-block:: py3tb
 | 
			
		||||
 | 
			
		||||
    Couldn’t open shared file mapping: <torch_14808_1591070686>, error code: <1455> at torch\lib\TH\THAllocator.c:154
 | 
			
		||||
 | 
			
		||||
    [windows] driver shut down
 | 
			
		||||
 | 
			
		||||
Please update your graphics driver. If this persists, this may be that your
 | 
			
		||||
graphics card is too old or the calculation is too heavy for your card. Please
 | 
			
		||||
update the TDR settings according to this `post
 | 
			
		||||
<https://www.pugetsystems.com/labs/hpc/Working-around-TDR-in-Windows-for-a-better-GPU-computing-experience-777/>`_.
 | 
			
		||||
 | 
			
		||||
CUDA IPC operations
 | 
			
		||||
^^^^^^^^^^^^^^^^^^^
 | 
			
		||||
 | 
			
		||||
.. code-block:: py3tb
 | 
			
		||||
 | 
			
		||||
   THCudaCheck FAIL file=torch\csrc\generic\StorageSharing.cpp line=252 error=63 : OS call failed or operation not supported on this OS
 | 
			
		||||
 | 
			
		||||
They are not supported on Windows. Something like doing multiprocessing on CUDA
 | 
			
		||||
tensors cannot succeed, there are two alternatives for this.
 | 
			
		||||
 | 
			
		||||
1. Don't use ``multiprocessing``. Set the ``num_worker`` of 
 | 
			
		||||
:class:`~torch.utils.data.DataLoader` to zero.
 | 
			
		||||
 | 
			
		||||
2. Share CPU tensors instead. Make sure your custom
 | 
			
		||||
:class:`~torch.utils.data.DataSet` returns CPU tensors.
 | 
			
		||||
 | 
			
		||||
@ -1,5 +1,7 @@
 | 
			
		||||
.. currentmodule:: torch.sparse
 | 
			
		||||
 | 
			
		||||
.. _sparse-docs:
 | 
			
		||||
 | 
			
		||||
torch.sparse
 | 
			
		||||
============
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
							
								
								
									
										131
									
								
								docs/source/tensor_attributes.rst
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										131
									
								
								docs/source/tensor_attributes.rst
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,131 @@
 | 
			
		||||
.. currentmodule:: torch
 | 
			
		||||
 | 
			
		||||
.. _tensor-attributes-doc:
 | 
			
		||||
 | 
			
		||||
Tensor Attributes
 | 
			
		||||
=================
 | 
			
		||||
 | 
			
		||||
Each ``torch.Tensor`` has a :class:`torch.dtype`, :class:`torch.device`, and :class:`torch.layout`.
 | 
			
		||||
 | 
			
		||||
.. _dtype-doc:
 | 
			
		||||
 | 
			
		||||
torch.dtype
 | 
			
		||||
-----------
 | 
			
		||||
 | 
			
		||||
.. class:: torch.dtype
 | 
			
		||||
 | 
			
		||||
A :class:`torch.dtype` is an object that represents the data type of a
 | 
			
		||||
:class:`torch.Tensor`. PyTorch has eight different data types:
 | 
			
		||||
 | 
			
		||||
========================   ===========================================   ===========================
 | 
			
		||||
Data type                  dtype                                         Tensor types
 | 
			
		||||
========================   ===========================================   ===========================
 | 
			
		||||
32-bit floating point      ``torch.float32`` or ``torch.float``          ``torch.*.FloatTensor``
 | 
			
		||||
64-bit floating point      ``torch.float64`` or ``torch.double``         ``torch.*.DoubleTensor``
 | 
			
		||||
16-bit floating point      ``torch.float16`` or ``torch.half``           ``torch.*.HalfTensor``
 | 
			
		||||
8-bit integer (unsigned)   ``torch.uint8``                               ``torch.*.ByteTensor``
 | 
			
		||||
8-bit integer (signed)     ``torch.int8``                                ``torch.*.CharTensor``
 | 
			
		||||
16-bit integer (signed)    ``torch.int16`` or ``torch.short``            ``torch.*.ShortTensor``
 | 
			
		||||
32-bit integer (signed)    ``torch.int32`` or ``torch.int``              ``torch.*.IntTensor``
 | 
			
		||||
64-bit integer (signed)    ``torch.int64`` or ``torch.long``             ``torch.*.LongTensor``
 | 
			
		||||
========================   ===========================================   ===========================
 | 
			
		||||
 | 
			
		||||
.. _device-doc:
 | 
			
		||||
 | 
			
		||||
torch.device
 | 
			
		||||
------------
 | 
			
		||||
 | 
			
		||||
.. class:: torch.device
 | 
			
		||||
 | 
			
		||||
A :class:`torch.device` is an object representing the device on which a :class:`torch.Tensor` is
 | 
			
		||||
or will be allocated.
 | 
			
		||||
 | 
			
		||||
The :class:`torch.device` contains a device type (``'cpu'`` or ``'cuda'``) and optional device ordinal for the
 | 
			
		||||
device type.  If the device ordinal is not present, this represents the current device for the device type;
 | 
			
		||||
e.g. a :class:`torch.Tensor` constructed with device ``'cuda'`` is equivalent to ``'cuda:X'`` where X is the result of
 | 
			
		||||
:func:`torch.cuda.current_device()`.
 | 
			
		||||
 | 
			
		||||
A :class:`torch.Tensor`'s device can be accessed via the :attr:`Tensor.device` property.
 | 
			
		||||
 | 
			
		||||
A :class:`torch.device` can be constructed via a string or via a string and device ordinal
 | 
			
		||||
 | 
			
		||||
Via a string:
 | 
			
		||||
::
 | 
			
		||||
 | 
			
		||||
    >>> torch.device('cuda:0')
 | 
			
		||||
    device(type='cuda', index=0)
 | 
			
		||||
 | 
			
		||||
    >>> torch.device('cpu')
 | 
			
		||||
    device(type='cpu')
 | 
			
		||||
 | 
			
		||||
    >>> torch.device('cuda')  # current cuda device
 | 
			
		||||
    device(type='cuda')
 | 
			
		||||
 | 
			
		||||
Via a string and device ordinal:
 | 
			
		||||
 | 
			
		||||
::
 | 
			
		||||
 | 
			
		||||
    >>> torch.device('cuda', 0)
 | 
			
		||||
    device(type='cuda', index=0)
 | 
			
		||||
 | 
			
		||||
    >>> torch.device('cpu', 0)
 | 
			
		||||
    device(type='cpu', index=0)
 | 
			
		||||
 | 
			
		||||
.. note::
 | 
			
		||||
   The :class:`torch.device` argument in functions can generally be substituted with a string.
 | 
			
		||||
   This allows for fast prototyping of code.
 | 
			
		||||
 | 
			
		||||
   >>> # Example of a function that takes in a torch.device
 | 
			
		||||
   >>> cuda1 = torch.device('cuda:1')
 | 
			
		||||
   >>> torch.randn((2,3), device=cuda1)
 | 
			
		||||
 | 
			
		||||
   >>> # You can substitute the torch.device with a string
 | 
			
		||||
   >>> torch.randn((2,3), 'cuda:1')
 | 
			
		||||
 | 
			
		||||
.. note::
 | 
			
		||||
   For legacy reasons, a device can be constructed via a single device ordinal, which is treated
 | 
			
		||||
   as a cuda device.  This matches :meth:`Tensor.get_device`, which returns an ordinal for cuda
 | 
			
		||||
   tensors and is not supported for cpu tensors.
 | 
			
		||||
 | 
			
		||||
   >>> torch.device(1)
 | 
			
		||||
   device(type='cuda', index=1)
 | 
			
		||||
 | 
			
		||||
.. note::
 | 
			
		||||
   Methods which take a device will generally accept a (properly formatted) string
 | 
			
		||||
   or (legacy) integer device ordinal, i.e. the following are all equivalent:
 | 
			
		||||
 | 
			
		||||
   >>> torch.randn((2,3), device=torch.device('cuda:1'))
 | 
			
		||||
   >>> torch.randn((2,3), device='cuda:1')
 | 
			
		||||
   >>> torch.randn((2,3), device=1)  # legacy
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
.. _layout-doc:
 | 
			
		||||
 | 
			
		||||
torch.layout
 | 
			
		||||
------------
 | 
			
		||||
 | 
			
		||||
.. class:: torch.layout
 | 
			
		||||
 | 
			
		||||
A :class:`torch.layout` is an object that represents the memory layout of a
 | 
			
		||||
:class:`torch.Tensor`. Currently, we support ``torch.strided`` (dense Tensors)
 | 
			
		||||
and have experimental support for ``torch.sparse_coo`` (sparse COO Tensors).
 | 
			
		||||
 | 
			
		||||
``torch.strided`` represents dense Tensors and is the memory layout that
 | 
			
		||||
is most commonly used. Each strided tensor has an associated
 | 
			
		||||
:class:`torch.Storage`, which holds its data. These tensors provide
 | 
			
		||||
multi-dimensional, `strided <https://en.wikipedia.org/wiki/Stride_of_an_array>`_
 | 
			
		||||
view of a storage. Strides are a list of integers: the k-th stride
 | 
			
		||||
represents the jump in the memory necessary to go from one element to the
 | 
			
		||||
next one in the k-th dimension of the Tensor. This concept makes it possible
 | 
			
		||||
to perform many tensor operations efficiently.
 | 
			
		||||
 | 
			
		||||
Example::
 | 
			
		||||
 | 
			
		||||
    >>> x = torch.Tensor([[1, 2, 3, 4, 5], [6, 7, 8, 9, 10]])
 | 
			
		||||
    >>> x.stride()
 | 
			
		||||
    (5, 1)
 | 
			
		||||
 | 
			
		||||
    >>> x.t().stride()
 | 
			
		||||
    (1, 5)
 | 
			
		||||
 | 
			
		||||
For more information on ``torch.sparse_coo`` tensors, see :ref:`sparse-docs`.
 | 
			
		||||
@ -10,18 +10,18 @@ a single data type.
 | 
			
		||||
 | 
			
		||||
Torch defines eight CPU tensor types and eight GPU tensor types:
 | 
			
		||||
 | 
			
		||||
========================   ===================   ===========================   ================================
 | 
			
		||||
Data type                  dtype                         CPU tensor                    GPU tensor
 | 
			
		||||
========================   ===================   ===========================   ================================
 | 
			
		||||
32-bit floating point      ``torch.float32``     :class:`torch.FloatTensor`    :class:`torch.cuda.FloatTensor`
 | 
			
		||||
64-bit floating point      ``torch.float64``     :class:`torch.DoubleTensor`   :class:`torch.cuda.DoubleTensor`
 | 
			
		||||
16-bit floating point      ``torch.float16``     :class:`torch.HalfTensor`     :class:`torch.cuda.HalfTensor`
 | 
			
		||||
8-bit integer (unsigned)   ``torch.uint8``       :class:`torch.ByteTensor`     :class:`torch.cuda.ByteTensor`
 | 
			
		||||
8-bit integer (signed)     ``torch.int8``        :class:`torch.CharTensor`     :class:`torch.cuda.CharTensor`
 | 
			
		||||
16-bit integer (signed)    ``torch.int16``       :class:`torch.ShortTensor`    :class:`torch.cuda.ShortTensor`
 | 
			
		||||
32-bit integer (signed)    ``torch.int32``       :class:`torch.IntTensor`      :class:`torch.cuda.IntTensor`
 | 
			
		||||
64-bit integer (signed)    ``torch.int64``       :class:`torch.LongTensor`     :class:`torch.cuda.LongTensor`
 | 
			
		||||
========================   ===================   ===========================   ================================
 | 
			
		||||
========================   ===========================================   ===========================   ================================
 | 
			
		||||
Data type                  dtype                                         CPU tensor                    GPU tensor
 | 
			
		||||
========================   ===========================================   ===========================   ================================
 | 
			
		||||
32-bit floating point      ``torch.float32`` or ``torch.float``          :class:`torch.FloatTensor`    :class:`torch.cuda.FloatTensor`
 | 
			
		||||
64-bit floating point      ``torch.float64`` or ``torch.double``         :class:`torch.DoubleTensor`   :class:`torch.cuda.DoubleTensor`
 | 
			
		||||
16-bit floating point      ``torch.float16`` or ``torch.half``           :class:`torch.HalfTensor`     :class:`torch.cuda.HalfTensor`
 | 
			
		||||
8-bit integer (unsigned)   ``torch.uint8``                               :class:`torch.ByteTensor`     :class:`torch.cuda.ByteTensor`
 | 
			
		||||
8-bit integer (signed)     ``torch.int8``                                :class:`torch.CharTensor`     :class:`torch.cuda.CharTensor`
 | 
			
		||||
16-bit integer (signed)    ``torch.int16`` or ``torch.short``            :class:`torch.ShortTensor`    :class:`torch.cuda.ShortTensor`
 | 
			
		||||
32-bit integer (signed)    ``torch.int32`` or ``torch.int``              :class:`torch.IntTensor`      :class:`torch.cuda.IntTensor`
 | 
			
		||||
64-bit integer (signed)    ``torch.int64`` or ``torch.long``             :class:`torch.LongTensor`     :class:`torch.cuda.LongTensor`
 | 
			
		||||
========================   ===========================================   ===========================   ================================
 | 
			
		||||
 | 
			
		||||
:class:`torch.Tensor` is an alias for the default tensor type (:class:`torch.FloatTensor`).
 | 
			
		||||
 | 
			
		||||
@ -31,16 +31,20 @@ A tensor can be constructed from a Python :class:`list` or sequence using the
 | 
			
		||||
::
 | 
			
		||||
 | 
			
		||||
    >>> torch.tensor([[1., -1.], [1., -1.]])
 | 
			
		||||
 | 
			
		||||
     1 -1
 | 
			
		||||
     1 -1
 | 
			
		||||
    [torch.FloatTensor of size (2,2)]
 | 
			
		||||
 | 
			
		||||
    tensor([[ 1.0000, -1.0000],
 | 
			
		||||
            [ 1.0000, -1.0000]])
 | 
			
		||||
    >>> torch.tensor(np.array([[1, 2, 3], [4, 5, 6]]))
 | 
			
		||||
    tensor([[ 1,  2,  3],
 | 
			
		||||
            [ 4,  5,  6]])
 | 
			
		||||
 | 
			
		||||
     1 -1
 | 
			
		||||
     1 -1
 | 
			
		||||
    [torch.FloatTensor of size (2,2)]
 | 
			
		||||
.. warning::
 | 
			
		||||
 | 
			
		||||
    :func:`torch.tensor` always copies :attr:`data`. If you have a Tensor
 | 
			
		||||
    :attr:`data` and just want to change its ``requires_grad`` flag, use
 | 
			
		||||
    :meth:`~torch.Tensor.requires_grad_` or
 | 
			
		||||
    :meth:`~torch.Tensor.detach` to avoid a copy.
 | 
			
		||||
    If you have a numpy array and want to avoid a copy, use
 | 
			
		||||
    :func:`torch.from_numpy`.
 | 
			
		||||
 | 
			
		||||
An tensor of specific data type can be constructed by passing a
 | 
			
		||||
:class:`torch.dtype` and/or a :class:`torch.device` to a
 | 
			
		||||
@ -49,16 +53,12 @@ constructor or tensor creation op:
 | 
			
		||||
::
 | 
			
		||||
 | 
			
		||||
    >>> torch.zeros([2, 4], dtype=torch.int32)
 | 
			
		||||
 | 
			
		||||
    0  0  0  0
 | 
			
		||||
    0  0  0  0
 | 
			
		||||
    [torch.IntTensor of size 2x4]
 | 
			
		||||
 | 
			
		||||
    >>> torch.ones([2, 4], dtype=torch.float64, device=torch.device('cuda:0'))
 | 
			
		||||
 | 
			
		||||
    1  1  1  1
 | 
			
		||||
    1  1  1  1
 | 
			
		||||
    [torch.cuda.DoubleTensor of size 2x4]
 | 
			
		||||
    tensor([[ 0,  0,  0,  0],
 | 
			
		||||
            [ 0,  0,  0,  0]], dtype=torch.int32)
 | 
			
		||||
    >>> cuda0 = torch.device('cuda:0')
 | 
			
		||||
    >>> torch.ones([2, 4], dtype=torch.float64, device=cuda0)
 | 
			
		||||
    tensor([[ 1.0000,  1.0000,  1.0000,  1.0000],
 | 
			
		||||
            [ 1.0000,  1.0000,  1.0000,  1.0000]], dtype=torch.float64, device='cuda:0')
 | 
			
		||||
 | 
			
		||||
The contents of a tensor can be accessed and modified using Python's indexing
 | 
			
		||||
and slicing notation:
 | 
			
		||||
@ -67,14 +67,27 @@ and slicing notation:
 | 
			
		||||
 | 
			
		||||
    >>> x = torch.tensor([[1, 2, 3], [4, 5, 6]])
 | 
			
		||||
    >>> print(x[1][2])
 | 
			
		||||
 | 
			
		||||
    6.0
 | 
			
		||||
    tensor(6)
 | 
			
		||||
    >>> x[0][1] = 8
 | 
			
		||||
    >>> print(x)
 | 
			
		||||
    tensor([[ 1,  8,  3],
 | 
			
		||||
            [ 4,  5,  6]])
 | 
			
		||||
 | 
			
		||||
     1  8  3
 | 
			
		||||
     4  5  6
 | 
			
		||||
    [torch.FloatTensor of size 2x3]
 | 
			
		||||
Use :meth:`torch.Tensor.item` to get a Python number from a tensor containing a
 | 
			
		||||
single value:
 | 
			
		||||
 | 
			
		||||
::
 | 
			
		||||
 | 
			
		||||
    >>> x = torch.tensor([[1]])
 | 
			
		||||
    >>> x
 | 
			
		||||
    tensor([[ 1]])
 | 
			
		||||
    >>> x.item()
 | 
			
		||||
    1
 | 
			
		||||
    >>> x = torch.tensor(2.5)
 | 
			
		||||
    >>> x
 | 
			
		||||
    tensor(2.5000)
 | 
			
		||||
    >>> x.item()
 | 
			
		||||
    2.5
 | 
			
		||||
 | 
			
		||||
A tensor can be created with :attr:`requires_grad=True` so that
 | 
			
		||||
:mod:`torch.autograd` records operations on them for automatic differentiation.
 | 
			
		||||
@ -84,26 +97,47 @@ A tensor can be created with :attr:`requires_grad=True` so that
 | 
			
		||||
    >>> x = torch.tensor([[1., -1.], [1., 1.]], requires_grad=True)
 | 
			
		||||
    >>> out = x.pow(2).sum()
 | 
			
		||||
    >>> out.backward()
 | 
			
		||||
    >>> out.grad
 | 
			
		||||
 | 
			
		||||
     2 -2
 | 
			
		||||
     2  2
 | 
			
		||||
    [torch.FloatTensor of size (2,2)]
 | 
			
		||||
    >>> x.grad
 | 
			
		||||
    tensor([[ 2.0000, -2.0000],
 | 
			
		||||
            [ 2.0000,  2.0000]])
 | 
			
		||||
 | 
			
		||||
Each tensor has an associated :class:`torch.Storage`, which holds its data.
 | 
			
		||||
The tensor class provides multi-dimensional, `strided <https://en.wikipedia.org/wiki/Stride_of_an_array>`_
 | 
			
		||||
view of a storage and defines numeric operations on it.
 | 
			
		||||
 | 
			
		||||
.. note::
 | 
			
		||||
   For more information on the :class:`torch.dtype`, :class:`torch.device`, and
 | 
			
		||||
   :class:`torch.layout` attributes of a :class:`torch.Tensor`, see
 | 
			
		||||
   :ref:`tensor-attributes-doc`.
 | 
			
		||||
 | 
			
		||||
.. note::
 | 
			
		||||
   Methods which mutate a tensor are marked with an underscore suffix.
 | 
			
		||||
   For example, :func:`torch.FloatTensor.abs_` computes the absolute value
 | 
			
		||||
   in-place and returns the modified tensor, while :func:`torch.FloatTensor.abs`
 | 
			
		||||
   computes the result in a new tensor.
 | 
			
		||||
 | 
			
		||||
.. note::
 | 
			
		||||
    To change an existing tensor's :class:`torch.device` and/or :class:`torch.dtype`, consider using
 | 
			
		||||
    :meth:`~torch.Tensor.to` method on the tensor.
 | 
			
		||||
 | 
			
		||||
.. class:: Tensor()
 | 
			
		||||
 | 
			
		||||
  Create a tensor using the :func:`torch.tensor` constructor or with
 | 
			
		||||
  tensor creation ops (see :ref:`tensor-creation-ops`)
 | 
			
		||||
   There are a few main ways to create a tensor, depending on your use case.
 | 
			
		||||
 | 
			
		||||
   - To create a tensor with pre-existing data, use :func:`torch.tensor`.
 | 
			
		||||
   - To create a tensor with specific size, use ``torch.*`` tensor creation
 | 
			
		||||
     ops (see :ref:`tensor-creation-ops`).
 | 
			
		||||
   - To create a tensor with the same size (and similar types) as another tensor,
 | 
			
		||||
     use ``torch.*_like`` tensor creation ops
 | 
			
		||||
     (see :ref:`tensor-creation-ops`).
 | 
			
		||||
   - To create a tensor with similar type but different size as another tensor,
 | 
			
		||||
     use ``tensor.new_*`` creation ops.
 | 
			
		||||
 | 
			
		||||
   .. automethod:: new_tensor
 | 
			
		||||
   .. automethod:: new_full
 | 
			
		||||
   .. automethod:: new_empty
 | 
			
		||||
   .. automethod:: new_ones
 | 
			
		||||
   .. automethod:: new_zeros
 | 
			
		||||
 | 
			
		||||
   .. automethod:: abs
 | 
			
		||||
   .. automethod:: abs_
 | 
			
		||||
@ -262,7 +296,6 @@ view of a storage and defines numeric operations on it.
 | 
			
		||||
   .. automethod:: neg
 | 
			
		||||
   .. automethod:: neg_
 | 
			
		||||
   .. automethod:: nelement
 | 
			
		||||
   .. automethod:: new
 | 
			
		||||
   .. automethod:: nonzero
 | 
			
		||||
   .. automethod:: norm
 | 
			
		||||
   .. automethod:: normal_
 | 
			
		||||
@ -289,6 +322,7 @@ view of a storage and defines numeric operations on it.
 | 
			
		||||
   .. automethod:: renorm
 | 
			
		||||
   .. automethod:: renorm_
 | 
			
		||||
   .. automethod:: repeat
 | 
			
		||||
   .. automethod:: requires_grad_
 | 
			
		||||
   .. automethod:: reshape
 | 
			
		||||
   .. automethod:: resize_
 | 
			
		||||
   .. automethod:: resize_as_
 | 
			
		||||
@ -329,6 +363,7 @@ view of a storage and defines numeric operations on it.
 | 
			
		||||
   .. automethod:: symeig
 | 
			
		||||
   .. automethod:: t
 | 
			
		||||
   .. automethod:: t_
 | 
			
		||||
   .. automethod:: to
 | 
			
		||||
   .. automethod:: take
 | 
			
		||||
   .. automethod:: tan
 | 
			
		||||
   .. automethod:: tan_
 | 
			
		||||
 | 
			
		||||
@ -6,8 +6,9 @@ Tensors
 | 
			
		||||
----------------------------------
 | 
			
		||||
.. autofunction:: is_tensor
 | 
			
		||||
.. autofunction:: is_storage
 | 
			
		||||
.. autofunction:: set_default_tensor_type
 | 
			
		||||
.. autofunction:: set_default_dtype
 | 
			
		||||
.. autofunction:: get_default_dtype
 | 
			
		||||
.. autofunction:: set_default_tensor_type
 | 
			
		||||
.. autofunction:: numel
 | 
			
		||||
.. autofunction:: set_printoptions
 | 
			
		||||
.. autofunction:: set_flush_denormal
 | 
			
		||||
@ -27,6 +28,9 @@ Creation Ops
 | 
			
		||||
    :func:`torch.randint`
 | 
			
		||||
    :func:`torch.randint_like`
 | 
			
		||||
    :func:`torch.randperm`
 | 
			
		||||
    You may also use :func:`torch.empty` with the :ref:`inplace-random-sampling`
 | 
			
		||||
    methods to create :class:`torch.Tensor` s with values sampled from a broader
 | 
			
		||||
    range of distributions.
 | 
			
		||||
 | 
			
		||||
.. autofunction:: tensor
 | 
			
		||||
.. autofunction:: from_numpy
 | 
			
		||||
@ -83,6 +87,8 @@ Random sampling
 | 
			
		||||
.. autofunction:: randn_like
 | 
			
		||||
.. autofunction:: randperm
 | 
			
		||||
 | 
			
		||||
.. _inplace-random-sampling:
 | 
			
		||||
 | 
			
		||||
In-place random sampling
 | 
			
		||||
~~~~~~~~~~~~~~~~~~~~~~~~
 | 
			
		||||
 | 
			
		||||
@ -109,6 +115,37 @@ Parallelism
 | 
			
		||||
.. autofunction:: get_num_threads
 | 
			
		||||
.. autofunction:: set_num_threads
 | 
			
		||||
 | 
			
		||||
Locally disabling gradient computation
 | 
			
		||||
--------------------------------------
 | 
			
		||||
The context managers :func:`torch.no_grad`, :func:`torch.enable_grad`, and
 | 
			
		||||
:func:`torch.set_grad_enabled` are helpful for locally disabling and enabling
 | 
			
		||||
gradient computation. See :ref:`locally-disable-grad` for more details on
 | 
			
		||||
their usage.
 | 
			
		||||
 | 
			
		||||
Examples::
 | 
			
		||||
 | 
			
		||||
  >>> x = torch.zeros(1, requires_grad=True)
 | 
			
		||||
  >>> with torch.no_grad():
 | 
			
		||||
  ...     y = x * 2
 | 
			
		||||
  >>> y.requires_grad
 | 
			
		||||
  False
 | 
			
		||||
 | 
			
		||||
  >>> is_train = False
 | 
			
		||||
  >>> with torch.set_grad_enabled(is_train):
 | 
			
		||||
  ...     y = x * 2
 | 
			
		||||
  >>> y.requires_grad
 | 
			
		||||
  False
 | 
			
		||||
 | 
			
		||||
  >>> torch.set_grad_enabled(True)  # this can also be used as a function
 | 
			
		||||
  >>> y = x * 2
 | 
			
		||||
  >>> y.requires_grad
 | 
			
		||||
  True
 | 
			
		||||
 | 
			
		||||
  >>> torch.set_grad_enabled(False)
 | 
			
		||||
  >>> y = x * 2
 | 
			
		||||
  >>> y.requires_grad
 | 
			
		||||
  False
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
Math operations
 | 
			
		||||
----------------------------------
 | 
			
		||||
 | 
			
		||||
							
								
								
									
										19
									
								
								setup.py
									
									
									
									
									
								
							
							
						
						
									
										19
									
								
								setup.py
									
									
									
									
									
								
							@ -43,10 +43,6 @@
 | 
			
		||||
#   WITH_GLOO_IBVERBS
 | 
			
		||||
#     toggle features related to distributed support
 | 
			
		||||
#
 | 
			
		||||
#   PYTORCH_BINARY_BUILD
 | 
			
		||||
#     toggle static linking against libstdc++, used when we're building
 | 
			
		||||
#     binaries for distribution
 | 
			
		||||
#
 | 
			
		||||
#   PYTORCH_BUILD_VERSION
 | 
			
		||||
#   PYTORCH_BUILD_NUMBER
 | 
			
		||||
#     specify the version of PyTorch, rather than the hard-coded version
 | 
			
		||||
@ -780,19 +776,6 @@ if DEBUG:
 | 
			
		||||
        extra_compile_args += ['-O0', '-g']
 | 
			
		||||
        extra_link_args += ['-O0', '-g']
 | 
			
		||||
 | 
			
		||||
if os.getenv('PYTORCH_BINARY_BUILD') and platform.system() == 'Linux':
 | 
			
		||||
    print('PYTORCH_BINARY_BUILD found. Static linking libstdc++ on Linux')
 | 
			
		||||
    # get path of libstdc++ and link manually.
 | 
			
		||||
    # for reasons unknown, -static-libstdc++ doesn't fully link some symbols
 | 
			
		||||
    CXXNAME = os.getenv('CXX', 'g++')
 | 
			
		||||
    STDCPP_LIB = subprocess.check_output([CXXNAME, '-print-file-name=libstdc++.a'])
 | 
			
		||||
    STDCPP_LIB = STDCPP_LIB[:-1]
 | 
			
		||||
    if type(STDCPP_LIB) != str:  # python 3
 | 
			
		||||
        STDCPP_LIB = STDCPP_LIB.decode(sys.stdout.encoding)
 | 
			
		||||
    main_link_args += [STDCPP_LIB]
 | 
			
		||||
    version_script = os.path.abspath("tools/pytorch.version")
 | 
			
		||||
    extra_link_args += ['-Wl,--version-script=' + version_script]
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
def make_relative_rpath(path):
 | 
			
		||||
    if IS_DARWIN:
 | 
			
		||||
@ -807,7 +790,7 @@ def make_relative_rpath(path):
 | 
			
		||||
################################################################################
 | 
			
		||||
 | 
			
		||||
extensions = []
 | 
			
		||||
packages = find_packages(exclude=('tools', 'tools.*', 'caffe2', 'caffe'))
 | 
			
		||||
packages = find_packages(exclude=('tools', 'tools.*', 'caffe2', 'caffe2.*', 'caffe', 'caffe.*'))
 | 
			
		||||
C = Extension("torch._C",
 | 
			
		||||
              libraries=main_libraries,
 | 
			
		||||
              sources=main_sources,
 | 
			
		||||
 | 
			
		||||
@ -8,7 +8,7 @@ import warnings
 | 
			
		||||
from copy import deepcopy
 | 
			
		||||
from collections import OrderedDict
 | 
			
		||||
from itertools import product
 | 
			
		||||
from operator import mul
 | 
			
		||||
from operator import mul, itemgetter
 | 
			
		||||
from functools import reduce, wraps
 | 
			
		||||
from torch.autograd.gradcheck import gradgradcheck, gradcheck
 | 
			
		||||
from torch.autograd.function import once_differentiable
 | 
			
		||||
@ -1289,6 +1289,12 @@ class TestAutograd(TestCase):
 | 
			
		||||
        Identity.apply(v).backward()
 | 
			
		||||
        self.assertEqual(device[0], 1)
 | 
			
		||||
 | 
			
		||||
    @unittest.skipIf(torch.cuda.device_count() < 2, "no multi-GPU")
 | 
			
		||||
    def test_inputbuffer_add_multigpu(self):
 | 
			
		||||
        input = torch.randn(1).cuda(0).requires_grad_()
 | 
			
		||||
        output = input.cuda(1) + input.cuda(1)
 | 
			
		||||
        output.backward()
 | 
			
		||||
 | 
			
		||||
    def test_detach(self):
 | 
			
		||||
        x = torch.randn(10, 10, requires_grad=True)
 | 
			
		||||
        y = x + 2
 | 
			
		||||
@ -2267,9 +2273,9 @@ S = 5
 | 
			
		||||
#   method name,
 | 
			
		||||
#   input size/constructing fn,
 | 
			
		||||
#   args (tuple represents shape of a tensor arg),
 | 
			
		||||
#   test variant name (will be used at test name suffix),  // optional
 | 
			
		||||
#   indices for possible dim arg,                          // optional
 | 
			
		||||
#   output indices that should be gradcheck'ed,            // optional
 | 
			
		||||
#   test variant name (will be used at test name suffix),    // optional
 | 
			
		||||
#   indices for possible dim arg,                            // optional
 | 
			
		||||
#   fn mapping output to part that should be gradcheck'ed,   // optional
 | 
			
		||||
# )
 | 
			
		||||
method_tests = [
 | 
			
		||||
    ('add', (S, S, S), ((S, S, S),)),
 | 
			
		||||
@ -2700,18 +2706,31 @@ method_tests = [
 | 
			
		||||
     'symmetric_pd', NO_ARGS, [skipIfNoLapack]),
 | 
			
		||||
    ('logdet', lambda: make_nonzero_det(random_fullrank_matrix_distinct_singular_value(S), 1, 0), NO_ARGS,
 | 
			
		||||
     'distinct_singular_values', NO_ARGS, [skipIfNoLapack]),
 | 
			
		||||
    ('slogdet', lambda: make_nonzero_det(torch.randn(1, 1), 1), NO_ARGS, '1x1_pos_det', NO_ARGS, [skipIfNoLapack], [1]),
 | 
			
		||||
    ('slogdet', lambda: make_nonzero_det(torch.randn(1, 1), 1), NO_ARGS,
 | 
			
		||||
     '1x1_pos_det', NO_ARGS, [skipIfNoLapack], itemgetter(1)),
 | 
			
		||||
    ('slogdet', lambda: make_nonzero_det(torch.randn(1, 1), -1), NO_ARGS,
 | 
			
		||||
     '1x1_neg_det', NO_ARGS, [skipIfNoLapack], [1]),
 | 
			
		||||
    ('slogdet', lambda: make_nonzero_det(torch.randn(S, S), 1), NO_ARGS, 'pos_det', NO_ARGS, [skipIfNoLapack], [1]),
 | 
			
		||||
    ('slogdet', lambda: make_nonzero_det(torch.randn(S, S), -1), NO_ARGS, 'neg_det', NO_ARGS, [skipIfNoLapack], [1]),
 | 
			
		||||
     '1x1_neg_det', NO_ARGS, [skipIfNoLapack], itemgetter(1)),
 | 
			
		||||
    ('slogdet', lambda: make_nonzero_det(torch.randn(S, S), 1), NO_ARGS,
 | 
			
		||||
     'pos_det', NO_ARGS, [skipIfNoLapack], itemgetter(1)),
 | 
			
		||||
    ('slogdet', lambda: make_nonzero_det(torch.randn(S, S), -1), NO_ARGS,
 | 
			
		||||
     'neg_det', NO_ARGS, [skipIfNoLapack], itemgetter(1)),
 | 
			
		||||
    ('slogdet', lambda: make_nonzero_det(random_symmetric_matrix(S)), NO_ARGS,
 | 
			
		||||
     'symmetric', NO_ARGS, [skipIfNoLapack], [1]),
 | 
			
		||||
    ('slogdet', lambda: random_symmetric_pd_matrix(S), NO_ARGS, 'symmetric_pd', NO_ARGS, [skipIfNoLapack], [1]),
 | 
			
		||||
     'symmetric', NO_ARGS, [skipIfNoLapack], itemgetter(1)),
 | 
			
		||||
    ('slogdet', lambda: random_symmetric_pd_matrix(S), NO_ARGS,
 | 
			
		||||
     'symmetric_pd', NO_ARGS, [skipIfNoLapack], itemgetter(1)),
 | 
			
		||||
    ('slogdet', lambda: random_fullrank_matrix_distinct_singular_value(S), NO_ARGS,
 | 
			
		||||
     'distinct_singular_values', NO_ARGS, [skipIfNoLapack], [1]),
 | 
			
		||||
     'distinct_singular_values', NO_ARGS, [skipIfNoLapack], itemgetter(1)),
 | 
			
		||||
    ('svd', lambda: random_fullrank_matrix_distinct_singular_value(S), NO_ARGS, '', NO_ARGS, [skipIfNoLapack]),
 | 
			
		||||
    ('svd', lambda: random_fullrank_matrix_distinct_singular_value(M), NO_ARGS, 'large', NO_ARGS, [skipIfNoLapack]),
 | 
			
		||||
    ('svd', lambda: random_fullrank_matrix_distinct_singular_value(S)[:(S - 2)], NO_ARGS,
 | 
			
		||||
     'wide', NO_ARGS, [skipIfNoLapack]),
 | 
			
		||||
    ('svd', lambda: random_fullrank_matrix_distinct_singular_value(S)[:, :(S - 2)], NO_ARGS,
 | 
			
		||||
     'tall', NO_ARGS, [skipIfNoLapack]),
 | 
			
		||||
    ('svd', lambda: random_fullrank_matrix_distinct_singular_value(S)[:(S - 2)], (False,),
 | 
			
		||||
     'wide_all', NO_ARGS, [skipIfNoLapack], lambda usv: (usv[0], usv[1], usv[2][:, :(S - 2)])),
 | 
			
		||||
    ('svd', lambda: random_fullrank_matrix_distinct_singular_value(S)[:, :(S - 2)], (False,),
 | 
			
		||||
     'tall_all', NO_ARGS, [skipIfNoLapack], lambda usv: (usv[0][:, :(S - 2)], usv[1], usv[2])),
 | 
			
		||||
    ('svd', lambda: random_fullrank_matrix_distinct_singular_value(M), NO_ARGS,
 | 
			
		||||
     'large', NO_ARGS, [skipIfNoLapack]),
 | 
			
		||||
    ('gesv', (S, S), ((S, S),), '', NO_ARGS, [skipIfNoLapack]),
 | 
			
		||||
    ('fill_', (S, S, S), (1,), 'number'),
 | 
			
		||||
    ('fill_', (), (1,), 'number_scalar'),
 | 
			
		||||
@ -3028,7 +3047,7 @@ for test in method_tests:
 | 
			
		||||
 | 
			
		||||
    skipTestIf = test[5] if len(test) >= 6 else []
 | 
			
		||||
 | 
			
		||||
    test_output_indices = test[6] if len(test) >= 7 else None
 | 
			
		||||
    output_process_fn = test[6] if len(test) >= 7 else lambda x: x
 | 
			
		||||
 | 
			
		||||
    for dim_perm in product([-1, 1], repeat=len(dim_args_idx)):
 | 
			
		||||
        test_name = basic_test_name
 | 
			
		||||
@ -3039,7 +3058,7 @@ for test in method_tests:
 | 
			
		||||
        # for-loop bodies don't define scopes, so we have to save the variables
 | 
			
		||||
        # we want to close over in some way
 | 
			
		||||
        def do_test(self, name=name, self_size=self_size, args=new_args, test_name=test_name,
 | 
			
		||||
                    test_output_indices=test_output_indices):
 | 
			
		||||
                    output_process_fn=output_process_fn):
 | 
			
		||||
            def check(name):
 | 
			
		||||
                is_magic_method = name[:2] == '__' and name[-2:] == '__'
 | 
			
		||||
                is_inplace = name[-1] == "_" and not is_magic_method
 | 
			
		||||
@ -3061,10 +3080,7 @@ for test in method_tests:
 | 
			
		||||
 | 
			
		||||
                def fn(*inputs):
 | 
			
		||||
                    output = getattr(inputs[0], name)(*inputs[1:])
 | 
			
		||||
                    if test_output_indices is None:
 | 
			
		||||
                        return output
 | 
			
		||||
                    else:
 | 
			
		||||
                        return tuple(output[i] for i in test_output_indices)
 | 
			
		||||
                    return output_process_fn(output)
 | 
			
		||||
 | 
			
		||||
                if not is_inplace and name not in EXCLUDE_GRADCHECK:
 | 
			
		||||
                    run_grad_and_gradgrad_checks(self, name, test_name, fn,
 | 
			
		||||
@ -3074,10 +3090,7 @@ for test in method_tests:
 | 
			
		||||
                if hasattr(torch, name) and name not in EXCLUDE_FUNCTIONAL:
 | 
			
		||||
                    def fn(*inputs):
 | 
			
		||||
                        output = getattr(torch, name)(*inputs)
 | 
			
		||||
                        if test_output_indices is None:
 | 
			
		||||
                            return output
 | 
			
		||||
                        else:
 | 
			
		||||
                            return tuple(output[i] for i in test_output_indices)
 | 
			
		||||
                        return output_process_fn(output)
 | 
			
		||||
 | 
			
		||||
                    f_args_variable = (self_variable,) + args_variable
 | 
			
		||||
                    f_args_tensor = (self_tensor,) + args_tensor
 | 
			
		||||
 | 
			
		||||
@ -1370,22 +1370,11 @@ class TestCuda(TestCase):
 | 
			
		||||
            # test setitem
 | 
			
		||||
            x_clone1 = x.clone()
 | 
			
		||||
            x_clone2 = x.clone()
 | 
			
		||||
            x_clone3 = x.clone()
 | 
			
		||||
            first_shape = x[:, ia, None, ib, 0].shape
 | 
			
		||||
            second_shape = x[ia].shape
 | 
			
		||||
            x_clone1[:, ia, None, ib, 0] = torch.randn(first_shape).to(x_clone1)
 | 
			
		||||
            x_clone2[ia] = torch.randn(second_shape).to(x_clone2)
 | 
			
		||||
 | 
			
		||||
            # fill equivalents
 | 
			
		||||
            x_clone1[:, ia, None, ib, 0] = 5
 | 
			
		||||
            x_clone2[ia] = 7
 | 
			
		||||
 | 
			
		||||
            # mask equivalents
 | 
			
		||||
            mask = (torch.randn(x_clone3.size()) < 0).to(ia.device)
 | 
			
		||||
            x_clone3[mask]
 | 
			
		||||
            self.assertEqual(x_clone3[mask].cpu(), x_clone3.cpu()[mask.cpu()])
 | 
			
		||||
            x_clone3[mask] = 6
 | 
			
		||||
 | 
			
		||||
        cpu = torch.device('cpu')
 | 
			
		||||
        for device in ['cuda:0', 'cuda:1'] if torch.cuda.device_count() > 1 else ['cuda']:
 | 
			
		||||
            # Index cpu tensor with cuda tensor
 | 
			
		||||
 | 
			
		||||
@ -1746,6 +1746,35 @@ class TestDistributions(TestCase):
 | 
			
		||||
            x = Beta(Tensor([1e-6]), Tensor([1e-6])).sample()[0]
 | 
			
		||||
            self.assertTrue(np.isfinite(x) and x > 0, 'Invalid Beta.sample(): {}'.format(x))
 | 
			
		||||
 | 
			
		||||
    def test_independent_shape(self):
 | 
			
		||||
        for Dist, params in EXAMPLES:
 | 
			
		||||
            for i, param in enumerate(params):
 | 
			
		||||
                base_dist = Dist(**param)
 | 
			
		||||
                x = base_dist.sample()
 | 
			
		||||
                base_log_prob_shape = base_dist.log_prob(x).shape
 | 
			
		||||
                for reinterpreted_batch_ndims in range(len(base_dist.batch_shape) + 1):
 | 
			
		||||
                    indep_dist = Independent(base_dist, reinterpreted_batch_ndims)
 | 
			
		||||
                    indep_log_prob_shape = base_log_prob_shape[:len(base_log_prob_shape) - reinterpreted_batch_ndims]
 | 
			
		||||
                    self.assertEqual(indep_dist.log_prob(x).shape, indep_log_prob_shape)
 | 
			
		||||
                    self.assertEqual(indep_dist.sample().shape, base_dist.sample().shape)
 | 
			
		||||
                    self.assertEqual(indep_dist.has_rsample, base_dist.has_rsample)
 | 
			
		||||
                    if indep_dist.has_rsample:
 | 
			
		||||
                        self.assertEqual(indep_dist.sample().shape, base_dist.sample().shape)
 | 
			
		||||
                    if indep_dist.has_enumerate_support:
 | 
			
		||||
                        self.assertEqual(indep_dist.enumerate_support().shape, base_dist.enumerate_support().shape)
 | 
			
		||||
                    try:
 | 
			
		||||
                        self.assertEqual(indep_dist.mean.shape, base_dist.mean.shape)
 | 
			
		||||
                    except NotImplementedError:
 | 
			
		||||
                        pass
 | 
			
		||||
                    try:
 | 
			
		||||
                        self.assertEqual(indep_dist.variance.shape, base_dist.variance.shape)
 | 
			
		||||
                    except NotImplementedError:
 | 
			
		||||
                        pass
 | 
			
		||||
                    try:
 | 
			
		||||
                        self.assertEqual(indep_dist.entropy().shape, indep_log_prob_shape)
 | 
			
		||||
                    except NotImplementedError:
 | 
			
		||||
                        pass
 | 
			
		||||
 | 
			
		||||
    def test_cdf_icdf_inverse(self):
 | 
			
		||||
        # Tests the invertibility property on the distributions
 | 
			
		||||
        for Dist, params in EXAMPLES:
 | 
			
		||||
 | 
			
		||||
@ -254,32 +254,6 @@ class TestIndexing(TestCase):
 | 
			
		||||
            self.assertEqual(x, x[0])
 | 
			
		||||
            self.assertEqual(len(w), 1)
 | 
			
		||||
 | 
			
		||||
    def test_legacy_dispatch(self):
 | 
			
		||||
        # compare with indexing using index_select / index_fill etc
 | 
			
		||||
        x = torch.arange(0, 9).view(3, 3)
 | 
			
		||||
        idx = torch.tensor([0, 2])
 | 
			
		||||
        self.assertEqual(x[idx], x.index_select(0, idx))
 | 
			
		||||
        self.assertEqual(x[:, idx], x.index_select(1, idx))
 | 
			
		||||
 | 
			
		||||
        mask = x > 4
 | 
			
		||||
        self.assertEqual(x[mask], x.masked_select(mask))
 | 
			
		||||
 | 
			
		||||
        y = x.clone()
 | 
			
		||||
        yr = x.clone()
 | 
			
		||||
        y[idx] = 0
 | 
			
		||||
        yr.index_fill_(0, idx, 0)
 | 
			
		||||
        self.assertEqual(y, yr)
 | 
			
		||||
        y[:, idx] = 2
 | 
			
		||||
        yr.index_fill_(1, idx, 2)
 | 
			
		||||
        self.assertEqual(y, yr)
 | 
			
		||||
 | 
			
		||||
        mask = x > 4
 | 
			
		||||
        y = x.clone()
 | 
			
		||||
        yr = x.clone()
 | 
			
		||||
        y[mask] = 10
 | 
			
		||||
        yr.masked_fill_(mask, 10)
 | 
			
		||||
        self.assertEqual(y, yr)
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
# The tests below are from NumPy test_indexing.py with some modifications to
 | 
			
		||||
# make them compatible with PyTorch. It's licensed under the BDS license below:
 | 
			
		||||
 | 
			
		||||
@ -121,17 +121,16 @@ class TestJit(TestCase):
 | 
			
		||||
    # index-2 is not implemented in interpreter
 | 
			
		||||
    @unittest.expectedFailure
 | 
			
		||||
    def test_index(self):
 | 
			
		||||
        x = Variable(torch.rand(2, 2, 2), requires_grad=True)
 | 
			
		||||
        x = Variable(torch.Tensor([0.4]), requires_grad=True)
 | 
			
		||||
        y = Variable(torch.LongTensor([0]), requires_grad=True)
 | 
			
		||||
        y2 = Variable(torch.LongTensor([1]), requires_grad=True)
 | 
			
		||||
 | 
			
		||||
        @torch.jit.compile(nderivs=0)
 | 
			
		||||
        def fn(x, y, y2):
 | 
			
		||||
            return x[y, y2]
 | 
			
		||||
        def fn(x, y):
 | 
			
		||||
            return x[y]
 | 
			
		||||
 | 
			
		||||
        z = fn(x, y, y2)
 | 
			
		||||
        z = fn(x, y)
 | 
			
		||||
        with self.assertCompiled(fn):
 | 
			
		||||
            z2 = fn(x, y, y2)
 | 
			
		||||
            z2 = fn(x, y)
 | 
			
		||||
        self.assertEqual(z, z2)
 | 
			
		||||
 | 
			
		||||
    # Backwards tracing was broken for indexing by a constant,
 | 
			
		||||
 | 
			
		||||
@ -859,20 +859,26 @@ Tensor svd_backward(const std::vector<torch::autograd::Variable> &grads, const T
 | 
			
		||||
  auto m = self.size(0);
 | 
			
		||||
  auto n = self.size(1);
 | 
			
		||||
  auto k = sigma.size(0);
 | 
			
		||||
  auto gsigma = grads[1];
 | 
			
		||||
 | 
			
		||||
  auto u = raw_u;
 | 
			
		||||
  auto v = raw_v;
 | 
			
		||||
  auto gu = grads[0];
 | 
			
		||||
  auto gv = grads[2];
 | 
			
		||||
 | 
			
		||||
  Tensor u, v;
 | 
			
		||||
  if (!some) {
 | 
			
		||||
    // ignore the free subspace
 | 
			
		||||
    // We ignore the free subspace here because possible base vectors cancel
 | 
			
		||||
    // each other, e.g., both -v and +v are valid base for a dimension.
 | 
			
		||||
    // Don't assume behavior of any particular implementation of svd.
 | 
			
		||||
    u = raw_u.narrow(1, 0, k);
 | 
			
		||||
    v = raw_v.narrow(1, 0, k);
 | 
			
		||||
  } else {
 | 
			
		||||
    u = raw_u;
 | 
			
		||||
    v = raw_v;
 | 
			
		||||
    if (gu.defined()) {
 | 
			
		||||
      gu = gu.narrow(1, 0, k);
 | 
			
		||||
    }
 | 
			
		||||
    if (gv.defined()) {
 | 
			
		||||
      gv = gv.narrow(1, 0, k);
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  auto gu = grads[0];
 | 
			
		||||
  auto gsigma = grads[1];
 | 
			
		||||
  auto gv = grads[2];
 | 
			
		||||
  auto vt = v.t();
 | 
			
		||||
 | 
			
		||||
  Tensor sigma_term;
 | 
			
		||||
 | 
			
		||||
@ -284,12 +284,4 @@ if [ -d "$INSTALL_DIR/bin/" ]; then
 | 
			
		||||
    cp "$INSTALL_DIR/bin/"/* .
 | 
			
		||||
fi
 | 
			
		||||
 | 
			
		||||
# this is for binary builds
 | 
			
		||||
if [[ $PYTORCH_BINARY_BUILD && $PYTORCH_SO_DEPS ]]
 | 
			
		||||
then
 | 
			
		||||
    echo "Copying over dependency libraries $PYTORCH_SO_DEPS"
 | 
			
		||||
    # copy over dependency libraries into the current dir
 | 
			
		||||
    cp "$PYTORCH_SO_DEPS" .
 | 
			
		||||
fi
 | 
			
		||||
 | 
			
		||||
popd
 | 
			
		||||
 | 
			
		||||
@ -129,21 +129,22 @@ def is_storage(obj):
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
def set_default_tensor_type(t):
 | 
			
		||||
    r"""Sets the default ``torch.Tensor`` type to type :attr:`t`.
 | 
			
		||||
    r"""Sets the default ``torch.Tensor`` type to floating point tensor type
 | 
			
		||||
    :attr:`t`. This type will also be used as default floating point type for
 | 
			
		||||
    type inference in :func:`torch.tensor`.
 | 
			
		||||
 | 
			
		||||
    The default tensor type is initially ``"torch.FloatTensor"``.
 | 
			
		||||
    The default floating point tensor type is initially ``torch.FloatTensor``.
 | 
			
		||||
 | 
			
		||||
    Args:
 | 
			
		||||
        t (type or string): the tensor type or its name
 | 
			
		||||
        t (type or string): the floating point tensor type or its name
 | 
			
		||||
 | 
			
		||||
    Example::
 | 
			
		||||
 | 
			
		||||
        >>> torch.set_default_tensor_type("torch.FloatTensor")
 | 
			
		||||
        >>> torch.Tensor([1.2, 3])
 | 
			
		||||
 | 
			
		||||
         1.2000
 | 
			
		||||
         3.0000
 | 
			
		||||
        [torch.FloatTensor of size (2,)]
 | 
			
		||||
        >>> torch.tensor([1.2, 3]).dtype    # initial default for floating point is torch.float32
 | 
			
		||||
        torch.float32
 | 
			
		||||
        >>> torch.set_default_tensor_type(torch.DoubleTensor)
 | 
			
		||||
        >>> torch.tensor([1.2, 3]).dtype    # a new floating point tensor
 | 
			
		||||
        torch.float64
 | 
			
		||||
 | 
			
		||||
    """
 | 
			
		||||
    if isinstance(t, _string_classes):
 | 
			
		||||
@ -152,19 +153,22 @@ def set_default_tensor_type(t):
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
def set_default_dtype(d):
 | 
			
		||||
    r"""Sets the default ``torch.dtype`` type to type :attr:`d`.
 | 
			
		||||
    r"""Sets the default floating point dtype to :attr:`d`. This type will be
 | 
			
		||||
    used as default floating point type for type inference in
 | 
			
		||||
    :func:`torch.tensor`.
 | 
			
		||||
 | 
			
		||||
    The default floating point dtype is initially ``torch.float32``.
 | 
			
		||||
 | 
			
		||||
    Args:
 | 
			
		||||
        d (dtype): the dtype to make the default
 | 
			
		||||
        d (:class:`torch.dtype`): the floating point dtype to make the default
 | 
			
		||||
 | 
			
		||||
    Example::
 | 
			
		||||
 | 
			
		||||
        >>> torch.set_default_tensor_type(torch.double)
 | 
			
		||||
        >>> torch.tensor([1.2, 3], device='cpu')
 | 
			
		||||
 | 
			
		||||
         1.2000
 | 
			
		||||
         3.0000
 | 
			
		||||
        [torch.DoubleTensor of size (2,)]
 | 
			
		||||
        >>> torch.tensor([1.2, 3]).dtype           # initial default for floating point is torch.float32
 | 
			
		||||
        torch.float32
 | 
			
		||||
        >>> torch.set_default_dtype(torch.float64)
 | 
			
		||||
        >>> torch.tensor([1.2, 3]).dtype           # a new floating point tensor
 | 
			
		||||
        torch.float64
 | 
			
		||||
 | 
			
		||||
    """
 | 
			
		||||
    _C._set_default_dtype(d)
 | 
			
		||||
 | 
			
		||||
@ -2,11 +2,148 @@
 | 
			
		||||
 | 
			
		||||
import torch._C
 | 
			
		||||
from torch._C import _add_docstr as add_docstr
 | 
			
		||||
from ._torch_docs import parse_kwargs
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
def add_docstr_all(method, docstr):
 | 
			
		||||
    add_docstr(getattr(torch._C._TensorBase, method), docstr)
 | 
			
		||||
 | 
			
		||||
new_common_args = parse_kwargs("""
 | 
			
		||||
    size (int...): a list, tuple, or :class:`torch.Size` of integers defining the
 | 
			
		||||
        shape of the output tensor.
 | 
			
		||||
    dtype (:class:`torch.dtype`, optional): the desired type of returned tensor.
 | 
			
		||||
        Default: if None, same :class:`torch.dtype` as this tensor.
 | 
			
		||||
    device (:class:`torch.device`, optional): the desired device of returned tensor.
 | 
			
		||||
        Default: if None, same :class:`torch.device` as this tensor.
 | 
			
		||||
    requires_grad (bool, optional): If autograd should record operations on the
 | 
			
		||||
        returned tensor. Default: ``False``.
 | 
			
		||||
""")
 | 
			
		||||
 | 
			
		||||
add_docstr_all('new_tensor',
 | 
			
		||||
               r"""
 | 
			
		||||
new_tensor(data, dtype=None, device=None, requires_grad=False) -> Tensor
 | 
			
		||||
 | 
			
		||||
Returns a new Tensor with :attr:`data` as the tensor data.
 | 
			
		||||
By default, the returned Tensor has the same :class:`torch.dtype` and
 | 
			
		||||
:class:`torch.device` as this tensor.
 | 
			
		||||
 | 
			
		||||
.. warning::
 | 
			
		||||
 | 
			
		||||
    :func:`new_tensor` always copies :attr:`data`. If you have a Tensor
 | 
			
		||||
    ``data`` and want to avoid a copy, use :func:`torch.Tensor.requires_grad_`
 | 
			
		||||
    or :func:`torch.Tensor.detach`.
 | 
			
		||||
    If you have a numpy array and want to avoid a copy, use
 | 
			
		||||
    :func:`torch.from_numpy`.
 | 
			
		||||
 | 
			
		||||
Args:
 | 
			
		||||
    data (array_like): The returned Tensor copies :attr:`data`.
 | 
			
		||||
    {dtype}
 | 
			
		||||
    {device}
 | 
			
		||||
    {requires_grad}
 | 
			
		||||
 | 
			
		||||
Example::
 | 
			
		||||
 | 
			
		||||
    >>> tensor = torch.ones((2,), dtype=torch.int8)
 | 
			
		||||
    >>> data = [[0, 1], [2, 3]]
 | 
			
		||||
    >>> tensor.new_tensor(data)
 | 
			
		||||
    tensor([[ 0,  1],
 | 
			
		||||
            [ 2,  3]], dtype=torch.int8)
 | 
			
		||||
 | 
			
		||||
""".format(**new_common_args))
 | 
			
		||||
 | 
			
		||||
add_docstr_all('new_full',
 | 
			
		||||
               r"""
 | 
			
		||||
new_full(size, fill_value, dtype=None, device=None, requires_grad=False) -> Tensor
 | 
			
		||||
 | 
			
		||||
Returns a Tensor of size :attr:`size` filled with :attr:`fill_value`.
 | 
			
		||||
By default, the returned Tensor has the same :class:`torch.dtype` and
 | 
			
		||||
:class:`torch.device` as this tensor.
 | 
			
		||||
 | 
			
		||||
Args:
 | 
			
		||||
    fill_value (scalar): the number to fill the output tensor with.
 | 
			
		||||
    {dtype}
 | 
			
		||||
    {device}
 | 
			
		||||
    {requires_grad}
 | 
			
		||||
 | 
			
		||||
Example::
 | 
			
		||||
 | 
			
		||||
    >>> tensor = torch.ones((2,), dtype=torch.float64)
 | 
			
		||||
    >>> tensor.new_full((3, 4), 3.141592)
 | 
			
		||||
    tensor([[ 3.1416,  3.1416,  3.1416,  3.1416],
 | 
			
		||||
            [ 3.1416,  3.1416,  3.1416,  3.1416],
 | 
			
		||||
            [ 3.1416,  3.1416,  3.1416,  3.1416]], dtype=torch.float64)
 | 
			
		||||
 | 
			
		||||
""".format(**new_common_args))
 | 
			
		||||
 | 
			
		||||
add_docstr_all('new_empty',
 | 
			
		||||
               r"""
 | 
			
		||||
new_empty(size, dtype=None, device=None, requires_grad=False) -> Tensor
 | 
			
		||||
 | 
			
		||||
Returns a Tensor of size :attr:`size` filled with uninitialized data.
 | 
			
		||||
By default, the returned Tensor has the same :class:`torch.dtype` and
 | 
			
		||||
:class:`torch.device` as this tensor.
 | 
			
		||||
 | 
			
		||||
Args:
 | 
			
		||||
    {dtype}
 | 
			
		||||
    {device}
 | 
			
		||||
    {requires_grad}
 | 
			
		||||
 | 
			
		||||
Example::
 | 
			
		||||
 | 
			
		||||
    >>> tensor = torch.ones(())
 | 
			
		||||
    >>> tensor.new_empty((2, 3))
 | 
			
		||||
    tensor([[ 5.8182e-18,  4.5765e-41, -1.0545e+30],
 | 
			
		||||
            [ 3.0949e-41,  4.4842e-44,  0.0000e+00]])
 | 
			
		||||
 | 
			
		||||
""".format(**new_common_args))
 | 
			
		||||
 | 
			
		||||
add_docstr_all('new_ones',
 | 
			
		||||
               r"""
 | 
			
		||||
new_ones(size, dtype=None, device=None, requires_grad=False) -> Tensor
 | 
			
		||||
 | 
			
		||||
Returns a Tensor of size :attr:`size` filled with ``1``.
 | 
			
		||||
By default, the returned Tensor has the same :class:`torch.dtype` and
 | 
			
		||||
:class:`torch.device` as this tensor.
 | 
			
		||||
 | 
			
		||||
Args:
 | 
			
		||||
    size (int...): a list, tuple, or :class:`torch.Size` of integers defining the
 | 
			
		||||
        shape of the output tensor.
 | 
			
		||||
    {dtype}
 | 
			
		||||
    {device}
 | 
			
		||||
    {requires_grad}
 | 
			
		||||
 | 
			
		||||
Example::
 | 
			
		||||
 | 
			
		||||
    >>> tensor = torch.tensor((), dtype=torch.int32)
 | 
			
		||||
    >>> tensor.new_ones((2, 3))
 | 
			
		||||
    tensor([[ 1,  1,  1],
 | 
			
		||||
            [ 1,  1,  1]], dtype=torch.int32)
 | 
			
		||||
 | 
			
		||||
""".format(**new_common_args))
 | 
			
		||||
 | 
			
		||||
add_docstr_all('new_zeros',
 | 
			
		||||
               r"""
 | 
			
		||||
new_zeros(size, dtype=None, device=None, requires_grad=False) -> Tensor
 | 
			
		||||
 | 
			
		||||
Returns a Tensor of size :attr:`size` filled with ``0``.
 | 
			
		||||
By default, the returned Tensor has the same :class:`torch.dtype` and
 | 
			
		||||
:class:`torch.device` as this tensor.
 | 
			
		||||
 | 
			
		||||
Args:
 | 
			
		||||
    size (int...): a list, tuple, or :class:`torch.Size` of integers defining the
 | 
			
		||||
        shape of the output tensor.
 | 
			
		||||
    {dtype}
 | 
			
		||||
    {device}
 | 
			
		||||
    {requires_grad}
 | 
			
		||||
 | 
			
		||||
Example::
 | 
			
		||||
 | 
			
		||||
    >>> tensor = torch.tensor((), dtype=torch.float64)
 | 
			
		||||
    >>> tensor.new_ones((2, 3))
 | 
			
		||||
    tensor([[ 1.,  1.,  1.],
 | 
			
		||||
            [ 1.,  1.,  1.]], dtype=torch.float64)
 | 
			
		||||
 | 
			
		||||
""".format(**new_common_args))
 | 
			
		||||
 | 
			
		||||
add_docstr_all('abs',
 | 
			
		||||
               r"""
 | 
			
		||||
@ -448,9 +585,9 @@ Returns the size in bytes of an individual element.
 | 
			
		||||
 | 
			
		||||
Example::
 | 
			
		||||
 | 
			
		||||
    >>> torch.FloatTensor().element_size()
 | 
			
		||||
    >>> torch.tensor([]).element_size()
 | 
			
		||||
    4
 | 
			
		||||
    >>> torch.ByteTensor().element_size()
 | 
			
		||||
    >>> torch.tensor([], dtype=torch.uint8).element_size()
 | 
			
		||||
    1
 | 
			
		||||
 | 
			
		||||
""")
 | 
			
		||||
@ -691,19 +828,15 @@ Args:
 | 
			
		||||
 | 
			
		||||
Example::
 | 
			
		||||
 | 
			
		||||
    >>> x = torch.Tensor(5, 3).fill_(1)
 | 
			
		||||
    >>> t = torch.Tensor([[1, 2, 3], [4, 5, 6], [7, 8, 9]])
 | 
			
		||||
    >>> index = torch.LongTensor([0, 4, 2])
 | 
			
		||||
    >>> x = torch.ones(5, 3)
 | 
			
		||||
    >>> t = torch.tensor([[1, 2, 3], [4, 5, 6], [7, 8, 9]], dtype=torch.float)
 | 
			
		||||
    >>> index = torch.tensor([0, 4, 2])
 | 
			
		||||
    >>> x.index_add_(0, index, t)
 | 
			
		||||
    >>> x
 | 
			
		||||
 | 
			
		||||
      2   3   4
 | 
			
		||||
      1   1   1
 | 
			
		||||
      8   9  10
 | 
			
		||||
      1   1   1
 | 
			
		||||
      5   6   7
 | 
			
		||||
    [torch.FloatTensor of size (5,3)]
 | 
			
		||||
 | 
			
		||||
    tensor([[  2.,   3.,   4.],
 | 
			
		||||
            [  1.,   1.,   1.],
 | 
			
		||||
            [  8.,   9.,  10.],
 | 
			
		||||
            [  1.,   1.,   1.],
 | 
			
		||||
            [  5.,   6.,   7.]])
 | 
			
		||||
""")
 | 
			
		||||
 | 
			
		||||
add_docstr_all('index_copy_',
 | 
			
		||||
@ -727,18 +860,14 @@ Args:
 | 
			
		||||
Example::
 | 
			
		||||
 | 
			
		||||
    >>> x = torch.zeros(5, 3)
 | 
			
		||||
    >>> t = torch.Tensor([[1, 2, 3], [4, 5, 6], [7, 8, 9]])
 | 
			
		||||
    >>> index = torch.LongTensor([0, 4, 2])
 | 
			
		||||
    >>> t = torch.tensor([[1, 2, 3], [4, 5, 6], [7, 8, 9]], dtype=torch.float)
 | 
			
		||||
    >>> index = torch.tensor([0, 4, 2])
 | 
			
		||||
    >>> x.index_copy_(0, index, t)
 | 
			
		||||
    >>> x
 | 
			
		||||
 | 
			
		||||
     1  2  3
 | 
			
		||||
     0  0  0
 | 
			
		||||
     7  8  9
 | 
			
		||||
     0  0  0
 | 
			
		||||
     4  5  6
 | 
			
		||||
    [torch.FloatTensor of size (5,3)]
 | 
			
		||||
 | 
			
		||||
    tensor([[ 1.,  2.,  3.],
 | 
			
		||||
            [ 0.,  0.,  0.],
 | 
			
		||||
            [ 7.,  8.,  9.],
 | 
			
		||||
            [ 0.,  0.,  0.],
 | 
			
		||||
            [ 4.,  5.,  6.]])
 | 
			
		||||
""")
 | 
			
		||||
 | 
			
		||||
add_docstr_all('index_fill_',
 | 
			
		||||
@ -754,16 +883,12 @@ Args:
 | 
			
		||||
    val (float): the value to fill with
 | 
			
		||||
 | 
			
		||||
Example::
 | 
			
		||||
    >>> x = torch.Tensor([[1, 2, 3], [4, 5, 6], [7, 8, 9]])
 | 
			
		||||
    >>> index = torch.LongTensor([0, 2])
 | 
			
		||||
    >>> x = torch.tensor([[1, 2, 3], [4, 5, 6], [7, 8, 9]], dtype=torch.float)
 | 
			
		||||
    >>> index = torch.tensor([0, 2])
 | 
			
		||||
    >>> x.index_fill_(1, index, -1)
 | 
			
		||||
    >>> x
 | 
			
		||||
 | 
			
		||||
    -1  2 -1
 | 
			
		||||
    -1  5 -1
 | 
			
		||||
    -1  8 -1
 | 
			
		||||
    [torch.FloatTensor of size (3,3)]
 | 
			
		||||
 | 
			
		||||
    tensor([[-1.,  2., -1.],
 | 
			
		||||
            [-1.,  5., -1.],
 | 
			
		||||
            [-1.,  8., -1.]])
 | 
			
		||||
""")
 | 
			
		||||
 | 
			
		||||
add_docstr_all('index_put_',
 | 
			
		||||
@ -819,7 +944,7 @@ This operation is not differentiable.
 | 
			
		||||
 | 
			
		||||
Example::
 | 
			
		||||
 | 
			
		||||
    >>> x = torch.Tensor([1.0])
 | 
			
		||||
    >>> x = torch.tensor([1.0])
 | 
			
		||||
    >>> x.item()
 | 
			
		||||
    1.0
 | 
			
		||||
 | 
			
		||||
@ -1081,20 +1206,14 @@ Args:
 | 
			
		||||
 | 
			
		||||
Example::
 | 
			
		||||
 | 
			
		||||
    >>> x = torch.Tensor([[1, 2, 3], [4, 5, 6], [7, 8, 9]])
 | 
			
		||||
    >>> x = torch.tensor([[1, 2, 3], [4, 5, 6], [7, 8, 9]])
 | 
			
		||||
    >>> x.narrow(0, 0, 2)
 | 
			
		||||
 | 
			
		||||
     1  2  3
 | 
			
		||||
     4  5  6
 | 
			
		||||
    [torch.FloatTensor of size (2,3)]
 | 
			
		||||
 | 
			
		||||
    tensor([[ 1,  2,  3],
 | 
			
		||||
            [ 4,  5,  6]])
 | 
			
		||||
    >>> x.narrow(1, 1, 2)
 | 
			
		||||
 | 
			
		||||
     2  3
 | 
			
		||||
     5  6
 | 
			
		||||
     8  9
 | 
			
		||||
    [torch.FloatTensor of size (3,2)]
 | 
			
		||||
 | 
			
		||||
    tensor([[ 2,  3],
 | 
			
		||||
            [ 5,  6],
 | 
			
		||||
            [ 8,  9]])
 | 
			
		||||
""")
 | 
			
		||||
 | 
			
		||||
add_docstr_all('ndimension',
 | 
			
		||||
@ -1259,13 +1378,11 @@ Args:
 | 
			
		||||
 | 
			
		||||
Example::
 | 
			
		||||
 | 
			
		||||
    >>> src = torch.Tensor([[4, 3, 5],
 | 
			
		||||
    >>> src = torch.tensor([[4, 3, 5],
 | 
			
		||||
                            [6, 7, 8]])
 | 
			
		||||
    >>> src.put_(torch.LongTensor([1, 3]), torch.Tensor([9, 10]))
 | 
			
		||||
 | 
			
		||||
      4   9   5
 | 
			
		||||
     10   7   8
 | 
			
		||||
    [torch.FloatTensor of size (2,3)]
 | 
			
		||||
    >>> src.put_(torch.tensor([1, 3]), torch.tensor([9, 10]))
 | 
			
		||||
    tensor([[  4,   9,   5],
 | 
			
		||||
            [ 10,   7,   8]])
 | 
			
		||||
""")
 | 
			
		||||
 | 
			
		||||
add_docstr_all('qr',
 | 
			
		||||
@ -1283,8 +1400,8 @@ Fills :attr:`self` tensor with numbers sampled from the discrete uniform
 | 
			
		||||
distribution over ``[from, to - 1]``. If not specified, the values are usually
 | 
			
		||||
only bounded by :attr:`self` tensor's data type. However, for floating point
 | 
			
		||||
types, if unspecified, range will be ``[0, 2^mantissa]`` to ensure that every
 | 
			
		||||
value is representable. For example, `torch.DoubleTensor(1).random_()` will be
 | 
			
		||||
uniform in ``[0, 2^53]``.
 | 
			
		||||
value is representable. For example, `torch.tensor(1, dtype=torch.double).random_()`
 | 
			
		||||
will be uniform in ``[0, 2^53]``.
 | 
			
		||||
""")
 | 
			
		||||
 | 
			
		||||
add_docstr_all('reciprocal',
 | 
			
		||||
@ -1343,18 +1460,49 @@ Args:
 | 
			
		||||
 | 
			
		||||
Example::
 | 
			
		||||
 | 
			
		||||
    >>> x = torch.Tensor([1, 2, 3])
 | 
			
		||||
    >>> x = torch.tensor([1, 2, 3])
 | 
			
		||||
    >>> x.repeat(4, 2)
 | 
			
		||||
 | 
			
		||||
     1  2  3  1  2  3
 | 
			
		||||
     1  2  3  1  2  3
 | 
			
		||||
     1  2  3  1  2  3
 | 
			
		||||
     1  2  3  1  2  3
 | 
			
		||||
    [torch.FloatTensor of size (4,6)]
 | 
			
		||||
 | 
			
		||||
    tensor([[ 1,  2,  3,  1,  2,  3],
 | 
			
		||||
            [ 1,  2,  3,  1,  2,  3],
 | 
			
		||||
            [ 1,  2,  3,  1,  2,  3],
 | 
			
		||||
            [ 1,  2,  3,  1,  2,  3]])
 | 
			
		||||
    >>> x.repeat(4, 2, 1).size()
 | 
			
		||||
 | 
			
		||||
    torch.Size([4, 2, 3])
 | 
			
		||||
""")
 | 
			
		||||
 | 
			
		||||
add_docstr_all('requires_grad_',
 | 
			
		||||
               r"""
 | 
			
		||||
requires_grad_(requires_grad=True) -> Tensor
 | 
			
		||||
 | 
			
		||||
Change if autograd should record operations on this tensor: sets this tensor's
 | 
			
		||||
:attr:`requires_grad` attribute in-place. Returns this tensor.
 | 
			
		||||
 | 
			
		||||
:func:`require_grad_`'s main use case is to tell autograd to begin recording
 | 
			
		||||
operations on a Tensor ``tensor``. If ``tensor`` has ``requires_grad=False``
 | 
			
		||||
(because it was obtained through a DataLoader, or required preprocessing or
 | 
			
		||||
initialization), ``tensor.requires_grad_()`` makes it so that autograd will
 | 
			
		||||
begin to record operations on ``tensor``.
 | 
			
		||||
 | 
			
		||||
Args:
 | 
			
		||||
    requires_grad (bool): If autograd should record operations on this tensor.
 | 
			
		||||
        Default: ``True``.
 | 
			
		||||
 | 
			
		||||
Example::
 | 
			
		||||
 | 
			
		||||
    >>> # Let's say we want to preprocess some saved weights and use
 | 
			
		||||
    >>> # the result as new weights.
 | 
			
		||||
    >>> saved_weights = [0.1, 0.2, 0.3, 0.25]
 | 
			
		||||
    >>> loaded_weights = torch.tensor(saved_weights)
 | 
			
		||||
    >>> weights = preprocess(loaded_weights)  # some function
 | 
			
		||||
    >>> weights
 | 
			
		||||
    tensor([-0.5503,  0.4926, -2.1158, -0.8303])
 | 
			
		||||
 | 
			
		||||
    >>> # Now, start to record operations done to weights
 | 
			
		||||
    >>> weights.requires_grad_()
 | 
			
		||||
    >>> out = weights.pow(2).sum()
 | 
			
		||||
    >>> out.backward()
 | 
			
		||||
    >>> weights.grad
 | 
			
		||||
    tensor([-1.1007,  0.9853, -4.2316, -1.6606])
 | 
			
		||||
 | 
			
		||||
""")
 | 
			
		||||
 | 
			
		||||
@ -1386,14 +1534,10 @@ Args:
 | 
			
		||||
 | 
			
		||||
Example::
 | 
			
		||||
 | 
			
		||||
    >>> x = torch.Tensor([[1, 2], [3, 4], [5, 6]])
 | 
			
		||||
    >>> x = torch.tensor([[1, 2], [3, 4], [5, 6]])
 | 
			
		||||
    >>> x.resize_(2, 2)
 | 
			
		||||
    >>> x
 | 
			
		||||
 | 
			
		||||
     1  2
 | 
			
		||||
     3  4
 | 
			
		||||
    [torch.FloatTensor of size (2,2)]
 | 
			
		||||
 | 
			
		||||
    tensor([[ 1,  2],
 | 
			
		||||
            [ 3,  4]])
 | 
			
		||||
""")
 | 
			
		||||
 | 
			
		||||
add_docstr_all('resize_as_',
 | 
			
		||||
@ -1468,25 +1612,17 @@ Example::
 | 
			
		||||
 | 
			
		||||
    >>> x = torch.rand(2, 5)
 | 
			
		||||
    >>> x
 | 
			
		||||
    tensor([[ 0.3992,  0.2908,  0.9044,  0.4850,  0.6004],
 | 
			
		||||
            [ 0.5735,  0.9006,  0.6797,  0.4152,  0.1732]])
 | 
			
		||||
    >>> torch.zeros(3, 5).scatter_(0, torch.tensor([[0, 1, 2, 0, 0], [2, 0, 0, 1, 2]]), x)
 | 
			
		||||
    tensor([[ 0.3992,  0.9006,  0.6797,  0.4850,  0.6004],
 | 
			
		||||
            [ 0.0000,  0.2908,  0.0000,  0.4152,  0.0000],
 | 
			
		||||
            [ 0.5735,  0.0000,  0.9044,  0.0000,  0.1732]])
 | 
			
		||||
 | 
			
		||||
     0.4319  0.6500  0.4080  0.8760  0.2355
 | 
			
		||||
     0.2609  0.4711  0.8486  0.8573  0.1029
 | 
			
		||||
    [torch.FloatTensor of size (2,5)]
 | 
			
		||||
 | 
			
		||||
    >>> torch.zeros(3, 5).scatter_(0, torch.LongTensor([[0, 1, 2, 0, 0], [2, 0, 0, 1, 2]]), x)
 | 
			
		||||
 | 
			
		||||
     0.4319  0.4711  0.8486  0.8760  0.2355
 | 
			
		||||
     0.0000  0.6500  0.0000  0.8573  0.0000
 | 
			
		||||
     0.2609  0.0000  0.4080  0.0000  0.1029
 | 
			
		||||
    [torch.FloatTensor of size (3,5)]
 | 
			
		||||
 | 
			
		||||
    >>> z = torch.zeros(2, 4).scatter_(1, torch.LongTensor([[2], [3]]), 1.23)
 | 
			
		||||
    >>> z = torch.zeros(2, 4).scatter_(1, torch.tensor([[2], [3]]), 1.23)
 | 
			
		||||
    >>> z
 | 
			
		||||
 | 
			
		||||
     0.0000  0.0000  1.2300  0.0000
 | 
			
		||||
     0.0000  0.0000  0.0000  1.2300
 | 
			
		||||
    [torch.FloatTensor of size (2,4)]
 | 
			
		||||
 | 
			
		||||
    tensor([[ 0.0000,  0.0000,  1.2300,  0.0000],
 | 
			
		||||
            [ 0.0000,  0.0000,  0.0000,  1.2300]])
 | 
			
		||||
""")
 | 
			
		||||
 | 
			
		||||
add_docstr_all('select',
 | 
			
		||||
@ -1591,7 +1727,7 @@ Returns the size of the :attr:`self` tensor. The returned value is a subclass of
 | 
			
		||||
 | 
			
		||||
Example::
 | 
			
		||||
 | 
			
		||||
    >>> torch.Tensor(3, 4, 5).size()
 | 
			
		||||
    >>> torch.empty(3, 4, 5).size()
 | 
			
		||||
    torch.Size([3, 4, 5])
 | 
			
		||||
 | 
			
		||||
""")
 | 
			
		||||
@ -1654,7 +1790,7 @@ number of storage elements (not bytes).
 | 
			
		||||
 | 
			
		||||
Example::
 | 
			
		||||
 | 
			
		||||
    >>> x = torch.Tensor([1, 2, 3, 4, 5])
 | 
			
		||||
    >>> x = torch.tensor([1, 2, 3, 4, 5])
 | 
			
		||||
    >>> x.storage_offset()
 | 
			
		||||
    0
 | 
			
		||||
    >>> x[3:].storage_offset()
 | 
			
		||||
@ -1678,7 +1814,7 @@ Args:
 | 
			
		||||
 | 
			
		||||
Example::
 | 
			
		||||
 | 
			
		||||
    >>> x = torch.Tensor([[1, 2, 3, 4, 5], [6, 7, 8, 9, 10]])
 | 
			
		||||
    >>> x = torch.tensor([[1, 2, 3, 4, 5], [6, 7, 8, 9, 10]])
 | 
			
		||||
    >>> x.stride()
 | 
			
		||||
    (5, 1)
 | 
			
		||||
    >>>x.stride(0)
 | 
			
		||||
@ -1744,6 +1880,115 @@ t_() -> Tensor
 | 
			
		||||
In-place version of :meth:`~Tensor.t`
 | 
			
		||||
""")
 | 
			
		||||
 | 
			
		||||
add_docstr_all('to',
 | 
			
		||||
               r"""
 | 
			
		||||
to(*args, **kwargs) -> Tensor
 | 
			
		||||
 | 
			
		||||
Performs Tensor dtype and/or device conversion. A :class:`torch.dtype` and :class:`torch.device` are
 | 
			
		||||
inferred from the arguments of ``self.to(*args, **kwargs)``.
 | 
			
		||||
 | 
			
		||||
.. note::
 | 
			
		||||
 | 
			
		||||
    If the ``self`` Tensor already
 | 
			
		||||
    has the correct :class:`torch.dtype` and :class:`torch.device`, then ``self`` is returned.
 | 
			
		||||
    Otherwise, the returned tensor is a copy of ``self`` with the desired
 | 
			
		||||
    :class:`torch.dtype` and :class:`torch.device`.
 | 
			
		||||
 | 
			
		||||
Here are the ways to call ``to``:
 | 
			
		||||
 | 
			
		||||
.. function:: to(dtype) -> Tensor
 | 
			
		||||
 | 
			
		||||
    Returns a Tensor with the specified :attr:`dtype`
 | 
			
		||||
 | 
			
		||||
.. function:: to(device, dtype=None) -> Tensor
 | 
			
		||||
 | 
			
		||||
    Returns a Tensor with the specified :attr:`device` and (optional)
 | 
			
		||||
    :attr:`dtype`. If :attr:`dtype` is ``None`` it is inferred to be ``self.dtype``.
 | 
			
		||||
 | 
			
		||||
.. function:: to(other) -> Tensor
 | 
			
		||||
 | 
			
		||||
    Returns a Tensor with same :class:`torch.dtype` and :class:`torch.device` as the Tensor
 | 
			
		||||
    :attr:`other`.
 | 
			
		||||
 | 
			
		||||
Example::
 | 
			
		||||
 | 
			
		||||
    >>> tensor = torch.randn(2, 2)  # Initially dtype=float32, device=cpu
 | 
			
		||||
    >>> tensor.to(torch.float64)
 | 
			
		||||
    tensor([[-0.5044,  0.0005],
 | 
			
		||||
            [ 0.3310, -0.0584]], dtype=torch.float64)
 | 
			
		||||
 | 
			
		||||
    >>> cuda0 = torch.device('cuda:0')
 | 
			
		||||
    >>> tensor.to(cuda0)
 | 
			
		||||
    tensor([[-0.5044,  0.0005],
 | 
			
		||||
            [ 0.3310, -0.0584]], device='cuda:0')
 | 
			
		||||
 | 
			
		||||
    >>> tensor.to(cuda0, dtype=torch.float64)
 | 
			
		||||
    tensor([[-0.5044,  0.0005],
 | 
			
		||||
            [ 0.3310, -0.0584]], dtype=torch.float64, device='cuda:0')
 | 
			
		||||
 | 
			
		||||
    >>> other = torch.randn((), dtype=torch.float64, device=cuda0)
 | 
			
		||||
    >>> tensor.to(other)
 | 
			
		||||
    tensor([[-0.5044,  0.0005],
 | 
			
		||||
            [ 0.3310, -0.0584]], dtype=torch.float64, device='cuda:0')
 | 
			
		||||
 | 
			
		||||
""")
 | 
			
		||||
 | 
			
		||||
add_docstr_all('byte',
 | 
			
		||||
               r"""
 | 
			
		||||
byte() -> Tensor
 | 
			
		||||
 | 
			
		||||
``self.byte()`` is equivalent to ``self.to(torch.uint8)``. See :func:`to`.
 | 
			
		||||
""")
 | 
			
		||||
 | 
			
		||||
add_docstr_all('char',
 | 
			
		||||
               r"""
 | 
			
		||||
char() -> Tensor
 | 
			
		||||
 | 
			
		||||
``self.char()`` is equivalent to ``self.to(torch.int8)``. See :func:`to`.
 | 
			
		||||
""")
 | 
			
		||||
 | 
			
		||||
add_docstr_all('double',
 | 
			
		||||
               r"""
 | 
			
		||||
double() -> Tensor
 | 
			
		||||
 | 
			
		||||
``self.double()`` is equivalent to ``self.to(torch.float64)``. See :func:`to`.
 | 
			
		||||
""")
 | 
			
		||||
 | 
			
		||||
add_docstr_all('float',
 | 
			
		||||
               r"""
 | 
			
		||||
float() -> Tensor
 | 
			
		||||
 | 
			
		||||
``self.float()`` is equivalent to ``self.to(torch.float32)``. See :func:`to`.
 | 
			
		||||
""")
 | 
			
		||||
 | 
			
		||||
add_docstr_all('half',
 | 
			
		||||
               r"""
 | 
			
		||||
half() -> Tensor
 | 
			
		||||
 | 
			
		||||
``self.half()`` is equivalent to ``self.to(torch.float16)``. See :func:`to`.
 | 
			
		||||
""")
 | 
			
		||||
 | 
			
		||||
add_docstr_all('int',
 | 
			
		||||
               r"""
 | 
			
		||||
int() -> Tensor
 | 
			
		||||
 | 
			
		||||
``self.int()`` is equivalent to ``self.to(torch.int32)``. See :func:`to`.
 | 
			
		||||
""")
 | 
			
		||||
 | 
			
		||||
add_docstr_all('long',
 | 
			
		||||
               r"""
 | 
			
		||||
long() -> Tensor
 | 
			
		||||
 | 
			
		||||
``self.long()`` is equivalent to ``self.to(torch.int64)``. See :func:`to`.
 | 
			
		||||
""")
 | 
			
		||||
 | 
			
		||||
add_docstr_all('short',
 | 
			
		||||
               r"""
 | 
			
		||||
short() -> Tensor
 | 
			
		||||
 | 
			
		||||
``self.short()`` is equivalent to ``self.to(torch.int16)``. See :func:`to`.
 | 
			
		||||
""")
 | 
			
		||||
 | 
			
		||||
add_docstr_all('take',
 | 
			
		||||
               r"""
 | 
			
		||||
take(indices) -> Tensor
 | 
			
		||||
@ -1907,33 +2152,18 @@ Example::
 | 
			
		||||
 | 
			
		||||
    >>> x = torch.arange(1, 8)
 | 
			
		||||
    >>> x
 | 
			
		||||
 | 
			
		||||
     1
 | 
			
		||||
     2
 | 
			
		||||
     3
 | 
			
		||||
     4
 | 
			
		||||
     5
 | 
			
		||||
     6
 | 
			
		||||
     7
 | 
			
		||||
    [torch.FloatTensor of size (7,)]
 | 
			
		||||
 | 
			
		||||
    tensor([ 1.,  2.,  3.,  4.,  5.,  6.,  7.])
 | 
			
		||||
    >>> x.unfold(0, 2, 1)
 | 
			
		||||
 | 
			
		||||
     1  2
 | 
			
		||||
     2  3
 | 
			
		||||
     3  4
 | 
			
		||||
     4  5
 | 
			
		||||
     5  6
 | 
			
		||||
     6  7
 | 
			
		||||
    [torch.FloatTensor of size (6,2)]
 | 
			
		||||
 | 
			
		||||
    tensor([[ 1.,  2.],
 | 
			
		||||
            [ 2.,  3.],
 | 
			
		||||
            [ 3.,  4.],
 | 
			
		||||
            [ 4.,  5.],
 | 
			
		||||
            [ 5.,  6.],
 | 
			
		||||
            [ 6.,  7.]])
 | 
			
		||||
    >>> x.unfold(0, 2, 2)
 | 
			
		||||
 | 
			
		||||
     1  2
 | 
			
		||||
     3  4
 | 
			
		||||
     5  6
 | 
			
		||||
    [torch.FloatTensor of size (3,2)]
 | 
			
		||||
 | 
			
		||||
    tensor([[ 1.,  2.],
 | 
			
		||||
            [ 3.,  4.],
 | 
			
		||||
            [ 5.,  6.]])
 | 
			
		||||
""")
 | 
			
		||||
 | 
			
		||||
add_docstr_all('uniform_',
 | 
			
		||||
@ -2031,23 +2261,17 @@ Args:
 | 
			
		||||
 | 
			
		||||
Example::
 | 
			
		||||
 | 
			
		||||
    >>> x = torch.Tensor([[1], [2], [3]])
 | 
			
		||||
    >>> x = torch.tensor([[1], [2], [3]])
 | 
			
		||||
    >>> x.size()
 | 
			
		||||
    torch.Size([3, 1])
 | 
			
		||||
    >>> x.expand(3, 4)
 | 
			
		||||
 | 
			
		||||
     1  1  1  1
 | 
			
		||||
     2  2  2  2
 | 
			
		||||
     3  3  3  3
 | 
			
		||||
    [torch.FloatTensor of size (3,4)]
 | 
			
		||||
 | 
			
		||||
    tensor([[ 1,  1,  1,  1],
 | 
			
		||||
            [ 2,  2,  2,  2],
 | 
			
		||||
            [ 3,  3,  3,  3]])
 | 
			
		||||
    >>> x.expand(-1, 4)   # -1 means not changing the size of that dimension
 | 
			
		||||
 | 
			
		||||
     1  1  1  1
 | 
			
		||||
     2  2  2  2
 | 
			
		||||
     3  3  3  3
 | 
			
		||||
    [torch.FloatTensor of size (3,4)]
 | 
			
		||||
 | 
			
		||||
    tensor([[ 1,  1,  1,  1],
 | 
			
		||||
            [ 2,  2,  2,  2],
 | 
			
		||||
            [ 3,  3,  3,  3]])
 | 
			
		||||
""")
 | 
			
		||||
 | 
			
		||||
add_docstr_all('zero_',
 | 
			
		||||
 | 
			
		||||
@ -73,7 +73,7 @@ def _get_min_log_scale():
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
def _number_format(tensor, min_sz=-1):
 | 
			
		||||
    int_mode = not tensor.dtype.is_floating_point
 | 
			
		||||
    floating_dtype = tensor.dtype.is_floating_point  # save this because we cast later
 | 
			
		||||
    _min_log_scale = _get_min_log_scale()
 | 
			
		||||
    min_sz = max(min_sz, 2)
 | 
			
		||||
    tensor = torch.DoubleTensor(tensor.size()).copy_(tensor).abs_().view(tensor.nelement())
 | 
			
		||||
@ -90,6 +90,13 @@ def _number_format(tensor, min_sz=-1):
 | 
			
		||||
    if invalid_value_mask.any():
 | 
			
		||||
        min_sz = max(min_sz, 3)
 | 
			
		||||
 | 
			
		||||
    int_mode = True
 | 
			
		||||
    # TODO: use fmod?
 | 
			
		||||
    for value in tensor:
 | 
			
		||||
        if value != math.ceil(value.item()):
 | 
			
		||||
            int_mode = False
 | 
			
		||||
            break
 | 
			
		||||
 | 
			
		||||
    exp_min = tensor.min()
 | 
			
		||||
    if exp_min != 0:
 | 
			
		||||
        exp_min = math.floor(math.log10(exp_min)) + 1
 | 
			
		||||
@ -100,6 +107,7 @@ def _number_format(tensor, min_sz=-1):
 | 
			
		||||
        exp_max = math.floor(math.log10(exp_max)) + 1
 | 
			
		||||
    else:
 | 
			
		||||
        exp_max = 1
 | 
			
		||||
    include_decimal_int_mode = floating_dtype and int_mode
 | 
			
		||||
 | 
			
		||||
    scale = 1
 | 
			
		||||
    exp_max = int(exp_max)
 | 
			
		||||
@ -111,6 +119,9 @@ def _number_format(tensor, min_sz=-1):
 | 
			
		||||
        else:
 | 
			
		||||
            sz = max(min_sz, exp_max + 1)
 | 
			
		||||
            format = '{:' + str(sz) + '.0f}'
 | 
			
		||||
            if include_decimal_int_mode:
 | 
			
		||||
                format += '.'
 | 
			
		||||
                sz += 1
 | 
			
		||||
    else:
 | 
			
		||||
        if exp_max - exp_min > prec:
 | 
			
		||||
            sz = 7 + prec
 | 
			
		||||
@ -179,7 +190,7 @@ def _tensor_str(self, indent, fmt, scale, sz, summarize):
 | 
			
		||||
def _str(self):
 | 
			
		||||
    if self.is_sparse:
 | 
			
		||||
        size_str = str(tuple(self.shape)).replace(' ', '')
 | 
			
		||||
        return '{} of size {} with indices:\n{}and values:\n{}'.format(
 | 
			
		||||
        return '{} of size {} with indices:\n{}\nand values:\n{}'.format(
 | 
			
		||||
            self.type(), size_str, self._indices(), self._values())
 | 
			
		||||
 | 
			
		||||
    prefix = 'tensor('
 | 
			
		||||
@ -194,12 +205,16 @@ def _str(self):
 | 
			
		||||
        if self.device.type == 'cpu' or torch.cuda.current_device() != self.device.index:
 | 
			
		||||
            suffix = ', device=\'' + str(self.device) + '\'' + suffix
 | 
			
		||||
 | 
			
		||||
    if self.dtype != torch.get_default_dtype() and self.dtype != torch.int64:
 | 
			
		||||
        suffix = ', dtype=' + str(self.dtype) + suffix
 | 
			
		||||
 | 
			
		||||
    if self.numel() == 0:
 | 
			
		||||
        # In an empty tensor, there are no elements to infer if the dtype should be int64,
 | 
			
		||||
        # so it must be shown explicitly.
 | 
			
		||||
        if self.dtype != torch.get_default_dtype():
 | 
			
		||||
            suffix = ', dtype=' + str(self.dtype) + suffix
 | 
			
		||||
        tensor_str = '[]'
 | 
			
		||||
    else:
 | 
			
		||||
        if self.dtype != torch.get_default_dtype() and self.dtype != torch.int64:
 | 
			
		||||
            suffix = ', dtype=' + str(self.dtype) + suffix
 | 
			
		||||
 | 
			
		||||
        fmt, scale, sz = _number_format(self)
 | 
			
		||||
        if scale != 1:
 | 
			
		||||
            prefix = prefix + SCALE_FORMAT.format(scale) + ' ' * indent
 | 
			
		||||
 | 
			
		||||
							
								
								
									
										2977
									
								
								torch/_torch_docs.py
									
									
									
									
									
								
							
							
						
						
									
										2977
									
								
								torch/_torch_docs.py
									
									
									
									
									
								
							
										
											
												File diff suppressed because it is too large
												Load Diff
											
										
									
								
							@ -16,6 +16,7 @@ void InputBuffer::add(size_t pos, Variable var) {
 | 
			
		||||
  if (!old_var.defined()) {
 | 
			
		||||
    buffer[pos] = std::move(var);
 | 
			
		||||
  } else {
 | 
			
		||||
    AutoGPU auto_gpu(var);
 | 
			
		||||
    // ATen doesn't route sparse additions correctly...
 | 
			
		||||
    if (old_var.type().is_sparse()) {
 | 
			
		||||
      buffer[pos] = var + old_var;
 | 
			
		||||
 | 
			
		||||
@ -9,8 +9,8 @@
 | 
			
		||||
#include "torch/csrc/autograd/variable.h"
 | 
			
		||||
#include "torch/csrc/utils/python_compat.h"
 | 
			
		||||
#include "torch/csrc/utils/python_numbers.h"
 | 
			
		||||
#include "torch/csrc/utils/tensor_conversion_dispatch.h"
 | 
			
		||||
#include "torch/csrc/utils/tensor_new.h"
 | 
			
		||||
#include "torch/csrc/utils/tensor_conversion_dispatch.h"
 | 
			
		||||
 | 
			
		||||
#include <ATen/ExpandUtils.h>
 | 
			
		||||
#include <vector>
 | 
			
		||||
@ -169,16 +169,6 @@ static Variable applySlicing(const Variable& self, PyObject* index, variable_lis
 | 
			
		||||
  return result;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static Tensor typeConvertIndex(const Variable& self, const Variable& ind) {
 | 
			
		||||
  int64_t device = self.is_cuda() ? self.get_device() : -1;
 | 
			
		||||
  if (ind.defined()) {
 | 
			
		||||
    auto& new_type = ind.type().toBackend(self.type().backend());
 | 
			
		||||
    return torch::utils::dispatch_type_conversion(ind, new_type, device, false);
 | 
			
		||||
  } else {
 | 
			
		||||
    return ind;
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static std::vector<Tensor> typeConvertIndices(const Variable& self, const variable_list& indices) {
 | 
			
		||||
  std::vector<Tensor> converted_inds(indices.size());
 | 
			
		||||
  int64_t device = self.is_cuda() ? self.get_device() : -1;
 | 
			
		||||
@ -271,97 +261,6 @@ static PyObject* applyBoolGetitem(const Variable& self, bool index) {
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
enum class LegacyIndexingType {
 | 
			
		||||
  None,
 | 
			
		||||
  Mask,
 | 
			
		||||
  Index,
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
static std::pair<LegacyIndexingType, int64_t>
 | 
			
		||||
getLegacyIndexingType(const Variable& self, const variable_list& vars) {
 | 
			
		||||
  // TODO: this could be that the broadcasted size is the same.
 | 
			
		||||
  if (vars.size() == 1 && vars[0].type().scalarType() == ScalarType::Byte && vars[0].is_same_size(self)) {
 | 
			
		||||
    return std::make_pair(LegacyIndexingType::Mask, -1);
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  // single tensor indexing
 | 
			
		||||
  int num_defined_variables = 0;
 | 
			
		||||
  int64_t index_dim = -1;
 | 
			
		||||
  for (size_t i = 0; i < vars.size(); i++) {
 | 
			
		||||
    auto& variable = vars[i];
 | 
			
		||||
    auto is_defined = variable.defined();
 | 
			
		||||
    num_defined_variables += is_defined;
 | 
			
		||||
    if (is_defined) {
 | 
			
		||||
      index_dim = (int64_t)i;
 | 
			
		||||
      if (num_defined_variables > 1) {
 | 
			
		||||
        break;
 | 
			
		||||
      }
 | 
			
		||||
      if (variable.dim() != 1 || variable.type().scalarType() != ScalarType::Long || variable.numel() == 0) {
 | 
			
		||||
        num_defined_variables = -1;
 | 
			
		||||
        break;
 | 
			
		||||
      }
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  if (num_defined_variables == 1) {
 | 
			
		||||
    return std::make_pair(LegacyIndexingType::Index, index_dim);
 | 
			
		||||
  }
 | 
			
		||||
  // advanced indexing
 | 
			
		||||
  return std::make_pair(LegacyIndexingType::None, -1);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static Variable dispatch_legacy_index(const Variable& self, const variable_list& vars,
 | 
			
		||||
                                      std::pair<LegacyIndexingType, int64_t> legacyIndex) {
 | 
			
		||||
  LegacyIndexingType indexingType = std::get<0>(legacyIndex);
 | 
			
		||||
  switch(indexingType) {
 | 
			
		||||
    case LegacyIndexingType::Mask: {
 | 
			
		||||
      auto mask = vars[0];
 | 
			
		||||
      auto mask_convert = typeConvertIndex(self, mask);
 | 
			
		||||
      AutoNoGIL no_gil;
 | 
			
		||||
      AutoGPU auto_gpu(self);
 | 
			
		||||
      return self.masked_select(mask_convert);
 | 
			
		||||
    }
 | 
			
		||||
    case LegacyIndexingType::Index: {
 | 
			
		||||
      int64_t index_dim = std::get<1>(legacyIndex);
 | 
			
		||||
      auto index = vars[index_dim];
 | 
			
		||||
      auto index_convert = typeConvertIndex(self, index);
 | 
			
		||||
      AutoNoGIL no_gil;
 | 
			
		||||
      AutoGPU auto_gpu(self);
 | 
			
		||||
      return self.index_select(index_dim, index_convert);
 | 
			
		||||
    }
 | 
			
		||||
    case LegacyIndexingType::None:
 | 
			
		||||
    default: {
 | 
			
		||||
      throw std::runtime_error("Unexpected indexing type");
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static Variable dispatch_legacy_index_put_(Variable& self, const variable_list& vars, const Variable& value,
 | 
			
		||||
                                           std::pair<LegacyIndexingType, int64_t> legacyIndex) {
 | 
			
		||||
  LegacyIndexingType indexingType = std::get<0>(legacyIndex);
 | 
			
		||||
  switch(indexingType) {
 | 
			
		||||
    case LegacyIndexingType::Mask: {
 | 
			
		||||
      auto mask = vars[0];
 | 
			
		||||
      auto mask_convert = typeConvertIndex(self, mask);
 | 
			
		||||
      AutoNoGIL no_gil;
 | 
			
		||||
      AutoGPU auto_gpu(self);
 | 
			
		||||
      return self.masked_fill_(mask_convert, value);
 | 
			
		||||
    }
 | 
			
		||||
    case LegacyIndexingType::Index: {
 | 
			
		||||
      int64_t index_dim = std::get<1>(legacyIndex);
 | 
			
		||||
      auto index = vars[index_dim];
 | 
			
		||||
      auto index_convert = typeConvertIndex(self, index);
 | 
			
		||||
      AutoNoGIL no_gil;
 | 
			
		||||
      AutoGPU auto_gpu(self);
 | 
			
		||||
      return self.index_fill_(index_dim, index_convert, value);
 | 
			
		||||
    }
 | 
			
		||||
    case LegacyIndexingType::None:
 | 
			
		||||
    default: {
 | 
			
		||||
      throw std::runtime_error("Unexpected indexing type");
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
PyObject* THPVariable_getitem(PyObject* self, PyObject* index) {
 | 
			
		||||
  HANDLE_TH_ERRORS
 | 
			
		||||
  auto& self_ = reinterpret_cast<THPVariable*>(self)->cdata;
 | 
			
		||||
@ -396,12 +295,6 @@ PyObject* THPVariable_getitem(PyObject* self, PyObject* index) {
 | 
			
		||||
    return applyBoolGetitem(self_, variableIndices[0].toCByte());
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  // TODO move this to ATen
 | 
			
		||||
  auto legacy_index = getLegacyIndexingType(sliced, variableIndices);
 | 
			
		||||
  if (std::get<0>(legacy_index) != LegacyIndexingType::None) {
 | 
			
		||||
    return wrap(dispatch_legacy_index(sliced, variableIndices, legacy_index));
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  // indexing by tensors ("advanced" indexing)
 | 
			
		||||
  return wrap(dispatch_index(sliced, variableIndices));
 | 
			
		||||
  Py_RETURN_NONE;
 | 
			
		||||
@ -468,16 +361,6 @@ int THPVariable_setitem(PyObject* self, PyObject* index, PyObject* py_value) {
 | 
			
		||||
    return 0;
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  // TODO move this to ATen
 | 
			
		||||
  // we are being overly cautious here and only considering the *_fill_ variants
 | 
			
		||||
  // (value is a scalar), as there could be broadcasting in the value that could
 | 
			
		||||
  // happen and is not handled by masked_scatter_ and index_copy_
 | 
			
		||||
  auto legacy_index = getLegacyIndexingType(sliced, variableIndices);
 | 
			
		||||
  if (std::get<0>(legacy_index) != LegacyIndexingType::None && value.dim() == 0) {
 | 
			
		||||
    dispatch_legacy_index_put_(sliced, variableIndices, value, legacy_index);
 | 
			
		||||
    return 0;
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  // indexing by tensors ("advanced" indexing)
 | 
			
		||||
  dispatch_index_put_(sliced, variableIndices, value);
 | 
			
		||||
  return 0;
 | 
			
		||||
 | 
			
		||||
@ -112,7 +112,7 @@ def _check_capability():
 | 
			
		||||
            warnings.warn(incorrect_binary_warn % (d, name, 8000, CUDA_VERSION))
 | 
			
		||||
        elif CUDA_VERSION < 9000 and major >= 7:
 | 
			
		||||
            warnings.warn(incorrect_binary_warn % (d, name, 9000, CUDA_VERSION))
 | 
			
		||||
        elif capability == (3, 0) or capability == (5, 0) or major < 3:
 | 
			
		||||
        elif capability == (3, 0) or major < 3:
 | 
			
		||||
            warnings.warn(old_gpu_warn % (d, name, major, capability[1]))
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@ -16,7 +16,7 @@ class Bernoulli(ExponentialFamily):
 | 
			
		||||
 | 
			
		||||
    Example::
 | 
			
		||||
 | 
			
		||||
        >>> m = Bernoulli(torch.Tensor([0.3]))
 | 
			
		||||
        >>> m = Bernoulli(torch.tensor([0.3]))
 | 
			
		||||
        >>> m.sample()  # 30% chance 1; 70% chance 0
 | 
			
		||||
         0.0
 | 
			
		||||
        [torch.FloatTensor of size 1]
 | 
			
		||||
 | 
			
		||||
@ -13,7 +13,7 @@ class Beta(ExponentialFamily):
 | 
			
		||||
 | 
			
		||||
    Example::
 | 
			
		||||
 | 
			
		||||
        >>> m = Beta(torch.Tensor([0.5]), torch.Tensor([0.5]))
 | 
			
		||||
        >>> m = Beta(torch.tensor([0.5]), torch.tensor([0.5]))
 | 
			
		||||
        >>> m.sample()  # Beta distributed with concentration concentration1 and concentration0
 | 
			
		||||
         0.1046
 | 
			
		||||
        [torch.FloatTensor of size 1]
 | 
			
		||||
@ -50,7 +50,7 @@ class Beta(ExponentialFamily):
 | 
			
		||||
    def rsample(self, sample_shape=()):
 | 
			
		||||
        value = self._dirichlet.rsample(sample_shape).select(-1, 0)
 | 
			
		||||
        if isinstance(value, Number):
 | 
			
		||||
            value = self._dirichlet.concentration.new([value])
 | 
			
		||||
            value = self._dirichlet.concentration.new_tensor(value)
 | 
			
		||||
        return value
 | 
			
		||||
 | 
			
		||||
    def log_prob(self, value):
 | 
			
		||||
 | 
			
		||||
@ -17,7 +17,7 @@ class Binomial(Distribution):
 | 
			
		||||
 | 
			
		||||
    Example::
 | 
			
		||||
 | 
			
		||||
        >>> m = Binomial(100, torch.Tensor([0 , .2, .8, 1]))
 | 
			
		||||
        >>> m = Binomial(100, torch.tensor([0 , .2, .8, 1]))
 | 
			
		||||
        >>> x = m.sample()
 | 
			
		||||
         0
 | 
			
		||||
         22
 | 
			
		||||
 | 
			
		||||
@ -27,7 +27,7 @@ class Categorical(Distribution):
 | 
			
		||||
 | 
			
		||||
    Example::
 | 
			
		||||
 | 
			
		||||
        >>> m = Categorical(torch.Tensor([ 0.25, 0.25, 0.25, 0.25 ]))
 | 
			
		||||
        >>> m = Categorical(torch.tensor([ 0.25, 0.25, 0.25, 0.25 ]))
 | 
			
		||||
        >>> m.sample()  # equal probability of 0, 1, 2, 3
 | 
			
		||||
         3
 | 
			
		||||
        [torch.LongTensor of size 1]
 | 
			
		||||
 | 
			
		||||
@ -15,7 +15,7 @@ class Cauchy(Distribution):
 | 
			
		||||
 | 
			
		||||
    Example::
 | 
			
		||||
 | 
			
		||||
        >>> m = Cauchy(torch.Tensor([0.0]), torch.Tensor([1.0]))
 | 
			
		||||
        >>> m = Cauchy(torch.tensor([0.0]), torch.tensor([1.0]))
 | 
			
		||||
        >>> m.sample()  # sample from a Cauchy distribution with loc=0 and scale=1
 | 
			
		||||
         2.3214
 | 
			
		||||
        [torch.FloatTensor of size 1]
 | 
			
		||||
@ -38,11 +38,11 @@ class Cauchy(Distribution):
 | 
			
		||||
 | 
			
		||||
    @property
 | 
			
		||||
    def mean(self):
 | 
			
		||||
        return self.loc.new([float('nan')]).expand(self._extended_shape())
 | 
			
		||||
        return self.loc.new_tensor(float('nan')).expand(self._extended_shape())
 | 
			
		||||
 | 
			
		||||
    @property
 | 
			
		||||
    def variance(self):
 | 
			
		||||
        return self.loc.new([float('inf')]).expand(self._extended_shape())
 | 
			
		||||
        return self.loc.new_tensor(float('inf')).expand(self._extended_shape())
 | 
			
		||||
 | 
			
		||||
    def rsample(self, sample_shape=torch.Size()):
 | 
			
		||||
        shape = self._extended_shape(sample_shape)
 | 
			
		||||
 | 
			
		||||
@ -9,7 +9,7 @@ class Chi2(Gamma):
 | 
			
		||||
 | 
			
		||||
    Example::
 | 
			
		||||
 | 
			
		||||
        >>> m = Chi2(torch.Tensor([1.0]))
 | 
			
		||||
        >>> m = Chi2(torch.tensor([1.0]))
 | 
			
		||||
        >>> m.sample()  # Chi2 distributed with shape df=1
 | 
			
		||||
         0.1046
 | 
			
		||||
        [torch.FloatTensor of size 1]
 | 
			
		||||
 | 
			
		||||
@ -42,7 +42,7 @@ class Dirichlet(ExponentialFamily):
 | 
			
		||||
 | 
			
		||||
    Example::
 | 
			
		||||
 | 
			
		||||
        >>> m = Dirichlet(torch.Tensor([0.5, 0.5]))
 | 
			
		||||
        >>> m = Dirichlet(torch.tensor([0.5, 0.5]))
 | 
			
		||||
        >>> m.sample()  # Dirichlet distributed with concentrarion concentration
 | 
			
		||||
         0.1046
 | 
			
		||||
         0.8954
 | 
			
		||||
@ -77,11 +77,11 @@ class Dirichlet(ExponentialFamily):
 | 
			
		||||
 | 
			
		||||
    @property
 | 
			
		||||
    def mean(self):
 | 
			
		||||
        return self.concentration / self.concentration.sum(-1)
 | 
			
		||||
        return self.concentration / self.concentration.sum(-1, True)
 | 
			
		||||
 | 
			
		||||
    @property
 | 
			
		||||
    def variance(self):
 | 
			
		||||
        con0 = self.concentration.sum(-1)
 | 
			
		||||
        con0 = self.concentration.sum(-1, True)
 | 
			
		||||
        return self.concentration * (con0 - self.concentration) / (con0.pow(2) * (con0 + 1))
 | 
			
		||||
 | 
			
		||||
    def entropy(self):
 | 
			
		||||
 | 
			
		||||
@ -12,7 +12,7 @@ class Exponential(ExponentialFamily):
 | 
			
		||||
 | 
			
		||||
    Example::
 | 
			
		||||
 | 
			
		||||
        >>> m = Exponential(torch.Tensor([1.0]))
 | 
			
		||||
        >>> m = Exponential(torch.tensor([1.0]))
 | 
			
		||||
        >>> m.sample()  # Exponential distributed with rate=1
 | 
			
		||||
         0.1046
 | 
			
		||||
        [torch.FloatTensor of size 1]
 | 
			
		||||
 | 
			
		||||
@ -13,7 +13,7 @@ class FisherSnedecor(Distribution):
 | 
			
		||||
 | 
			
		||||
    Example::
 | 
			
		||||
 | 
			
		||||
        >>> m = FisherSnedecor(torch.Tensor([1.0]), torch.Tensor([2.0]))
 | 
			
		||||
        >>> m = FisherSnedecor(torch.tensor([1.0]), torch.tensor([2.0]))
 | 
			
		||||
        >>> m.sample()  # Fisher-Snedecor-distributed with df1=1 and df2=2
 | 
			
		||||
         0.2453
 | 
			
		||||
        [torch.FloatTensor of size 1]
 | 
			
		||||
 | 
			
		||||
@ -18,7 +18,7 @@ class Gamma(ExponentialFamily):
 | 
			
		||||
 | 
			
		||||
    Example::
 | 
			
		||||
 | 
			
		||||
        >>> m = Gamma(torch.Tensor([1.0]), torch.Tensor([1.0]))
 | 
			
		||||
        >>> m = Gamma(torch.tensor([1.0]), torch.tensor([1.0]))
 | 
			
		||||
        >>> m.sample()  # Gamma distributed with concentration=1 and rate=1
 | 
			
		||||
         0.1046
 | 
			
		||||
        [torch.FloatTensor of size 1]
 | 
			
		||||
 | 
			
		||||
@ -17,7 +17,7 @@ class Geometric(Distribution):
 | 
			
		||||
 | 
			
		||||
    Example::
 | 
			
		||||
 | 
			
		||||
        >>> m = Geometric(torch.Tensor([0.3]))
 | 
			
		||||
        >>> m = Geometric(torch.tensor([0.3]))
 | 
			
		||||
        >>> m.sample()  # underlying Bernoulli has 30% chance 1; 70% chance 0
 | 
			
		||||
         2
 | 
			
		||||
        [torch.FloatTensor of size 1]
 | 
			
		||||
 | 
			
		||||
@ -16,7 +16,7 @@ class Gumbel(TransformedDistribution):
 | 
			
		||||
 | 
			
		||||
    Examples::
 | 
			
		||||
 | 
			
		||||
        >>> m = Gumbel(torch.Tensor([1.0]), torch.Tensor([2.0]))
 | 
			
		||||
        >>> m = Gumbel(torch.tensor([1.0]), torch.tensor([2.0]))
 | 
			
		||||
        >>> m.sample()  # sample from Gumbel distribution with loc=1, scale=2
 | 
			
		||||
         1.0124
 | 
			
		||||
        [torch.FloatTensor of size 1]
 | 
			
		||||
 | 
			
		||||
@ -52,6 +52,8 @@ class Independent(Distribution):
 | 
			
		||||
 | 
			
		||||
    @property
 | 
			
		||||
    def has_enumerate_support(self):
 | 
			
		||||
        if self.reinterpreted_batch_ndims > 0:
 | 
			
		||||
            return False
 | 
			
		||||
        return self.base_dist.has_enumerate_support
 | 
			
		||||
 | 
			
		||||
    @constraints.dependent_property
 | 
			
		||||
@ -70,7 +72,7 @@ class Independent(Distribution):
 | 
			
		||||
        return self.base_dist.sample(sample_shape)
 | 
			
		||||
 | 
			
		||||
    def rsample(self, sample_shape=torch.Size()):
 | 
			
		||||
        return self.base_dist.rsample(self, sample_shape)
 | 
			
		||||
        return self.base_dist.rsample(sample_shape)
 | 
			
		||||
 | 
			
		||||
    def log_prob(self, value):
 | 
			
		||||
        log_prob = self.base_dist.log_prob(value)
 | 
			
		||||
@ -81,4 +83,6 @@ class Independent(Distribution):
 | 
			
		||||
        return _sum_rightmost(entropy, self.reinterpreted_batch_ndims)
 | 
			
		||||
 | 
			
		||||
    def enumerate_support(self):
 | 
			
		||||
        if self.reinterpreted_batch_ndims > 0:
 | 
			
		||||
            raise NotImplementedError("Enumeration over cartesian product is not implemented")
 | 
			
		||||
        return self.base_dist.enumerate_support()
 | 
			
		||||
 | 
			
		||||
@ -11,7 +11,7 @@ class Laplace(Distribution):
 | 
			
		||||
 | 
			
		||||
    Example::
 | 
			
		||||
 | 
			
		||||
        >>> m = Laplace(torch.Tensor([0.0]), torch.Tensor([1.0]))
 | 
			
		||||
        >>> m = Laplace(torch.tensor([0.0]), torch.tensor([1.0]))
 | 
			
		||||
        >>> m.sample()  # Laplace distributed with loc=0, scale=1
 | 
			
		||||
         0.1046
 | 
			
		||||
        [torch.FloatTensor of size 1]
 | 
			
		||||
 | 
			
		||||
@ -14,7 +14,7 @@ class LogNormal(TransformedDistribution):
 | 
			
		||||
 | 
			
		||||
    Example::
 | 
			
		||||
 | 
			
		||||
        >>> m = LogNormal(torch.Tensor([0.0]), torch.Tensor([1.0]))
 | 
			
		||||
        >>> m = LogNormal(torch.tensor([0.0]), torch.tensor([1.0]))
 | 
			
		||||
        >>> m.sample()  # log-normal distributed with mean=0 and stddev=1
 | 
			
		||||
         0.1046
 | 
			
		||||
        [torch.FloatTensor of size 1]
 | 
			
		||||
 | 
			
		||||
@ -14,20 +14,18 @@ class LogisticNormal(TransformedDistribution):
 | 
			
		||||
        X ~ LogisticNormal(loc, scale)
 | 
			
		||||
        Y = log(X / (1 - X.cumsum(-1)))[..., :-1] ~ Normal(loc, scale)
 | 
			
		||||
 | 
			
		||||
    Example::
 | 
			
		||||
 | 
			
		||||
        >>> m = LogisticNormal(torch.Tensor([0.0] * 3), torch.Tensor([1.0] * 3))
 | 
			
		||||
        >>> m.sample()  # logistic-normal distributed with mean=(0, 0, 0) and
 | 
			
		||||
                        # stddev=(1, 1, 1) of the base Normal distribution
 | 
			
		||||
         0.4163
 | 
			
		||||
         0.1386
 | 
			
		||||
         0.3539
 | 
			
		||||
         0.0912
 | 
			
		||||
        [torch.FloatTensor of size (4,)]
 | 
			
		||||
 | 
			
		||||
    Args:
 | 
			
		||||
        loc (float or Tensor): mean of the base distribution
 | 
			
		||||
        scale (float or Tensor): standard deviation of the base distribution
 | 
			
		||||
 | 
			
		||||
    Example::
 | 
			
		||||
 | 
			
		||||
        >>> # logistic-normal distributed with mean=(0, 0, 0) and stddev=(1, 1, 1)
 | 
			
		||||
        >>> # of the base Normal distribution
 | 
			
		||||
        >>> m = distributions.LogisticNormal(torch.tensor([0.0] * 3), torch.tensor([1.0] * 3))
 | 
			
		||||
        >>> m.sample()
 | 
			
		||||
        tensor([ 0.7653,  0.0341,  0.0579,  0.1427])
 | 
			
		||||
 | 
			
		||||
    """
 | 
			
		||||
    arg_constraints = {'loc': constraints.real, 'scale': constraints.positive}
 | 
			
		||||
    support = constraints.simplex
 | 
			
		||||
 | 
			
		||||
@ -24,7 +24,7 @@ class Multinomial(Distribution):
 | 
			
		||||
 | 
			
		||||
    Example::
 | 
			
		||||
 | 
			
		||||
        >>> m = Multinomial(100, torch.Tensor([ 1, 1, 1, 1]))
 | 
			
		||||
        >>> m = Multinomial(100, torch.tensor([ 1, 1, 1, 1]))
 | 
			
		||||
        >>> x = m.sample()  # equal probability of 0, 1, 2, 3
 | 
			
		||||
         21
 | 
			
		||||
         24
 | 
			
		||||
@ -32,7 +32,7 @@ class Multinomial(Distribution):
 | 
			
		||||
         25
 | 
			
		||||
        [torch.FloatTensor of size 4]]
 | 
			
		||||
 | 
			
		||||
        >>> Multinomial(probs=torch.Tensor([1, 1, 1, 1])).log_prob(x)
 | 
			
		||||
        >>> Multinomial(probs=torch.tensor([1, 1, 1, 1])).log_prob(x)
 | 
			
		||||
        -4.1338
 | 
			
		||||
        [torch.FloatTensor of size 1]
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@ -14,7 +14,7 @@ class Normal(ExponentialFamily):
 | 
			
		||||
 | 
			
		||||
    Example::
 | 
			
		||||
 | 
			
		||||
        >>> m = Normal(torch.Tensor([0.0]), torch.Tensor([1.0]))
 | 
			
		||||
        >>> m = Normal(torch.tensor([0.0]), torch.tensor([1.0]))
 | 
			
		||||
        >>> m.sample()  # normally distributed with loc=0 and scale=1
 | 
			
		||||
         0.1046
 | 
			
		||||
        [torch.FloatTensor of size 1]
 | 
			
		||||
 | 
			
		||||
@ -18,7 +18,7 @@ class OneHotCategorical(Distribution):
 | 
			
		||||
 | 
			
		||||
    Example::
 | 
			
		||||
 | 
			
		||||
        >>> m = OneHotCategorical(torch.Tensor([ 0.25, 0.25, 0.25, 0.25 ]))
 | 
			
		||||
        >>> m = OneHotCategorical(torch.tensor([ 0.25, 0.25, 0.25, 0.25 ]))
 | 
			
		||||
        >>> m.sample()  # equal probability of 0, 1, 2, 3
 | 
			
		||||
         0
 | 
			
		||||
         0
 | 
			
		||||
 | 
			
		||||
@ -16,7 +16,7 @@ class Pareto(TransformedDistribution):
 | 
			
		||||
 | 
			
		||||
    Example::
 | 
			
		||||
 | 
			
		||||
        >>> m = Pareto(torch.Tensor([1.0]), torch.Tensor([1.0]))
 | 
			
		||||
        >>> m = Pareto(torch.tensor([1.0]), torch.tensor([1.0]))
 | 
			
		||||
        >>> m.sample()  # sample from a Pareto distribution with scale=1 and alpha=1
 | 
			
		||||
         1.5623
 | 
			
		||||
        [torch.FloatTensor of size 1]
 | 
			
		||||
 | 
			
		||||
@ -15,7 +15,7 @@ class Poisson(ExponentialFamily):
 | 
			
		||||
 | 
			
		||||
    Example::
 | 
			
		||||
 | 
			
		||||
        >>> m = Poisson(torch.Tensor([4]))
 | 
			
		||||
        >>> m = Poisson(torch.tensor([4]))
 | 
			
		||||
        >>> m.sample()
 | 
			
		||||
         3
 | 
			
		||||
        [torch.LongTensor of size 1]
 | 
			
		||||
 | 
			
		||||
@ -82,8 +82,8 @@ class RelaxedBernoulli(TransformedDistribution):
 | 
			
		||||
 | 
			
		||||
    Example::
 | 
			
		||||
 | 
			
		||||
        >>> m = RelaxedBernoulli(torch.Tensor([2.2]),
 | 
			
		||||
                                 torch.Tensor([0.1, 0.2, 0.3, 0.99]))
 | 
			
		||||
        >>> m = RelaxedBernoulli(torch.tensor([2.2]),
 | 
			
		||||
                                 torch.tensor([0.1, 0.2, 0.3, 0.99]))
 | 
			
		||||
        >>> m.sample()
 | 
			
		||||
         0.2951
 | 
			
		||||
         0.3442
 | 
			
		||||
 | 
			
		||||
@ -80,8 +80,8 @@ class RelaxedOneHotCategorical(TransformedDistribution):
 | 
			
		||||
 | 
			
		||||
    Example::
 | 
			
		||||
 | 
			
		||||
        >>> m = RelaxedOneHotCategorical(torch.Tensor([2.2]),
 | 
			
		||||
                                         torch.Tensor([0.1, 0.2, 0.3, 0.4]))
 | 
			
		||||
        >>> m = RelaxedOneHotCategorical(torch.tensor([2.2]),
 | 
			
		||||
                                         torch.tensor([0.1, 0.2, 0.3, 0.4]))
 | 
			
		||||
        >>> m.sample()  # equal probability of 1, 1, 2, 3
 | 
			
		||||
         0.1294
 | 
			
		||||
         0.2324
 | 
			
		||||
 | 
			
		||||
@ -13,7 +13,7 @@ class StudentT(Distribution):
 | 
			
		||||
 | 
			
		||||
    Example::
 | 
			
		||||
 | 
			
		||||
        >>> m = StudentT(torch.Tensor([2.0]))
 | 
			
		||||
        >>> m = StudentT(torch.tensor([2.0]))
 | 
			
		||||
        >>> m.sample()  # Student's t-distributed with degrees of freedom=2
 | 
			
		||||
         0.1046
 | 
			
		||||
        [torch.FloatTensor of size 1]
 | 
			
		||||
 | 
			
		||||
@ -14,7 +14,7 @@ class Uniform(Distribution):
 | 
			
		||||
 | 
			
		||||
    Example::
 | 
			
		||||
 | 
			
		||||
        >>> m = Uniform(torch.Tensor([0.0]), torch.Tensor([5.0]))
 | 
			
		||||
        >>> m = Uniform(torch.tensor([0.0]), torch.tensor([5.0]))
 | 
			
		||||
        >>> m.sample()  # uniformly distributed in the range [0.0, 5.0)
 | 
			
		||||
         2.3418
 | 
			
		||||
        [torch.FloatTensor of size 1]
 | 
			
		||||
 | 
			
		||||
@ -72,24 +72,17 @@ def btrifact(A, info=None, pivot=True):
 | 
			
		||||
        >>> A = torch.randn(2, 3, 3)
 | 
			
		||||
        >>> A_LU, pivots = torch.btrifact(A)
 | 
			
		||||
        >>> A_LU
 | 
			
		||||
        tensor([[[ 1.3506,  2.5558, -0.0816],
 | 
			
		||||
                 [ 0.1684,  1.1551,  0.1940],
 | 
			
		||||
                 [ 0.1193,  0.6189, -0.5497]],
 | 
			
		||||
 | 
			
		||||
        (0 ,.,.) =
 | 
			
		||||
          0.7908 -0.0854  0.1522
 | 
			
		||||
          0.2757 -1.2942 -1.3715
 | 
			
		||||
         -0.6029  0.3609  0.3210
 | 
			
		||||
 | 
			
		||||
        (1 ,.,.) =
 | 
			
		||||
          0.9091  0.1719  0.7741
 | 
			
		||||
          0.1625  0.6720  0.1687
 | 
			
		||||
         -0.1927 -0.9420 -0.4891
 | 
			
		||||
        [torch.FloatTensor of size (2,3,3)]
 | 
			
		||||
                [[ 0.4526,  1.2526, -0.3285],
 | 
			
		||||
                 [-0.7988,  0.7175, -0.9701],
 | 
			
		||||
                 [ 0.2634, -0.9255, -0.3459]]])
 | 
			
		||||
 | 
			
		||||
        >>> pivots
 | 
			
		||||
 | 
			
		||||
         2  2  3
 | 
			
		||||
         1  3  3
 | 
			
		||||
        [torch.IntTensor of size (2,3)]
 | 
			
		||||
 | 
			
		||||
        tensor([[ 3,  3,  3],
 | 
			
		||||
                [ 3,  3,  3]], dtype=torch.int32)
 | 
			
		||||
    """
 | 
			
		||||
    # Overwriting reason:
 | 
			
		||||
    # `info` is being deprecated in favor of `btrifact_with_info`. This warning
 | 
			
		||||
@ -124,11 +117,10 @@ def btriunpack(LU_data, LU_pivots, unpack_data=True, unpack_pivots=True):
 | 
			
		||||
 | 
			
		||||
        >>> A = torch.randn(2, 3, 3)
 | 
			
		||||
        >>> A_LU, pivots = A.btrifact()
 | 
			
		||||
        >>> P, a_L, a_U = torch.btriunpack(A_LU, pivots)
 | 
			
		||||
        >>> P, A_L, A_U = torch.btriunpack(A_LU, pivots)
 | 
			
		||||
        >>>
 | 
			
		||||
        >>> # test that (P, A_L, A_U) gives LU factorization
 | 
			
		||||
        >>> # can recover A from factorization
 | 
			
		||||
        >>> A_ = torch.bmm(P, torch.bmm(A_L, A_U))
 | 
			
		||||
        >>> assert torch.equal(A_, A) == True  # can recover A
 | 
			
		||||
    """
 | 
			
		||||
 | 
			
		||||
    nBatch, sz, _ = LU_data.size()
 | 
			
		||||
@ -311,11 +303,8 @@ def isnan(tensor):
 | 
			
		||||
 | 
			
		||||
    Example::
 | 
			
		||||
 | 
			
		||||
        >>> torch.isnan(torch.Tensor([1, float('nan'), 2]))
 | 
			
		||||
         0
 | 
			
		||||
         1
 | 
			
		||||
         0
 | 
			
		||||
        [torch.ByteTensor of size 3]
 | 
			
		||||
        >>> torch.isnan(torch.tensor([1, float('nan'), 2]))
 | 
			
		||||
        tensor([ 0,  1,  0], dtype=torch.uint8)
 | 
			
		||||
    """
 | 
			
		||||
    if not isinstance(tensor, torch.Tensor):
 | 
			
		||||
        raise ValueError("The argument is not a tensor")
 | 
			
		||||
@ -344,45 +333,25 @@ def unique(input, sorted=False, return_inverse=False):
 | 
			
		||||
 | 
			
		||||
    Example::
 | 
			
		||||
 | 
			
		||||
        >>>> output = torch.unique(torch.LongTensor([1, 3, 2, 3]))
 | 
			
		||||
        >>>> output
 | 
			
		||||
        >>> output = torch.unique(torch.tensor([1, 3, 2, 3], dtype=torch.long))
 | 
			
		||||
        >>> output
 | 
			
		||||
        tensor([ 2,  3,  1])
 | 
			
		||||
 | 
			
		||||
         2
 | 
			
		||||
         3
 | 
			
		||||
         1
 | 
			
		||||
        [torch.LongTensor of size (3,)]
 | 
			
		||||
        >>> output, inverse_indices = torch.unique(
 | 
			
		||||
                torch.tensor([1, 3, 2, 3], dtype=torch.long), sorted=True, return_inverse=True)
 | 
			
		||||
        >>> output
 | 
			
		||||
        tensor([ 1,  2,  3])
 | 
			
		||||
        >>> inverse_indices
 | 
			
		||||
        tensor([ 0,  2,  1,  2])
 | 
			
		||||
 | 
			
		||||
        >>>> output, inverse_indices = torch.unique(
 | 
			
		||||
                 torch.LongTensor([1, 3, 2, 3]), sorted=True, return_inverse=True)
 | 
			
		||||
        >>>> output
 | 
			
		||||
        >>> output, inverse_indices = torch.unique(
 | 
			
		||||
                torch.tensor([[1, 3], [2, 3]], dtype=torch.long), sorted=True, return_inverse=True)
 | 
			
		||||
        >>> output
 | 
			
		||||
        tensor([ 1,  2,  3])
 | 
			
		||||
        >>> inverse_indices
 | 
			
		||||
        tensor([[ 0,  2],
 | 
			
		||||
                [ 1,  2]])
 | 
			
		||||
 | 
			
		||||
         1
 | 
			
		||||
         2
 | 
			
		||||
         3
 | 
			
		||||
        [torch.LongTensor of size (3,)]
 | 
			
		||||
 | 
			
		||||
        >>>> inverse_indices
 | 
			
		||||
 | 
			
		||||
         0
 | 
			
		||||
         2
 | 
			
		||||
         1
 | 
			
		||||
         2
 | 
			
		||||
        [torch.LongTensor of size (4,)]
 | 
			
		||||
 | 
			
		||||
        >>>> output, inverse_indices = torch.unique(
 | 
			
		||||
                 torch.LongTensor([[1, 3], [2, 3]]), sorted=True, return_inverse=True)
 | 
			
		||||
        >>>> output
 | 
			
		||||
 | 
			
		||||
         1
 | 
			
		||||
         2
 | 
			
		||||
         3
 | 
			
		||||
        [torch.LongTensor of size (3,)]
 | 
			
		||||
 | 
			
		||||
        >>>> inverse_indices
 | 
			
		||||
 | 
			
		||||
         0  2
 | 
			
		||||
         1  2
 | 
			
		||||
        [torch.LongTensor of size (2,2)]
 | 
			
		||||
    """
 | 
			
		||||
    output, inverse_indices = torch._unique(
 | 
			
		||||
        input,
 | 
			
		||||
@ -412,19 +381,14 @@ def argmax(input, dim=None, keepdim=False):
 | 
			
		||||
 | 
			
		||||
        >>> a = torch.randn(4, 4)
 | 
			
		||||
        >>> a
 | 
			
		||||
        tensor([[ 1.3398,  0.2663, -0.2686,  0.2450],
 | 
			
		||||
                [-0.7401, -0.8805, -0.3402, -1.1936],
 | 
			
		||||
                [ 0.4907, -1.3948, -1.0691, -0.3132],
 | 
			
		||||
                [-1.6092,  0.5419, -0.2993,  0.3195]])
 | 
			
		||||
 | 
			
		||||
         2.3461  0.0056  1.4846  0.3911
 | 
			
		||||
        -1.3584 -1.0066  0.0530  1.1754
 | 
			
		||||
        -0.7929 -0.3194 -1.4865  0.4020
 | 
			
		||||
         0.1101  0.6694  1.3456  0.8235
 | 
			
		||||
        [torch.FloatTensor of size (4,4)]
 | 
			
		||||
 | 
			
		||||
        >>> torch.argmax(a, dim=1)
 | 
			
		||||
        0
 | 
			
		||||
        3
 | 
			
		||||
        3
 | 
			
		||||
        2
 | 
			
		||||
        [torch.LongTensor of size (4,)]
 | 
			
		||||
        tensor([ 0,  2,  0,  1])
 | 
			
		||||
    """
 | 
			
		||||
    if dim is None:
 | 
			
		||||
        return torch._argmax(input.contiguous().view(-1), dim=0, keepdim=False)
 | 
			
		||||
@ -448,19 +412,14 @@ def argmin(input, dim=None, keepdim=False):
 | 
			
		||||
 | 
			
		||||
        >>> a = torch.randn(4, 4)
 | 
			
		||||
        >>> a
 | 
			
		||||
        tensor([[ 0.1139,  0.2254, -0.1381,  0.3687],
 | 
			
		||||
                [ 1.0100, -1.1975, -0.0102, -0.4732],
 | 
			
		||||
                [-0.9240,  0.1207, -0.7506, -1.0213],
 | 
			
		||||
                [ 1.7809, -1.2960,  0.9384,  0.1438]])
 | 
			
		||||
 | 
			
		||||
         2.3461  0.0056  1.4846  0.3911
 | 
			
		||||
        -1.3584 -1.0066  0.0530  1.1754
 | 
			
		||||
        -0.7929 -0.3194 -1.4865  0.4020
 | 
			
		||||
         0.1101  0.6694  1.3456  0.8235
 | 
			
		||||
        [torch.FloatTensor of size (4,4)]
 | 
			
		||||
 | 
			
		||||
        >>> torch.argmin(a, dim=1)
 | 
			
		||||
         1
 | 
			
		||||
         0
 | 
			
		||||
         2
 | 
			
		||||
         0
 | 
			
		||||
        [torch.LongTensor of size (4,)]
 | 
			
		||||
        tensor([ 2,  1,  3,  1])
 | 
			
		||||
    """
 | 
			
		||||
    if dim is None:
 | 
			
		||||
        return torch._argmin(input.contiguous().view(-1), dim=0, keepdim=False)
 | 
			
		||||
 | 
			
		||||
@ -21,17 +21,6 @@ ELSE ()
 | 
			
		||||
  SET(CMAKE_CXX_STANDARD 11)
 | 
			
		||||
ENDIF ()
 | 
			
		||||
 | 
			
		||||
IF ($ENV{PYTORCH_BINARY_BUILD})
 | 
			
		||||
  MESSAGE(STATUS "PYTORCH_BINARY_BUILD detected. Statically linking libstdc++")
 | 
			
		||||
  SET(CMAKE_CXX_FLAGS "-static-libstdc++ ${CMAKE_CXX_FLAGS}")
 | 
			
		||||
 | 
			
		||||
  IF (UNIX AND NOT APPLE)
 | 
			
		||||
    # hiding statically linked library symbols, this flag is not available for the linker under macOS
 | 
			
		||||
    SET(CMAKE_CXX_FLAGS "-Wl,--exclude-libs,libstdc++.a ${CMAKE_CXX_FLAGS}")
 | 
			
		||||
  ENDIF(UNIX AND NOT APPLE)
 | 
			
		||||
 | 
			
		||||
ENDIF()
 | 
			
		||||
 | 
			
		||||
ADD_LIBRARY(shm SHARED core.cpp)
 | 
			
		||||
ADD_EXECUTABLE(torch_shm_manager manager.cpp)
 | 
			
		||||
INCLUDE_DIRECTORIES(${CMAKE_CURRENT_SOURCE_DIR})
 | 
			
		||||
 | 
			
		||||
@ -232,11 +232,9 @@ def avg_pool1d(input, kernel_size, stride=None, padding=0,
 | 
			
		||||
 | 
			
		||||
    Example::
 | 
			
		||||
        >>> # pool of square window of size=3, stride=2
 | 
			
		||||
        >>> input = torch.Tensor([[[1,2,3,4,5,6,7]]])
 | 
			
		||||
        >>> input = torch.tensor([[[1,2,3,4,5,6,7]]])
 | 
			
		||||
        >>> F.avg_pool1d(input, kernel_size=3, stride=2)
 | 
			
		||||
        (0 ,.,.) =
 | 
			
		||||
          2  4  6
 | 
			
		||||
        [torch.FloatTensor of size (1,1,3)]
 | 
			
		||||
        tensor([[[ 2.,  4.,  6.]]])
 | 
			
		||||
    """
 | 
			
		||||
    if input.dim() != 3:
 | 
			
		||||
        raise ValueError('expected 3D input (got {} dimensions)'
 | 
			
		||||
@ -1038,38 +1036,30 @@ def embedding(input, weight, padding_idx=None, max_norm=None, norm_type=2,
 | 
			
		||||
    Examples::
 | 
			
		||||
 | 
			
		||||
        >>> # a batch of 2 samples of 4 indices each
 | 
			
		||||
        >>> input = torch.LongTensor([[1,2,4,5],[4,3,2,9]])
 | 
			
		||||
        >>> input = torch.tensor([[1,2,4,5],[4,3,2,9]])
 | 
			
		||||
        >>> # an embedding matrix containing 10 tensors of size 3
 | 
			
		||||
        >>> embedding_matrix = torch.rand(10, 3)
 | 
			
		||||
        >>> F.embedding(input, embedding_matrix)
 | 
			
		||||
        tensor([[[ 0.8490,  0.9625,  0.6753],
 | 
			
		||||
                 [ 0.9666,  0.7761,  0.6108],
 | 
			
		||||
                 [ 0.6246,  0.9751,  0.3618],
 | 
			
		||||
                 [ 0.4161,  0.2419,  0.7383]],
 | 
			
		||||
 | 
			
		||||
        (0 ,.,.) =
 | 
			
		||||
         -1.0822  1.2522  0.2434
 | 
			
		||||
          0.8393 -0.6062 -0.3348
 | 
			
		||||
          0.6597  0.0350  0.0837
 | 
			
		||||
          0.5521  0.9447  0.0498
 | 
			
		||||
 | 
			
		||||
        (1 ,.,.) =
 | 
			
		||||
          0.6597  0.0350  0.0837
 | 
			
		||||
         -0.1527  0.0877  0.4260
 | 
			
		||||
          0.8393 -0.6062 -0.3348
 | 
			
		||||
         -0.8738 -0.9054  0.4281
 | 
			
		||||
        [torch.FloatTensor of size (2,4,3)]
 | 
			
		||||
                [[ 0.6246,  0.9751,  0.3618],
 | 
			
		||||
                 [ 0.0237,  0.7794,  0.0528],
 | 
			
		||||
                 [ 0.9666,  0.7761,  0.6108],
 | 
			
		||||
                 [ 0.3385,  0.8612,  0.1867]]])
 | 
			
		||||
 | 
			
		||||
        >>> # example with padding_idx
 | 
			
		||||
        >>> weights = torch.rand(10, 3)
 | 
			
		||||
        >>> weights[0, :].zero_()
 | 
			
		||||
        >>> embedding_matrix = weights
 | 
			
		||||
        >>> input = torch.LongTensor([[0,2,0,5]])
 | 
			
		||||
        >>> input = torch.tensor([[0,2,0,5]])
 | 
			
		||||
        >>> F.embedding(input, embedding_matrix, padding_idx=0)
 | 
			
		||||
 | 
			
		||||
        (0 ,.,.) =
 | 
			
		||||
          0.0000  0.0000  0.0000
 | 
			
		||||
          0.3452  0.4937 -0.9361
 | 
			
		||||
          0.0000  0.0000  0.0000
 | 
			
		||||
          0.0706 -2.1962 -0.6276
 | 
			
		||||
        [torch.FloatTensor of size (1,4,3)]
 | 
			
		||||
 | 
			
		||||
        tensor([[[ 0.0000,  0.0000,  0.0000],
 | 
			
		||||
                 [ 0.5609,  0.5384,  0.8720],
 | 
			
		||||
                 [ 0.0000,  0.0000,  0.0000],
 | 
			
		||||
                 [ 0.6262,  0.2438,  0.7471]]])
 | 
			
		||||
    """
 | 
			
		||||
    input = input.contiguous()
 | 
			
		||||
    if padding_idx is not None:
 | 
			
		||||
@ -1133,14 +1123,11 @@ def embedding_bag(embedding_matrix, indices, offsets=None,
 | 
			
		||||
            >>> # an Embedding module containing 10 tensors of size 3
 | 
			
		||||
            >>> embedding_matrix = torch.rand(10, 3)
 | 
			
		||||
            >>> # a batch of 2 samples of 4 indices each
 | 
			
		||||
            >>> input = torch.LongTensor([1,2,4,5,4,3,2,9])
 | 
			
		||||
            >>> offsets = torch.LongTensor([0,4])
 | 
			
		||||
            >>> embedding_bag(embedding_matrix, input, offsets)
 | 
			
		||||
 | 
			
		||||
            -1.1840 -0.2547 -0.5860
 | 
			
		||||
            -0.7126  0.0002 -0.3411
 | 
			
		||||
            [torch.FloatTensor of size (2,3)]
 | 
			
		||||
 | 
			
		||||
            >>> input = torch.tensor([1,2,4,5,4,3,2,9])
 | 
			
		||||
            >>> offsets = torch.tensor([0,4])
 | 
			
		||||
            >>> F.embedding_bag(embedding_matrix, input, offsets)
 | 
			
		||||
            tensor([[ 0.3397,  0.3552,  0.5545],
 | 
			
		||||
                    [ 0.5893,  0.4386,  0.5882]])
 | 
			
		||||
        """
 | 
			
		||||
    if indices.dim() == 2:
 | 
			
		||||
        if offsets is not None:
 | 
			
		||||
@ -1328,9 +1315,9 @@ def nll_loss(input, target, weight=None, size_average=True, ignore_index=-100, r
 | 
			
		||||
    Example::
 | 
			
		||||
 | 
			
		||||
        >>> # input is of size N x C = 3 x 5
 | 
			
		||||
        >>> input = torch.randn(3, 5)
 | 
			
		||||
        >>> input = torch.randn(3, 5, requires_grad=True)
 | 
			
		||||
        >>> # each element in target has to have 0 <= value < C
 | 
			
		||||
        >>> target = torch.LongTensor([1, 0, 4])
 | 
			
		||||
        >>> target = torch.tensor([1, 0, 4])
 | 
			
		||||
        >>> output = F.nll_loss(F.log_softmax(input), target)
 | 
			
		||||
        >>> output.backward()
 | 
			
		||||
    """
 | 
			
		||||
@ -1448,7 +1435,7 @@ def cross_entropy(input, target, weight=None, size_average=True, ignore_index=-1
 | 
			
		||||
    Examples::
 | 
			
		||||
 | 
			
		||||
        >>> input = torch.randn(3, 5, requires_grad=True)
 | 
			
		||||
        >>> target = torch.LongTensor(3).random_(5)
 | 
			
		||||
        >>> target = torch.randint(5, (3,), dtype=torch.int64)
 | 
			
		||||
        >>> loss = F.cross_entropy(input, target)
 | 
			
		||||
        >>> loss.backward()
 | 
			
		||||
    """
 | 
			
		||||
@ -1477,8 +1464,8 @@ def binary_cross_entropy(input, target, weight=None, size_average=True, reduce=T
 | 
			
		||||
 | 
			
		||||
    Examples::
 | 
			
		||||
 | 
			
		||||
        >>> input = torch.randn(3, requires_grad=True)
 | 
			
		||||
        >>> target = torch.LongTensor(3).random_(2)
 | 
			
		||||
        >>> input = torch.randn((3, 2), requires_grad=True)
 | 
			
		||||
        >>> target = torch.rand((3, 2), requires_grad=False)
 | 
			
		||||
        >>> loss = F.binary_cross_entropy(F.sigmoid(input), target)
 | 
			
		||||
        >>> loss.backward()
 | 
			
		||||
    """
 | 
			
		||||
@ -1519,7 +1506,7 @@ def binary_cross_entropy_with_logits(input, target, weight=None, size_average=Tr
 | 
			
		||||
    Examples::
 | 
			
		||||
 | 
			
		||||
         >>> input = torch.randn(3, requires_grad=True)
 | 
			
		||||
         >>> target = torch.FloatTensor(3).random_(2)
 | 
			
		||||
         >>> target = torch.empty(3).random_(2)
 | 
			
		||||
         >>> loss = F.binary_cross_entropy_with_logits(input, target)
 | 
			
		||||
         >>> loss.backward()
 | 
			
		||||
    """
 | 
			
		||||
@ -1657,7 +1644,7 @@ def pixel_shuffle(input, upscale_factor):
 | 
			
		||||
    Examples::
 | 
			
		||||
 | 
			
		||||
        >>> ps = nn.PixelShuffle(3)
 | 
			
		||||
        >>> input = torch.Tensor(1, 9, 4, 4)
 | 
			
		||||
        >>> input = torch.empty(1, 9, 4, 4)
 | 
			
		||||
        >>> output = ps(input)
 | 
			
		||||
        >>> print(output.size())
 | 
			
		||||
        torch.Size([1, 1, 12, 12])
 | 
			
		||||
@ -1920,7 +1907,7 @@ def pad(input, pad, mode='constant', value=0):
 | 
			
		||||
 | 
			
		||||
    Examples::
 | 
			
		||||
 | 
			
		||||
        >>> t4d = torch.Tensor(3, 3, 4, 2)
 | 
			
		||||
        >>> t4d = torch.empty(3, 3, 4, 2)
 | 
			
		||||
        >>> p1d = (1, 1) # pad last dim by 1 on each side
 | 
			
		||||
        >>> out = F.pad(t4d, p1d, "constant", 0)  # effectively zero padding
 | 
			
		||||
        >>> print(out.data.size())
 | 
			
		||||
@ -1929,7 +1916,7 @@ def pad(input, pad, mode='constant', value=0):
 | 
			
		||||
        >>> out = F.pad(t4d, p2d, "constant", 0)
 | 
			
		||||
        >>> print(out.data.size())
 | 
			
		||||
        torch.Size([3, 3, 8, 4])
 | 
			
		||||
        >>> t4d = torch.Tensor(3, 3, 4, 2)
 | 
			
		||||
        >>> t4d = torch.empty(3, 3, 4, 2)
 | 
			
		||||
        >>> p3d = (0, 1, 2, 1, 3, 3) # pad by (0, 1), (2, 1), and (3, 3)
 | 
			
		||||
        >>> out = F.pad(t4d, p3d, "constant", 0)
 | 
			
		||||
        >>> print(out.data.size())
 | 
			
		||||
 | 
			
		||||
@ -57,7 +57,7 @@ def uniform_(tensor, a=0, b=1):
 | 
			
		||||
        b: the upper bound of the uniform distribution
 | 
			
		||||
 | 
			
		||||
    Examples:
 | 
			
		||||
        >>> w = torch.Tensor(3, 5)
 | 
			
		||||
        >>> w = torch.empty(3, 5)
 | 
			
		||||
        >>> nn.init.uniform_(w)
 | 
			
		||||
    """
 | 
			
		||||
    with torch.no_grad():
 | 
			
		||||
@ -74,7 +74,7 @@ def normal_(tensor, mean=0, std=1):
 | 
			
		||||
        std: the standard deviation of the normal distribution
 | 
			
		||||
 | 
			
		||||
    Examples:
 | 
			
		||||
        >>> w = torch.Tensor(3, 5)
 | 
			
		||||
        >>> w = torch.empty(3, 5)
 | 
			
		||||
        >>> nn.init.normal_(w)
 | 
			
		||||
    """
 | 
			
		||||
    with torch.no_grad():
 | 
			
		||||
@ -89,7 +89,7 @@ def constant_(tensor, val):
 | 
			
		||||
        val: the value to fill the tensor with
 | 
			
		||||
 | 
			
		||||
    Examples:
 | 
			
		||||
        >>> w = torch.Tensor(3, 5)
 | 
			
		||||
        >>> w = torch.empty(3, 5)
 | 
			
		||||
        >>> nn.init.constant_(w, 0.3)
 | 
			
		||||
    """
 | 
			
		||||
    with torch.no_grad():
 | 
			
		||||
@ -105,7 +105,7 @@ def eye_(tensor):
 | 
			
		||||
        tensor: a 2-dimensional `torch.Tensor`
 | 
			
		||||
 | 
			
		||||
    Examples:
 | 
			
		||||
        >>> w = torch.Tensor(3, 5)
 | 
			
		||||
        >>> w = torch.empty(3, 5)
 | 
			
		||||
        >>> nn.init.eye_(w)
 | 
			
		||||
    """
 | 
			
		||||
    if tensor.ndimension() != 2:
 | 
			
		||||
@ -125,7 +125,7 @@ def dirac_(tensor):
 | 
			
		||||
        tensor: a {3, 4, 5}-dimensional `torch.Tensor`
 | 
			
		||||
 | 
			
		||||
    Examples:
 | 
			
		||||
        >>> w = torch.Tensor(3, 16, 5, 5)
 | 
			
		||||
        >>> w = torch.empty(3, 16, 5, 5)
 | 
			
		||||
        >>> nn.init.dirac_(w)
 | 
			
		||||
    """
 | 
			
		||||
    dimensions = tensor.ndimension()
 | 
			
		||||
@ -184,7 +184,7 @@ def xavier_uniform_(tensor, gain=1):
 | 
			
		||||
        gain: an optional scaling factor
 | 
			
		||||
 | 
			
		||||
    Examples:
 | 
			
		||||
        >>> w = torch.Tensor(3, 5)
 | 
			
		||||
        >>> w = torch.empty(3, 5)
 | 
			
		||||
        >>> nn.init.xavier_uniform_(w, gain=nn.init.calculate_gain('relu'))
 | 
			
		||||
    """
 | 
			
		||||
    fan_in, fan_out = _calculate_fan_in_and_fan_out(tensor)
 | 
			
		||||
@ -211,7 +211,7 @@ def xavier_normal_(tensor, gain=1):
 | 
			
		||||
        gain: an optional scaling factor
 | 
			
		||||
 | 
			
		||||
    Examples:
 | 
			
		||||
        >>> w = torch.Tensor(3, 5)
 | 
			
		||||
        >>> w = torch.empty(3, 5)
 | 
			
		||||
        >>> nn.init.xavier_normal_(w)
 | 
			
		||||
    """
 | 
			
		||||
    fan_in, fan_out = _calculate_fan_in_and_fan_out(tensor)
 | 
			
		||||
@ -254,7 +254,7 @@ def kaiming_uniform_(tensor, a=0, mode='fan_in', nonlinearity='leaky_relu'):
 | 
			
		||||
            recommended to use only with 'relu' or 'leaky_relu' (default).
 | 
			
		||||
 | 
			
		||||
    Examples:
 | 
			
		||||
        >>> w = torch.Tensor(3, 5)
 | 
			
		||||
        >>> w = torch.empty(3, 5)
 | 
			
		||||
        >>> nn.init.kaiming_uniform_(w, mode='fan_in', nonlinearity='relu')
 | 
			
		||||
    """
 | 
			
		||||
    fan = _calculate_correct_fan(tensor, mode)
 | 
			
		||||
@ -289,7 +289,7 @@ def kaiming_normal_(tensor, a=0, mode='fan_in', nonlinearity='leaky_relu'):
 | 
			
		||||
            recommended to use only with 'relu' or 'leaky_relu' (default).
 | 
			
		||||
 | 
			
		||||
    Examples:
 | 
			
		||||
        >>> w = torch.Tensor(3, 5)
 | 
			
		||||
        >>> w = torch.empty(3, 5)
 | 
			
		||||
        >>> nn.init.kaiming_normal_(w, mode='fan_out', nonlinearity='relu')
 | 
			
		||||
    """
 | 
			
		||||
    fan = _calculate_correct_fan(tensor, mode)
 | 
			
		||||
@ -311,7 +311,7 @@ def orthogonal_(tensor, gain=1):
 | 
			
		||||
        gain: optional scaling factor
 | 
			
		||||
 | 
			
		||||
    Examples:
 | 
			
		||||
        >>> w = torch.Tensor(3, 5)
 | 
			
		||||
        >>> w = torch.empty(3, 5)
 | 
			
		||||
        >>> nn.init.orthogonal_(w)
 | 
			
		||||
    """
 | 
			
		||||
    if tensor.ndimension() < 2:
 | 
			
		||||
@ -353,7 +353,7 @@ def sparse_(tensor, sparsity, std=0.01):
 | 
			
		||||
            the non-zero values
 | 
			
		||||
 | 
			
		||||
    Examples:
 | 
			
		||||
        >>> w = torch.Tensor(3, 5)
 | 
			
		||||
        >>> w = torch.empty(3, 5)
 | 
			
		||||
        >>> nn.init.sparse_(w, sparsity=0.1)
 | 
			
		||||
    """
 | 
			
		||||
    if tensor.ndimension() != 2:
 | 
			
		||||
 | 
			
		||||
@ -166,7 +166,7 @@ class NLLLoss(_WeightedLoss):
 | 
			
		||||
        >>> # input is of size N x C = 3 x 5
 | 
			
		||||
        >>> input = torch.randn(3, 5, requires_grad=True)
 | 
			
		||||
        >>> # each element in target has to have 0 <= value < C
 | 
			
		||||
        >>> target = torch.LongTensor([1, 0, 4])
 | 
			
		||||
        >>> target = torch.tensor([1, 0, 4])
 | 
			
		||||
        >>> output = loss(m(input), target)
 | 
			
		||||
        >>> output.backward()
 | 
			
		||||
        >>>
 | 
			
		||||
@ -178,7 +178,7 @@ class NLLLoss(_WeightedLoss):
 | 
			
		||||
        >>> data = torch.randn(N, 16, 10, 10)
 | 
			
		||||
        >>> m = nn.Conv2d(16, C, (3, 3))
 | 
			
		||||
        >>> # each element in target has to have 0 <= value < C
 | 
			
		||||
        >>> target = torch.LongTensor(N, 8, 8).random_(0, C)
 | 
			
		||||
        >>> target = torch.tensor(N, 8, 8).random_(0, C)
 | 
			
		||||
        >>> output = loss(m(data), target)
 | 
			
		||||
        >>> output.backward()
 | 
			
		||||
    """
 | 
			
		||||
@ -419,7 +419,7 @@ class BCELoss(_WeightedLoss):
 | 
			
		||||
        >>> m = nn.Sigmoid()
 | 
			
		||||
        >>> loss = nn.BCELoss()
 | 
			
		||||
        >>> input = torch.randn(3, requires_grad=True)
 | 
			
		||||
        >>> target = torch.FloatTensor(3).random_(2)
 | 
			
		||||
        >>> target = torch.empty(3).random_(2)
 | 
			
		||||
        >>> output = loss(m(input), target)
 | 
			
		||||
        >>> output.backward()
 | 
			
		||||
    """
 | 
			
		||||
@ -480,7 +480,7 @@ class BCEWithLogitsLoss(_Loss):
 | 
			
		||||
 | 
			
		||||
        >>> loss = nn.BCEWithLogitsLoss()
 | 
			
		||||
        >>> input = torch.randn(3, requires_grad=True)
 | 
			
		||||
        >>> target = torch.FloatTensor(3).random_(2)
 | 
			
		||||
        >>> target = torch.empty(3).random_(2)
 | 
			
		||||
        >>> output = loss(input, target)
 | 
			
		||||
        >>> output.backward()
 | 
			
		||||
    """
 | 
			
		||||
@ -744,7 +744,7 @@ class CrossEntropyLoss(_WeightedLoss):
 | 
			
		||||
 | 
			
		||||
        >>> loss = nn.CrossEntropyLoss()
 | 
			
		||||
        >>> input = torch.randn(3, 5, requires_grad=True)
 | 
			
		||||
        >>> target = torch.LongTensor(3).random_(5)
 | 
			
		||||
        >>> target = torch.empty(3, dtype=torch.long).random_(5)
 | 
			
		||||
        >>> output = loss(input, target)
 | 
			
		||||
        >>> output.backward()
 | 
			
		||||
    """
 | 
			
		||||
 | 
			
		||||
@ -211,17 +211,13 @@ class Module(object):
 | 
			
		||||
            >>> net = nn.Sequential(nn.Linear(2, 2), nn.Linear(2, 2))
 | 
			
		||||
            >>> net.apply(init_weights)
 | 
			
		||||
            Linear(in_features=2, out_features=2, bias=True)
 | 
			
		||||
 | 
			
		||||
             1  1
 | 
			
		||||
             1  1
 | 
			
		||||
            [torch.FloatTensor of size (2,2)]
 | 
			
		||||
 | 
			
		||||
            Parameter containing:
 | 
			
		||||
            tensor([[ 1.,  1.],
 | 
			
		||||
                    [ 1.,  1.]])
 | 
			
		||||
            Linear(in_features=2, out_features=2, bias=True)
 | 
			
		||||
 | 
			
		||||
             1  1
 | 
			
		||||
             1  1
 | 
			
		||||
            [torch.FloatTensor of size (2,2)]
 | 
			
		||||
 | 
			
		||||
            Parameter containing:
 | 
			
		||||
            tensor([[ 1.,  1.],
 | 
			
		||||
                    [ 1.,  1.]])
 | 
			
		||||
            Sequential(
 | 
			
		||||
              (0): Linear(in_features=2, out_features=2, bias=True)
 | 
			
		||||
              (1): Linear(in_features=2, out_features=2, bias=True)
 | 
			
		||||
@ -230,7 +226,6 @@ class Module(object):
 | 
			
		||||
              (0): Linear(in_features=2, out_features=2, bias=True)
 | 
			
		||||
              (1): Linear(in_features=2, out_features=2, bias=True)
 | 
			
		||||
            )
 | 
			
		||||
 | 
			
		||||
        """
 | 
			
		||||
        for module in self.children():
 | 
			
		||||
            module.apply(fn)
 | 
			
		||||
 | 
			
		||||
@ -23,7 +23,7 @@ class PixelShuffle(Module):
 | 
			
		||||
    Examples::
 | 
			
		||||
 | 
			
		||||
        >>> ps = nn.PixelShuffle(3)
 | 
			
		||||
        >>> input = torch.Tensor(1, 9, 4, 4)
 | 
			
		||||
        >>> input = torch.tensor(1, 9, 4, 4)
 | 
			
		||||
        >>> output = ps(input)
 | 
			
		||||
        >>> print(output.size())
 | 
			
		||||
        torch.Size([1, 1, 12, 12])
 | 
			
		||||
 | 
			
		||||
@ -256,29 +256,19 @@ class MaxUnpool1d(_MaxUnpoolNd):
 | 
			
		||||
 | 
			
		||||
        >>> pool = nn.MaxPool1d(2, stride=2, return_indices=True)
 | 
			
		||||
        >>> unpool = nn.MaxUnpool1d(2, stride=2)
 | 
			
		||||
        >>> input = torch.Tensor([[[1, 2, 3, 4, 5, 6, 7, 8]]])
 | 
			
		||||
        >>> input = torch.tensor([[[1., 2, 3, 4, 5, 6, 7, 8]]])
 | 
			
		||||
        >>> output, indices = pool(input)
 | 
			
		||||
        >>> unpool(output, indices)
 | 
			
		||||
 | 
			
		||||
        (0 ,.,.) =
 | 
			
		||||
           0   2   0   4   0   6   0   8
 | 
			
		||||
        [torch.FloatTensor of size (1,1,8)]
 | 
			
		||||
        tensor([[[ 0.,  2.,  0.,  4.,  0.,  6.,  0., 8.]]])
 | 
			
		||||
 | 
			
		||||
        >>> # Example showcasing the use of output_size
 | 
			
		||||
        >>> input = torch.Tensor([[[1, 2, 3, 4, 5, 6, 7, 8, 9]]])
 | 
			
		||||
        >>> input = torch.tensor([[[1., 2, 3, 4, 5, 6, 7, 8, 9]]])
 | 
			
		||||
        >>> output, indices = pool(input)
 | 
			
		||||
        >>> unpool(output, indices, output_size=input.size())
 | 
			
		||||
 | 
			
		||||
        (0 ,.,.) =
 | 
			
		||||
           0   2   0   4   0   6   0   8   0
 | 
			
		||||
        [torch.FloatTensor of size (1,1,9)]
 | 
			
		||||
        tensor([[[ 0.,  2.,  0.,  4.,  0.,  6.,  0., 8.,  0.]]])
 | 
			
		||||
 | 
			
		||||
        >>> unpool(output, indices)
 | 
			
		||||
 | 
			
		||||
        (0 ,.,.) =
 | 
			
		||||
           0   2   0   4   0   6   0   8
 | 
			
		||||
        [torch.FloatTensor of size (1,1,8)]
 | 
			
		||||
 | 
			
		||||
        tensor([[[ 0.,  2.,  0.,  4.,  0.,  6.,  0., 8.]]])
 | 
			
		||||
    """
 | 
			
		||||
 | 
			
		||||
    def __init__(self, kernel_size, stride=None, padding=0):
 | 
			
		||||
@ -333,31 +323,24 @@ class MaxUnpool2d(_MaxUnpoolNd):
 | 
			
		||||
 | 
			
		||||
        >>> pool = nn.MaxPool2d(2, stride=2, return_indices=True)
 | 
			
		||||
        >>> unpool = nn.MaxUnpool2d(2, stride=2)
 | 
			
		||||
        >>> input = torch.Tensor([[[[ 1,  2,  3,  4],
 | 
			
		||||
        >>> input = torch.tensor([[[[ 1.,  2,  3,  4],
 | 
			
		||||
                                    [ 5,  6,  7,  8],
 | 
			
		||||
                                    [ 9, 10, 11, 12],
 | 
			
		||||
                                    [13, 14, 15, 16]]]])
 | 
			
		||||
        >>> output, indices = pool(input)
 | 
			
		||||
        >>> unpool(output, indices)
 | 
			
		||||
 | 
			
		||||
        (0 ,0 ,.,.) =
 | 
			
		||||
           0   0   0   0
 | 
			
		||||
           0   6   0   8
 | 
			
		||||
           0   0   0   0
 | 
			
		||||
           0  14   0  16
 | 
			
		||||
        [torch.FloatTensor of size (1,1,4,4)]
 | 
			
		||||
        tensor([[[[  0.,   0.,   0.,   0.],
 | 
			
		||||
                  [  0.,   6.,   0.,   8.],
 | 
			
		||||
                  [  0.,   0.,   0.,   0.],
 | 
			
		||||
                  [  0.,  14.,   0.,  16.]]]])
 | 
			
		||||
 | 
			
		||||
        >>> # specify a different output size than input size
 | 
			
		||||
        >>> unpool(output, indices, output_size=torch.Size([1, 1, 5, 5]))
 | 
			
		||||
 | 
			
		||||
        (0 ,0 ,.,.) =
 | 
			
		||||
           0   0   0   0   0
 | 
			
		||||
           6   0   8   0   0
 | 
			
		||||
           0   0   0  14   0
 | 
			
		||||
          16   0   0   0   0
 | 
			
		||||
           0   0   0   0   0
 | 
			
		||||
        [torch.FloatTensor of size (1,1,5,5)]
 | 
			
		||||
 | 
			
		||||
        tensor([[[[  0.,   0.,   0.,   0.,   0.],
 | 
			
		||||
                  [  6.,   0.,   8.,   0.,   0.],
 | 
			
		||||
                  [  0.,   0.,   0.,  14.,   0.],
 | 
			
		||||
                  [ 16.,   0.,   0.,   0.,   0.],
 | 
			
		||||
                  [  0.,   0.,   0.,   0.,   0.]]]])
 | 
			
		||||
    """
 | 
			
		||||
 | 
			
		||||
    def __init__(self, kernel_size, stride=None, padding=0):
 | 
			
		||||
@ -479,11 +462,8 @@ class AvgPool1d(_AvgPoolNd):
 | 
			
		||||
 | 
			
		||||
        >>> # pool with window of size=3, stride=2
 | 
			
		||||
        >>> m = nn.AvgPool1d(3, stride=2)
 | 
			
		||||
        >>> m(torch.Tensor([[[1,2,3,4,5,6,7]]]))
 | 
			
		||||
 | 
			
		||||
        (0 ,.,.) =
 | 
			
		||||
          2  4  6
 | 
			
		||||
        [torch.FloatTensor of size (1,1,3)]
 | 
			
		||||
        >>> m(torch.tensor([[[1.,2,3,4,5,6,7]]]))
 | 
			
		||||
        tensor([[[ 2.,  4.,  6.]]])
 | 
			
		||||
    """
 | 
			
		||||
 | 
			
		||||
    def __init__(self, kernel_size, stride=None, padding=0, ceil_mode=False,
 | 
			
		||||
 | 
			
		||||
@ -51,32 +51,25 @@ class Embedding(Module):
 | 
			
		||||
        >>> # a batch of 2 samples of 4 indices each
 | 
			
		||||
        >>> input = torch.LongTensor([[1,2,4,5],[4,3,2,9]])
 | 
			
		||||
        >>> embedding(input)
 | 
			
		||||
        tensor([[[-0.0251, -1.6902,  0.7172],
 | 
			
		||||
                 [-0.6431,  0.0748,  0.6969],
 | 
			
		||||
                 [ 1.4970,  1.3448, -0.9685],
 | 
			
		||||
                 [-0.3677, -2.7265, -0.1685]],
 | 
			
		||||
 | 
			
		||||
        (0 ,.,.) =
 | 
			
		||||
         -1.0822  1.2522  0.2434
 | 
			
		||||
          0.8393 -0.6062 -0.3348
 | 
			
		||||
          0.6597  0.0350  0.0837
 | 
			
		||||
          0.5521  0.9447  0.0498
 | 
			
		||||
                [[ 1.4970,  1.3448, -0.9685],
 | 
			
		||||
                 [ 0.4362, -0.4004,  0.9400],
 | 
			
		||||
                 [-0.6431,  0.0748,  0.6969],
 | 
			
		||||
                 [ 0.9124, -2.3616,  1.1151]]])
 | 
			
		||||
 | 
			
		||||
        (1 ,.,.) =
 | 
			
		||||
          0.6597  0.0350  0.0837
 | 
			
		||||
         -0.1527  0.0877  0.4260
 | 
			
		||||
          0.8393 -0.6062 -0.3348
 | 
			
		||||
         -0.8738 -0.9054  0.4281
 | 
			
		||||
        [torch.FloatTensor of size (2,4,3)]
 | 
			
		||||
 | 
			
		||||
        >>> # example with padding_idx
 | 
			
		||||
        >>> embedding = nn.Embedding(10, 3, padding_idx=0)
 | 
			
		||||
        >>> input = torch.LongTensor([[0,2,0,5]])
 | 
			
		||||
        >>> embedding(input)
 | 
			
		||||
 | 
			
		||||
        (0 ,.,.) =
 | 
			
		||||
          0.0000  0.0000  0.0000
 | 
			
		||||
          0.3452  0.4937 -0.9361
 | 
			
		||||
          0.0000  0.0000  0.0000
 | 
			
		||||
          0.0706 -2.1962 -0.6276
 | 
			
		||||
        [torch.FloatTensor of size (1,4,3)]
 | 
			
		||||
 | 
			
		||||
        tensor([[[ 0.0000,  0.0000,  0.0000],
 | 
			
		||||
                 [ 0.1535, -2.0309,  0.9315],
 | 
			
		||||
                 [ 0.0000,  0.0000,  0.0000],
 | 
			
		||||
                 [-0.1655,  0.9897,  0.0635]]])
 | 
			
		||||
    """
 | 
			
		||||
 | 
			
		||||
    def __init__(self, num_embeddings, embedding_dim, padding_idx=None,
 | 
			
		||||
@ -140,15 +133,13 @@ class Embedding(Module):
 | 
			
		||||
 | 
			
		||||
        Examples::
 | 
			
		||||
 | 
			
		||||
            >> # FloatTensor containing pretrained weights
 | 
			
		||||
            >> weight = torch.FloatTensor([[1, 2.3, 3], [4, 5.1, 6.3]])
 | 
			
		||||
            >> embedding = nn.Embedding.from_pretrained(weight)
 | 
			
		||||
            >> # Get embeddings for index 1
 | 
			
		||||
            >> input = torch.LongTensor([1])
 | 
			
		||||
            >> embedding(input)
 | 
			
		||||
 | 
			
		||||
             4.0000  5.1000  6.3000
 | 
			
		||||
            [torch.FloatTensor of size (1,3)]
 | 
			
		||||
            >>> # FloatTensor containing pretrained weights
 | 
			
		||||
            >>> weight = torch.FloatTensor([[1, 2.3, 3], [4, 5.1, 6.3]])
 | 
			
		||||
            >>> embedding = nn.Embedding.from_pretrained(weight)
 | 
			
		||||
            >>> # Get embeddings for index 1
 | 
			
		||||
            >>> input = torch.LongTensor([1])
 | 
			
		||||
            >>> embedding(input)
 | 
			
		||||
            tensor([[ 4.0000,  5.1000,  6.3000]])
 | 
			
		||||
        """
 | 
			
		||||
        assert embeddings.dim() == 2, \
 | 
			
		||||
            'Embeddings parameter is expected to be 2-dimensional'
 | 
			
		||||
@ -215,11 +206,8 @@ class EmbeddingBag(Module):
 | 
			
		||||
        >>> input = torch.LongTensor([1,2,4,5,4,3,2,9])
 | 
			
		||||
        >>> offsets = torch.LongTensor([0,4])
 | 
			
		||||
        >>> embedding_sum(input, offsets)
 | 
			
		||||
 | 
			
		||||
        -0.7296 -4.6926  0.3295
 | 
			
		||||
        -0.5186 -0.5631 -0.2792
 | 
			
		||||
        [torch.FloatTensor of size (2,3)]
 | 
			
		||||
 | 
			
		||||
        tensor([[-0.8861, -5.4350, -0.0523],
 | 
			
		||||
                [ 1.1306, -2.5798, -1.0044]])
 | 
			
		||||
    """
 | 
			
		||||
 | 
			
		||||
    def __init__(self, num_embeddings, embedding_dim,
 | 
			
		||||
 | 
			
		||||
@ -52,80 +52,60 @@ class Upsample(Module):
 | 
			
		||||
 | 
			
		||||
        >>> input = torch.arange(1, 5).view(1, 1, 2, 2)
 | 
			
		||||
        >>> input
 | 
			
		||||
 | 
			
		||||
        (0 ,0 ,.,.) =
 | 
			
		||||
          1  2
 | 
			
		||||
          3  4
 | 
			
		||||
        [torch.FloatTensor of size (1,1,2,2)]
 | 
			
		||||
        tensor([[[[ 1.,  2.],
 | 
			
		||||
                  [ 3.,  4.]]]])
 | 
			
		||||
 | 
			
		||||
        >>> m = nn.Upsample(scale_factor=2, mode='nearest')
 | 
			
		||||
        >>> m(input)
 | 
			
		||||
 | 
			
		||||
        (0 ,0 ,.,.) =
 | 
			
		||||
          1  1  2  2
 | 
			
		||||
          1  1  2  2
 | 
			
		||||
          3  3  4  4
 | 
			
		||||
          3  3  4  4
 | 
			
		||||
        [torch.FloatTensor of size (1,1,4,4)]
 | 
			
		||||
        tensor([[[[ 1.,  1.,  2.,  2.],
 | 
			
		||||
                  [ 1.,  1.,  2.,  2.],
 | 
			
		||||
                  [ 3.,  3.,  4.,  4.],
 | 
			
		||||
                  [ 3.,  3.,  4.,  4.]]]])
 | 
			
		||||
 | 
			
		||||
        >>> m = nn.Upsample(scale_factor=2, mode='bilinear')  # align_corners=False
 | 
			
		||||
        >>> m(input)
 | 
			
		||||
 | 
			
		||||
        (0 ,0 ,.,.) =
 | 
			
		||||
          1.0000  1.2500  1.7500  2.0000
 | 
			
		||||
          1.5000  1.7500  2.2500  2.5000
 | 
			
		||||
          2.5000  2.7500  3.2500  3.5000
 | 
			
		||||
          3.0000  3.2500  3.7500  4.0000
 | 
			
		||||
        [torch.FloatTensor of size (1,1,4,4)]
 | 
			
		||||
        tensor([[[[ 1.0000,  1.2500,  1.7500,  2.0000],
 | 
			
		||||
                  [ 1.5000,  1.7500,  2.2500,  2.5000],
 | 
			
		||||
                  [ 2.5000,  2.7500,  3.2500,  3.5000],
 | 
			
		||||
                  [ 3.0000,  3.2500,  3.7500,  4.0000]]]])
 | 
			
		||||
 | 
			
		||||
        >>> m = nn.Upsample(scale_factor=2, mode='bilinear', align_corners=True)
 | 
			
		||||
        >>> m(input)
 | 
			
		||||
 | 
			
		||||
        (0 ,0 ,.,.) =
 | 
			
		||||
          1.0000  1.3333  1.6667  2.0000
 | 
			
		||||
          1.6667  2.0000  2.3333  2.6667
 | 
			
		||||
          2.3333  2.6667  3.0000  3.3333
 | 
			
		||||
          3.0000  3.3333  3.6667  4.0000
 | 
			
		||||
        [torch.FloatTensor of size (1,1,4,4)]
 | 
			
		||||
        tensor([[[[ 1.0000,  1.3333,  1.6667,  2.0000],
 | 
			
		||||
                  [ 1.6667,  2.0000,  2.3333,  2.6667],
 | 
			
		||||
                  [ 2.3333,  2.6667,  3.0000,  3.3333],
 | 
			
		||||
                  [ 3.0000,  3.3333,  3.6667,  4.0000]]]])
 | 
			
		||||
 | 
			
		||||
        >>> # Try scaling the same data in a larger tensor
 | 
			
		||||
        >>>
 | 
			
		||||
        >>> input_3x3 = torch.zeros(3, 3).view(1, 1, 3, 3)
 | 
			
		||||
        >>> input_3x3[:, :, :2, :2].copy_(input)
 | 
			
		||||
        tensor([[[[ 1.,  2.],
 | 
			
		||||
                  [ 3.,  4.]]]])
 | 
			
		||||
        >>> input_3x3
 | 
			
		||||
 | 
			
		||||
        (0 ,0 ,.,.) =
 | 
			
		||||
          1  2  0
 | 
			
		||||
          3  4  0
 | 
			
		||||
          0  0  0
 | 
			
		||||
        [torch.FloatTensor of size (1,1,3,3)]
 | 
			
		||||
        tensor([[[[ 1.,  2.,  0.],
 | 
			
		||||
                  [ 3.,  4.,  0.],
 | 
			
		||||
                  [ 0.,  0.,  0.]]]])
 | 
			
		||||
 | 
			
		||||
        >>> m = nn.Upsample(scale_factor=2, mode='bilinear')  # align_corners=False
 | 
			
		||||
        >>> # Notice that values in top left corner are the same with the small input (except at boundary)
 | 
			
		||||
        >>> m(input_3x3)
 | 
			
		||||
 | 
			
		||||
        (0 ,0 ,.,.) =
 | 
			
		||||
          1.0000  1.2500  1.7500  1.5000  0.5000  0.0000
 | 
			
		||||
          1.5000  1.7500  2.2500  1.8750  0.6250  0.0000
 | 
			
		||||
          2.5000  2.7500  3.2500  2.6250  0.8750  0.0000
 | 
			
		||||
          2.2500  2.4375  2.8125  2.2500  0.7500  0.0000
 | 
			
		||||
          0.7500  0.8125  0.9375  0.7500  0.2500  0.0000
 | 
			
		||||
          0.0000  0.0000  0.0000  0.0000  0.0000  0.0000
 | 
			
		||||
        [torch.FloatTensor of size (1,1,6,6)]
 | 
			
		||||
        tensor([[[[ 1.0000,  1.2500,  1.7500,  1.5000,  0.5000,  0.0000],
 | 
			
		||||
                  [ 1.5000,  1.7500,  2.2500,  1.8750,  0.6250,  0.0000],
 | 
			
		||||
                  [ 2.5000,  2.7500,  3.2500,  2.6250,  0.8750,  0.0000],
 | 
			
		||||
                  [ 2.2500,  2.4375,  2.8125,  2.2500,  0.7500,  0.0000],
 | 
			
		||||
                  [ 0.7500,  0.8125,  0.9375,  0.7500,  0.2500,  0.0000],
 | 
			
		||||
                  [ 0.0000,  0.0000,  0.0000,  0.0000,  0.0000,  0.0000]]]])
 | 
			
		||||
 | 
			
		||||
        >>> m = nn.Upsample(scale_factor=2, mode='bilinear', align_corners=True)
 | 
			
		||||
        >>> # Notice that values in top left corner are now changed
 | 
			
		||||
        >>> m(input_3x3)
 | 
			
		||||
 | 
			
		||||
        (0 ,0 ,.,.) =
 | 
			
		||||
          1.0000  1.4000  1.8000  1.6000  0.8000  0.0000
 | 
			
		||||
          1.8000  2.2000  2.6000  2.2400  1.1200  0.0000
 | 
			
		||||
          2.6000  3.0000  3.4000  2.8800  1.4400  0.0000
 | 
			
		||||
          2.4000  2.7200  3.0400  2.5600  1.2800  0.0000
 | 
			
		||||
          1.2000  1.3600  1.5200  1.2800  0.6400  0.0000
 | 
			
		||||
          0.0000  0.0000  0.0000  0.0000  0.0000  0.0000
 | 
			
		||||
        [torch.FloatTensor of size (1,1,6,6)]
 | 
			
		||||
 | 
			
		||||
        tensor([[[[ 1.0000,  1.4000,  1.8000,  1.6000,  0.8000,  0.0000],
 | 
			
		||||
                  [ 1.8000,  2.2000,  2.6000,  2.2400,  1.1200,  0.0000],
 | 
			
		||||
                  [ 2.6000,  3.0000,  3.4000,  2.8800,  1.4400,  0.0000],
 | 
			
		||||
                  [ 2.4000,  2.7200,  3.0400,  2.5600,  1.2800,  0.0000],
 | 
			
		||||
                  [ 1.2000,  1.3600,  1.5200,  1.2800,  0.6400,  0.0000],
 | 
			
		||||
                  [ 0.0000,  0.0000,  0.0000,  0.0000,  0.0000,  0.0000]]]])
 | 
			
		||||
    """
 | 
			
		||||
 | 
			
		||||
    def __init__(self, size=None, scale_factor=None, mode='nearest', align_corners=None):
 | 
			
		||||
@ -176,22 +156,15 @@ class UpsamplingNearest2d(Upsample):
 | 
			
		||||
 | 
			
		||||
        >>> input = torch.arange(1, 5).view(1, 1, 2, 2)
 | 
			
		||||
        >>> input
 | 
			
		||||
 | 
			
		||||
        (0 ,0 ,.,.) =
 | 
			
		||||
          1  2
 | 
			
		||||
          3  4
 | 
			
		||||
        [torch.FloatTensor of size (1,1,2,2)]
 | 
			
		||||
        tensor([[[[ 1.,  2.],
 | 
			
		||||
                  [ 3.,  4.]]]])
 | 
			
		||||
 | 
			
		||||
        >>> m = nn.UpsamplingNearest2d(scale_factor=2)
 | 
			
		||||
        >>> m(input)
 | 
			
		||||
 | 
			
		||||
        (0 ,0 ,.,.) =
 | 
			
		||||
          1  1  2  2
 | 
			
		||||
          1  1  2  2
 | 
			
		||||
          3  3  4  4
 | 
			
		||||
          3  3  4  4
 | 
			
		||||
        [torch.FloatTensor of size (1,1,4,4)]
 | 
			
		||||
 | 
			
		||||
        tensor([[[[ 1.,  1.,  2.,  2.],
 | 
			
		||||
                  [ 1.,  1.,  2.,  2.],
 | 
			
		||||
                  [ 3.,  3.,  4.,  4.],
 | 
			
		||||
                  [ 3.,  3.,  4.,  4.]]]])
 | 
			
		||||
    """
 | 
			
		||||
    def __init__(self, size=None, scale_factor=None):
 | 
			
		||||
        super(UpsamplingNearest2d, self).__init__(size, scale_factor, mode='nearest')
 | 
			
		||||
@ -231,22 +204,15 @@ class UpsamplingBilinear2d(Upsample):
 | 
			
		||||
 | 
			
		||||
        >>> input = torch.arange(1, 5).view(1, 1, 2, 2)
 | 
			
		||||
        >>> input
 | 
			
		||||
 | 
			
		||||
        (0 ,0 ,.,.) =
 | 
			
		||||
          1  2
 | 
			
		||||
          3  4
 | 
			
		||||
        [torch.FloatTensor of size (1,1,2,2)]
 | 
			
		||||
        tensor([[[[ 1.,  2.],
 | 
			
		||||
                  [ 3.,  4.]]]])
 | 
			
		||||
 | 
			
		||||
        >>> m = nn.UpsamplingBilinear2d(scale_factor=2)
 | 
			
		||||
        >>> m(input)
 | 
			
		||||
 | 
			
		||||
        (0 ,0 ,.,.) =
 | 
			
		||||
          1.0000  1.3333  1.6667  2.0000
 | 
			
		||||
          1.6667  2.0000  2.3333  2.6667
 | 
			
		||||
          2.3333  2.6667  3.0000  3.3333
 | 
			
		||||
          3.0000  3.3333  3.6667  4.0000
 | 
			
		||||
        [torch.FloatTensor of size (1,1,4,4)]
 | 
			
		||||
 | 
			
		||||
        tensor([[[[ 1.0000,  1.3333,  1.6667,  2.0000],
 | 
			
		||||
                  [ 1.6667,  2.0000,  2.3333,  2.6667],
 | 
			
		||||
                  [ 2.3333,  2.6667,  3.0000,  3.3333],
 | 
			
		||||
                  [ 3.0000,  3.3333,  3.6667,  4.0000]]]])
 | 
			
		||||
    """
 | 
			
		||||
    def __init__(self, size=None, scale_factor=None):
 | 
			
		||||
        super(UpsamplingBilinear2d, self).__init__(size, scale_factor, mode='bilinear', align_corners=True)
 | 
			
		||||
 | 
			
		||||
@ -318,19 +318,11 @@ def pack_sequence(sequences):
 | 
			
		||||
 | 
			
		||||
    Example:
 | 
			
		||||
        >>> from torch.nn.utils.rnn import pack_sequence
 | 
			
		||||
        >>> a = torch.Tensor([1,2,3])
 | 
			
		||||
        >>> b = torch.Tensor([4,5])
 | 
			
		||||
        >>> c = torch.Tensor([6])
 | 
			
		||||
        >>> a = torch.tensor([1,2,3])
 | 
			
		||||
        >>> b = torch.tensor([4,5])
 | 
			
		||||
        >>> c = torch.tensor([6])
 | 
			
		||||
        >>> pack_sequence([a, b, c]])
 | 
			
		||||
        PackedSequence(data=
 | 
			
		||||
         1
 | 
			
		||||
         4
 | 
			
		||||
         6
 | 
			
		||||
         2
 | 
			
		||||
         5
 | 
			
		||||
         3
 | 
			
		||||
        [torch.FloatTensor of size 6]
 | 
			
		||||
        , batch_sizes=[3, 2, 1])
 | 
			
		||||
        PackedSequence(data=tensor([ 1,  4,  6,  2,  5,  3]), batch_sizes=tensor([ 3,  2,  1]))
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
    Arguments:
 | 
			
		||||
 | 
			
		||||
@ -152,7 +152,7 @@ def save(obj, f, pickle_module=pickle, pickle_protocol=DEFAULT_PROTOCOL):
 | 
			
		||||
 | 
			
		||||
    Example:
 | 
			
		||||
        >>> # Save to file
 | 
			
		||||
        >>> x = torch.Tensor([0, 1, 2, 3, 4])
 | 
			
		||||
        >>> x = torch.tensor([0, 1, 2, 3, 4])
 | 
			
		||||
        >>> torch.save(x, 'tensor.pt')
 | 
			
		||||
        >>> # Save to io.BytesIO buffer
 | 
			
		||||
        >>> buffer = io.BytesIO()
 | 
			
		||||
 | 
			
		||||
@ -1,4 +1,5 @@
 | 
			
		||||
import torch
 | 
			
		||||
import warnings
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
def detach_variable(inputs):
 | 
			
		||||
@ -14,10 +15,16 @@ def detach_variable(inputs):
 | 
			
		||||
            "Only tuple of tensors is supported. Got Unsupported input type: ", type(inputs).__name__)
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
def check_backward_validity(inputs):
 | 
			
		||||
    if not any(inp.requires_grad for inp in inputs):
 | 
			
		||||
        warnings.warn("None of the inputs have requires_grad=True. Gradients will be None")
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
class CheckpointFunction(torch.autograd.Function):
 | 
			
		||||
 | 
			
		||||
    @staticmethod
 | 
			
		||||
    def forward(ctx, run_function, *args):
 | 
			
		||||
        check_backward_validity(args)
 | 
			
		||||
        ctx.run_function = run_function
 | 
			
		||||
        ctx.save_for_backward(*args)
 | 
			
		||||
        with torch.no_grad():
 | 
			
		||||
@ -66,6 +73,11 @@ def checkpoint(function, *args):
 | 
			
		||||
        checkpointed version won't be equivalent, and unfortunately it can't be
 | 
			
		||||
        detected.
 | 
			
		||||
 | 
			
		||||
    .. warning:
 | 
			
		||||
        At least one of the inputs needs to have :code:`requires_grad=True` if
 | 
			
		||||
        grads are needed for model inputs, otherwise the checkpointed part of the
 | 
			
		||||
        model won't have gradients.
 | 
			
		||||
 | 
			
		||||
    Args:
 | 
			
		||||
        function: describes what to run in the forward pass of the model or
 | 
			
		||||
            part of the model. It should also know how to handle the inputs
 | 
			
		||||
@ -96,6 +108,11 @@ def checkpoint_sequential(functions, segments, *inputs):
 | 
			
		||||
        Checkpointing doesn't work with :func:`torch.autograd.grad`, but only
 | 
			
		||||
        with :func:`torch.autograd.backward`.
 | 
			
		||||
 | 
			
		||||
    .. warning:
 | 
			
		||||
        At least one of the inputs needs to have :code:`requires_grad=True` if
 | 
			
		||||
        grads are needed for model inputs, otherwise the checkpointed part of the
 | 
			
		||||
        model won't have gradients.
 | 
			
		||||
 | 
			
		||||
    Args:
 | 
			
		||||
        functions: A :class:`torch.nn.Sequential` or the list of modules or
 | 
			
		||||
            functions (comprising the model) to run sequentially.
 | 
			
		||||
 | 
			
		||||
		Reference in New Issue
	
	Block a user