grx-tensor 0.1.0 → 0.2.1
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 +26 -0
- data/GUIA_PRINCIPIANTES.md +1046 -0
- data/README.es.md +1199 -0
- data/README.md +1026 -283
- data/ext/grx/extconf.rb +4 -18
- data/ext/grx/grx_core.c +411 -331
- data/ext/grx/grx_core.h +23 -13
- data/ext/unix/Makefile +3 -27
- data/ext/windows/Makefile.mingw +3 -23
- data/grx-tensor.gemspec +41 -35
- data/lib/grx/c_api.rb +75 -39
- data/lib/grx/data.rb +87 -0
- data/lib/grx/loss.rb +55 -25
- data/lib/grx/nn.rb +160 -41
- data/lib/grx/optim.rb +21 -16
- data/lib/grx/serialization.rb +66 -0
- data/lib/grx/storage.rb +19 -27
- data/lib/grx/tensor.rb +234 -65
- data/lib/grx/utils.rb +43 -0
- data/lib/grx/version.rb +1 -1
- data/lib/grx.rb +22 -6
- metadata +37 -28
data/lib/grx/utils.rb
ADDED
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module GRX
|
|
4
|
+
module Utils
|
|
5
|
+
# ================================================================
|
|
6
|
+
# clip_grad_norm! — Clips gradients of parameter collection so their
|
|
7
|
+
# combined L2 norm does not exceed max_norm.
|
|
8
|
+
# Prevents exploding gradient problems during deep network training.
|
|
9
|
+
# ================================================================
|
|
10
|
+
def self.clip_grad_norm!(parameters, max_norm)
|
|
11
|
+
max_norm = max_norm.to_f
|
|
12
|
+
total_norm_sq = 0.0
|
|
13
|
+
parameters.each do |p|
|
|
14
|
+
next unless p.grad
|
|
15
|
+
total_norm_sq += p.grad.square.to_a.sum
|
|
16
|
+
end
|
|
17
|
+
total_norm = Math.sqrt(total_norm_sq)
|
|
18
|
+
clip_coef = max_norm / (total_norm + 1e-6)
|
|
19
|
+
if clip_coef < 1.0
|
|
20
|
+
parameters.each do |p|
|
|
21
|
+
next unless p.grad
|
|
22
|
+
p.grad = p.grad.scale(clip_coef)
|
|
23
|
+
end
|
|
24
|
+
end
|
|
25
|
+
total_norm
|
|
26
|
+
end
|
|
27
|
+
|
|
28
|
+
# ================================================================
|
|
29
|
+
# one_hot — Generates a 2D One-Hot encoded Tensor from class indices
|
|
30
|
+
# ================================================================
|
|
31
|
+
def self.one_hot(indices, num_classes: nil, requires_grad: false)
|
|
32
|
+
ids = indices.is_a?(Tensor) ? indices.to_a.map(&:to_i) : Array(indices).map(&:to_i)
|
|
33
|
+
c = num_classes || (ids.empty? ? 0 : ids.max + 1)
|
|
34
|
+
n = ids.size
|
|
35
|
+
matrix_data = Array.new(n * c, 0.0)
|
|
36
|
+
ids.each_with_index do |class_id, row|
|
|
37
|
+
raise IndexError, "Class index #{class_id} out of bounds [0, #{c})" if class_id < 0 || class_id >= c
|
|
38
|
+
matrix_data[row * c + class_id] = 1.0
|
|
39
|
+
end
|
|
40
|
+
Tensor.create(matrix_data, [n, c], requires_grad: requires_grad)
|
|
41
|
+
end
|
|
42
|
+
end
|
|
43
|
+
end
|
data/lib/grx/version.rb
CHANGED
data/lib/grx.rb
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
# frozen_string_literal: true
|
|
2
2
|
|
|
3
3
|
# =====================================================================
|
|
4
|
-
# GRX —
|
|
4
|
+
# GRX — Tensor framework with autograd and C+SIMD compute core
|
|
5
5
|
# require "grx"
|
|
6
6
|
# =====================================================================
|
|
7
7
|
|
|
@@ -10,12 +10,15 @@ require_relative "grx/errors"
|
|
|
10
10
|
require_relative "grx/c_api"
|
|
11
11
|
require_relative "grx/storage"
|
|
12
12
|
require_relative "grx/tensor"
|
|
13
|
+
require_relative "grx/serialization"
|
|
13
14
|
require_relative "grx/nn"
|
|
14
15
|
require_relative "grx/optim"
|
|
15
16
|
require_relative "grx/loss"
|
|
17
|
+
require_relative "grx/data"
|
|
18
|
+
require_relative "grx/utils"
|
|
16
19
|
|
|
17
20
|
module GRX
|
|
18
|
-
#
|
|
21
|
+
# Quick factory helpers
|
|
19
22
|
def self.tensor(data, shape, requires_grad: false)
|
|
20
23
|
Tensor.create(data, shape, requires_grad: requires_grad)
|
|
21
24
|
end
|
|
@@ -34,16 +37,29 @@ module GRX
|
|
|
34
37
|
end
|
|
35
38
|
|
|
36
39
|
def self.randn(shape, requires_grad: false)
|
|
37
|
-
# Box-Muller
|
|
40
|
+
# Box-Muller from Ruby (C backend executes faster via he_normal)
|
|
38
41
|
n = shape.reduce(1, :*)
|
|
39
42
|
data = []
|
|
40
43
|
(n / 2.0).ceil.times do
|
|
41
|
-
u1 = ::Kernel.rand
|
|
44
|
+
u1 = ::Kernel.rand
|
|
45
|
+
u1 = ::Kernel.rand while u1 < 1e-15
|
|
42
46
|
u2 = ::Kernel.rand
|
|
43
47
|
r = Math.sqrt(-2.0 * Math.log(u1))
|
|
44
|
-
data << r * Math.cos(2 * Math::PI * u2)
|
|
45
|
-
data << r * Math.sin(2 * Math::PI * u2)
|
|
48
|
+
data << (r * Math.cos(2 * Math::PI * u2))
|
|
49
|
+
data << (r * Math.sin(2 * Math::PI * u2))
|
|
46
50
|
end
|
|
47
51
|
Tensor.create(data.first(n), shape, requires_grad: requires_grad)
|
|
48
52
|
end
|
|
53
|
+
|
|
54
|
+
def self.c_loaded?
|
|
55
|
+
CAPI::LOADED
|
|
56
|
+
end
|
|
57
|
+
|
|
58
|
+
def self.mode
|
|
59
|
+
CAPI::LOADED ? :c : :ruby
|
|
60
|
+
end
|
|
61
|
+
|
|
62
|
+
def self.simd_mode
|
|
63
|
+
CAPI.simd_mode
|
|
64
|
+
end
|
|
49
65
|
end
|
metadata
CHANGED
|
@@ -1,10 +1,10 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: grx-tensor
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 0.1
|
|
4
|
+
version: 0.2.1
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
|
-
-
|
|
7
|
+
- Razo
|
|
8
8
|
bindir: bin
|
|
9
9
|
cert_chain: []
|
|
10
10
|
date: 1980-01-02 00:00:00.000000000 Z
|
|
@@ -67,8 +67,9 @@ dependencies:
|
|
|
67
67
|
version: '2.0'
|
|
68
68
|
description: |
|
|
69
69
|
GRX brings PyTorch-style tensor operations to Ruby. Every arithmetic op,
|
|
70
|
-
activation, and optimizer step runs through a native C library
|
|
71
|
-
|
|
70
|
+
activation, and optimizer step runs through a native C library with
|
|
71
|
+
dynamic multi-target SIMD dispatch (AVX2+FMA, SSE, and scalar fallback).
|
|
72
|
+
Ruby is the interface — C does the work.
|
|
72
73
|
|
|
73
74
|
Features: autograd, SGD/Adam optimizers, Linear/Sequential/Dropout/BatchNorm
|
|
74
75
|
layers, MSE/BCE/CrossEntropy loss functions, Xavier and He weight init.
|
|
@@ -81,7 +82,9 @@ extensions:
|
|
|
81
82
|
extra_rdoc_files: []
|
|
82
83
|
files:
|
|
83
84
|
- CHANGELOG.md
|
|
85
|
+
- GUIA_PRINCIPIANTES.md
|
|
84
86
|
- LICENSE.txt
|
|
87
|
+
- README.es.md
|
|
85
88
|
- README.md
|
|
86
89
|
- ext/grx/extconf.rb
|
|
87
90
|
- ext/grx/grx_core.c
|
|
@@ -91,12 +94,15 @@ files:
|
|
|
91
94
|
- grx-tensor.gemspec
|
|
92
95
|
- lib/grx.rb
|
|
93
96
|
- lib/grx/c_api.rb
|
|
97
|
+
- lib/grx/data.rb
|
|
94
98
|
- lib/grx/errors.rb
|
|
95
99
|
- lib/grx/loss.rb
|
|
96
100
|
- lib/grx/nn.rb
|
|
97
101
|
- lib/grx/optim.rb
|
|
102
|
+
- lib/grx/serialization.rb
|
|
98
103
|
- lib/grx/storage.rb
|
|
99
104
|
- lib/grx/tensor.rb
|
|
105
|
+
- lib/grx/utils.rb
|
|
100
106
|
- lib/grx/version.rb
|
|
101
107
|
homepage: https://github.com/Gabo-Razo/grx-tensor
|
|
102
108
|
licenses:
|
|
@@ -107,36 +113,39 @@ metadata:
|
|
|
107
113
|
bug_tracker_uri: https://github.com/Gabo-Razo/grx-tensor/issues
|
|
108
114
|
post_install_message: |2+
|
|
109
115
|
|
|
110
|
-
|
|
111
|
-
GRX-Tensor 0.1
|
|
112
|
-
|
|
116
|
+
============================================================
|
|
117
|
+
GRX-Tensor 0.2.1
|
|
118
|
+
============================================================
|
|
113
119
|
|
|
114
|
-
|
|
120
|
+
[ENGLISH]
|
|
121
|
+
Thank you for choosing and using GRX-Tensor!
|
|
115
122
|
|
|
116
|
-
|
|
117
|
-
|
|
123
|
+
* Native C acceleration with dynamic SIMD dispatch
|
|
124
|
+
(AVX2+FMA, SSE, and portable scalar C) is built and
|
|
125
|
+
configured automatically.
|
|
126
|
+
* Windows Note: Native C acceleration is supported when
|
|
127
|
+
using RubyInstaller with DevKit (MSYS2 / MinGW-w64).
|
|
128
|
+
Standalone pre-compiled Windows binaries are currently
|
|
129
|
+
in active development.
|
|
130
|
+
* Documentation, guides, and tutorials:
|
|
131
|
+
https://github.com/Gabo-Razo/grx-tensor
|
|
118
132
|
|
|
119
|
-
|
|
133
|
+
----------------------------------------------------------
|
|
120
134
|
|
|
121
|
-
|
|
135
|
+
[ESPAÑOL]
|
|
136
|
+
Muchas gracias por elegir y utilizar GRX-Tensor!
|
|
122
137
|
|
|
123
|
-
|
|
138
|
+
* La aceleracion nativa en C con despacho dinamico SIMD
|
|
139
|
+
(AVX2+FMA, SSE y C escalar portable) se compila y
|
|
140
|
+
configura de forma totalmente automatica.
|
|
141
|
+
* Nota para Windows: La aceleracion nativa esta soportada
|
|
142
|
+
al utilizar RubyInstaller con DevKit (MSYS2 / MinGW-w64).
|
|
143
|
+
Los binarios pre-compilados independientes para Windows
|
|
144
|
+
se encuentran actualmente en desarrollo activo.
|
|
145
|
+
* Documentacion, guias y tutoriales:
|
|
146
|
+
https://github.com/Gabo-Razo/grx-tensor
|
|
124
147
|
|
|
125
|
-
|
|
126
|
-
b = GRX.tensor([4.0, 5.0, 6.0], [3], requires_grad: true)
|
|
127
|
-
c = a + b
|
|
128
|
-
c.backward
|
|
129
|
-
puts a.grad.to_a # [1.0, 1.0, 1.0]
|
|
130
|
-
|
|
131
|
-
net = GRX::NN::Sequential.new(
|
|
132
|
-
GRX::NN::Linear.new(4, 16),
|
|
133
|
-
GRX::NN::ReLU.new,
|
|
134
|
-
GRX::NN::Linear.new(16, 1)
|
|
135
|
-
)
|
|
136
|
-
opt = GRX::Optim::Adam.new(net.parameters, lr: 0.001)
|
|
137
|
-
|
|
138
|
-
Docs: https://github.com/Gabo-Razo/grx-tensor
|
|
139
|
-
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
|
|
148
|
+
============================================================
|
|
140
149
|
|
|
141
150
|
rdoc_options: []
|
|
142
151
|
require_paths:
|