Skip to content

Commit b6f542f

Browse files
XiaobingSuperfacebook-github-bot
authored andcommitted
Add aten mkldnn transpose (#21943)
Summary: This PR is about: 1. Make mkldnn reshape can share same memory fro plain format tensor. 2. Add mkldnn transpose operator. Pull Request resolved: #21943 Differential Revision: D15916063 Pulled By: bddppq fbshipit-source-id: d1971c67341f277c1e80c1fa34e213b6c27f4062
1 parent 3d44cd6 commit b6f542f

File tree

4 files changed

+63
-3
lines changed

4 files changed

+63
-3
lines changed

aten/src/ATen/native/TensorShape.cpp

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -624,6 +624,10 @@ Tensor & transpose_(Tensor & self, int64_t dim0, int64_t dim1) {
624624
return sparse_transpose_(self, dim0, dim1);
625625
}
626626

627+
if (self.is_mkldnn()) {
628+
return at::mkldnn_transpose_(self, dim0, dim1);
629+
}
630+
627631
auto strides = self.strides().vec();
628632
auto sizes = self.sizes().vec();
629633
std::swap(strides[dim0], strides[dim1]);
@@ -644,6 +648,10 @@ Tensor transpose(const Tensor & self, int64_t dim0, int64_t dim1) {
644648
return sparse_transpose_(self_clone, dim0, dim1);
645649
}
646650

651+
if (self.is_mkldnn()) {
652+
return at::mkldnn_transpose(self, dim0, dim1);
653+
}
654+
647655
auto strides = self.strides().vec();
648656
auto sizes = self.sizes().vec();
649657
std::swap(strides[dim0], strides[dim1]);

aten/src/ATen/native/mkldnn/TensorShape.cpp

Lines changed: 27 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,14 @@ Tensor mkldnn_clone(const Tensor& self) {
2020
AT_ERROR("mkldnn_clone: ATen not compiled with MKLDNN support");
2121
}
2222

23+
Tensor mkldnn_transpose(const Tensor& self, int64_t dim0, int64_t dim1) {
24+
AT_ERROR("mkldnn_transpose: ATen not compiled with MKLDNN support");
25+
}
26+
27+
Tensor& mkldnn_transpose_(Tensor& self, int64_t dim0, int64_t dim1) {
28+
AT_ERROR("mkldnn_transpose_: ATen not compiled with MKLDNN support");
29+
}
30+
2331
} // namespace native
2432
} // namespace at
2533

@@ -37,10 +45,12 @@ Tensor mkldnn_view(const Tensor& self, IntArrayRef size) {
3745

3846
Tensor mkldnn_reshape(const Tensor& self, IntArrayRef size) {
3947
auto inferred_size = at::infer_size(size, self.numel());
48+
if (self.sizes() == inferred_size) {
49+
return self;
50+
}
4051
const ideep::tensor& x = itensor_from_mkldnn(self);
41-
ideep::tensor y;
42-
ideep::direct_copy::compute<AllocForMKLDNN>(x, y);
43-
y.reshape({inferred_size.cbegin(), inferred_size.cend()});
52+
ideep::tensor y{x};
53+
y.reshape<AllocForMKLDNN>({inferred_size.cbegin(), inferred_size.cend()});
4454
return new_with_itensor_mkldnn(std::move(y), self.options());
4555
}
4656

@@ -51,6 +61,20 @@ Tensor mkldnn_clone(const Tensor& self) {
5161
return new_with_itensor_mkldnn(std::move(dst), self.options());
5262
}
5363

64+
Tensor mkldnn_transpose(const Tensor & self, int64_t dim0, int64_t dim1) {
65+
const ideep::tensor& x = itensor_from_mkldnn(self);
66+
ideep::tensor y;
67+
std::vector<int> axes(x.ndims());
68+
std::iota(axes.begin(), axes.end(), 0);
69+
std::swap(axes[dim0], axes[dim1]);
70+
y.transpose_from<AllocForMKLDNN>(x, axes);
71+
return new_with_itensor_mkldnn(std::move(y), self.options());
72+
}
73+
74+
Tensor& mkldnn_transpose_(Tensor& self, int64_t dim0, int64_t dim1) {
75+
AT_ERROR("mkldnn_transpose_: in-place mkldnn operations are not supported yet");
76+
}
77+
5478
} // namespace native
5579
} // namespace at
5680

aten/src/ATen/native/native_functions.yaml

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1987,10 +1987,22 @@
19871987
variants: function, method
19881988
device_guard: False
19891989

1990+
- func: mkldnn_transpose(Tensor self, int dim0, int dim1) -> Tensor
1991+
device_guard: False
1992+
requires_tensor: True
1993+
dispatch:
1994+
MkldnnCPU: mkldnn_transpose
1995+
19901996
- func: transpose_(Tensor(a!) self, int dim0, int dim1) -> Tensor(a!)
19911997
variants: method
19921998
device_guard: False
19931999

2000+
- func: mkldnn_transpose_(Tensor(a!) self, int dim0, int dim1) -> Tensor(a!)
2001+
device_guard: False
2002+
requires_tensor: True
2003+
dispatch:
2004+
MkldnnCPU: mkldnn_transpose_
2005+
19942006
- func: one_hot(Tensor self, int num_classes=-1) -> Tensor
19952007
python_module: nn
19962008
variants: function

test/test_mkldnn.py

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -279,6 +279,13 @@ def test_reshape(self):
279279
x.reshape(size),
280280
x.to_mkldnn().reshape(size).to_dense(),
281281
)
282+
# test whether share same memory for plain format tensor
283+
y = x.to_mkldnn()
284+
z = y.reshape(size).add_(y.reshape(size))
285+
self.assertEqual(
286+
y.reshape(size).to_dense(),
287+
z.to_dense(),
288+
)
282289

283290
def test_clone(self):
284291
x = torch.randn(4, 5, dtype=torch.float32) * 10
@@ -294,6 +301,15 @@ def test_clone(self):
294301
z.to_dense(),
295302
)
296303

304+
def test_transpose(self):
305+
x = torch.randn(3, 4, 5, dtype=torch.float32) * 10
306+
for dim1 in range(x.ndim):
307+
for dim2 in range(x.ndim):
308+
self.assertEqual(
309+
x.transpose(dim1, dim2),
310+
x.to_mkldnn().transpose(dim1, dim2).to_dense(),
311+
)
312+
297313
def test_linear(self):
298314
in_features = torch.randint(3, 10, (1,)).item()
299315
out_features = torch.randint(3, 100, (1,)).item()

0 commit comments

Comments
 (0)