torch-rb 0.8.0 → 0.9.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: fdc46d7eba97851841de58e63b35badbd579ce1bc2a3e311998db03956cb84ad
4
- data.tar.gz: 944520049bd683d303e4587d18394eeb13102aa9f4addeca87875ee214806de4
3
+ metadata.gz: '09221364dad232f1b76129fe9dc9407675cc2afbd03bd1339c736d4eec752df7'
4
+ data.tar.gz: a37a0584aed809009ebd74e7c0da9430481ccabf1ac915d2468ee7511c249588
5
5
  SHA512:
6
- metadata.gz: 9026cbd9b0cdf286e79e7b296f2fae95712bd553c2cd58a34044feeed482f1ed2630b7b1e852a82e87d1011478b7e24d442d634f07de67b2c0a6a8e1cf6ade9a
7
- data.tar.gz: 193e25fc5065d42160b0584f3e53512606c1b4329c6d872b90a972d7c4d46a4be81eef8c709e3060339c96758fe504dc8618da9e69ff411d9351d528983da72b
6
+ metadata.gz: c220d35971b9ce3e5a7a80f6a5d1ae4324f3524d0e0171c680deced66fe2f29342a46eecb1a4447d84a401a677c7bb1ef910a0c7ee6c925ea4b578b7e5712772
7
+ data.tar.gz: 807fe2907de1caac92da6dddb0154b7971dda3aa0ee2c53f6b3046732f4bf3c02310e59a6441efa0fdf1ad3d0ddb5dcd7a3c1a946adbfbea73b6b30f10a71487
data/CHANGELOG.md CHANGED
@@ -1,3 +1,25 @@
1
+ ## 0.9.0 (2021-10-23)
2
+
3
+ - Updated LibTorch to 1.10.0
4
+ - Added `real` and `imag` methods to tensors
5
+
6
+ ## 0.8.3 (2021-10-17)
7
+
8
+ - Fixed `dup` method for tensors and parameters
9
+ - Fixed issues with transformers
10
+
11
+ ## 0.8.2 (2021-10-03)
12
+
13
+ - Added transformers
14
+ - Added left shift and right shift
15
+
16
+ ## 0.8.1 (2021-06-15)
17
+
18
+ - Added `Backends` module
19
+ - Added `FFT` module
20
+ - Added `Linalg` module
21
+ - Added `Special` module
22
+
1
23
  ## 0.8.0 (2021-06-15)
2
24
 
