forked from pytorch/pytorch
-
Notifications
You must be signed in to change notification settings - Fork 0
/
THTensor.hpp
132 lines (110 loc) · 4.86 KB
/
THTensor.hpp
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
#pragma once
// STOP!!! Thinking of including this header directly? Please
// read Note [TH abstraction violation]
#include <TH/THTensor.h>
#include <TH/THStorageFunctions.hpp>
#include <atomic>
#include <ATen/ATen.h>
// Returns a Tensor given a TensorImpl. The TensorImpl remains valid after the
// the Tensor is destroyed.
inline at::Tensor THTensor_wrap(THTensor* tensor) {
c10::raw::intrusive_ptr::incref(tensor);
return at::Tensor(c10::intrusive_ptr<at::TensorImpl>::reclaim(tensor));
}
inline const int64_t* THTensor_getSizePtr(THTensor* tensor) {
return tensor->sizes().data();
}
inline const int64_t* THTensor_getStridePtr(THTensor* tensor) {
return tensor->strides().data();
}
// NB: Non-retaining
inline THStorage* THTensor_getStoragePtr(const THTensor* tensor) {
// Within PyTorch, the invariant is that storage_ is always
// initialized; we never have tensors that don't have any storage.
// However, for Caffe2, this is not true, because they have permitted
// tensors to be allocated without specifying what scalar type
// they should be, only to be filled when GetMutableData is called
// for the first time (providing the necessary type). It is an ERROR to
// invoke any PyTorch operations on such a half-constructed storage,
// and this check tests for that case.
AT_CHECK(tensor->storage(), "Cannot use PyTorch operations on a half-constructed "
"tensor. If this tensor came from Caffe2, please call GetMutableData on "
"it first; otherwise, this is a bug, please report it.");
return tensor->storage().unsafeGetStorageImpl();
}
inline void THTensor_maybe_zero_dim(THTensor *tensor, bool condition_when_zero_dim) {
bool set_zero_dim = condition_when_zero_dim && tensor->sizes().size() == 1 && tensor->size(0) == 1;
if (set_zero_dim) {
tensor->set_sizes_and_strides({}, {});
}
}
// [NOTE: nDimension vs nDimensionLegacyNoScalars vs nDimensionLegacyAll]
// nDimension corresponds to the "true" ATen dimension.
// nDimensionLegacyNoScalars correpsonds to the ATen dimension, except scalars are viewed as 1-dimensional tensors.
// nDimensionLegacyAll corresponds to the ATen dimension, except scalars are viewed as 1-dimensional tensors
// and tensors with a dimension of size zero are collapsed to 0-dimensional tensors.
//
// Eventually, everything should go through nDimension or tensor->dim().
inline int THTensor_nDimension(const THTensor* tensor) {
return tensor->dim();
}
inline int THTensor_nDimensionLegacyNoScalars(const THTensor* tensor) {
if (tensor->dim() == 0) {
return 1;
} else {
return tensor->dim();
}
}
inline int THTensor_nDimensionLegacyAll(const THTensor* tensor) {
if (tensor->is_empty()) {
return 0;
} else if (tensor->dim() == 0) {
return 1;
} else {
return tensor->dim();
}
}
inline int64_t THTensor_strideLegacyNoScalars(const THTensor *self, int dim) {
THArgCheck((dim >= 0) && (dim < THTensor_nDimensionLegacyNoScalars(self)), 2, "dimension %d out of range of %dD tensor",
dim, THTensor_nDimensionLegacyNoScalars(self));
return self->dim() == 0 ? 1 : self->stride(dim);
}
inline int64_t THTensor_sizeLegacyNoScalars(const THTensor *self, int dim)
{
THArgCheck((dim >= 0) && (dim < THTensor_nDimensionLegacyNoScalars(self)), 2, "dimension %d out of range of %dD tensor",
dim, THTensor_nDimensionLegacyNoScalars(self));
return self->dim() == 0 ? 1 : self->size(dim);
}
#include <TH/generic/THTensorFastGetSet.hpp>
#include <TH/THGenerateAllTypes.h>
inline std::vector<int64_t> THTensor_sizesLegacyNoScalars(const THTensor *self) {
if (self->dim() == 0) {
return {1};
} else {
return self->sizes().vec();
}
}
inline std::vector<int64_t> THTensor_stridesLegacyNoScalars(const THTensor *self) {
if (self->dim() == 0) {
return {1};
} else {
return self->strides().vec();
}
}
// NB: Steals ownership of storage
TH_API void THTensor_stealAndSetStoragePtr(THTensor* tensor, THStorage* storage);
TH_API void THTensor_free(THTensor *self);
TH_API void THTensor_setStorageNd(THTensor *self, THStorage *storage, ptrdiff_t storageOffset, int nDimension, const int64_t *size, const int64_t *stride);
TH_API void THTensor_resizeNd(THTensor *self, int nDimension, const int64_t *size, const int64_t *stride);
TH_CPP_API void THTensor_resize(THTensor *self, at::IntArrayRef size, at::IntArrayRef stride);
TH_CPP_API void THTensor_setStorage(THTensor *self, THStorage *storage_, ptrdiff_t storageOffset_, at::IntArrayRef size_, at::IntArrayRef stride_);
TH_CPP_API c10::optional<std::vector<int64_t>> THTensor_compute_stride(
at::IntArrayRef oldshape,
at::IntArrayRef oldstride,
at::IntArrayRef newshape);
#include <TH/generic/THTensor.hpp>
#include <TH/THGenerateAllTypes.h>
#include <TH/generic/THTensor.hpp>
#include <TH/THGenerateHalfType.h>
#include <TH/generic/THTensor.hpp>
#include <TH/THGenerateBoolType.h>