addernet 1.2.2__tar.gz → 1.2.6__tar.gz
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.
- {addernet-1.2.2 → addernet-1.2.6}/Makefile +1 -1
- addernet-1.2.6/PKG-INFO +200 -0
- addernet-1.2.6/README.md +170 -0
- {addernet-1.2.2 → addernet-1.2.6}/addernet/__init__.py +1 -1
- {addernet-1.2.2 → addernet-1.2.6}/addernet/addernet_hdc.py +19 -3
- addernet-1.2.6/addernet.egg-info/PKG-INFO +200 -0
- {addernet-1.2.2 → addernet-1.2.6}/addernet.egg-info/SOURCES.txt +2 -0
- {addernet-1.2.2 → addernet-1.2.6}/pyproject.toml +1 -1
- {addernet-1.2.2 → addernet-1.2.6}/python/addernet_hdc.py +19 -3
- {addernet-1.2.2 → addernet-1.2.6}/setup.py +2 -2
- {addernet-1.2.2 → addernet-1.2.6}/src/addernet_cuda.cu +12 -11
- {addernet-1.2.2 → addernet-1.2.6}/src/addernet_hdc.c +214 -206
- addernet-1.2.6/src/addernet_hdc.h +93 -0
- addernet-1.2.6/src/addernet_hdc_train_cuda.cu +235 -0
- addernet-1.2.6/src/cuda_runtime.h +0 -0
- addernet-1.2.6/src/hdc_core.c +302 -0
- addernet-1.2.6/src/hdc_core.h +78 -0
- {addernet-1.2.2 → addernet-1.2.6}/src/hdc_cuda_batch.c +19 -19
- addernet-1.2.6/src/hdc_lsh.c +92 -0
- addernet-1.2.6/src/hdc_lsh.h +42 -0
- addernet-1.2.2/PKG-INFO +0 -351
- addernet-1.2.2/README.md +0 -321
- addernet-1.2.2/addernet.egg-info/PKG-INFO +0 -351
- addernet-1.2.2/src/addernet_hdc.h +0 -238
- addernet-1.2.2/src/hdc_core.c +0 -511
- addernet-1.2.2/src/hdc_core.h +0 -151
- addernet-1.2.2/src/hdc_lsh.c +0 -92
- addernet-1.2.2/src/hdc_lsh.h +0 -40
- {addernet-1.2.2 → addernet-1.2.6}/LICENSE +0 -0
- {addernet-1.2.2 → addernet-1.2.6}/MANIFEST.in +0 -0
- {addernet-1.2.2 → addernet-1.2.6}/README_DEV.md +0 -0
- {addernet-1.2.2 → addernet-1.2.6}/addernet/addernet.py +0 -0
- {addernet-1.2.2 → addernet-1.2.6}/addernet/attention.py +0 -0
- {addernet-1.2.2 → addernet-1.2.6}/addernet/boost.py +0 -0
- {addernet-1.2.2 → addernet-1.2.6}/addernet/build_ext.py +0 -0
- {addernet-1.2.2 → addernet-1.2.6}/addernet/cluster.py +0 -0
- {addernet-1.2.2 → addernet-1.2.6}/addernet/libaddernet.so +0 -0
- {addernet-1.2.2 → addernet-1.2.6}/addernet/libaddernet_hdc.so +0 -0
- {addernet-1.2.2 → addernet-1.2.6}/addernet/src/addernet.c +0 -0
- {addernet-1.2.2 → addernet-1.2.6}/addernet/src/addernet.h +0 -0
- {addernet-1.2.2 → addernet-1.2.6}/addernet/src/addernet_hdc.c +0 -0
- {addernet-1.2.2 → addernet-1.2.6}/addernet/src/addernet_hdc.h +0 -0
- {addernet-1.2.2 → addernet-1.2.6}/addernet/src/hdc_core.c +0 -0
- {addernet-1.2.2 → addernet-1.2.6}/addernet/src/hdc_core.h +0 -0
- {addernet-1.2.2 → addernet-1.2.6}/addernet/src/hdc_core_cuda.c +0 -0
- {addernet-1.2.2 → addernet-1.2.6}/addernet/src/hdc_cuda_batch.c +0 -0
- {addernet-1.2.2 → addernet-1.2.6}/addernet/src/hdc_lsh.c +0 -0
- {addernet-1.2.2 → addernet-1.2.6}/addernet/src/hdc_lsh.h +0 -0
- {addernet-1.2.2 → addernet-1.2.6}/addernet.egg-info/dependency_links.txt +0 -0
- {addernet-1.2.2 → addernet-1.2.6}/addernet.egg-info/entry_points.txt +0 -0
- {addernet-1.2.2 → addernet-1.2.6}/addernet.egg-info/requires.txt +0 -0
- {addernet-1.2.2 → addernet-1.2.6}/addernet.egg-info/top_level.txt +0 -0
- {addernet-1.2.2 → addernet-1.2.6}/python/__init__.py +0 -0
- {addernet-1.2.2 → addernet-1.2.6}/python/addernet.py +0 -0
- {addernet-1.2.2 → addernet-1.2.6}/setup.cfg +0 -0
- {addernet-1.2.2 → addernet-1.2.6}/src/addernet.c +0 -0
- {addernet-1.2.2 → addernet-1.2.6}/src/addernet.h +0 -0
- {addernet-1.2.2 → addernet-1.2.6}/src/hdc_core_cuda.c +0 -0
|
@@ -112,7 +112,7 @@ $(CUDA_SO): $(HDC_CORE_OBJ) $(CUDA_OBJ) $(CUDA_BATCH_OBJ) $(HDC_OBJ)
|
|
|
112
112
|
$(CC) -shared -o $(CUDA_SO) $(HDC_CORE_OBJ) $(CUDA_OBJ) $(CUDA_BATCH_OBJ) $(HDC_OBJ) $(LDFLAGS) -ldl
|
|
113
113
|
|
|
114
114
|
# --- CUDA (nvcc native build) ---
|
|
115
|
-
CUDA_NATIVE_SRC = $(SRC_DIR)/addernet_cuda.cu
|
|
115
|
+
CUDA_NATIVE_SRC = $(SRC_DIR)/addernet_cuda.cu $(SRC_DIR)/addernet_hdc_train_cuda.cu
|
|
116
116
|
CUDA_NATIVE_SO = $(BUILD_DIR)/libaddernet_cuda.so
|
|
117
117
|
|
|
118
118
|
NVCC := $(shell command -v nvcc 2> /dev/null)
|
addernet-1.2.6/PKG-INFO
ADDED
|
@@ -0,0 +1,200 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: addernet
|
|
3
|
+
Version: 1.2.6
|
|
4
|
+
Summary: Neural networks with zero multiplications at inference. AdderNet + HDC for embedded systems.
|
|
5
|
+
Author: AdderNet Team
|
|
6
|
+
License: Apache-2.0
|
|
7
|
+
Project-URL: Homepage, https://github.com/addernet/addernet
|
|
8
|
+
Project-URL: Repository, https://github.com/addernet/addernet
|
|
9
|
+
Keywords: machine-learning,neural-network,addernet,hyperdimensional-computing,embedded,no-fpu
|
|
10
|
+
Classifier: Development Status :: 4 - Beta
|
|
11
|
+
Classifier: Intended Audience :: Developers
|
|
12
|
+
Classifier: Intended Audience :: Science/Research
|
|
13
|
+
Classifier: License :: OSI Approved :: Apache Software License
|
|
14
|
+
Classifier: Programming Language :: Python :: 3
|
|
15
|
+
Classifier: Programming Language :: Python :: 3.8
|
|
16
|
+
Classifier: Programming Language :: Python :: 3.9
|
|
17
|
+
Classifier: Programming Language :: Python :: 3.10
|
|
18
|
+
Classifier: Programming Language :: Python :: 3.11
|
|
19
|
+
Classifier: Programming Language :: Python :: 3.12
|
|
20
|
+
Classifier: Topic :: Scientific/Engineering :: Artificial Intelligence
|
|
21
|
+
Requires-Python: >=3.8
|
|
22
|
+
Description-Content-Type: text/markdown
|
|
23
|
+
License-File: LICENSE
|
|
24
|
+
Requires-Dist: numpy
|
|
25
|
+
Requires-Dist: scikit-learn
|
|
26
|
+
Requires-Dist: scipy
|
|
27
|
+
Provides-Extra: dev
|
|
28
|
+
Requires-Dist: pytest; extra == "dev"
|
|
29
|
+
Dynamic: license-file
|
|
30
|
+
|
|
31
|
+
# AdderNet
|
|
32
|
+
|
|
33
|
+
[](https://pypi.org/project/addernet/)
|
|
34
|
+
[](https://pypi.org/project/addernet/)
|
|
35
|
+
[](LICENSE)
|
|
36
|
+
|
|
37
|
+
Biblioteca de machine learning que **não usa multiplicação de ponto flutuante** na inferência. Zero.
|
|
38
|
+
|
|
39
|
+
> Benchmarks medidos em CPU x86-64 com backend **AVX2** e GPUs NVIDIA via **CUDA**, Python 3.x, v1.2.5.
|
|
40
|
+
|
|
41
|
+
---
|
|
42
|
+
|
|
43
|
+
## O que é?
|
|
44
|
+
|
|
45
|
+
AdderNet substitui multiplicações por **lookups em tabela** (LUT) e operações de soma inteiras,
|
|
46
|
+
tornando a inferência viável em microcontroladores sem FPU (ESP32, STM32, RPi).
|
|
47
|
+
|
|
48
|
+
A biblioteca expõe quatro componentes principais:
|
|
49
|
+
|
|
50
|
+
| Classe | Descrição |
|
|
51
|
+
|---|---|
|
|
52
|
+
| `AdderNetLayer` | Rede de uma variável — LUT + soma, zero multiplicação |
|
|
53
|
+
| `AdderNetHDC` | Classificador multivariável — Hyperdimensional Computing (HDC) |
|
|
54
|
+
| `AdderCluster` | Ensemble de `AdderNetLayer` com estratégias de combinação |
|
|
55
|
+
| `AdderBoost` | Gradient Boosting com `AdderNetLayer` — inferência sem multiplicação |
|
|
56
|
+
|
|
57
|
+
---
|
|
58
|
+
|
|
59
|
+
## Novidades v1.2.5 🚀
|
|
60
|
+
|
|
61
|
+
- **HV_DIM Dinâmico**: A dimensionalidade hiperdimensional (`hv_dim`) agora é configurável em tempo de execução (`512`, `1024`, `2048`, `4096`, etc), sem precisar recompilar a biblioteca C!
|
|
62
|
+
- **Aceleração CUDA NATIVA no Treinamento**: O loop iterativo de retreino (`AdaptHD`) foi reescrito em CUDA para ser executado massivamente em paralelo usando `atomicAdd` e otimizações de bitwise. Basta usar `use_gpu_training=True`.
|
|
63
|
+
- **Aceleração CUDA na Inferência**: O processo de `predict_batch` agora tem suporte a GPU via kernels CUDA dedicados. Basta instanciar o modelo com `use_gpu=True`.
|
|
64
|
+
- **Compatibilidade e Fallback**: O pacote compila nativamente o C++ e CUDA no momento do `pip install`. Se a máquina alvo (como um Raspberry Pi) não tiver placa de vídeo NVIDIA, a biblioteca roda perfeitamente fazendo fallback silencioso para CPU com `AVX2`, `NEON` ou `SCALAR`.
|
|
65
|
+
- Correção de bugs de Ctypes FFI e memory alignment (agora todos os `aligned_alloc` usam arrays flats dinâmicos, preservando compatibilidade absoluta entre os tensores C contíguos e o numpy).
|
|
66
|
+
|
|
67
|
+
---
|
|
68
|
+
|
|
69
|
+
## Instalação
|
|
70
|
+
|
|
71
|
+
```bash
|
|
72
|
+
pip install addernet
|
|
73
|
+
```
|
|
74
|
+
|
|
75
|
+
Ou do código-fonte (para compilar com otimizações nativas e CUDA opcional):
|
|
76
|
+
|
|
77
|
+
```bash
|
|
78
|
+
git clone https://github.com/PedroHenriqueBatistaSilva/AdderNet.git
|
|
79
|
+
cd AdderNet
|
|
80
|
+
make all # Compila binários da CPU
|
|
81
|
+
make cuda_native # Opcional: Compila o backend de GPU (requer nvcc)
|
|
82
|
+
pip install -e .
|
|
83
|
+
```
|
|
84
|
+
|
|
85
|
+
---
|
|
86
|
+
|
|
87
|
+
## Uso — AdderNetLayer (uma variável)
|
|
88
|
+
|
|
89
|
+
```python
|
|
90
|
+
from addernet import AdderNetLayer
|
|
91
|
+
|
|
92
|
+
rede = AdderNetLayer(size=256, bias=50, input_min=-50, input_max=200, lr=0.1)
|
|
93
|
+
|
|
94
|
+
celsius = [0, 10, 20, 25, 30, 37, 50, 80, 100]
|
|
95
|
+
fahrenheit = [32, 50, 68, 77, 86, 98.6, 122, 176, 212]
|
|
96
|
+
|
|
97
|
+
rede.train(celsius, fahrenheit)
|
|
98
|
+
|
|
99
|
+
print(rede.predict(37)) # 98.60
|
|
100
|
+
print(rede.predict(100)) # 212.00
|
|
101
|
+
```
|
|
102
|
+
|
|
103
|
+
### Previsão em lote (numpy)
|
|
104
|
+
|
|
105
|
+
```python
|
|
106
|
+
import numpy as np
|
|
107
|
+
|
|
108
|
+
entradas = np.linspace(-50, 200, 1_000_000, dtype=np.float64)
|
|
109
|
+
saidas = rede.predict_batch(entradas) # ~178M pred/s com AVX2
|
|
110
|
+
```
|
|
111
|
+
|
|
112
|
+
---
|
|
113
|
+
|
|
114
|
+
## Uso — AdderNetHDC (Aceleração GPU e HDC Dinâmico)
|
|
115
|
+
|
|
116
|
+
```python
|
|
117
|
+
from addernet import AdderNetHDC
|
|
118
|
+
import numpy as np
|
|
119
|
+
from sklearn.datasets import load_iris
|
|
120
|
+
from sklearn.preprocessing import MinMaxScaler
|
|
121
|
+
|
|
122
|
+
iris = load_iris()
|
|
123
|
+
X = MinMaxScaler(feature_range=(0, 150)).fit_transform(iris.data)
|
|
124
|
+
y = iris.target
|
|
125
|
+
|
|
126
|
+
# HV_DIM dinâmico configurável (ex: 2048, 4096)
|
|
127
|
+
model = AdderNetHDC(
|
|
128
|
+
n_vars=4,
|
|
129
|
+
n_classes=3,
|
|
130
|
+
table_size=256,
|
|
131
|
+
hv_dim=4096, # <- Dimensionalidade configurável no runtime!
|
|
132
|
+
use_gpu=True, # <- Ativa inferência batch em CUDA
|
|
133
|
+
use_gpu_training=True # <- Ativa treinamento iterativo em CUDA
|
|
134
|
+
)
|
|
135
|
+
|
|
136
|
+
# Arrays numpy precisam ser "C Contiguous"
|
|
137
|
+
X_c = np.ascontiguousarray(X, dtype=np.float64)
|
|
138
|
+
y_c = np.ascontiguousarray(y, dtype=np.int32)
|
|
139
|
+
|
|
140
|
+
# Treino single-pass (OnlineHD)
|
|
141
|
+
model.train(X_c, y_c)
|
|
142
|
+
|
|
143
|
+
# Retreino iterativo (AdaptHD) — massivamente paralelo na GPU
|
|
144
|
+
model.train(X_c, y_c, n_iter=20, lr=1.0)
|
|
145
|
+
|
|
146
|
+
# Inferência massiva e ultrarrápida via GPU
|
|
147
|
+
preds = model.predict_batch(X_c)
|
|
148
|
+
|
|
149
|
+
print(f"Acurácia: {model.accuracy(X_c, y_c)*100:.1f}%")
|
|
150
|
+
```
|
|
151
|
+
|
|
152
|
+
---
|
|
153
|
+
|
|
154
|
+
## Uso — AdderCluster (ensemble multi-nó)
|
|
155
|
+
|
|
156
|
+
```python
|
|
157
|
+
from addernet import AdderCluster
|
|
158
|
+
import numpy as np
|
|
159
|
+
|
|
160
|
+
cluster = AdderCluster(
|
|
161
|
+
n_nodes=4,
|
|
162
|
+
strategy='feature', # 'random' | 'range' | 'feature' | 'boosting'
|
|
163
|
+
combination='vote', # 'vote' | 'mean' | 'stack'
|
|
164
|
+
input_min=0,
|
|
165
|
+
input_max=150,
|
|
166
|
+
)
|
|
167
|
+
|
|
168
|
+
cluster.fit(X, y)
|
|
169
|
+
preds = cluster.predict_batch(X)
|
|
170
|
+
|
|
171
|
+
cluster.info()
|
|
172
|
+
```
|
|
173
|
+
|
|
174
|
+
---
|
|
175
|
+
|
|
176
|
+
## Otimizações disponíveis
|
|
177
|
+
|
|
178
|
+
```python
|
|
179
|
+
from addernet import hdc_detect_backend
|
|
180
|
+
|
|
181
|
+
print(hdc_detect_backend()) # 'AVX2', 'NEON', ou 'SCALAR'
|
|
182
|
+
|
|
183
|
+
model.set_threads(4) # multithreading CPU (AdderNetHDC)
|
|
184
|
+
model.warm_cache() # pré-computar hipervectors
|
|
185
|
+
model.set_cache(False) # desligar cache (hardware com pouca RAM)
|
|
186
|
+
```
|
|
187
|
+
|
|
188
|
+
---
|
|
189
|
+
|
|
190
|
+
## Limitações
|
|
191
|
+
|
|
192
|
+
- **AdderNetLayer**: apenas uma variável de entrada por camada
|
|
193
|
+
- **AdderNetHDC**: acurácia inferior a MLPs profundas em datasets complexos (troca por zero multiplicação)
|
|
194
|
+
- `hv_dim` muito pequeno (< 1000) pode colapsar a acurácia, use a Dimensionalidade Dinâmica para testar!
|
|
195
|
+
|
|
196
|
+
---
|
|
197
|
+
|
|
198
|
+
## Licença
|
|
199
|
+
|
|
200
|
+
[Apache 2.0](LICENSE) — © Pedro Henrique Batista Silva
|
addernet-1.2.6/README.md
ADDED
|
@@ -0,0 +1,170 @@
|
|
|
1
|
+
# AdderNet
|
|
2
|
+
|
|
3
|
+
[](https://pypi.org/project/addernet/)
|
|
4
|
+
[](https://pypi.org/project/addernet/)
|
|
5
|
+
[](LICENSE)
|
|
6
|
+
|
|
7
|
+
Biblioteca de machine learning que **não usa multiplicação de ponto flutuante** na inferência. Zero.
|
|
8
|
+
|
|
9
|
+
> Benchmarks medidos em CPU x86-64 com backend **AVX2** e GPUs NVIDIA via **CUDA**, Python 3.x, v1.2.5.
|
|
10
|
+
|
|
11
|
+
---
|
|
12
|
+
|
|
13
|
+
## O que é?
|
|
14
|
+
|
|
15
|
+
AdderNet substitui multiplicações por **lookups em tabela** (LUT) e operações de soma inteiras,
|
|
16
|
+
tornando a inferência viável em microcontroladores sem FPU (ESP32, STM32, RPi).
|
|
17
|
+
|
|
18
|
+
A biblioteca expõe quatro componentes principais:
|
|
19
|
+
|
|
20
|
+
| Classe | Descrição |
|
|
21
|
+
|---|---|
|
|
22
|
+
| `AdderNetLayer` | Rede de uma variável — LUT + soma, zero multiplicação |
|
|
23
|
+
| `AdderNetHDC` | Classificador multivariável — Hyperdimensional Computing (HDC) |
|
|
24
|
+
| `AdderCluster` | Ensemble de `AdderNetLayer` com estratégias de combinação |
|
|
25
|
+
| `AdderBoost` | Gradient Boosting com `AdderNetLayer` — inferência sem multiplicação |
|
|
26
|
+
|
|
27
|
+
---
|
|
28
|
+
|
|
29
|
+
## Novidades v1.2.5 🚀
|
|
30
|
+
|
|
31
|
+
- **HV_DIM Dinâmico**: A dimensionalidade hiperdimensional (`hv_dim`) agora é configurável em tempo de execução (`512`, `1024`, `2048`, `4096`, etc), sem precisar recompilar a biblioteca C!
|
|
32
|
+
- **Aceleração CUDA NATIVA no Treinamento**: O loop iterativo de retreino (`AdaptHD`) foi reescrito em CUDA para ser executado massivamente em paralelo usando `atomicAdd` e otimizações de bitwise. Basta usar `use_gpu_training=True`.
|
|
33
|
+
- **Aceleração CUDA na Inferência**: O processo de `predict_batch` agora tem suporte a GPU via kernels CUDA dedicados. Basta instanciar o modelo com `use_gpu=True`.
|
|
34
|
+
- **Compatibilidade e Fallback**: O pacote compila nativamente o C++ e CUDA no momento do `pip install`. Se a máquina alvo (como um Raspberry Pi) não tiver placa de vídeo NVIDIA, a biblioteca roda perfeitamente fazendo fallback silencioso para CPU com `AVX2`, `NEON` ou `SCALAR`.
|
|
35
|
+
- Correção de bugs de Ctypes FFI e memory alignment (agora todos os `aligned_alloc` usam arrays flats dinâmicos, preservando compatibilidade absoluta entre os tensores C contíguos e o numpy).
|
|
36
|
+
|
|
37
|
+
---
|
|
38
|
+
|
|
39
|
+
## Instalação
|
|
40
|
+
|
|
41
|
+
```bash
|
|
42
|
+
pip install addernet
|
|
43
|
+
```
|
|
44
|
+
|
|
45
|
+
Ou do código-fonte (para compilar com otimizações nativas e CUDA opcional):
|
|
46
|
+
|
|
47
|
+
```bash
|
|
48
|
+
git clone https://github.com/PedroHenriqueBatistaSilva/AdderNet.git
|
|
49
|
+
cd AdderNet
|
|
50
|
+
make all # Compila binários da CPU
|
|
51
|
+
make cuda_native # Opcional: Compila o backend de GPU (requer nvcc)
|
|
52
|
+
pip install -e .
|
|
53
|
+
```
|
|
54
|
+
|
|
55
|
+
---
|
|
56
|
+
|
|
57
|
+
## Uso — AdderNetLayer (uma variável)
|
|
58
|
+
|
|
59
|
+
```python
|
|
60
|
+
from addernet import AdderNetLayer
|
|
61
|
+
|
|
62
|
+
rede = AdderNetLayer(size=256, bias=50, input_min=-50, input_max=200, lr=0.1)
|
|
63
|
+
|
|
64
|
+
celsius = [0, 10, 20, 25, 30, 37, 50, 80, 100]
|
|
65
|
+
fahrenheit = [32, 50, 68, 77, 86, 98.6, 122, 176, 212]
|
|
66
|
+
|
|
67
|
+
rede.train(celsius, fahrenheit)
|
|
68
|
+
|
|
69
|
+
print(rede.predict(37)) # 98.60
|
|
70
|
+
print(rede.predict(100)) # 212.00
|
|
71
|
+
```
|
|
72
|
+
|
|
73
|
+
### Previsão em lote (numpy)
|
|
74
|
+
|
|
75
|
+
```python
|
|
76
|
+
import numpy as np
|
|
77
|
+
|
|
78
|
+
entradas = np.linspace(-50, 200, 1_000_000, dtype=np.float64)
|
|
79
|
+
saidas = rede.predict_batch(entradas) # ~178M pred/s com AVX2
|
|
80
|
+
```
|
|
81
|
+
|
|
82
|
+
---
|
|
83
|
+
|
|
84
|
+
## Uso — AdderNetHDC (Aceleração GPU e HDC Dinâmico)
|
|
85
|
+
|
|
86
|
+
```python
|
|
87
|
+
from addernet import AdderNetHDC
|
|
88
|
+
import numpy as np
|
|
89
|
+
from sklearn.datasets import load_iris
|
|
90
|
+
from sklearn.preprocessing import MinMaxScaler
|
|
91
|
+
|
|
92
|
+
iris = load_iris()
|
|
93
|
+
X = MinMaxScaler(feature_range=(0, 150)).fit_transform(iris.data)
|
|
94
|
+
y = iris.target
|
|
95
|
+
|
|
96
|
+
# HV_DIM dinâmico configurável (ex: 2048, 4096)
|
|
97
|
+
model = AdderNetHDC(
|
|
98
|
+
n_vars=4,
|
|
99
|
+
n_classes=3,
|
|
100
|
+
table_size=256,
|
|
101
|
+
hv_dim=4096, # <- Dimensionalidade configurável no runtime!
|
|
102
|
+
use_gpu=True, # <- Ativa inferência batch em CUDA
|
|
103
|
+
use_gpu_training=True # <- Ativa treinamento iterativo em CUDA
|
|
104
|
+
)
|
|
105
|
+
|
|
106
|
+
# Arrays numpy precisam ser "C Contiguous"
|
|
107
|
+
X_c = np.ascontiguousarray(X, dtype=np.float64)
|
|
108
|
+
y_c = np.ascontiguousarray(y, dtype=np.int32)
|
|
109
|
+
|
|
110
|
+
# Treino single-pass (OnlineHD)
|
|
111
|
+
model.train(X_c, y_c)
|
|
112
|
+
|
|
113
|
+
# Retreino iterativo (AdaptHD) — massivamente paralelo na GPU
|
|
114
|
+
model.train(X_c, y_c, n_iter=20, lr=1.0)
|
|
115
|
+
|
|
116
|
+
# Inferência massiva e ultrarrápida via GPU
|
|
117
|
+
preds = model.predict_batch(X_c)
|
|
118
|
+
|
|
119
|
+
print(f"Acurácia: {model.accuracy(X_c, y_c)*100:.1f}%")
|
|
120
|
+
```
|
|
121
|
+
|
|
122
|
+
---
|
|
123
|
+
|
|
124
|
+
## Uso — AdderCluster (ensemble multi-nó)
|
|
125
|
+
|
|
126
|
+
```python
|
|
127
|
+
from addernet import AdderCluster
|
|
128
|
+
import numpy as np
|
|
129
|
+
|
|
130
|
+
cluster = AdderCluster(
|
|
131
|
+
n_nodes=4,
|
|
132
|
+
strategy='feature', # 'random' | 'range' | 'feature' | 'boosting'
|
|
133
|
+
combination='vote', # 'vote' | 'mean' | 'stack'
|
|
134
|
+
input_min=0,
|
|
135
|
+
input_max=150,
|
|
136
|
+
)
|
|
137
|
+
|
|
138
|
+
cluster.fit(X, y)
|
|
139
|
+
preds = cluster.predict_batch(X)
|
|
140
|
+
|
|
141
|
+
cluster.info()
|
|
142
|
+
```
|
|
143
|
+
|
|
144
|
+
---
|
|
145
|
+
|
|
146
|
+
## Otimizações disponíveis
|
|
147
|
+
|
|
148
|
+
```python
|
|
149
|
+
from addernet import hdc_detect_backend
|
|
150
|
+
|
|
151
|
+
print(hdc_detect_backend()) # 'AVX2', 'NEON', ou 'SCALAR'
|
|
152
|
+
|
|
153
|
+
model.set_threads(4) # multithreading CPU (AdderNetHDC)
|
|
154
|
+
model.warm_cache() # pré-computar hipervectors
|
|
155
|
+
model.set_cache(False) # desligar cache (hardware com pouca RAM)
|
|
156
|
+
```
|
|
157
|
+
|
|
158
|
+
---
|
|
159
|
+
|
|
160
|
+
## Limitações
|
|
161
|
+
|
|
162
|
+
- **AdderNetLayer**: apenas uma variável de entrada por camada
|
|
163
|
+
- **AdderNetHDC**: acurácia inferior a MLPs profundas em datasets complexos (troca por zero multiplicação)
|
|
164
|
+
- `hv_dim` muito pequeno (< 1000) pode colapsar a acurácia, use a Dimensionalidade Dinâmica para testar!
|
|
165
|
+
|
|
166
|
+
---
|
|
167
|
+
|
|
168
|
+
## Licença
|
|
169
|
+
|
|
170
|
+
[Apache 2.0](LICENSE) — © Pedro Henrique Batista Silva
|
|
@@ -61,7 +61,7 @@ _AnHdcPtr = ctypes.c_void_p
|
|
|
61
61
|
_lib.an_hdc_create.restype = _AnHdcPtr
|
|
62
62
|
_lib.an_hdc_create.argtypes = [
|
|
63
63
|
ctypes.c_int, ctypes.c_int, ctypes.c_int,
|
|
64
|
-
ctypes.POINTER(ctypes.c_int),
|
|
64
|
+
ctypes.POINTER(ctypes.c_int), ctypes.c_int
|
|
65
65
|
]
|
|
66
66
|
|
|
67
67
|
_lib.an_hdc_free.restype = None
|
|
@@ -111,6 +111,20 @@ _lib.an_hdc_predict_batch_avx.argtypes = [
|
|
|
111
111
|
]
|
|
112
112
|
|
|
113
113
|
if _lib_cuda is not None:
|
|
114
|
+
_lib_cuda.an_hdc_retrain_cuda.restype = ctypes.c_int
|
|
115
|
+
_lib_cuda.an_hdc_retrain_cuda.argtypes = [
|
|
116
|
+
_AnHdcPtr,
|
|
117
|
+
ctypes.POINTER(ctypes.c_double),
|
|
118
|
+
ctypes.POINTER(ctypes.c_int),
|
|
119
|
+
ctypes.c_int,
|
|
120
|
+
ctypes.c_int,
|
|
121
|
+
ctypes.c_float,
|
|
122
|
+
ctypes.c_int,
|
|
123
|
+
ctypes.c_int,
|
|
124
|
+
ctypes.c_int,
|
|
125
|
+
ctypes.POINTER(ctypes.c_int),
|
|
126
|
+
]
|
|
127
|
+
|
|
114
128
|
_lib_cuda.an_hdc_predict_batch_cuda.restype = ctypes.c_int
|
|
115
129
|
_lib_cuda.an_hdc_predict_batch_cuda.argtypes = [
|
|
116
130
|
_AnHdcPtr,
|
|
@@ -225,7 +239,7 @@ class AdderNetHDC:
|
|
|
225
239
|
"""
|
|
226
240
|
|
|
227
241
|
def __init__(self, n_vars=1, n_classes=2, table_size=256, bias=None,
|
|
228
|
-
seed=42, use_gpu=False, _ptr=None):
|
|
242
|
+
seed=42, use_gpu=False, hv_dim=2500, use_gpu_training=False, _ptr=None):
|
|
229
243
|
"""
|
|
230
244
|
Create a new model.
|
|
231
245
|
|
|
@@ -238,6 +252,8 @@ class AdderNetHDC:
|
|
|
238
252
|
use_gpu: toggle between CPU and CUDA backend
|
|
239
253
|
"""
|
|
240
254
|
self.use_gpu = use_gpu
|
|
255
|
+
self.use_gpu_training = use_gpu_training
|
|
256
|
+
self.hv_dim = hv_dim
|
|
241
257
|
|
|
242
258
|
if _ptr is not None:
|
|
243
259
|
self._ptr = _ptr
|
|
@@ -252,7 +268,7 @@ class AdderNetHDC:
|
|
|
252
268
|
if bias is not None:
|
|
253
269
|
bias_arr = (ctypes.c_int * n_vars)(*bias)
|
|
254
270
|
|
|
255
|
-
self._ptr = _lib.an_hdc_create(n_vars, n_classes, table_size, bias_arr)
|
|
271
|
+
self._ptr = _lib.an_hdc_create(n_vars, n_classes, table_size, bias_arr, hv_dim)
|
|
256
272
|
if not self._ptr:
|
|
257
273
|
raise MemoryError("an_hdc_create failed")
|
|
258
274
|
self._n_vars = n_vars
|
|
@@ -0,0 +1,200 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: addernet
|
|
3
|
+
Version: 1.2.6
|
|
4
|
+
Summary: Neural networks with zero multiplications at inference. AdderNet + HDC for embedded systems.
|
|
5
|
+
Author: AdderNet Team
|
|
6
|
+
License: Apache-2.0
|
|
7
|
+
Project-URL: Homepage, https://github.com/addernet/addernet
|
|
8
|
+
Project-URL: Repository, https://github.com/addernet/addernet
|
|
9
|
+
Keywords: machine-learning,neural-network,addernet,hyperdimensional-computing,embedded,no-fpu
|
|
10
|
+
Classifier: Development Status :: 4 - Beta
|
|
11
|
+
Classifier: Intended Audience :: Developers
|
|
12
|
+
Classifier: Intended Audience :: Science/Research
|
|
13
|
+
Classifier: License :: OSI Approved :: Apache Software License
|
|
14
|
+
Classifier: Programming Language :: Python :: 3
|
|
15
|
+
Classifier: Programming Language :: Python :: 3.8
|
|
16
|
+
Classifier: Programming Language :: Python :: 3.9
|
|
17
|
+
Classifier: Programming Language :: Python :: 3.10
|
|
18
|
+
Classifier: Programming Language :: Python :: 3.11
|
|
19
|
+
Classifier: Programming Language :: Python :: 3.12
|
|
20
|
+
Classifier: Topic :: Scientific/Engineering :: Artificial Intelligence
|
|
21
|
+
Requires-Python: >=3.8
|
|
22
|
+
Description-Content-Type: text/markdown
|
|
23
|
+
License-File: LICENSE
|
|
24
|
+
Requires-Dist: numpy
|
|
25
|
+
Requires-Dist: scikit-learn
|
|
26
|
+
Requires-Dist: scipy
|
|
27
|
+
Provides-Extra: dev
|
|
28
|
+
Requires-Dist: pytest; extra == "dev"
|
|
29
|
+
Dynamic: license-file
|
|
30
|
+
|
|
31
|
+
# AdderNet
|
|
32
|
+
|
|
33
|
+
[](https://pypi.org/project/addernet/)
|
|
34
|
+
[](https://pypi.org/project/addernet/)
|
|
35
|
+
[](LICENSE)
|
|
36
|
+
|
|
37
|
+
Biblioteca de machine learning que **não usa multiplicação de ponto flutuante** na inferência. Zero.
|
|
38
|
+
|
|
39
|
+
> Benchmarks medidos em CPU x86-64 com backend **AVX2** e GPUs NVIDIA via **CUDA**, Python 3.x, v1.2.5.
|
|
40
|
+
|
|
41
|
+
---
|
|
42
|
+
|
|
43
|
+
## O que é?
|
|
44
|
+
|
|
45
|
+
AdderNet substitui multiplicações por **lookups em tabela** (LUT) e operações de soma inteiras,
|
|
46
|
+
tornando a inferência viável em microcontroladores sem FPU (ESP32, STM32, RPi).
|
|
47
|
+
|
|
48
|
+
A biblioteca expõe quatro componentes principais:
|
|
49
|
+
|
|
50
|
+
| Classe | Descrição |
|
|
51
|
+
|---|---|
|
|
52
|
+
| `AdderNetLayer` | Rede de uma variável — LUT + soma, zero multiplicação |
|
|
53
|
+
| `AdderNetHDC` | Classificador multivariável — Hyperdimensional Computing (HDC) |
|
|
54
|
+
| `AdderCluster` | Ensemble de `AdderNetLayer` com estratégias de combinação |
|
|
55
|
+
| `AdderBoost` | Gradient Boosting com `AdderNetLayer` — inferência sem multiplicação |
|
|
56
|
+
|
|
57
|
+
---
|
|
58
|
+
|
|
59
|
+
## Novidades v1.2.5 🚀
|
|
60
|
+
|
|
61
|
+
- **HV_DIM Dinâmico**: A dimensionalidade hiperdimensional (`hv_dim`) agora é configurável em tempo de execução (`512`, `1024`, `2048`, `4096`, etc), sem precisar recompilar a biblioteca C!
|
|
62
|
+
- **Aceleração CUDA NATIVA no Treinamento**: O loop iterativo de retreino (`AdaptHD`) foi reescrito em CUDA para ser executado massivamente em paralelo usando `atomicAdd` e otimizações de bitwise. Basta usar `use_gpu_training=True`.
|
|
63
|
+
- **Aceleração CUDA na Inferência**: O processo de `predict_batch` agora tem suporte a GPU via kernels CUDA dedicados. Basta instanciar o modelo com `use_gpu=True`.
|
|
64
|
+
- **Compatibilidade e Fallback**: O pacote compila nativamente o C++ e CUDA no momento do `pip install`. Se a máquina alvo (como um Raspberry Pi) não tiver placa de vídeo NVIDIA, a biblioteca roda perfeitamente fazendo fallback silencioso para CPU com `AVX2`, `NEON` ou `SCALAR`.
|
|
65
|
+
- Correção de bugs de Ctypes FFI e memory alignment (agora todos os `aligned_alloc` usam arrays flats dinâmicos, preservando compatibilidade absoluta entre os tensores C contíguos e o numpy).
|
|
66
|
+
|
|
67
|
+
---
|
|
68
|
+
|
|
69
|
+
## Instalação
|
|
70
|
+
|
|
71
|
+
```bash
|
|
72
|
+
pip install addernet
|
|
73
|
+
```
|
|
74
|
+
|
|
75
|
+
Ou do código-fonte (para compilar com otimizações nativas e CUDA opcional):
|
|
76
|
+
|
|
77
|
+
```bash
|
|
78
|
+
git clone https://github.com/PedroHenriqueBatistaSilva/AdderNet.git
|
|
79
|
+
cd AdderNet
|
|
80
|
+
make all # Compila binários da CPU
|
|
81
|
+
make cuda_native # Opcional: Compila o backend de GPU (requer nvcc)
|
|
82
|
+
pip install -e .
|
|
83
|
+
```
|
|
84
|
+
|
|
85
|
+
---
|
|
86
|
+
|
|
87
|
+
## Uso — AdderNetLayer (uma variável)
|
|
88
|
+
|
|
89
|
+
```python
|
|
90
|
+
from addernet import AdderNetLayer
|
|
91
|
+
|
|
92
|
+
rede = AdderNetLayer(size=256, bias=50, input_min=-50, input_max=200, lr=0.1)
|
|
93
|
+
|
|
94
|
+
celsius = [0, 10, 20, 25, 30, 37, 50, 80, 100]
|
|
95
|
+
fahrenheit = [32, 50, 68, 77, 86, 98.6, 122, 176, 212]
|
|
96
|
+
|
|
97
|
+
rede.train(celsius, fahrenheit)
|
|
98
|
+
|
|
99
|
+
print(rede.predict(37)) # 98.60
|
|
100
|
+
print(rede.predict(100)) # 212.00
|
|
101
|
+
```
|
|
102
|
+
|
|
103
|
+
### Previsão em lote (numpy)
|
|
104
|
+
|
|
105
|
+
```python
|
|
106
|
+
import numpy as np
|
|
107
|
+
|
|
108
|
+
entradas = np.linspace(-50, 200, 1_000_000, dtype=np.float64)
|
|
109
|
+
saidas = rede.predict_batch(entradas) # ~178M pred/s com AVX2
|
|
110
|
+
```
|
|
111
|
+
|
|
112
|
+
---
|
|
113
|
+
|
|
114
|
+
## Uso — AdderNetHDC (Aceleração GPU e HDC Dinâmico)
|
|
115
|
+
|
|
116
|
+
```python
|
|
117
|
+
from addernet import AdderNetHDC
|
|
118
|
+
import numpy as np
|
|
119
|
+
from sklearn.datasets import load_iris
|
|
120
|
+
from sklearn.preprocessing import MinMaxScaler
|
|
121
|
+
|
|
122
|
+
iris = load_iris()
|
|
123
|
+
X = MinMaxScaler(feature_range=(0, 150)).fit_transform(iris.data)
|
|
124
|
+
y = iris.target
|
|
125
|
+
|
|
126
|
+
# HV_DIM dinâmico configurável (ex: 2048, 4096)
|
|
127
|
+
model = AdderNetHDC(
|
|
128
|
+
n_vars=4,
|
|
129
|
+
n_classes=3,
|
|
130
|
+
table_size=256,
|
|
131
|
+
hv_dim=4096, # <- Dimensionalidade configurável no runtime!
|
|
132
|
+
use_gpu=True, # <- Ativa inferência batch em CUDA
|
|
133
|
+
use_gpu_training=True # <- Ativa treinamento iterativo em CUDA
|
|
134
|
+
)
|
|
135
|
+
|
|
136
|
+
# Arrays numpy precisam ser "C Contiguous"
|
|
137
|
+
X_c = np.ascontiguousarray(X, dtype=np.float64)
|
|
138
|
+
y_c = np.ascontiguousarray(y, dtype=np.int32)
|
|
139
|
+
|
|
140
|
+
# Treino single-pass (OnlineHD)
|
|
141
|
+
model.train(X_c, y_c)
|
|
142
|
+
|
|
143
|
+
# Retreino iterativo (AdaptHD) — massivamente paralelo na GPU
|
|
144
|
+
model.train(X_c, y_c, n_iter=20, lr=1.0)
|
|
145
|
+
|
|
146
|
+
# Inferência massiva e ultrarrápida via GPU
|
|
147
|
+
preds = model.predict_batch(X_c)
|
|
148
|
+
|
|
149
|
+
print(f"Acurácia: {model.accuracy(X_c, y_c)*100:.1f}%")
|
|
150
|
+
```
|
|
151
|
+
|
|
152
|
+
---
|
|
153
|
+
|
|
154
|
+
## Uso — AdderCluster (ensemble multi-nó)
|
|
155
|
+
|
|
156
|
+
```python
|
|
157
|
+
from addernet import AdderCluster
|
|
158
|
+
import numpy as np
|
|
159
|
+
|
|
160
|
+
cluster = AdderCluster(
|
|
161
|
+
n_nodes=4,
|
|
162
|
+
strategy='feature', # 'random' | 'range' | 'feature' | 'boosting'
|
|
163
|
+
combination='vote', # 'vote' | 'mean' | 'stack'
|
|
164
|
+
input_min=0,
|
|
165
|
+
input_max=150,
|
|
166
|
+
)
|
|
167
|
+
|
|
168
|
+
cluster.fit(X, y)
|
|
169
|
+
preds = cluster.predict_batch(X)
|
|
170
|
+
|
|
171
|
+
cluster.info()
|
|
172
|
+
```
|
|
173
|
+
|
|
174
|
+
---
|
|
175
|
+
|
|
176
|
+
## Otimizações disponíveis
|
|
177
|
+
|
|
178
|
+
```python
|
|
179
|
+
from addernet import hdc_detect_backend
|
|
180
|
+
|
|
181
|
+
print(hdc_detect_backend()) # 'AVX2', 'NEON', ou 'SCALAR'
|
|
182
|
+
|
|
183
|
+
model.set_threads(4) # multithreading CPU (AdderNetHDC)
|
|
184
|
+
model.warm_cache() # pré-computar hipervectors
|
|
185
|
+
model.set_cache(False) # desligar cache (hardware com pouca RAM)
|
|
186
|
+
```
|
|
187
|
+
|
|
188
|
+
---
|
|
189
|
+
|
|
190
|
+
## Limitações
|
|
191
|
+
|
|
192
|
+
- **AdderNetLayer**: apenas uma variável de entrada por camada
|
|
193
|
+
- **AdderNetHDC**: acurácia inferior a MLPs profundas em datasets complexos (troca por zero multiplicação)
|
|
194
|
+
- `hv_dim` muito pequeno (< 1000) pode colapsar a acurácia, use a Dimensionalidade Dinâmica para testar!
|
|
195
|
+
|
|
196
|
+
---
|
|
197
|
+
|
|
198
|
+
## Licença
|
|
199
|
+
|
|
200
|
+
[Apache 2.0](LICENSE) — © Pedro Henrique Batista Silva
|
|
@@ -4,7 +4,7 @@ build-backend = "setuptools.build_meta"
|
|
|
4
4
|
|
|
5
5
|
[project]
|
|
6
6
|
name = "addernet"
|
|
7
|
-
version = "1.2.
|
|
7
|
+
version = "1.2.6"
|
|
8
8
|
description = "Neural networks with zero multiplications at inference. AdderNet + HDC for embedded systems."
|
|
9
9
|
readme = "README.md"
|
|
10
10
|
license = { text = "Apache-2.0" }
|