3
25
  - Updated LibTorch to 1.9.0
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
- Deep learning is significantly faster with a GPU. If you don’t have an NVIDIA GPU, we recommend using a cloud service. [Paperspace](https://www.paperspace.com/) has a great free plan.
31
+ A good place to start is [Deep Learning with Torch.rb: A 60 Minute Blitz](tutorials/blitz/README.md).
32
32
 
33
- 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:
33
+ ## Tutorials
34
34
 
35
- ```text
36
- ankane/ml-stack:torch-gpu
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
- 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).
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
- ## Tutorial
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 = x.view(-1, num_flat_features(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
- x = @fc3.call(x)
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/). For Linux, use the `cxx11 ABI` version. Then run:
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.8.0+ | 1.9.0+
411
+ 0.9.0+ | 1.10.0+
412
+ 0.8.0-0.8.3 | 1.9.0-1.9.1
428
413
  0.6.0-0.7.0 | 1.8.0-1.8.1
429
414
  0.5.0-0.5.3 | 1.7.0-1.7.1
430
415
  0.3.0-0.4.2 | 1.6.0
@@ -444,9 +429,7 @@ Then install the gem (no need for `bundle config`).
444
429
 
445
430
  ## Performance
446
431
 
447
- ### Linux
448
-
449
- 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.
432
+ 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.
450
433
 
451
434
  Check if CUDA is available
452
435
 
@@ -460,15 +443,14 @@ Move a neural network to a GPU
460
443
  net.cuda
461
444
  ```
462
445
 
463
- ## rbenv
446
+ 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:
464
447
 
465
- This library uses [Rice](https://github.com/jasonroelofs/rice) to interface with LibTorch. Rice and earlier versions of rbenv don’t play nicely together. If you encounter an error during installation, upgrade ruby-build and reinstall your Ruby version.
466
-
467
- ```sh
468
- brew upgrade ruby-build
469
- rbenv install [version]
448
+ ```text
449
+ ankane/ml-stack:torch-gpu
470
450
  ```
471
451
 
452
+ 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).
453
+
472
454
  ## History
473
455
 
474
456
  View the [changelog](https://github.com/ankane/torch.rb/blob/master/CHANGELOG.md)
@@ -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,11 +23,14 @@ 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" ||
27
30
  f.base_name == "record_stream" ||
31
+ f.base_name == "is_pinned" ||
32
+ f.base_name == "pin_memory" ||
33
+ f.base_name == "fused_moving_avg_obs_fake_quant" ||
28
34
  # in ext.cpp
29
35
  f.base_name == "index" ||
30
36
  f.base_name == "index_put_" ||
@@ -38,10 +44,26 @@ end
38
44
 
39
45
  def group_functions(functions)
40
46
  nn_functions, other_functions = functions.partition { |f| f.python_module == "nn" }
47
+ linalg_functions, other_functions = other_functions.partition { |f| f.python_module == "linalg" }
48
+ fft_functions, other_functions = other_functions.partition { |f| f.python_module == "fft" }
49
+ special_functions, other_functions = other_functions.partition { |f| f.python_module == "special" }
50
+ unexpected_functions, other_functions = other_functions.partition { |f| f.python_module }
41
51
  torch_functions = other_functions.select { |f| f.variants.include?("function") }
42
52
  tensor_functions = other_functions.select { |f| f.variants.include?("method") }
43
53
 
44
- {torch: torch_functions, tensor: tensor_functions, nn: nn_functions}
54
+ if unexpected_functions.any?
55
+ unexpected_modules = unexpected_functions.map(&:python_module).uniq
56
+ raise "Unexpected modules: #{unexpected_modules.join(", ")}"
57
+ end
58
+
59
+ {
60
+ torch: torch_functions,
61
+ tensor: tensor_functions,
62
+ nn: nn_functions,
63
+ linalg: linalg_functions,
64
+ fft: fft_functions,
65
+ special: special_functions
66
+ }
45
67
  end
46
68
 
47
69
  def generate_files(type, def_method, functions)
@@ -111,11 +133,15 @@ def generate_attach_def(name, type, def_method)
111
133
  end
112
134
 
113
135
  ruby_name = "_#{ruby_name}" if ["size", "stride", "random!", "stft"].include?(ruby_name)
136
+ ruby_name = ruby_name.sub(/\Afft_/, "") if type == "fft"
137
+ ruby_name = ruby_name.sub(/\Alinalg_/, "") if type == "linalg"
138
+ ruby_name = ruby_name.sub(/\Aspecial_/, "") if type == "special"
139
+ ruby_name = name if name.start_with?("__")
114
140
 
115
141
  # cast for Ruby < 2.7 https://github.com/thisMagpie/fftw/issues/22#issuecomment-49508900
116
142
  cast = RUBY_VERSION.to_f > 2.7 ? "" : "(VALUE (*)(...)) "
117
143
 
118
- "rb_#{def_method}(m, \"#{ruby_name}\", #{cast}#{type}_#{name}, -1);"
144
+ "rb_#{def_method}(m, \"#{ruby_name}\", #{cast}#{full_name(name, type)}, -1);"
119
145
  end
120
146
 
121
147
  def generate_method_def(name, functions, type, def_method)
@@ -128,7 +154,7 @@ def generate_method_def(name, functions, type, def_method)
128
154
 
129
155
  template = <<~EOS
130
156
  // #{name}
131
- static VALUE #{type}_#{name}(int argc, VALUE* argv, VALUE self_)
157
+ static VALUE #{full_name(name, type)}(int argc, VALUE* argv, VALUE self_)
132
158
  {
133
159
  HANDLE_TH_ERRORS#{assign_self}
134
160
  static RubyArgParser parser({
@@ -364,6 +390,8 @@ def generate_function_params(function, params, remove_self)
364
390
  end
365
391
  when "generator", "tensorlist", "intlist"
366
392
  func
393
+ when "string"
394
+ "stringViewOptional"
367
395
  else
368
396
  "#{func}Optional"
369
397
  end
@@ -401,9 +429,7 @@ def generate_dispatch_params(function, params)
401
429
  if function.out?
402
430
  "const Tensor &"
403
431
  else
404
- # TODO
405
- # "const c10::optional<at::Tensor> &"
406
- "const OptionalTensor &"
432
+ "const c10::optional<at::Tensor> &"
407
433
  end
408
434
  elsif param[:modifier]
409
435
  if param[:modifier].include?("!") && function.retvals.size > 1
@@ -427,7 +453,11 @@ def generate_dispatch_params(function, params)
427
453
  when "float[]"
428
454
  "ArrayRef<double>"
429
455
  when "str"
430
- "std::string"
456
+ if param[:optional]
457
+ "c10::string_view"
458
+ else
459
+ "std::string"
460
+ end
431
461
  when "Scalar", "bool", "ScalarType", "Layout", "Device", "Storage", "Generator", "MemoryFormat", "Storage"
432
462
  param[:type]
433
463
  else
@@ -560,3 +590,11 @@ def signature_type(param)
560
590
  type += "?" if param[:optional]
561
591
  type
562
592
  end
593
+
594
+ def full_name(name, type)
595
+ if %w(fft linalg special).include?(type) && name.start_with?("#{type}_")
596
+ name
597
+ else
598
+ "#{type}_#{name}"
599
+ end
600
+ end