Skip to content
This repository was archived by the owner on Nov 15, 2022. It is now read-only.

Commit a2c1a07

Browse files
cpuhrschfacebook-github-bot
authored andcommitted
20210518 nestedtensor import
Reviewed By: datumbox Differential Revision: D28521166 fbshipit-source-id: 9761a92aa22c3979a175b8934c5daa4b7d2663af
1 parent cf952fe commit a2c1a07

28 files changed

+1199
-271
lines changed

benchmarks/jit_apply.py

Lines changed: 74 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,74 @@
1+
import torch
2+
import nestedtensor
3+
import nestedtensor
4+
import utils
5+
6+
7+
def vmap(fn):
8+
def decorator(arg):
9+
if torch.is_tensor(arg):
10+
return fn(arg)
11+
else:
12+
def asd(x):
13+
return fn(x)
14+
return arg.jit_apply(torch.jit.script(asd))
15+
return decorator
16+
17+
18+
@torch.jit.script
19+
def my_fun(x):
20+
x = x + 1
21+
y = x.abs()
22+
return y
23+
24+
# print(e)
25+
26+
27+
def gen_current():
28+
n = nestedtensor.as_nested_tensor(
29+
[torch.randn(256, 128).to(device='cuda') for _ in range(128)])
30+
31+
def _algorithm():
32+
n1 = n + 1
33+
n1.abs()
34+
35+
return _algorithm
36+
37+
38+
def gen_jit():
39+
40+
n = nestedtensor._C._ListNestedTensor(
41+
[torch.randn(256, 128).to(device='cuda') for _ in range(128)])
42+
43+
def gen_my_fun(scalar, tensor):
44+
@torch.jit.ignore
45+
def get_scalar():
46+
return scalar
47+
48+
@torch.jit.ignore
49+
def get_tensor():
50+
return tensor
51+
52+
@torch.jit.script
53+
def my_fun(x, y):
54+
x = x + get_scalar()
55+
x = x + get_tensor()
56+
y = y + x.abs()
57+
return y
58+
return my_fun
59+
my_fun = gen_my_fun(3.0, torch.randn(1).to(device='cuda'))
60+
61+
def _algorithm_jit():
62+
nestedtensor._C.jit_apply_function((n, n), my_fun)
63+
64+
return _algorithm_jit
65+
66+
67+
if __name__ == "__main__":
68+
# print(utils.benchmark_fn(alg, use_cprofile=True))
69+
# alg = gen_list_nested_tensor_construction()
70+
# print(utils.benchmark_fn(alg))
71+
alg1 = gen_current()
72+
print(utils.benchmark_fn(alg1))
73+
alg2 = gen_jit()
74+
print(utils.benchmark_fn(alg2))

benchmarks/linear.py

Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,43 @@
1+
import torch
2+
import nestedtensor
3+
import utils
4+
5+
import random
6+
random.seed(1010)
7+
8+
BDIM=10
9+
10+
# Performance tanks hard for lots of small Tensors as expected
11+
RAND_INTS = [random.randint(100, 300) for _ in range(BDIM)]
12+
13+
OUTDIM=256
14+
GOALDIM=512
15+
16+
TENSORS0 = [torch.rand(i, OUTDIM).cuda() for i in RAND_INTS]
17+
18+
def gen_t_linear():
19+
nt0 = nestedtensor.nested_tensor(TENSORS0, device=torch.device('cuda'), dtype=torch.float)
20+
data, _ = nt0.to_tensor_mask()
21+
lin = torch.nn.Linear(OUTDIM, GOALDIM).cuda()
22+
23+
def t():
24+
lin(data)
25+
return t
26+
27+
28+
@torch.inference_mode()
29+
def gen_nt_linear():
30+
nt0 = nestedtensor.nested_tensor(TENSORS0, device=torch.device('cuda'), dtype=torch.float)
31+
lin = torch.nn.Linear(OUTDIM, GOALDIM).cuda()
32+
33+
def nt():
34+
lin(nt0)
35+
# print("nt0.size()")
36+
# print(nt0.size())
37+
# import sys; sys.exit(1)
38+
return nt
39+
40+
41+
if __name__ == "__main__":
42+
print(utils.benchmark_fn(gen_t_linear()))
43+
print(utils.benchmark_fn(gen_nt_linear()))
Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
#!/bin/bash
2+
# This script is meant to be called by the "after_success" step defined in
3+
# .travis.yml. See http://docs.travis-ci.com/ for more details.
4+
5+
set -e
6+
7+
if [[ "$COVERAGE" == "true" ]]; then
8+
# Ignore codecov failures as the codecov server is not
9+
# very reliable but we don't want travis to report a failure
10+
# in the github UI just because the coverage report failed to
11+
# be published.
12+
codecov || echo "codecov upload failed"
13+
fi

