torch-rb 0.1.1 → 0.1.6
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/CHANGELOG.md +40 -0
- data/LICENSE.txt +46 -22
- data/README.md +73 -9
- data/ext/torch/ext.cpp +148 -315
- data/ext/torch/extconf.rb +6 -0
- data/ext/torch/nn_functions.cpp +615 -0
- data/ext/torch/nn_functions.hpp +6 -0
- data/ext/torch/templates.cpp +55 -0
- data/ext/torch/templates.hpp +298 -0
- data/ext/torch/tensor_functions.cpp +1920 -0
- data/ext/torch/tensor_functions.hpp +6 -0
- data/ext/torch/torch_functions.cpp +2975 -0
- data/ext/torch/torch_functions.hpp +6 -0
- data/lib/torch.rb +236 -112
- data/lib/torch/ext.bundle +0 -0
- data/lib/torch/inspector.rb +52 -25
- data/lib/torch/native/dispatcher.rb +48 -0
- data/lib/torch/native/function.rb +109 -0
- data/lib/torch/native/generator.rb +168 -0
- data/lib/torch/native/native_functions.yaml +6837 -0
- data/lib/torch/native/parser.rb +134 -0
- data/lib/torch/nn/alpha_dropout.rb +9 -0
- data/lib/torch/nn/avg_pool1d.rb +18 -0
- data/lib/torch/nn/avg_pool2d.rb +19 -0
- data/lib/torch/nn/avg_pool3d.rb +19 -0
- data/lib/torch/nn/avg_poolnd.rb +9 -0
- data/lib/torch/nn/batch_norm.rb +75 -0
- data/lib/torch/nn/batch_norm1d.rb +11 -0
- data/lib/torch/nn/batch_norm2d.rb +11 -0
- data/lib/torch/nn/batch_norm3d.rb +11 -0
- data/lib/torch/nn/bce_loss.rb +13 -0
- data/lib/torch/nn/bce_with_logits_loss.rb +15 -0
- data/lib/torch/nn/bilinear.rb +38 -0
- data/lib/torch/nn/constant_pad1d.rb +10 -0
- data/lib/torch/nn/constant_pad2d.rb +10 -0
- data/lib/torch/nn/constant_pad3d.rb +10 -0
- data/lib/torch/nn/constant_padnd.rb +18 -0
- data/lib/torch/nn/conv1d.rb +22 -0
- data/lib/torch/nn/conv2d.rb +16 -39
- data/lib/torch/nn/conv3d.rb +22 -0
- data/lib/torch/nn/convnd.rb +41 -0
- data/lib/torch/nn/cosine_embedding_loss.rb +14 -0
- data/lib/torch/nn/cosine_similarity.rb +15 -0
- data/lib/torch/nn/cross_entropy_loss.rb +14 -0
- data/lib/torch/nn/ctc_loss.rb +15 -0
- data/lib/torch/nn/dropout.rb +9 -0
- data/lib/torch/nn/dropout2d.rb +9 -0
- data/lib/torch/nn/dropout3d.rb +9 -0
- data/lib/torch/nn/dropoutnd.rb +15 -0
- data/lib/torch/nn/embedding.rb +52 -0
- data/lib/torch/nn/embedding_bag.rb +34 -0
- data/lib/torch/nn/feature_alpha_dropout.rb +9 -0
- data/lib/torch/nn/fold.rb +20 -0
- data/lib/torch/nn/functional.rb +419 -16
- data/lib/torch/nn/group_norm.rb +36 -0
- data/lib/torch/nn/gru.rb +49 -0
- data/lib/torch/nn/hardshrink.rb +18 -0
- data/lib/torch/nn/hinge_embedding_loss.rb +14 -0
- data/lib/torch/nn/identity.rb +14 -0
- data/lib/torch/nn/init.rb +58 -1
- data/lib/torch/nn/instance_norm.rb +20 -0
- data/lib/torch/nn/instance_norm1d.rb +18 -0
- data/lib/torch/nn/instance_norm2d.rb +11 -0
- data/lib/torch/nn/instance_norm3d.rb +11 -0
- data/lib/torch/nn/kl_div_loss.rb +13 -0
- data/lib/torch/nn/l1_loss.rb +13 -0
- data/lib/torch/nn/layer_norm.rb +35 -0
- data/lib/torch/nn/leaky_relu.rb +20 -0
- data/lib/torch/nn/linear.rb +12 -11
- data/lib/torch/nn/local_response_norm.rb +21 -0
- data/lib/torch/nn/log_sigmoid.rb +9 -0
- data/lib/torch/nn/log_softmax.rb +14 -0
- data/lib/torch/nn/loss.rb +10 -0
- data/lib/torch/nn/lp_pool1d.rb +9 -0
- data/lib/torch/nn/lp_pool2d.rb +9 -0
- data/lib/torch/nn/lp_poolnd.rb +22 -0
- data/lib/torch/nn/lstm.rb +66 -0
- data/lib/torch/nn/margin_ranking_loss.rb +14 -0
- data/lib/torch/nn/max_pool1d.rb +9 -0
- data/lib/torch/nn/max_pool2d.rb +9 -0
- data/lib/torch/nn/max_pool3d.rb +9 -0
- data/lib/torch/nn/max_poolnd.rb +19 -0
- data/lib/torch/nn/max_unpool1d.rb +16 -0
- data/lib/torch/nn/max_unpool2d.rb +16 -0
- data/lib/torch/nn/max_unpool3d.rb +16 -0
- data/lib/torch/nn/max_unpoolnd.rb +9 -0
- data/lib/torch/nn/module.rb +191 -19
- data/lib/torch/nn/mse_loss.rb +2 -2
- data/lib/torch/nn/multi_label_margin_loss.rb +13 -0
- data/lib/torch/nn/multi_label_soft_margin_loss.rb +13 -0
- data/lib/torch/nn/multi_margin_loss.rb +17 -0
- data/lib/torch/nn/nll_loss.rb +14 -0
- data/lib/torch/nn/pairwise_distance.rb +16 -0
- data/lib/torch/nn/parameter.rb +4 -0
- data/lib/torch/nn/poisson_nll_loss.rb +16 -0
- data/lib/torch/nn/prelu.rb +19 -0
- data/lib/torch/nn/reflection_pad1d.rb +10 -0
- data/lib/torch/nn/reflection_pad2d.rb +10 -0
- data/lib/torch/nn/reflection_padnd.rb +13 -0
- data/lib/torch/nn/relu.rb +8 -3
- data/lib/torch/nn/replication_pad1d.rb +10 -0
- data/lib/torch/nn/replication_pad2d.rb +10 -0
- data/lib/torch/nn/replication_pad3d.rb +10 -0
- data/lib/torch/nn/replication_padnd.rb +13 -0
- data/lib/torch/nn/rnn.rb +22 -0
- data/lib/torch/nn/rnn_base.rb +198 -0
- data/lib/torch/nn/sequential.rb +1 -10
- data/lib/torch/nn/sigmoid.rb +9 -0
- data/lib/torch/nn/smooth_l1_loss.rb +13 -0
- data/lib/torch/nn/soft_margin_loss.rb +13 -0
- data/lib/torch/nn/softmax.rb +18 -0
- data/lib/torch/nn/softmax2d.rb +10 -0
- data/lib/torch/nn/softmin.rb +14 -0
- data/lib/torch/nn/softplus.rb +19 -0
- data/lib/torch/nn/softshrink.rb +18 -0
- data/lib/torch/nn/softsign.rb +9 -0
- data/lib/torch/nn/tanh.rb +9 -0
- data/lib/torch/nn/tanhshrink.rb +9 -0
- data/lib/torch/nn/triplet_margin_loss.rb +18 -0
- data/lib/torch/nn/unfold.rb +19 -0
- data/lib/torch/nn/utils.rb +25 -0
- data/lib/torch/nn/weighted_loss.rb +10 -0
- data/lib/torch/nn/zero_pad2d.rb +9 -0
- data/lib/torch/optim/adadelta.rb +57 -0
- data/lib/torch/optim/adagrad.rb +71 -0
- data/lib/torch/optim/adam.rb +81 -0
- data/lib/torch/optim/adamax.rb +68 -0
- data/lib/torch/optim/adamw.rb +82 -0
- data/lib/torch/optim/asgd.rb +65 -0
- data/lib/torch/optim/lr_scheduler/lr_scheduler.rb +33 -0
- data/lib/torch/optim/lr_scheduler/step_lr.rb +17 -0
- data/lib/torch/optim/optimizer.rb +62 -0
- data/lib/torch/optim/rmsprop.rb +76 -0
- data/lib/torch/optim/rprop.rb +68 -0
- data/lib/torch/optim/sgd.rb +60 -0
- data/lib/torch/random.rb +10 -0
- data/lib/torch/tensor.rb +90 -30
- data/lib/torch/utils/data/data_loader.rb +15 -0
- data/lib/torch/utils/data/tensor_dataset.rb +8 -1
- data/lib/torch/version.rb +1 -1
- metadata +122 -3
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 9667f9d3256f5e2d39937f17ae8eb00449dd14f79bb01cd647800bd7ed972fc6
|
4
|
+
data.tar.gz: 54c23612c79355e09c97da5fcf6b97c183da8316d1c2a53d6f8f0463e98342a2
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: bb2c8e5aae436367aeb871a2d19958e59ed9e9c7601b1b8b4473e33094cadf6d657947582b0ec93a29cb08723f8f7c81178a2d50beb23a125d5a356769d92177
|
7
|
+
data.tar.gz: 62feef39da31a19415e2e6c453aed4972e34db7367161a088944c06a977637a8b25cecc8eb2ad052b3b9deee0707f364e616cc33e7674cf0314899421f18fbee
|
data/CHANGELOG.md
CHANGED
@@ -1,3 +1,43 @@
|
|
1
|
+
## 0.1.6 (2019-12-09)
|
2
|
+
|
3
|
+
- Added recurrent layers
|
4
|
+
- Added more pooling layers
|
5
|
+
- Added normalization layers
|
6
|
+
|
7
|
+
## 0.1.5 (2019-12-06)
|
8
|
+
|
9
|
+
- Added many more functions
|
10
|
+
- Added tensor classes - `FloatTensor`, `LongTensor`, etc
|
11
|
+
- Improved modules
|
12
|
+
|
13
|
+
## 0.1.4 (2019-12-01)
|
14
|
+
|
15
|
+
- Added distance functions
|
16
|
+
- Added more activations
|
17
|
+
- Added more linear layers
|
18
|
+
- Added more loss functions
|
19
|
+
- Added more init methods
|
20
|
+
- Added support for tensor assignment
|
21
|
+
|
22
|
+
## 0.1.3 (2019-11-30)
|
23
|
+
|
24
|
+
- Changed to BSD 3-Clause license to match PyTorch
|
25
|
+
- Added many optimizers
|
26
|
+
- Added `StepLR` learning rate scheduler
|
27
|
+
- Added dropout
|
28
|
+
- Added embedding
|
29
|
+
- Added support for `bool` type
|
30
|
+
- Improved performance of `from_numo`
|
31
|
+
|
32
|
+
## 0.1.2 (2019-11-27)
|
33
|
+
|
34
|
+
- Added SGD optimizer
|
35
|
+
- Added support for gradient to `backward` method
|
36
|
+
- Added `argmax`, `eq`, `leaky_relu`, `prelu`, and `reshape` methods
|
37
|
+
- Improved indexing
|
38
|
+
- Fixed `zero_grad`
|
39
|
+
- Fixed error with infinite values
|
40
|
+
|
1
41
|
## 0.1.1 (2019-11-26)
|
2
42
|
|
3
43
|
- Added support for `uint8` and `int8` types
|
data/LICENSE.txt
CHANGED
@@ -1,22 +1,46 @@
|
|
1
|
-
|
2
|
-
|
3
|
-
|
4
|
-
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
1
|
+
BSD 3-Clause License
|
2
|
+
|
3
|
+
From Torch-rb:
|
4
|
+
|
5
|
+
Copyright (c) 2019- Andrew Kane
|
6
|
+
|
7
|
+
From PyTorch (for ported code):
|
8
|
+
|
9
|
+
Copyright (c) 2016- Facebook, Inc (Adam Paszke)
|
10
|
+
Copyright (c) 2014- Facebook, Inc (Soumith Chintala)
|
11
|
+
Copyright (c) 2011-2014 Idiap Research Institute (Ronan Collobert)
|
12
|
+
Copyright (c) 2012-2014 Deepmind Technologies (Koray Kavukcuoglu)
|
13
|
+
Copyright (c) 2011-2012 NEC Laboratories America (Koray Kavukcuoglu)
|
14
|
+
Copyright (c) 2011-2013 NYU (Clement Farabet)
|
15
|
+
Copyright (c) 2006-2010 NEC Laboratories America (Ronan Collobert, Leon Bottou, Iain Melvin, Jason Weston)
|
16
|
+
Copyright (c) 2006 Idiap Research Institute (Samy Bengio)
|
17
|
+
Copyright (c) 2001-2004 Idiap Research Institute (Ronan Collobert, Samy Bengio, Johnny Mariethoz)
|
18
|
+
|
19
|
+
All rights reserved.
|
20
|
+
|
21
|
+
Redistribution and use in source and binary forms, with or without
|
22
|
+
modification, are permitted provided that the following conditions are met:
|
23
|
+
|
24
|
+
1. Redistributions of source code must retain the above copyright
|
25
|
+
notice, this list of conditions and the following disclaimer.
|
26
|
+
|
27
|
+
2. Redistributions in binary form must reproduce the above copyright
|
28
|
+
notice, this list of conditions and the following disclaimer in the
|
29
|
+
documentation and/or other materials provided with the distribution.
|
30
|
+
|
31
|
+
3. Neither the names of Facebook, Deepmind Technologies, NYU, NEC Laboratories America
|
32
|
+
and IDIAP Research Institute nor the names of its contributors may be
|
33
|
+
used to endorse or promote products derived from this software without
|
34
|
+
specific prior written permission.
|
35
|
+
|
36
|
+
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
37
|
+
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
38
|
+
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
39
|
+
ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
|
40
|
+
LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
41
|
+
CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
42
|
+
SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
43
|
+
INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
44
|
+
CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
45
|
+
ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
46
|
+
POSSIBILITY OF SUCH DAMAGE.
|
data/README.md
CHANGED
@@ -2,7 +2,7 @@
|
|
2
2
|
|
3
3
|
:fire: Deep learning for Ruby, powered by [LibTorch](https://pytorch.org)
|
4
4
|
|
5
|
-
This gem is currently experimental. There may be breaking changes between each release.
|
5
|
+
This gem is currently experimental. There may be breaking changes between each release. Please report any issues you experience.
|
6
6
|
|
7
7
|
[](https://travis-ci.org/ankane/torch-rb)
|
8
8
|
|
@@ -20,6 +20,8 @@ Add this line to your application’s Gemfile:
|
|
20
20
|
gem 'torch-rb'
|
21
21
|
```
|
22
22
|
|
23
|
+
It can take a few minutes to compile the extension.
|
24
|
+
|
23
25
|
## Getting Started
|
24
26
|
|
25
27
|
This library follows the [PyTorch API](https://pytorch.org/docs/stable/torch.html). There are a few changes to make it more Ruby-like:
|
@@ -28,9 +30,11 @@ This library follows the [PyTorch API](https://pytorch.org/docs/stable/torch.htm
|
|
28
30
|
- Methods that return booleans use `?` instead of `is_` (`tensor?` instead of `is_tensor`)
|
29
31
|
- Numo is used instead of NumPy (`x.numo` instead of `x.numpy()`)
|
30
32
|
|
31
|
-
|
33
|
+
Some methods and options are missing at the moment. PRs welcome!
|
34
|
+
|
35
|
+
## Tutorial
|
32
36
|
|
33
|
-
Some examples below are from [Deep Learning with PyTorch: A 60 Minutes Blitz](https://pytorch.org/tutorials/beginner/deep_learning_60min_blitz.html)
|
37
|
+
Some examples below are from [Deep Learning with PyTorch: A 60 Minutes Blitz](https://pytorch.org/tutorials/beginner/deep_learning_60min_blitz.html)
|
34
38
|
|
35
39
|
### Tensors
|
36
40
|
|
@@ -145,7 +149,7 @@ Convert a Numo array to a tensor
|
|
145
149
|
|
146
150
|
```ruby
|
147
151
|
b = Numo::NArray.cast([1, 2, 3])
|
148
|
-
Torch.
|
152
|
+
Torch.from_numo(b)
|
149
153
|
```
|
150
154
|
|
151
155
|
### Autograd
|
@@ -180,10 +184,10 @@ Stop autograd from tracking history
|
|
180
184
|
|
181
185
|
```ruby
|
182
186
|
x.requires_grad # true
|
183
|
-
(x
|
187
|
+
(x**2).requires_grad # true
|
184
188
|
|
185
189
|
Torch.no_grad do
|
186
|
-
(x
|
190
|
+
(x**2).requires_grad # false
|
187
191
|
end
|
188
192
|
```
|
189
193
|
|
@@ -223,7 +227,7 @@ class Net < Torch::NN::Module
|
|
223
227
|
end
|
224
228
|
```
|
225
229
|
|
226
|
-
|
230
|
+
Create an instance of it
|
227
231
|
|
228
232
|
```ruby
|
229
233
|
net = Net.new
|
@@ -231,6 +235,58 @@ input = Torch.randn(1, 1, 32, 32)
|
|
231
235
|
net.call(input)
|
232
236
|
```
|
233
237
|
|
238
|
+
Get trainable parameters
|
239
|
+
|
240
|
+
```ruby
|
241
|
+
net.parameters
|
242
|
+
```
|
243
|
+
|
244
|
+
Zero the gradient buffers and backprop with random gradients
|
245
|
+
|
246
|
+
```ruby
|
247
|
+
net.zero_grad
|
248
|
+
out.backward(Torch.randn(1, 10))
|
249
|
+
```
|
250
|
+
|
251
|
+
Define a loss function
|
252
|
+
|
253
|
+
```ruby
|
254
|
+
output = net.call(input)
|
255
|
+
target = Torch.randn(10)
|
256
|
+
target = target.view(1, -1)
|
257
|
+
criterion = Torch::NN::MSELoss.new
|
258
|
+
loss = criterion.call(output, target)
|
259
|
+
```
|
260
|
+
|
261
|
+
Backprop
|
262
|
+
|
263
|
+
```ruby
|
264
|
+
net.zero_grad
|
265
|
+
p net.conv1.bias.grad
|
266
|
+
loss.backward
|
267
|
+
p net.conv1.bias.grad
|
268
|
+
```
|
269
|
+
|
270
|
+
Update the weights
|
271
|
+
|
272
|
+
```ruby
|
273
|
+
learning_rate = 0.01
|
274
|
+
net.parameters.each do |f|
|
275
|
+
f.data.sub!(f.grad.data * learning_rate)
|
276
|
+
end
|
277
|
+
```
|
278
|
+
|
279
|
+
Use an optimizer
|
280
|
+
|
281
|
+
```ruby
|
282
|
+
optimizer = Torch::Optim::SGD.new(net.parameters, lr: 0.01)
|
283
|
+
optimizer.zero_grad
|
284
|
+
output = net.call(input)
|
285
|
+
loss = criterion.call(output, target)
|
286
|
+
loss.backward
|
287
|
+
optimizer.step
|
288
|
+
```
|
289
|
+
|
234
290
|
### Tensor Creation
|
235
291
|
|
236
292
|
Here’s a list of functions to create tensors (descriptions from the [C++ docs](https://pytorch.org/cppdocs/notes/tensor_creation.html)):
|
@@ -307,6 +363,14 @@ Here’s a list of functions to create tensors (descriptions from the [C++ docs]
|
|
307
363
|
Torch.zeros(3) # tensor([0, 0, 0])
|
308
364
|
```
|
309
365
|
|
366
|
+
## Examples
|
367
|
+
|
368
|
+
Here are a few full examples:
|
369
|
+
|
370
|
+
- [Image classification with MNIST](examples/mnist) ([日本語版](https://qiita.com/kojix2/items/c19c36dc1bf73ea93409))
|
371
|
+
- [Collaborative filtering with MovieLens](examples/movielens)
|
372
|
+
- [Sequence models and word embeddings](examples/nlp)
|
373
|
+
|
310
374
|
## LibTorch Installation
|
311
375
|
|
312
376
|
[Download LibTorch](https://pytorch.org/). For Linux, use the `cxx11 ABI` version. Then run:
|
@@ -351,9 +415,9 @@ To get started with development:
|
|
351
415
|
|
352
416
|
```sh
|
353
417
|
git clone https://github.com/ankane/torch-rb.git
|
354
|
-
cd torch
|
418
|
+
cd torch-rb
|
355
419
|
bundle install
|
356
|
-
bundle exec rake compile
|
420
|
+
bundle exec rake compile -- --with-torch-dir=/path/to/libtorch
|
357
421
|
bundle exec rake test
|
358
422
|
```
|
359
423
|
|
data/ext/torch/ext.cpp
CHANGED
@@ -6,95 +6,29 @@
|
|
6
6
|
#include <rice/Class.hpp>
|
7
7
|
#include <rice/Constructor.hpp>
|
8
8
|
|
9
|
-
|
10
|
-
|
11
|
-
template<>
|
12
|
-
inline
|
13
|
-
long long from_ruby<long long>(Object x)
|
14
|
-
{
|
15
|
-
return NUM2LL(x);
|
16
|
-
}
|
17
|
-
|
18
|
-
template<>
|
19
|
-
inline
|
20
|
-
Object to_ruby<long long>(long long const & x)
|
21
|
-
{
|
22
|
-
return LL2NUM(x);
|
23
|
-
}
|
9
|
+
#include "templates.hpp"
|
24
10
|
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
}
|
11
|
+
// generated with:
|
12
|
+
// rake generate:functions
|
13
|
+
#include "torch_functions.hpp"
|
14
|
+
#include "tensor_functions.hpp"
|
15
|
+
#include "nn_functions.hpp"
|
31
16
|
|
32
|
-
|
33
|
-
inline
|
34
|
-
Object to_ruby<unsigned long long>(unsigned long long const & x)
|
35
|
-
{
|
36
|
-
return ULL2NUM(x);
|
37
|
-
}
|
38
|
-
|
39
|
-
template<>
|
40
|
-
inline
|
41
|
-
short from_ruby<short>(Object x)
|
42
|
-
{
|
43
|
-
return NUM2SHORT(x);
|
44
|
-
}
|
45
|
-
|
46
|
-
template<>
|
47
|
-
inline
|
48
|
-
Object to_ruby<short>(short const & x)
|
49
|
-
{
|
50
|
-
return INT2NUM(x);
|
51
|
-
}
|
52
|
-
|
53
|
-
template<>
|
54
|
-
inline
|
55
|
-
unsigned short from_ruby<unsigned short>(Object x)
|
56
|
-
{
|
57
|
-
return NUM2USHORT(x);
|
58
|
-
}
|
17
|
+
using namespace Rice;
|
59
18
|
|
60
|
-
|
61
|
-
|
62
|
-
Object to_ruby<unsigned short>(unsigned short const & x)
|
19
|
+
extern "C"
|
20
|
+
void Init_ext()
|
63
21
|
{
|
64
|
-
|
65
|
-
|
22
|
+
Module rb_mTorch = define_module("Torch");
|
23
|
+
add_torch_functions(rb_mTorch);
|
66
24
|
|
67
|
-
|
68
|
-
|
69
|
-
class IntArrayRef {
|
70
|
-
std::vector<int64_t> vec;
|
71
|
-
public:
|
72
|
-
IntArrayRef(Object o) {
|
73
|
-
Array a = Array(o);
|
74
|
-
for (size_t i = 0; i < a.size(); i++) {
|
75
|
-
vec.push_back(from_ruby<int64_t>(a[i]));
|
76
|
-
}
|
77
|
-
}
|
78
|
-
operator torch::IntArrayRef() {
|
79
|
-
return torch::IntArrayRef(vec);
|
80
|
-
}
|
81
|
-
};
|
25
|
+
Class rb_cTensor = define_class_under<torch::Tensor>(rb_mTorch, "Tensor");
|
26
|
+
add_tensor_functions(rb_cTensor);
|
82
27
|
|
83
|
-
|
84
|
-
|
85
|
-
IntArrayRef from_ruby<IntArrayRef>(Object x)
|
86
|
-
{
|
87
|
-
return IntArrayRef(x);
|
88
|
-
}
|
89
|
-
|
90
|
-
// for now
|
91
|
-
typedef float Scalar;
|
28
|
+
Module rb_mNN = define_module_under(rb_mTorch, "NN");
|
29
|
+
add_nn_functions(rb_mNN);
|
92
30
|
|
93
|
-
|
94
|
-
void Init_ext()
|
95
|
-
{
|
96
|
-
Module rb_mTorch = define_module("Torch")
|
97
|
-
.define_singleton_method(
|
31
|
+
rb_mTorch.define_singleton_method(
|
98
32
|
"grad_enabled?",
|
99
33
|
*[]() {
|
100
34
|
return torch::GradMode::is_enabled();
|
@@ -104,11 +38,6 @@ void Init_ext()
|
|
104
38
|
*[](bool enabled) {
|
105
39
|
torch::GradMode::set_enabled(enabled);
|
106
40
|
})
|
107
|
-
.define_singleton_method(
|
108
|
-
"floating_point?",
|
109
|
-
*[](torch::Tensor& input) {
|
110
|
-
return torch::is_floating_point(input);
|
111
|
-
})
|
112
41
|
.define_singleton_method(
|
113
42
|
"manual_seed",
|
114
43
|
*[](uint64_t seed) {
|
@@ -177,266 +106,93 @@ void Init_ext()
|
|
177
106
|
})
|
178
107
|
// begin operations
|
179
108
|
.define_singleton_method(
|
180
|
-
"
|
181
|
-
*[](
|
182
|
-
return torch::
|
183
|
-
})
|
184
|
-
.define_singleton_method(
|
185
|
-
"_mean_dim",
|
186
|
-
*[](torch::Tensor& input, int64_t dim, bool keepdim) {
|
187
|
-
return torch::mean(input, dim, keepdim);
|
109
|
+
"_binary_cross_entropy_with_logits",
|
110
|
+
*[](const Tensor &input, const Tensor &target, OptionalTensor weight, OptionalTensor pos_weight, MyReduction reduction) {
|
111
|
+
return torch::binary_cross_entropy_with_logits(input, target, weight, pos_weight, reduction);
|
188
112
|
})
|
189
113
|
.define_singleton_method(
|
190
|
-
"
|
191
|
-
*[](torch::
|
192
|
-
|
193
|
-
|
194
|
-
.define_singleton_method(
|
195
|
-
"_sum_dim",
|
196
|
-
*[](torch::Tensor& input, int64_t dim, bool keepdim) {
|
197
|
-
return torch::sum(input, dim, keepdim);
|
198
|
-
})
|
199
|
-
.define_singleton_method(
|
200
|
-
"_norm",
|
201
|
-
*[](torch::Tensor& input) {
|
202
|
-
return torch::norm(input);
|
203
|
-
})
|
204
|
-
.define_singleton_method(
|
205
|
-
"_min",
|
206
|
-
*[](torch::Tensor& input) {
|
207
|
-
return torch::min(input);
|
208
|
-
})
|
209
|
-
.define_singleton_method(
|
210
|
-
"_max",
|
211
|
-
*[](torch::Tensor& input) {
|
212
|
-
return torch::max(input);
|
213
|
-
})
|
214
|
-
.define_singleton_method(
|
215
|
-
"_exp",
|
216
|
-
*[](torch::Tensor& input) {
|
217
|
-
return torch::exp(input);
|
218
|
-
})
|
219
|
-
.define_singleton_method(
|
220
|
-
"_log",
|
221
|
-
*[](torch::Tensor& input) {
|
222
|
-
return torch::log(input);
|
223
|
-
})
|
224
|
-
.define_singleton_method(
|
225
|
-
"_unsqueeze",
|
226
|
-
*[](torch::Tensor& input, int64_t dim) {
|
227
|
-
return torch::unsqueeze(input, dim);
|
228
|
-
})
|
229
|
-
.define_singleton_method(
|
230
|
-
"_dot",
|
231
|
-
*[](torch::Tensor& input, torch::Tensor& tensor) {
|
232
|
-
return torch::dot(input, tensor);
|
233
|
-
})
|
234
|
-
.define_singleton_method(
|
235
|
-
"_matmul",
|
236
|
-
*[](torch::Tensor& input, torch::Tensor& other) {
|
237
|
-
return torch::matmul(input, other);
|
238
|
-
})
|
239
|
-
.define_singleton_method(
|
240
|
-
"_add",
|
241
|
-
*[](torch::Tensor& input, torch::Tensor& other) {
|
242
|
-
return torch::add(input, other);
|
243
|
-
})
|
244
|
-
.define_singleton_method(
|
245
|
-
"_add_scalar",
|
246
|
-
*[](torch::Tensor& input, float other) {
|
247
|
-
return torch::add(input, other);
|
248
|
-
})
|
249
|
-
.define_singleton_method(
|
250
|
-
"_add_out",
|
251
|
-
*[](torch::Tensor& out, torch::Tensor& input, torch::Tensor& other) {
|
252
|
-
return torch::add_out(out, input, other);
|
253
|
-
})
|
254
|
-
.define_singleton_method(
|
255
|
-
"_sub",
|
256
|
-
*[](torch::Tensor& input, torch::Tensor& other) {
|
257
|
-
return torch::sub(input, other);
|
258
|
-
})
|
259
|
-
.define_singleton_method(
|
260
|
-
"_sub_scalar",
|
261
|
-
*[](torch::Tensor& input, float other) {
|
262
|
-
return torch::sub(input, other);
|
263
|
-
})
|
264
|
-
.define_singleton_method(
|
265
|
-
"_mul",
|
266
|
-
*[](torch::Tensor& input, torch::Tensor& other) {
|
267
|
-
return torch::mul(input, other);
|
268
|
-
})
|
269
|
-
.define_singleton_method(
|
270
|
-
"_mul_scalar",
|
271
|
-
*[](torch::Tensor& input, float other) {
|
272
|
-
return torch::mul(input, other);
|
273
|
-
})
|
274
|
-
.define_singleton_method(
|
275
|
-
"_div",
|
276
|
-
*[](torch::Tensor& input, torch::Tensor& other) {
|
277
|
-
return torch::div(input, other);
|
278
|
-
})
|
279
|
-
.define_singleton_method(
|
280
|
-
"_div_scalar",
|
281
|
-
*[](torch::Tensor& input, float other) {
|
282
|
-
return torch::div(input, other);
|
283
|
-
})
|
284
|
-
.define_singleton_method(
|
285
|
-
"_remainder",
|
286
|
-
*[](torch::Tensor& input, torch::Tensor& other) {
|
287
|
-
return torch::remainder(input, other);
|
288
|
-
})
|
289
|
-
.define_singleton_method(
|
290
|
-
"_remainder_scalar",
|
291
|
-
*[](torch::Tensor& input, float other) {
|
292
|
-
return torch::remainder(input, other);
|
293
|
-
})
|
294
|
-
.define_singleton_method(
|
295
|
-
"_pow",
|
296
|
-
*[](torch::Tensor& input, Scalar exponent) {
|
297
|
-
return torch::pow(input, exponent);
|
298
|
-
})
|
299
|
-
.define_singleton_method(
|
300
|
-
"_neg",
|
301
|
-
*[](torch::Tensor& input) {
|
302
|
-
return torch::neg(input);
|
303
|
-
})
|
304
|
-
.define_singleton_method(
|
305
|
-
"relu",
|
306
|
-
*[](torch::Tensor& input) {
|
307
|
-
return torch::relu(input);
|
308
|
-
})
|
309
|
-
.define_singleton_method(
|
310
|
-
"conv2d",
|
311
|
-
*[](torch::Tensor& input, torch::Tensor& weight, torch::Tensor& bias) {
|
312
|
-
return torch::conv2d(input, weight, bias);
|
313
|
-
})
|
314
|
-
.define_singleton_method(
|
315
|
-
"linear",
|
316
|
-
*[](torch::Tensor& input, torch::Tensor& weight, torch::Tensor& bias) {
|
317
|
-
return torch::linear(input, weight, bias);
|
318
|
-
})
|
319
|
-
.define_singleton_method(
|
320
|
-
"max_pool2d",
|
321
|
-
*[](torch::Tensor& input, IntArrayRef kernel_size) {
|
322
|
-
return torch::max_pool2d(input, kernel_size);
|
323
|
-
})
|
324
|
-
.define_singleton_method(
|
325
|
-
"mse_loss",
|
326
|
-
*[](torch::Tensor& input, torch::Tensor& target, std::string reduction) {
|
327
|
-
auto red = reduction == "mean" ? Reduction::Mean : Reduction::Sum;
|
328
|
-
return torch::mse_loss(input, target, red);
|
329
|
-
})
|
330
|
-
.define_singleton_method(
|
331
|
-
"nll_loss",
|
332
|
-
*[](torch::Tensor& input, torch::Tensor& target) {
|
333
|
-
return torch::nll_loss(input, target);
|
114
|
+
"_from_blob",
|
115
|
+
*[](String s, IntArrayRef size, const torch::TensorOptions &options) {
|
116
|
+
void *data = const_cast<char *>(s.c_str());
|
117
|
+
return torch::from_blob(data, size, options);
|
334
118
|
})
|
335
119
|
.define_singleton_method(
|
336
120
|
"_tensor",
|
337
121
|
*[](Object o, IntArrayRef size, const torch::TensorOptions &options) {
|
338
122
|
Array a = Array(o);
|
339
|
-
|
340
|
-
|
341
|
-
|
123
|
+
auto dtype = options.dtype();
|
124
|
+
torch::Tensor t;
|
125
|
+
if (dtype == torch::kBool) {
|
126
|
+
throw std::runtime_error("Cannot create bool from tensor method yet");
|
127
|
+
} else {
|
128
|
+
std::vector<float> vec;
|
129
|
+
for (size_t i = 0; i < a.size(); i++) {
|
130
|
+
vec.push_back(from_ruby<float>(a[i]));
|
131
|
+
}
|
132
|
+
t = torch::tensor(vec, options);
|
342
133
|
}
|
343
|
-
return
|
134
|
+
return t.reshape(size);
|
344
135
|
});
|
345
136
|
|
346
|
-
|
137
|
+
rb_cTensor
|
347
138
|
.define_method("cuda?", &torch::Tensor::is_cuda)
|
348
|
-
.define_method("distributed?", &torch::Tensor::is_distributed)
|
349
|
-
.define_method("complex?", &torch::Tensor::is_complex)
|
350
|
-
.define_method("floating_point?", &torch::Tensor::is_floating_point)
|
351
|
-
.define_method("signed?", &torch::Tensor::is_signed)
|
352
139
|
.define_method("sparse?", &torch::Tensor::is_sparse)
|
353
140
|
.define_method("quantized?", &torch::Tensor::is_quantized)
|
354
141
|
.define_method("dim", &torch::Tensor::dim)
|
355
|
-
.define_method("numel", &torch::Tensor::numel)
|
356
142
|
.define_method("element_size", &torch::Tensor::element_size)
|
357
143
|
.define_method("requires_grad", &torch::Tensor::requires_grad)
|
358
144
|
.define_method(
|
359
|
-
"
|
360
|
-
*[](
|
361
|
-
return self.
|
362
|
-
})
|
363
|
-
.define_method(
|
364
|
-
"detach!",
|
365
|
-
*[](torch::Tensor& self) {
|
366
|
-
return self.detach_();
|
145
|
+
"addcmul!",
|
146
|
+
*[](Tensor& self, Scalar value, const Tensor & tensor1, const Tensor & tensor2) {
|
147
|
+
return self.addcmul_(tensor1, tensor2, value);
|
367
148
|
})
|
368
149
|
.define_method(
|
369
|
-
"
|
370
|
-
*[](
|
371
|
-
return self
|
150
|
+
"addcdiv!",
|
151
|
+
*[](Tensor& self, Scalar value, const Tensor & tensor1, const Tensor & tensor2) {
|
152
|
+
return self.addcdiv_(tensor1, tensor2, value);
|
372
153
|
})
|
373
154
|
.define_method(
|
374
155
|
"_requires_grad!",
|
375
|
-
*[](
|
156
|
+
*[](Tensor& self, bool requires_grad) {
|
376
157
|
return self.set_requires_grad(requires_grad);
|
377
158
|
})
|
378
159
|
.define_method(
|
379
|
-
"
|
380
|
-
*[](
|
381
|
-
return self.backward();
|
160
|
+
"_backward",
|
161
|
+
*[](Tensor& self, Object gradient) {
|
162
|
+
return gradient.is_nil() ? self.backward() : self.backward(from_ruby<torch::Tensor>(gradient));
|
382
163
|
})
|
383
164
|
.define_method(
|
384
165
|
"grad",
|
385
|
-
*[](
|
166
|
+
*[](Tensor& self) {
|
386
167
|
return self.grad();
|
387
168
|
})
|
388
169
|
.define_method(
|
389
170
|
"_dtype",
|
390
|
-
*[](
|
171
|
+
*[](Tensor& self) {
|
391
172
|
return (int) at::typeMetaToScalarType(self.dtype());
|
392
173
|
})
|
174
|
+
.define_method(
|
175
|
+
"_type",
|
176
|
+
*[](Tensor& self, int dtype) {
|
177
|
+
return self.toType((torch::ScalarType) dtype);
|
178
|
+
})
|
393
179
|
.define_method(
|
394
180
|
"_layout",
|
395
|
-
*[](
|
181
|
+
*[](Tensor& self) {
|
396
182
|
std::stringstream s;
|
397
183
|
s << self.layout();
|
398
184
|
return s.str();
|
399
185
|
})
|
400
186
|
.define_method(
|
401
187
|
"device",
|
402
|
-
*[](
|
188
|
+
*[](Tensor& self) {
|
403
189
|
std::stringstream s;
|
404
190
|
s << self.device();
|
405
191
|
return s.str();
|
406
192
|
})
|
407
193
|
.define_method(
|
408
|
-
"
|
409
|
-
*[](
|
410
|
-
return self.view(size);
|
411
|
-
})
|
412
|
-
.define_method(
|
413
|
-
"add!",
|
414
|
-
*[](torch::Tensor& self, torch::Tensor& other) {
|
415
|
-
self.add_(other);
|
416
|
-
})
|
417
|
-
.define_method(
|
418
|
-
"sub!",
|
419
|
-
*[](torch::Tensor& self, torch::Tensor& other) {
|
420
|
-
self.sub_(other);
|
421
|
-
})
|
422
|
-
.define_method(
|
423
|
-
"mul!",
|
424
|
-
*[](torch::Tensor& self, torch::Tensor& other) {
|
425
|
-
self.mul_(other);
|
426
|
-
})
|
427
|
-
.define_method(
|
428
|
-
"div!",
|
429
|
-
*[](torch::Tensor& self, torch::Tensor& other) {
|
430
|
-
self.div_(other);
|
431
|
-
})
|
432
|
-
.define_method(
|
433
|
-
"log_softmax",
|
434
|
-
*[](torch::Tensor& self, int64_t dim) {
|
435
|
-
return self.log_softmax(dim);
|
436
|
-
})
|
437
|
-
.define_method(
|
438
|
-
"_data",
|
439
|
-
*[](torch::Tensor& self) {
|
194
|
+
"_flat_data",
|
195
|
+
*[](Tensor& self) {
|
440
196
|
Array a;
|
441
197
|
auto dtype = self.dtype();
|
442
198
|
|
@@ -477,21 +233,23 @@ void Init_ext()
|
|
477
233
|
a.push(data[i]);
|
478
234
|
}
|
479
235
|
} else if (dtype == torch::kBool) {
|
480
|
-
|
481
|
-
|
236
|
+
bool* data = self.data_ptr<bool>();
|
237
|
+
for (int i = 0; i < self.numel(); i++) {
|
238
|
+
a.push(data[i] ? True : False);
|
239
|
+
}
|
482
240
|
} else {
|
483
241
|
throw std::runtime_error("Unsupported type");
|
484
242
|
}
|
485
243
|
return a;
|
486
244
|
})
|
487
245
|
.define_method(
|
488
|
-
"
|
489
|
-
*[](
|
490
|
-
return self.
|
246
|
+
"_to",
|
247
|
+
*[](Tensor& self, torch::Device device, int dtype, bool non_blocking, bool copy) {
|
248
|
+
return self.to(device, (torch::ScalarType) dtype, non_blocking, copy);
|
491
249
|
})
|
492
250
|
.define_singleton_method(
|
493
251
|
"_make_subclass",
|
494
|
-
*[](
|
252
|
+
*[](Tensor& rd, bool requires_grad) {
|
495
253
|
auto data = torch::autograd::as_variable_ref(rd).detach();
|
496
254
|
data.unsafeGetTensorImpl()->set_allow_tensor_metadata_change(true);
|
497
255
|
auto var = data.set_requires_grad(requires_grad);
|
@@ -538,24 +296,99 @@ void Init_ext()
|
|
538
296
|
return self.requires_grad(requires_grad);
|
539
297
|
});
|
540
298
|
|
541
|
-
Module rb_mNN = define_module_under(rb_mTorch, "NN");
|
542
|
-
|
543
299
|
Module rb_mInit = define_module_under(rb_mNN, "Init")
|
544
300
|
.define_singleton_method(
|
545
|
-
"
|
546
|
-
*[](
|
547
|
-
return torch::nn::init::
|
301
|
+
"_calculate_gain",
|
302
|
+
*[](NonlinearityType nonlinearity, double param) {
|
303
|
+
return torch::nn::init::calculate_gain(nonlinearity, param);
|
304
|
+
})
|
305
|
+
.define_singleton_method(
|
306
|
+
"_uniform!",
|
307
|
+
*[](Tensor tensor, double low, double high) {
|
308
|
+
return torch::nn::init::uniform_(tensor, low, high);
|
309
|
+
})
|
310
|
+
.define_singleton_method(
|
311
|
+
"_normal!",
|
312
|
+
*[](Tensor tensor, double mean, double std) {
|
313
|
+
return torch::nn::init::normal_(tensor, mean, std);
|
314
|
+
})
|
315
|
+
.define_singleton_method(
|
316
|
+
"_constant!",
|
317
|
+
*[](Tensor tensor, Scalar value) {
|
318
|
+
return torch::nn::init::constant_(tensor, value);
|
319
|
+
})
|
320
|
+
.define_singleton_method(
|
321
|
+
"_ones!",
|
322
|
+
*[](Tensor tensor) {
|
323
|
+
return torch::nn::init::ones_(tensor);
|
324
|
+
})
|
325
|
+
.define_singleton_method(
|
326
|
+
"_zeros!",
|
327
|
+
*[](Tensor tensor) {
|
328
|
+
return torch::nn::init::zeros_(tensor);
|
329
|
+
})
|
330
|
+
.define_singleton_method(
|
331
|
+
"_eye!",
|
332
|
+
*[](Tensor tensor) {
|
333
|
+
return torch::nn::init::eye_(tensor);
|
334
|
+
})
|
335
|
+
.define_singleton_method(
|
336
|
+
"_dirac!",
|
337
|
+
*[](Tensor tensor) {
|
338
|
+
return torch::nn::init::dirac_(tensor);
|
339
|
+
})
|
340
|
+
.define_singleton_method(
|
341
|
+
"_xavier_uniform!",
|
342
|
+
*[](Tensor tensor, double gain) {
|
343
|
+
return torch::nn::init::xavier_uniform_(tensor, gain);
|
344
|
+
})
|
345
|
+
.define_singleton_method(
|
346
|
+
"_xavier_normal!",
|
347
|
+
*[](Tensor tensor, double gain) {
|
348
|
+
return torch::nn::init::xavier_normal_(tensor, gain);
|
349
|
+
})
|
350
|
+
.define_singleton_method(
|
351
|
+
"_kaiming_uniform!",
|
352
|
+
*[](Tensor tensor, double a, FanModeType mode, NonlinearityType nonlinearity) {
|
353
|
+
return torch::nn::init::kaiming_uniform_(tensor, a, mode, nonlinearity);
|
354
|
+
})
|
355
|
+
.define_singleton_method(
|
356
|
+
"_kaiming_normal!",
|
357
|
+
*[](Tensor tensor, double a, FanModeType mode, NonlinearityType nonlinearity) {
|
358
|
+
return torch::nn::init::kaiming_normal_(tensor, a, mode, nonlinearity);
|
548
359
|
})
|
549
360
|
.define_singleton_method(
|
550
|
-
"
|
551
|
-
*[](
|
552
|
-
return torch::nn::init::
|
361
|
+
"_orthogonal!",
|
362
|
+
*[](Tensor tensor, double gain) {
|
363
|
+
return torch::nn::init::orthogonal_(tensor, gain);
|
364
|
+
})
|
365
|
+
.define_singleton_method(
|
366
|
+
"_sparse!",
|
367
|
+
*[](Tensor tensor, double sparsity, double std) {
|
368
|
+
return torch::nn::init::sparse_(tensor, sparsity, std);
|
553
369
|
});
|
554
370
|
|
555
371
|
Class rb_cParameter = define_class_under<torch::autograd::Variable, torch::Tensor>(rb_mNN, "Parameter")
|
556
372
|
.define_method(
|
557
373
|
"grad",
|
558
374
|
*[](torch::autograd::Variable& self) {
|
559
|
-
|
375
|
+
auto grad = self.grad();
|
376
|
+
return grad.defined() ? to_ruby<torch::Tensor>(grad) : Nil;
|
560
377
|
});
|
378
|
+
|
379
|
+
Class rb_cDevice = define_class_under<torch::Device>(rb_mTorch, "Device")
|
380
|
+
.define_constructor(Constructor<torch::Device, std::string>())
|
381
|
+
.define_method("index", &torch::Device::index)
|
382
|
+
.define_method("index?", &torch::Device::has_index)
|
383
|
+
.define_method(
|
384
|
+
"type",
|
385
|
+
*[](torch::Device& self) {
|
386
|
+
std::stringstream s;
|
387
|
+
s << self.type();
|
388
|
+
return s.str();
|
389
|
+
});
|
390
|
+
|
391
|
+
Module rb_mCUDA = define_module_under(rb_mTorch, "CUDA")
|
392
|
+
.define_singleton_method("available?", &torch::cuda::is_available)
|
393
|
+
.define_singleton_method("device_count", &torch::cuda::device_count);
|
561
394
|
}
|