torch-rb 0.7.0 → 0.8.3
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 +21 -0
- data/README.md +23 -41
- data/codegen/function.rb +2 -0
- data/codegen/generate_functions.rb +41 -4
- data/codegen/native_functions.yaml +2007 -1327
- data/ext/torch/backends.cpp +17 -0
- data/ext/torch/ext.cpp +8 -0
- data/ext/torch/fft.cpp +13 -0
- data/ext/torch/fft_functions.h +6 -0
- data/ext/torch/linalg.cpp +13 -0
- data/ext/torch/linalg_functions.h +6 -0
- data/ext/torch/ruby_arg_parser.h +7 -1
- data/ext/torch/special.cpp +13 -0
- data/ext/torch/special_functions.h +6 -0
- data/ext/torch/templates.h +1 -0
- data/lib/torch/nn/convnd.rb +2 -0
- data/lib/torch/nn/functional_attention.rb +241 -0
- data/lib/torch/nn/module.rb +30 -0
- data/lib/torch/nn/module_list.rb +49 -0
- data/lib/torch/nn/multihead_attention.rb +123 -0
- data/lib/torch/nn/parameter.rb +6 -0
- data/lib/torch/nn/transformer.rb +92 -0
- data/lib/torch/nn/transformer_decoder.rb +25 -0
- data/lib/torch/nn/transformer_decoder_layer.rb +43 -0
- data/lib/torch/nn/transformer_encoder.rb +25 -0
- data/lib/torch/nn/transformer_encoder_layer.rb +36 -0
- data/lib/torch/nn/utils.rb +12 -0
- data/lib/torch/tensor.rb +8 -0
- data/lib/torch/utils/data/data_loader.rb +2 -0
- data/lib/torch/version.rb +1 -1
- data/lib/torch.rb +6 -0
- metadata +18 -3
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 19fb3b7bb14f4b45424591ac7d5f65c5290b372c6e54d65f36188869d267410d
|
4
|
+
data.tar.gz: c2c8878412b46febea4af13881169a74a577b4ac1a7de0e2d567058c06695e1a
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 6a11fd1965d00e43cfbccd658ee14c95f2a032253842a6d6ec8cb33e91fbeedae5594b2d641ccc9593d2bc967376cf4538d0d12d9ded7bbd1e816945a30d1b28
|
7
|
+
data.tar.gz: 5a6febd08b15c544fd4dfef13b56efa2aab8a80c7e171fdf434f9fa692e13381654fbe3c8ea021ac661a71d310bebe942a01161f910c2931bc8ee336fe237afe
|
data/CHANGELOG.md
CHANGED
@@ -1,3 +1,24 @@
|
|
1
|
+
## 0.8.3 (2021-10-17)
|
2
|
+
|
3
|
+
- Fixed `dup` method for tensors and parameters
|
4
|
+
- Fixed issues with transformers
|
5
|
+
|
6
|
+
## 0.8.2 (2021-10-03)
|
7
|
+
|
8
|
+
- Added transformers
|
9
|
+
- Added left shift and right shift
|
10
|
+
|
11
|
+
## 0.8.1 (2021-06-15)
|
12
|
+
|
13
|
+
- Added `Backends` module
|
14
|
+
- Added `FFT` module
|
15
|
+
- Added `Linalg` module
|
16
|
+
- Added `Special` module
|
17
|
+
|
18
|
+
## 0.8.0 (2021-06-15)
|
19
|
+
|
20
|
+
- Updated LibTorch to 1.9.0
|
21
|
+
|
1
22
|
## 0.7.0 (2021-05-23)
|
2
23
|
|
3
24
|
- Updated to Rice 4
|
data/README.md
CHANGED
@@ -28,15 +28,19 @@ It can take a few minutes to compile the extension.
|
|
28
28
|
|
29
29
|
## Getting Started
|
30
30
|
|
31
|
-
|
31
|
+
A good place to start is [Deep Learning with Torch.rb: A 60 Minute Blitz](tutorials/blitz/README.md).
|
32
32
|
|
33
|
-
|
33
|
+
## Tutorials
|
34
34
|
|
35
|
-
|
36
|
-
|
37
|
-
|
35
|
+
- [Transfer learning](tutorials/transfer_learning/README.md)
|
36
|
+
- [Sequence models](tutorials/nlp/sequence_models.md)
|
37
|
+
- [Word embeddings](tutorials/nlp/word_embeddings.md)
|
38
38
|
|
39
|
-
|
39
|
+
## Examples
|
40
|
+
|
41
|
+
- [Image classification with MNIST](examples/mnist) ([日本語版](https://qiita.com/kojix2/items/c19c36dc1bf73ea93409))
|
42
|
+
- [Collaborative filtering with MovieLens](examples/movielens)
|
43
|
+
- [Generative adversarial networks](examples/gan)
|
40
44
|
|
41
45
|
## API
|
42
46
|
|
@@ -48,7 +52,7 @@ This library follows the [PyTorch API](https://pytorch.org/docs/stable/torch.htm
|
|
48
52
|
|
49
53
|
You can follow PyTorch tutorials and convert the code to Ruby in many cases. Feel free to open an issue if you run into problems.
|
50
54
|
|
51
|
-
##
|
55
|
+
## Overview
|
52
56
|
|
53
57
|
Some examples below are from [Deep Learning with PyTorch: A 60 Minutes Blitz](https://pytorch.org/tutorials/beginner/deep_learning_60min_blitz.html)
|
54
58
|
|
@@ -214,7 +218,7 @@ Define a neural network
|
|
214
218
|
```ruby
|
215
219
|
class MyNet < Torch::NN::Module
|
216
220
|
def initialize
|
217
|
-
super
|
221
|
+
super()
|
218
222
|
@conv1 = Torch::NN::Conv2d.new(1, 6, 3)
|
219
223
|
@conv2 = Torch::NN::Conv2d.new(6, 16, 3)
|
220
224
|
@fc1 = Torch::NN::Linear.new(16 * 6 * 6, 120)
|
@@ -225,20 +229,10 @@ class MyNet < Torch::NN::Module
|
|
225
229
|
def forward(x)
|
226
230
|
x = Torch::NN::F.max_pool2d(Torch::NN::F.relu(@conv1.call(x)), [2, 2])
|
227
231
|
x = Torch::NN::F.max_pool2d(Torch::NN::F.relu(@conv2.call(x)), 2)
|
228
|
-
x =
|
232
|
+
x = Torch.flatten(x, 1)
|
229
233
|
x = Torch::NN::F.relu(@fc1.call(x))
|
230
234
|
x = Torch::NN::F.relu(@fc2.call(x))
|
231
|
-
|
232
|
-
x
|
233
|
-
end
|
234
|
-
|
235
|
-
def num_flat_features(x)
|
236
|
-
size = x.size[1..-1]
|
237
|
-
num_features = 1
|
238
|
-
size.each do |s|
|
239
|
-
num_features *= s
|
240
|
-
end
|
241
|
-
num_features
|
235
|
+
@fc3.call(x)
|
242
236
|
end
|
243
237
|
end
|
244
238
|
```
|
@@ -402,19 +396,9 @@ Here’s a list of functions to create tensors (descriptions from the [C++ docs]
|
|
402
396
|
Torch.zeros(3) # tensor([0, 0, 0])
|
403
397
|
```
|
404
398
|
|
405
|
-
## Examples
|
406
|
-
|
407
|
-
Here are a few full examples:
|
408
|
-
|
409
|
-
- [Image classification with MNIST](examples/mnist) ([日本語版](https://qiita.com/kojix2/items/c19c36dc1bf73ea93409))
|
410
|
-
- [Collaborative filtering with MovieLens](examples/movielens)
|
411
|
-
- [Sequence models and word embeddings](examples/nlp)
|
412
|
-
- [Generative adversarial networks](examples/gan)
|
413
|
-
- [Transfer learning](examples/transfer-learning)
|
414
|
-
|
415
399
|
## LibTorch Installation
|
416
400
|
|
417
|
-
[Download LibTorch](https://pytorch.org/)
|
401
|
+
[Download LibTorch](https://pytorch.org/) (for Linux, use the `cxx11 ABI` version). Then run:
|
418
402
|
|
419
403
|
```sh
|
420
404
|
bundle config build.torch-rb --with-torch-dir=/path/to/libtorch
|
@@ -424,7 +408,8 @@ Here’s the list of compatible versions.
|
|
424
408
|
|
425
409
|
Torch.rb | LibTorch
|
426
410
|
--- | ---
|
427
|
-
0.
|
411
|
+
0.8.0+ | 1.9.0+
|
412
|
+
0.6.0-0.7.0 | 1.8.0-1.8.1
|
428
413
|
0.5.0-0.5.3 | 1.7.0-1.7.1
|
429
414
|
0.3.0-0.4.2 | 1.6.0
|
430
415
|
0.2.0-0.2.7 | 1.5.0-1.5.1
|
@@ -443,9 +428,7 @@ Then install the gem (no need for `bundle config`).
|
|
443
428
|
|
444
429
|
## Performance
|
445
430
|
|
446
|
-
|
447
|
-
|
448
|
-
Deep learning is significantly faster on a GPU. Install [CUDA](https://developer.nvidia.com/cuda-downloads) and [cuDNN](https://developer.nvidia.com/cudnn) and reinstall the gem.
|
431
|
+
Deep learning is significantly faster on a GPU. With Linux, install [CUDA](https://developer.nvidia.com/cuda-downloads) and [cuDNN](https://developer.nvidia.com/cudnn) and reinstall the gem.
|
449
432
|
|
450
433
|
Check if CUDA is available
|
451
434
|
|
@@ -459,15 +442,14 @@ Move a neural network to a GPU
|
|
459
442
|
net.cuda
|
460
443
|
```
|
461
444
|
|
462
|
-
|
445
|
+
If you don’t have a GPU that supports CUDA, we recommend using a cloud service. [Paperspace](https://www.paperspace.com/) has a great free plan. We’ve put together a [Docker image](https://github.com/ankane/ml-stack) to make it easy to get started. On Paperspace, create a notebook with a custom container. Under advanced options, set the container name to:
|
463
446
|
|
464
|
-
|
465
|
-
|
466
|
-
```sh
|
467
|
-
brew upgrade ruby-build
|
468
|
-
rbenv install [version]
|
447
|
+
```text
|
448
|
+
ankane/ml-stack:torch-gpu
|
469
449
|
```
|
470
450
|
|
451
|
+
And leave the other fields in that section blank. Once the notebook is running, you can run the [MNIST example](https://github.com/ankane/ml-stack/blob/master/torch-gpu/MNIST.ipynb).
|
452
|
+
|
471
453
|
## History
|
472
454
|
|
473
455
|
View the [changelog](https://github.com/ankane/torch.rb/blob/master/CHANGELOG.md)
|
data/codegen/function.rb
CHANGED
@@ -11,6 +11,9 @@ def generate_functions
|
|
11
11
|
generate_files("torch", :define_singleton_method, functions[:torch])
|
12
12
|
generate_files("tensor", :define_method, functions[:tensor])
|
13
13
|
generate_files("nn", :define_singleton_method, functions[:nn])
|
14
|
+
generate_files("fft", :define_singleton_method, functions[:fft])
|
15
|
+
generate_files("linalg", :define_singleton_method, functions[:linalg])
|
16
|
+
generate_files("special", :define_singleton_method, functions[:special])
|
14
17
|
end
|
15
18
|
|
16
19
|
def load_functions
|
@@ -20,7 +23,7 @@ end
|
|
20
23
|
|
21
24
|
def skip_functions(functions)
|
22
25
|
functions.reject do |f|
|
23
|
-
f.base_name.start_with?("_") ||
|
26
|
+
(f.base_name.start_with?("_") && f.base_name != "__lshift__" && f.base_name != "__rshift__") ||
|
24
27
|
f.base_name.include?("_backward") ||
|
25
28
|
f.base_name.include?("_forward") ||
|
26
29
|
f.base_name == "to" ||
|
@@ -38,10 +41,26 @@ end
|
|
38
41
|
|
39
42
|
def group_functions(functions)
|
40
43
|
nn_functions, other_functions = functions.partition { |f| f.python_module == "nn" }
|
44
|
+
linalg_functions, other_functions = other_functions.partition { |f| f.python_module == "linalg" }
|
45
|
+
fft_functions, other_functions = other_functions.partition { |f| f.python_module == "fft" }
|
46
|
+
special_functions, other_functions = other_functions.partition { |f| f.python_module == "special" }
|
47
|
+
unexpected_functions, other_functions = other_functions.partition { |f| f.python_module }
|
41
48
|
torch_functions = other_functions.select { |f| f.variants.include?("function") }
|
42
49
|
tensor_functions = other_functions.select { |f| f.variants.include?("method") }
|
43
50
|
|
44
|
-
|
51
|
+
if unexpected_functions.any?
|
52
|
+
unexpected_modules = unexpected_functions.map(&:python_module).uniq
|
53
|
+
raise "Unexpected modules: #{unexpected_modules.join(", ")}"
|
54
|
+
end
|
55
|
+
|
56
|
+
{
|
57
|
+
torch: torch_functions,
|
58
|
+
tensor: tensor_functions,
|
59
|
+
nn: nn_functions,
|
60
|
+
linalg: linalg_functions,
|
61
|
+
fft: fft_functions,
|
62
|
+
special: special_functions
|
63
|
+
}
|
45
64
|
end
|
46
65
|
|
47
66
|
def generate_files(type, def_method, functions)
|
@@ -111,11 +130,15 @@ def generate_attach_def(name, type, def_method)
|
|
111
130
|
end
|
112
131
|
|
113
132
|
ruby_name = "_#{ruby_name}" if ["size", "stride", "random!", "stft"].include?(ruby_name)
|
133
|
+
ruby_name = ruby_name.sub(/\Afft_/, "") if type == "fft"
|
134
|
+
ruby_name = ruby_name.sub(/\Alinalg_/, "") if type == "linalg"
|
135
|
+
ruby_name = ruby_name.sub(/\Aspecial_/, "") if type == "special"
|
136
|
+
ruby_name = name if name.start_with?("__")
|
114
137
|
|
115
138
|
# cast for Ruby < 2.7 https://github.com/thisMagpie/fftw/issues/22#issuecomment-49508900
|
116
139
|
cast = RUBY_VERSION.to_f > 2.7 ? "" : "(VALUE (*)(...)) "
|
117
140
|
|
118
|
-
"rb_#{def_method}(m, \"#{ruby_name}\", #{cast}#{type}
|
141
|
+
"rb_#{def_method}(m, \"#{ruby_name}\", #{cast}#{full_name(name, type)}, -1);"
|
119
142
|
end
|
120
143
|
|
121
144
|
def generate_method_def(name, functions, type, def_method)
|
@@ -128,7 +151,7 @@ def generate_method_def(name, functions, type, def_method)
|
|
128
151
|
|
129
152
|
template = <<~EOS
|
130
153
|
// #{name}
|
131
|
-
static VALUE #{type}
|
154
|
+
static VALUE #{full_name(name, type)}(int argc, VALUE* argv, VALUE self_)
|
132
155
|
{
|
133
156
|
HANDLE_TH_ERRORS#{assign_self}
|
134
157
|
static RubyArgParser parser({
|
@@ -325,6 +348,8 @@ def generate_function_params(function, params, remove_self)
|
|
325
348
|
"tensor"
|
326
349
|
when "Tensor[]"
|
327
350
|
"tensorlist"
|
351
|
+
when "Scalar[]"
|
352
|
+
"scalarlist"
|
328
353
|
when /\Aint\[/
|
329
354
|
"intlist"
|
330
355
|
when "float[]"
|
@@ -414,6 +439,8 @@ def generate_dispatch_params(function, params)
|
|
414
439
|
end
|
415
440
|
when "Tensor[]"
|
416
441
|
"TensorList"
|
442
|
+
when "Scalar[]"
|
443
|
+
"ScalarList"
|
417
444
|
when "int"
|
418
445
|
"int64_t"
|
419
446
|
when "float"
|
@@ -532,6 +559,8 @@ def signature_type(param)
|
|
532
559
|
"Tensor"
|
533
560
|
when /\Tensor\[\d*\]\z/
|
534
561
|
"TensorList"
|
562
|
+
when "Scalar[]"
|
563
|
+
"ScalarList"
|
535
564
|
when /\ADimname\[\d*\]\z/
|
536
565
|
"DirnameList"
|
537
566
|
when /\Aint\[\d*\]\z/
|
@@ -554,3 +583,11 @@ def signature_type(param)
|
|
554
583
|
type += "?" if param[:optional]
|
555
584
|
type
|
556
585
|
end
|
586
|
+
|
587
|
+
def full_name(name, type)
|
588
|
+
if %w(fft linalg special).include?(type) && name.start_with?("#{type}_")
|
589
|
+
name
|
590
|
+
else
|
591
|
+
"#{type}_#{name}"
|
592
|
+
end
|
593
|
+
end
|