build_tools/travis/install.sh

Lines changed: 60 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,60 @@
1+
#!/bin/bash
2+
# This script is meant to be called by the "install" step defined in
3+
# .travis.yml. See http://docs.travis-ci.com/ for more details.
4+
# The behavior of the script is controlled by environment variabled defined
5+
# in the .travis.yml in the top level folder of the project.
6+
7+
set -e
8+
9+
echo 'List files from cached directories'
10+
if [ -d $HOME/download ]; then
11+
echo 'download:'
12+
ls $HOME/download
13+
fi
14+
if [ -d $HOME/.cache/pip ]; then
15+
echo 'pip:'
16+
ls $HOME/.cache/pip
17+
fi
18+
19+
# Deactivate the travis-provided virtual environment and setup a
20+
# conda-based environment instead
21+
deactivate
22+
23+
# Add the miniconda bin directory to $PATH
24+
export PATH=/home/travis/miniconda3/bin:$PATH
25+
echo $PATH
26+
27+
# Use the miniconda installer for setup of conda itself
28+
pushd .
29+
cd
30+
mkdir -p download
31+
cd download
32+
if [[ ! -f /home/travis/miniconda3/bin/activate ]]
33+
then
34+
if [[ ! -f miniconda.sh ]]
35+
then
36+
wget http://repo.continuum.io/miniconda/Miniconda3-latest-Linux-x86_64.sh \
37+
-O miniconda.sh
38+
fi
39+
chmod +x miniconda.sh && ./miniconda.sh -b -f
40+
conda update --yes conda
41+
echo "Creating environment to run tests in."
42+
conda create -n testenv --yes python="$PYTHON_VERSION"
43+
fi
44+
cd ..
45+
popd
46+
47+
# Activate the python environment we created.
48+
source activate testenv
49+
50+
# Install requirements via pip in our conda environment
51+
pip install -r requirements.txt
52+
53+
# Install the following only if running tests
54+
if [[ "$SKIP_TESTS" != "true" ]]; then
55+
# PyTorch
56+
conda install --yes pytorch torchvision -c pytorch
57+
58+
# Installation
59+
python setup.py install
60+
fi

build_tools/travis/test_script.sh

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
#!/bin/bash
2+
# This script is meant to be called by the "script" step defined in
3+
# .travis.yml. See http://docs.travis-ci.com/ for more details.
4+
# The behavior of the script is controlled by environment variabled defined
5+
# in the .travis.yml in the top level folder of the project.
6+
7+
set -e
8+
9+
python --version
10+
11+
run_tests() {
12+
if [[ "$RUN_SLOW" == "true" ]]; then
13+
TEST_CMD="py.test --runslow -s -v --cov=nestedtensor --durations=20"
14+
else
15+
TEST_CMD="py.test -v --cov=nestedtensor --durations=20"
16+
fi
17+
$TEST_CMD
18+
}
19+
20+
if [[ "$RUN_FLAKE8" == "true" ]]; then
21+
flake8
22+
fi
23+
24+
if [[ "$SKIP_TESTS" != "true" ]]; then
25+
run_tests
26+
fi

nestedtensor/__init__.py

Lines changed: 0 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -14,8 +14,3 @@
1414
from . import _C
1515

1616
from . import nn
17-
18-
# TODO: https://github.com/pytorch/pytorch/issues/34294
19-
# torch.cat does not call __torch_function__ properly
20-
from .nested.nested import _new_torch_stack as stack
21-
from .nested.nested import _new_torch_cat as cat

nestedtensor/csrc/BinaryOps.cpp

Lines changed: 81 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,22 @@ Tensor NestedTensor_add_Tensor(
1111
Tensor self;
1212
Tensor other;
1313
std::tie(self, other) = _expand_other_as(self_, other_);
14+
if (is_nested_tensor_impl(self) && !is_nested_tensor_impl(other) &&
15+
get_is_contiguous(self)) {
16+
int64_t self_dim = get_dim(self);
17+
auto self_opt_sizes = get_opt_sizes(self);
18+
if (self_opt_sizes[self_dim - 1] && other.dim() == 1 &&
19+
(*(self_opt_sizes[self_dim - 1])) == other.size(0)) {
20+
Tensor self_buffer = get_buffer(self);
21+
Tensor result_buffer =
22+
at::add(self_buffer.reshape({-1, other.size(0)}), other)
23+
.reshape({-1});
24+
return wrap_buffer(
25+
std::move(result_buffer),
26+
get_efficient_nested_size(self),
27+
get_efficient_nested_stride(self));
28+
}
29+
}
1430
return map_nested_tensor(
1531
[&alpha](Tensor s, Tensor o) { return at::add(s, o, alpha); },
1632
self,
@@ -97,6 +113,50 @@ Tensor& NestedTensor_div_out(
97113
return out;
98114
}
99115

116+
Tensor NestedTensor_floor_divide_Tensor(
117+
const Tensor& self_,
118+
const Tensor& other_) {
119+
Tensor self;
120+
Tensor other;
121+
std::tie(self, other) = _expand_other_as(self_, other_);
122+
return map_nested_tensor(
123+
[](Tensor s, Tensor o) { return at::floor_divide(s, o); }, self, other);
124+
}
125+
126+
Tensor& NestedTensor_floor_divide__Tensor(Tensor& self_, const Tensor& other_) {
127+
at::Tensor self;
128+
at::Tensor other;
129+
std::tie(self, other) = _expand_other_as(self_, other_);
130+
apply_nested_tensor(
131+
[](Tensor& tensor, const Tensor other) {
132+
tensor.floor_divide_(other);
133+
return tensor;
134+
},
135+
self,
136+
other);
137+
return self_;
138+
}
139+
140+
Tensor& NestedTensor_floor_divide_out(
141+
const Tensor& self,
142+
const Tensor& other,
143+
Tensor& out) {
144+
TORCH_CHECK(
145+
is_nested_tensor_impl(out),
146+
"NT binary out variant requires NT as out argument.");
147+
TORCH_CHECK(
148+
is_nested_tensor_impl(out, self, other),
149+
"binary_out doesn't support non-NT arguments.")
150+
apply_nested_tensor(
151+
[](Tensor& self, Tensor& other, Tensor& out) {
152+
return at::floor_divide_out(self, other, out);
153+
},
154+
self,
155+
other,
156+
out);
157+
return out;
158+
}
159+
100160
Tensor NestedTensor_mul_Tensor(const Tensor& self_, const Tensor& other_) {
101161
Tensor self;
102162
Tensor other;
@@ -270,13 +330,32 @@ Tensor& NestedTensor_pow__Tensor(Tensor& self_, const Tensor& other_) {
270330
return self_;
271331
}
272332

333+
Tensor NestedTensor_pow_Scalar(const Scalar& base, const Tensor& exponent_) {
334+
Tensor exponent = exponent_;
335+
return map_nested_tensor(
336+
[&base](Tensor exponent) { return at::pow(base, exponent); }, exponent);
337+
}
338+
339+
Tensor NestedTensor_pow_Tensor_Tensor(
340+
const Tensor& self_,
341+
const Tensor& other_) {
342+
Tensor self;
343+
Tensor other;
344+
std::tie(self, other) = _expand_other_as(self_, other_);
345+
return map_nested_tensor(
346+
[](Tensor s, Tensor o) { return at::pow(s, o); }, self, other);
347+
}
348+
273349
TORCH_LIBRARY_IMPL(aten, NestedTensor, m) {
274350
nt_impl(m, "add.Tensor", NestedTensor_add_Tensor);
275351
nt_impl(m, "add_.Tensor", NestedTensor_add__Tensor);
276352
nt_impl(m, "add.out", NestedTensor_add_out);
277353
nt_impl(m, "div.Tensor", NestedTensor_div_Tensor);
278354
nt_impl(m, "div_.Tensor", NestedTensor_div__Tensor);
279355
nt_impl(m, "div.out", NestedTensor_div_out);
356+
nt_impl(m, "floor_divide", NestedTensor_floor_divide_Tensor);
357+
nt_impl(m, "floor_divide_.Tensor", NestedTensor_floor_divide__Tensor);
358+
nt_impl(m, "floor_divide.out", NestedTensor_floor_divide_out);
280359
nt_impl(m, "mul.Tensor", NestedTensor_mul_Tensor);
281360
nt_impl(m, "mul_.Tensor", NestedTensor_mul__Tensor);
282361
nt_impl(m, "mul.out", NestedTensor_mul_out);
@@ -289,6 +368,8 @@ TORCH_LIBRARY_IMPL(aten, NestedTensor, m) {
289368
nt_impl(m, "atan2", NestedTensor_atan2);
290369
nt_impl(m, "remainder.Tensor", NestedTensor_remainder_Tensor);
291370
nt_impl(m, "pow_.Tensor", NestedTensor_pow__Tensor);
371+
nt_impl(m, "pow.Scalar", NestedTensor_pow_Scalar);
372+
nt_impl(m, "pow.Tensor_Tensor", NestedTensor_pow_Tensor_Tensor);
292373
}
293374

294375
} // namespace at

nestedtensor/csrc/activation.cpp

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,12 @@ namespace F = torch::nn::functional;
99
namespace at {
1010

1111
Tensor NestedTensor_gelu(const Tensor& self) {
12+
if (is_nested_tensor_impl(self) && get_is_contiguous(self)) {
13+
return wrap_buffer(
14+
at::gelu(get_buffer(self)),
15+
get_efficient_nested_size(self),
16+
get_efficient_nested_stride(self));
17+
}
1218
return map_nested_tensor(
1319
[](at::Tensor tensor) { return at::gelu(tensor); }, self);
1420
}

nestedtensor/csrc/autograd_functions.cpp

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -9,8 +9,11 @@ namespace F = torch::nn::functional;
99
namespace at {
1010

1111
Tensor NestedTensor_dropout(const Tensor& input, double p, bool train) {
12-
return map_nested_tensor(
13-
[&](const at::Tensor t) { return at::dropout(t, p, train); }, input);
12+
if (train) {
13+
return map_nested_tensor(
14+
[&](const at::Tensor t) { return at::dropout(t, p, train); }, input);
15+
}
16+
return input;
1417
}
1518

1619
Tensor NestedTensor_upsample_bilinear2d(
@@ -100,8 +103,7 @@ Tensor NestedTensor_batch_norm(
100103
AT_ERROR("running_var must be defined in evaluation mode");
101104
}
102105
if (weight) {
103-
check_dims_match_num_input_features(
104-
"weight", n_input, weight->numel());
106+
check_dims_match_num_input_features("weight", n_input, weight->numel());
105107
}
106108
if (bias) {
107109
check_dims_match_num_input_features("bias", n_input, bias->numel());

0 commit comments

Comments
 (0)