netcl 0.1.0__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.
Files changed (86) hide show
  1. netcl-0.1.0/LICENSE +21 -0
  2. netcl-0.1.0/MANIFEST.in +6 -0
  3. netcl-0.1.0/PKG-INFO +84 -0
  4. netcl-0.1.0/README.md +178 -0
  5. netcl-0.1.0/README_PACKAGE.md +66 -0
  6. netcl-0.1.0/netcl/__init__.py +37 -0
  7. netcl-0.1.0/netcl/amp.py +147 -0
  8. netcl-0.1.0/netcl/autograd/__init__.py +86 -0
  9. netcl-0.1.0/netcl/autograd/debug.py +12 -0
  10. netcl-0.1.0/netcl/autograd/engine.py +121 -0
  11. netcl-0.1.0/netcl/autograd/ops.py +558 -0
  12. netcl-0.1.0/netcl/core/__init__.py +17 -0
  13. netcl-0.1.0/netcl/core/capabilities.py +102 -0
  14. netcl-0.1.0/netcl/core/device.py +66 -0
  15. netcl-0.1.0/netcl/core/kernels/__init__.py +12 -0
  16. netcl-0.1.0/netcl/core/kernels/primitives.py +159 -0
  17. netcl-0.1.0/netcl/core/memory.py +59 -0
  18. netcl-0.1.0/netcl/core/parameter.py +60 -0
  19. netcl-0.1.0/netcl/core/tensor.py +130 -0
  20. netcl-0.1.0/netcl/data/augment.py +43 -0
  21. netcl-0.1.0/netcl/data/augment_gpu.py +135 -0
  22. netcl-0.1.0/netcl/data/dataloader.py +87 -0
  23. netcl-0.1.0/netcl/data/filters.py +65 -0
  24. netcl-0.1.0/netcl/distributed/__init__.py +22 -0
  25. netcl-0.1.0/netcl/distributed/collectives.py +125 -0
  26. netcl-0.1.0/netcl/distributed/data_parallel.py +55 -0
  27. netcl-0.1.0/netcl/distributed/device_manager.py +33 -0
  28. netcl-0.1.0/netcl/distributed/trainer.py +63 -0
  29. netcl-0.1.0/netcl/io/__init__.py +3 -0
  30. netcl-0.1.0/netcl/io/checkpoint.py +58 -0
  31. netcl-0.1.0/netcl/io/serialization.py +117 -0
  32. netcl-0.1.0/netcl/nn/__init__.py +48 -0
  33. netcl-0.1.0/netcl/nn/batchnorm.py +258 -0
  34. netcl-0.1.0/netcl/nn/decorators.py +48 -0
  35. netcl-0.1.0/netcl/nn/factory.py +123 -0
  36. netcl-0.1.0/netcl/nn/functional.py +45 -0
  37. netcl-0.1.0/netcl/nn/groupnorm.py +45 -0
  38. netcl-0.1.0/netcl/nn/init.py +34 -0
  39. netcl-0.1.0/netcl/nn/layernorm.py +41 -0
  40. netcl-0.1.0/netcl/nn/layers.py +369 -0
  41. netcl-0.1.0/netcl/nn/loss.py +27 -0
  42. netcl-0.1.0/netcl/nn/modules.py +100 -0
  43. netcl-0.1.0/netcl/nn/padding.py +57 -0
  44. netcl-0.1.0/netcl/nn/pooling.py +267 -0
  45. netcl-0.1.0/netcl/nn/residual.py +22 -0
  46. netcl-0.1.0/netcl/nn/resnet.py +155 -0
  47. netcl-0.1.0/netcl/nn/simple.py +41 -0
  48. netcl-0.1.0/netcl/ops/__init__.py +45 -0
  49. netcl-0.1.0/netcl/ops/broadcast.py +103 -0
  50. netcl-0.1.0/netcl/ops/conv2d.py +745 -0
  51. netcl-0.1.0/netcl/ops/conv_transpose2d.py +200 -0
  52. netcl-0.1.0/netcl/ops/depthwise_conv2d.py +235 -0
  53. netcl-0.1.0/netcl/ops/elementwise.py +477 -0
  54. netcl-0.1.0/netcl/ops/im2col.py +122 -0
  55. netcl-0.1.0/netcl/ops/matmul.py +182 -0
  56. netcl-0.1.0/netcl/ops/reduction.py +102 -0
  57. netcl-0.1.0/netcl/ops/softmax.py +96 -0
  58. netcl-0.1.0/netcl/ops/softmax_fp16.py +33 -0
  59. netcl-0.1.0/netcl/ops/transpose.py +60 -0
  60. netcl-0.1.0/netcl/optim/__init__.py +11 -0
  61. netcl-0.1.0/netcl/optim/adam.py +55 -0
  62. netcl-0.1.0/netcl/optim/adamw.py +58 -0
  63. netcl-0.1.0/netcl/optim/amp.py +42 -0
  64. netcl-0.1.0/netcl/optim/clip.py +28 -0
  65. netcl-0.1.0/netcl/optim/lr_plateau.py +26 -0
  66. netcl-0.1.0/netcl/optim/lr_scheduler.py +14 -0
  67. netcl-0.1.0/netcl/optim/momentum.py +38 -0
  68. netcl-0.1.0/netcl/optim/rmsprop.py +51 -0
  69. netcl-0.1.0/netcl/optim/sgd.py +43 -0
  70. netcl-0.1.0/netcl/profiling/__init__.py +7 -0
  71. netcl-0.1.0/netcl/profiling/timing.py +33 -0
  72. netcl-0.1.0/netcl/runtime/__init__.py +8 -0
  73. netcl-0.1.0/netcl/runtime/graph.py +131 -0
  74. netcl-0.1.0/netcl/runtime/scheduler.py +36 -0
  75. netcl-0.1.0/netcl/trainer/__init__.py +3 -0
  76. netcl-0.1.0/netcl/trainer/trainer.py +148 -0
  77. netcl-0.1.0/netcl/utils/__init__.py +4 -0
  78. netcl-0.1.0/netcl/utils/data.py +33 -0
  79. netcl-0.1.0/netcl/utils/progress.py +58 -0
  80. netcl-0.1.0/netcl.egg-info/PKG-INFO +84 -0
  81. netcl-0.1.0/netcl.egg-info/SOURCES.txt +84 -0
  82. netcl-0.1.0/netcl.egg-info/dependency_links.txt +1 -0
  83. netcl-0.1.0/netcl.egg-info/requires.txt +2 -0
  84. netcl-0.1.0/netcl.egg-info/top_level.txt +1 -0
  85. netcl-0.1.0/pyproject.toml +36 -0
  86. netcl-0.1.0/setup.cfg +4 -0
netcl-0.1.0/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2024 netcl contributors
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
@@ -0,0 +1,6 @@
1
+ include LICENSE
2
+ include README_PACKAGE.md
3
+ recursive-exclude tests *
4
+ recursive-exclude docs *
5
+ recursive-exclude wiki *
6
+ recursive-exclude scripts *
netcl-0.1.0/PKG-INFO ADDED
@@ -0,0 +1,84 @@
1
+ Metadata-Version: 2.4
2
+ Name: netcl
3
+ Version: 0.1.0
4
+ Summary: PyOpenCL-based deep learning playground with autograd, kernels, and high-level APIs.
5
+ Author: netcl contributors
6
+ License: MIT
7
+ Project-URL: Repository, https://bbwebservice.online/lukas/netcl
8
+ Keywords: opencl,deep-learning,autograd,gpu
9
+ Classifier: Programming Language :: Python :: 3
10
+ Classifier: License :: OSI Approved :: MIT License
11
+ Classifier: Operating System :: OS Independent
12
+ Requires-Python: >=3.10
13
+ Description-Content-Type: text/markdown
14
+ License-File: LICENSE
15
+ Requires-Dist: numpy>=1.22
16
+ Requires-Dist: pyopencl>=2022.3
17
+ Dynamic: license-file
18
+
19
+ # netcl – PyOpenCL Deep Learning Playground
20
+
21
+ `netcl` ist ein experimentelles Deep-Learning-Framework auf Basis von PyOpenCL. Es kombiniert low-level Kernel (Conv/Matmul/Elementwise) mit einer einfachen Autograd-Engine und einer High-Level API (Module, Trainer, Serializer), ohne Abhängigkeiten zu anderen DL-Frameworks.
22
+
23
+ ## Installation
24
+ ```bash
25
+ pip install .
26
+ ```
27
+ Voraussetzungen: Python ≥ 3.10, NumPy, PyOpenCL und ein verfügbares OpenCL-Gerät.
28
+
29
+ ## Schnelles Beispiel (MNIST-Mini-MLP)
30
+ ```python
31
+ import numpy as np
32
+ from netcl.core.device import manager
33
+ from netcl.nn.layers import Sequential, Flatten, Linear, ReLU
34
+ from netcl import autograd as ag
35
+ from netcl.optim import Adam
36
+ from netcl.core.tensor import Tensor
37
+
38
+ dev = manager.default()
39
+ q = dev.queue
40
+
41
+ model = Sequential(
42
+ Flatten(),
43
+ Linear(q, in_features=28*28, out_features=128),
44
+ ReLU(),
45
+ Linear(q, in_features=128, out_features=10),
46
+ )
47
+ opt = Adam(model.parameters(), lr=5e-3)
48
+
49
+ def one_hot(y, n=10):
50
+ oh = np.zeros((y.shape[0], n), dtype=np.float32)
51
+ oh[np.arange(y.shape[0]), y] = 1
52
+ return oh
53
+
54
+ xb = np.random.randn(32, 1, 28, 28).astype(np.float32)
55
+ yb = one_hot(np.random.randint(0, 10, size=(32,)))
56
+
57
+ tape = ag.Tape()
58
+ ag.set_current_tape(tape)
59
+ x = ag.tensor(Tensor.from_host(q, xb))
60
+ y = ag.tensor(Tensor.from_host(q, yb))
61
+ logits = model(x)
62
+ loss = ag.cross_entropy(logits, y)
63
+ tape.backward(loss)
64
+ opt.step(); opt.zero_grad()
65
+ ag.set_current_tape(None)
66
+ ```
67
+
68
+ ## Kernfeatures
69
+ - **Autograd**: Tape-basiert, elementare Ops (Matmul, Conv2d, Pooling, Elementwise) mit Backward.
70
+ - **Module/High-Level API**: `Linear`, `Conv2d`, `BatchNorm2d`, `Sequential`, `@model`-Dekorator, Trainer.
71
+ - **Optimierungen**: Conv-Algo-Heuristik/Autotuning, optional Mixed Precision, Buffer-Pool.
72
+ - **Serialization**: Speichert `Sequential`-Modelle als JSON (Architektur) + NPZ (Gewichte) via `netcl.io.serialization`.
73
+
74
+ ## Speichern & Laden eines Modells
75
+ ```python
76
+ from netcl.io.serialization import save_model, load_model
77
+ save_model(model, "checkpoints/mnist_mlp")
78
+ model2 = load_model("checkpoints/mnist_mlp") # queue auto="default"
79
+ ```
80
+
81
+ ## Hinweise
82
+ - Tests werden nicht mitinstalliert. Für lokale Entwicklung: `python -m pytest`.
83
+ - Für Performance: Batch-Größe erhöhen, Augment minimieren, optional Mixed Precision (`Trainer(..., mixed_precision=True)`).
84
+ - Conv-Algorithmen wählen automatisch optimierte Pfade; env-Flags wie `NETCL_CONV_AUTOTUNE=1` aktivieren Tuning.
netcl-0.1.0/README.md ADDED
@@ -0,0 +1,178 @@
1
+ # PyOpenCL KI-Framework Plan
2
+
3
+ ## Ueberblick & Ziele
4
+ - Hochperformantes KI-Framework auf Basis von PyOpenCL mit klarer Trennung zwischen Low-Level-Kernel-Implementierungen und High-Level-Ausfuehrungsmodellen.
5
+ - Minimierung des Host-Device-Overheads durch effiziente Speicherverwaltung, asynchrone Transfers und Kernel-Fusion.
6
+ - Multi-GPU-Skalierung (Daten- und perspektivisch Modellparallelismus) mit reproduzierbarem Verhalten und robustem Autograd.
7
+
8
+ ## Leitprinzipien
9
+ - Trennung der Schichten: Devices/Memory/Kernels (Low-Level) vs. Ops/Autograd/Runtime/Distributed (High-Level).
10
+ - Alle Ops setzen auf rudimentaere OpenCL-Bausteine (Loads/Stores, simple Arithmetik, lokale Reduktionen); komplexe Ops werden als Komposition/Fusion daraus erzeugt.
11
+ - Datenbewegungen minimieren: Reuse von Buffern, Pinned Host Memory, Overlap von Compute & Copy, Zero-Copy wo moeglich.
12
+ - Determinismus optional: reproduzierbare Seeds, konsistente Reduktionen.
13
+ - Erweiterbarkeit: neue Ops, neue Devices, austauschbare Kernel-Build-Parameter via Cache, Autotuning und dynamische Kernel-Generierung.
14
+ - Graph/Pipeline-fokussiert: Aehnlich TF: User baut ANN/Graph; Runtime generiert eine Pipeline aus elementaren Ops, alloziert/reused Buffer, minimiert Python-Interaktion zur Laufzeit.
15
+
16
+ ## Anforderungen
17
+ - Funktional:
18
+ - Geraete-Discovery, Kontext- und Queue-Management mit Fallback-Strategie.
19
+ - Speicher-Allocator/Pool (Buckets, Reuse, Sub-Buffers), Pinned Host Buffers, asynchrone Copies.
20
+ - Kernel-Bibliothek: Matmul/GEMM, Convolution (im2col + Spezialfaelle), Elementwise (unary/binary), Reduktionen, Softmax, LayerNorm/BatchNorm, Scatter/Gather, RNG.
21
+ - Autograd-Engine mit Grad-Registrierung pro Op; Unterstuetzung fuer Gradient-Accumulation.
22
+ - Multi-GPU-Kollektive: AllReduce, Broadcast, Scatter/Gather; Datenparallelismus als erster Modus.
23
+ - API: Tensor mit Dtype/Device/Strides, Eager-Ausfuehrung; optional Graph/Lazy spaeter.
24
+ - Profiling/Tracing: Event-Timing, Bandbreitenmessung, Kernel-Stats.
25
+ - Nicht-funktional:
26
+ - Performance-Portabilitaet ueber OpenCL; Feature-Detection (Subgroups, FP16/BF16, Images).
27
+ - Stabilitaet unter Stress (viele kleine Kernels, grosse Tensors); sauberes Fehler-Handling (Build-Fail, OOM).
28
+ - Klare Fehlermeldungen und Debug-Optionen (Assertions fuer Shapes/Strides).
29
+
30
+ ## Architektur (Schichten)
31
+ - `core.devices`: Device/Kontext/Queue-Discovery, Capability-Cache, Seed-Management.
32
+ - `core.memory`: Buffer-Objekte, Pool/Allocator, Pinned Host Buffers, Sub-Buffers, Async Copy.
33
+ - `core.kernels`: Kernel-Quellen, Build/Cache, Feature-Gates, Tuning-Parameter (Workgroup, Vectorization).
34
+ - `ops` (Low-Level): Matmul, Conv2D/Depthwise, Elementwise, Reduce, Softmax, LayerNorm/BatchNorm, RNG.
35
+ - `autograd`: Tape oder Graph, Grad-Registrierung pro Op, Backward-Kernels, Grad-Accumulation.
36
+ - `distributed`: AllReduce/Broadcast/Scatter-Gather, Parameter-Sharding, Host-Relay als Fallback.
37
+ - `runtime`: Scheduler fuer Queues/Events, Stream-Ordering, Overlap von Compute/Copy (Double-Buffering); Graph Executor der ANN/Op-Graph in Pipelines uebersetzt und Buffer-Lebenszeiten verwaltet.
38
+ - `api`: Tensor-Klasse, Module/Layer-Primitives, Optimizer (SGD/Adam), Checkpointing.
39
+ - `profiling`: Event-Timing, Bandwidth/Flops-Schaetzung, Kernel-Stats Dump.
40
+
41
+ ## Speicher- & Transfer-Strategie
42
+ - Memory Pool mit Buckets; Reuse ueber Lebenszeit-Tracking; Minimierung von Fragmentation.
43
+ - Pinned Host Memory fuer H2D/D2H; `enqueue_copy` asynchron mit Events; Batch-Transfers.
44
+ - Zero-Copy nutzen, wenn Plattform Host-Device-Sharing erlaubt; sonst Staging-Puffer.
45
+ - Layout-Planer (z. B. NHWC vs. NCHW) abhaengig vom Kernel; Stride-Awareness in Ops.
46
+ - Double-/Triple-Buffering fuer Datenpipelines, um IO und Compute zu ueberlappen.
47
+ - Graph-basierte Buffer-Reuse: Lebenszeit-Analyse des ANN/Op-Graphs fuer Platzierung/Reuse; Inplace- und Alias-Strategien wo sicher.
48
+
49
+ ## Kernel-Bibliothek & Optimierung
50
+ - Primitives: Load/Store, einfache Arithmetik, Shuffle/Subgroup-Reduce (falls verfuegbar), lokale Speicher-Kacheln, atomare Operationen. Alle komplexen Ops bauen darauf auf.
51
+ - Dynamischer Kernel-Generator: erzeugt Quellcode basierend auf Hyperstrategie (Layout, Fusion, Tiling) und Device-Capabilities; wendet Template-Parameter und Konstantenfaltung an.
52
+ - Matmul/GEMM: Tiling + lokale Speicher-Kacheln; Vectorization; Autotuning von M/N/K-Tiles und Workgroup-Groessen.
53
+ - Convolution: Im2col + GEMM als Baseline; Spezialkernel fuer 1x1 und 3x3; Depthwise-Kernels.
54
+ - Elementwise: Fused Kernel Generator (AST -> OpenCL C) fuer Ketten (bias + activation).
55
+ - Reduktionen: Hierarchisch (Workgroup-Reduktion -> global), optionale Subgroup-Optimierung; deterministische Pfade.
56
+ - RNG: Counter-based (z. B. Philox/Threefry); pro Work-Item Streams; reproduzierbare Seeds.
57
+ - Mixed Precision: FP16/BF16 wenn verfuegbar; Akkumulation in FP32; Fallback auf FP32.
58
+
59
+ ## Multi-GPU & Distributed
60
+ - Datenparallel: Parameter repliziert; Batch-Sharding; Gradient AllReduce (Ring/Tree). Start mit Host-Relay (Copy -> Reduce -> Scatter), spaetere Device-zu-Device-Pfade pruefen.
61
+ - Modellparallel (spaeter): Parameter-Shards, Pipeline-Parallelismus, Punkt-zu-Punkt Copies.
62
+ - Konsistenz: Events/Barrieren fuer Ordering; deterministische Reduktionen optional; FP32 Master Weights moeglich.
63
+ - Hyperstrategie fuer Ressourcenaufteilung: Tiling/Partitionierung pro Device (Batch-Splits, Tensor-Shards) wird dynamisch nach Device-Memory/Compute/Link-Bandbreite bestimmt; Scheduler verteilt Work-Items und Buffers entsprechend.
64
+
65
+ ## Build/Cache & Autotuning
66
+ - Kernel-Build-Cache pro Device (Hash aus Source, Build-Options, Treiber-Version).
67
+ - Autotuning-DB pro Device (Tile- und Workgroup-Sizes); Persistenz auf Disk; konservative Defaults ohne Tuning.
68
+ - Capability-Checks (Subgroups, FP16/BF16, Images vs. Buffers) steuern Kernel-Pfade.
69
+
70
+ ## API-Skizze (Python)
71
+ - `Tensor(device, shape, dtype, data=None, requires_grad=False)`
72
+ - `ops.matmul(a, b)`, `ops.conv2d(x, w, stride, pad)`, `ops.relu(x)`, `ops.softmax(x, axis)`, `ops.layer_norm(x, gamma, beta)`
73
+ - `tensor.backward(grad=None)`; `optimizer.step()`, `optimizer.zero_grad()`
74
+ - `with device.stream(): ...` fuer explizite Queue/Stream-Wahl.
75
+ - `distributed.init(devices=[...])`, `distributed.all_reduce(tensor)`
76
+ - Graph/Pipeline: `with graph(): y = model(x)` erzeugt statischen Graph; `executor.run(graph, inputs)` uebersetzt in Pipeline mit minimaler Python-Beteiligung.
77
+
78
+ ## High-Level Interface (Plan)
79
+ - `netcl.Tensor`: Zentrale Datenstruktur; Flags fuer `requires_grad`; Methoden `to_host()`, `from_host()`, `from_shape(pool=...)`.
80
+ - `netcl.autograd`:
81
+ - `tensor(x, requires_grad=False)` -> Node
82
+ - Ops: `add`, `relu`, `bias_add`, `matmul_op` (weitere Ops folgen: conv2d, softmax, reduce_sum)
83
+ - `Tape.backward(loss, grad=None)` mit Grad-Akkumulation und ones_like-Seed.
84
+ - Optimizer (geplant):
85
+ - Basis: `Optimizer(params, lr)`, API: `step()`, `zero_grad()`, `clip_grad(norm)` optional.
86
+ - Implementierungen: `SGD(lr, momentum=0, weight_decay=0)`, `Adam(lr, betas=(0.9,0.999), eps=1e-8, weight_decay=0)`.
87
+ - Params sind `Tensor` mit `requires_grad=True`; Grad-Lesen via `tensor.grad`.
88
+ - `netcl.ops` (High-Level Wrappers auf Kernels):
89
+ - Elementwise: `elementwise_binary(expr)`, `relu`, `bias_add`
90
+ - Reduktionen: `reduce_sum(x, axis=None/0/1)`
91
+ - Softmax: `softmax(x, axis=1)`
92
+ - Matmul: `matmul(a, b, pool=None)`
93
+ - Conv: `conv2d(x, w, pool=None)` (NCHW, stride=1, pad=0 als Start)
94
+ - Layers (geplant):
95
+ - `Linear(in_features, out_features, bias=True)` -> nutzt `matmul + bias_add`; init Xavier/kaiming; Parameter sind Tensoren.
96
+ - `Conv2d(in_channels, out_channels, kernel_size, stride=1, padding=0)` -> nutzt `conv2d`; Parameter: weights (+ optional bias).
97
+ - Aktivierungen: `ReLU`, `Sigmoid`, `Tanh`, `LeakyReLU`, `Dropout(p)`.
98
+ - Pooling: `max_pool2d`.
99
+ - `Sequential(*layers)` -> Vorwaertsverkettung, sammelt Parameter fuer Optimizer.
100
+ - Convenience-Funktionen:
101
+ - Initializer: `xavier_uniform(tensor)`, `kaiming_uniform(tensor)`.
102
+ - Losses: `mse_loss(pred, target)`, `cross_entropy(logits, targets)` (Softmax + NLL).
103
+ - Data movement: `to_host()`, `from_host()`, `to(device)` (spaeter).
104
+ - Graph shortcuts: `Graph.from_layers(layers, input_tensors)` baut Ops-Graph aus Layer-Liste.
105
+ - Serialisierung/Checkpointing (ohne andere AI-Framework-Imports):
106
+ - Format-Vorschlag: Metadaten als JSON (Layer-Typ, Shapes, Hyperparams), Gewichte als `.npz` (NumPy-kompatibel) oder Binär-Blob pro Tensor.
107
+ - API: `save(model, path)` schreibt JSON+Gewichte; `load(path, device=None)` rekonstruiert Layer/Tensoren; kompatibel mit Lazy-Loading fuer grosse Gewichte.
108
+ - Graph-Snapshots: `save_graph(graph, path)` speichert Op-Listen und Topologie; `load_graph(path)` rekonstruiert fuer Executor.
109
+ - Versionierung: Schema-Version im JSON, Hash pro Gewicht fuer Integritaet.
110
+ - Training Loop (geplant Muster):
111
+ ```
112
+ tape = Tape()
113
+ model = Sequential(Linear(784, 256), ReLU(), Linear(256, 10))
114
+ opt = Adam(model.parameters(), lr=1e-3)
115
+ out = model(tensor(x, True), tape=tape)
116
+ loss = cross_entropy(out, tensor(targets))
117
+ tape.backward(loss)
118
+ opt.step(); opt.zero_grad()
119
+ ```
120
+ - Progress/Monitoring:
121
+ - `ProgressBar(total, epoch=None)` aus `netcl.utils.progress`; `update(step, info={"loss":..., "acc":..., "it/s":...})` zeigt animierten Balken (it/s, ETA, Epochen).
122
+ - Graph/Pipeline:
123
+ - `Graph.add_op(name, fn, inputs, shape, dtype)` -> TensorRef
124
+ - `GraphExecutor.run(graph)` mit Toposort, optionaler `fusion_hook`, BufferPool-Reuse, (spaeter) async overlap.
125
+ - Memory/Pooling:
126
+ - `BufferPool` bucket-basiert; Tensor speichert `pool_handle`; Executor gibt Buffers nach Refcount frei.
127
+ - Distributed (Platzhalter):
128
+ - API-Signaturen: `all_reduce`, `broadcast`, `scatter`, `gather` (Implementierung folgt).
129
+ - Profiling:
130
+ - `EventTimer.time_event(event)` -> Dauer in ms; spaeter: Hook in Executor.
131
+
132
+ ## High-Level Usage-Fluss (geplant)
133
+ 1) Daten auf Device laden: `tx = Tensor.from_host(queue, x, dtype="float32")`.
134
+ 2) Modelldefinition mit Autograd-Nodes: `tape = Tape(); y = relu(matmul_op(tensor(tx, True), tensor(w, True), tape=tape))`.
135
+ 3) Loss berechnen (zu ergaenzen: MSE/CrossEntropy Ops) und `tape.backward(loss)`.
136
+ 4) Parameter-Update (zu ergaenzen: Optimizer-API).
137
+ 5) Fuer statische Ausfuehrung: Graph aufbauen (`Graph`), Pipeline aus Ops, Executor run -> minimale Python-Interaktion.
138
+
139
+ ## Profiling/Tracing & Debug
140
+ - Event-basierte Timings pro Kernel/Copy; Bandbreitenmessung; Roofline-Hinweise.
141
+ - Kernel-Stats (Auslastung, Workgroup-Groesse, Registerdruck falls verfuegbar).
142
+ - Debug-Modus: zusaetzliche Checks (NaN/Inf, Bounds, Shape/Stride-Assertions), deterministische Reduktionen.
143
+
144
+ ## Testplan
145
+ - Unit-Tests:
146
+ - Kernels gegen NumPy/Referenz: Matmul, Conv, Reduce, Softmax, LayerNorm.
147
+ - Gradient Checks (finite differences) pro Op.
148
+ - Memory Pool: Reuse, Fragmentation, Leak-Detection.
149
+ - RNG: deterministische Sequenzen pro Seed/Device.
150
+ - Kernel-Generator: erzeugte Kernels aus Primitives muessen korrekt und deterministisch sein; AST/Template-Expansion Tests.
151
+ - Integrationstests:
152
+ - Mehr-Op-Graph mit aktivierter Fusion; Ergebnisvergleich zu NumPy/PyTorch.
153
+ - Autograd ueber kleine Netze (MLP, CNN) mit Loss; Gradients gegen PyTorch.
154
+ - Multi-GPU: AllReduce-Korrektheit (sum/mean), Sharded Batch; deterministische Runs.
155
+ - Overlap-Test: Compute+Copy parallel (Timing via Events).
156
+ - Performance-/Regressions-Tests:
157
+ - Benchmarks pro Device: GEMM-GFLOPs, Conv-Throughput, Bandbreite.
158
+ - Autotuning/Hyperstrategie: waehlt beste Config (Tiling/Partitionierung) und bleibt korrekt.
159
+ - Pipeline/Executor: Test, dass Graph-zu-Pipeline-Plan mit Buffer-Reuse erzeugt wird und zur Laufzeit minimale Python-Overhead verursacht (Timing-basierte Smoke-Tests).
160
+ - Stress-/Robustheitstests:
161
+ - Grosse Tensors, viele kleine Kernels (Scheduler/Pool-Stabilitaet).
162
+ - Fehlerpfade: Build-Failure, OOM -> sauberes Recovery ohne Leaks.
163
+
164
+ ## Roadmap (iterativ)
165
+ 1. Core: Device/Queue-Management, Memory Pool, Tensor-Basis; Definition der rudimentaeren OpenCL-Primitives.
166
+ 2. Kernels: Elementwise, Reduce, Matmul (mit leichtem Autotuning) auf Basis der Primitives; dynamischer Kernel-Generator MVP.
167
+ 3. Autograd: Tape + Grad-Registrierung; Grund-Ops mit Backward; Grad-Check-Tests.
168
+ 4. Ops: Conv2D (im2col), Softmax, Normen; Fusion-Generator erweitert Hyperstrategie (Layout/Tiling-Auswahl).
169
+ 5. Graph/Executor: Graph-Capture (ANN-Style), Buffer-Lebenszeit-Planung, Pipeline-Executor mit minimaler Python-Interaktion, Memory-Pooling-Integration.
170
+ 6. Distributed: AllReduce/Broadcast (Host-Relay zuerst, spaeter direkte Pfade); dynamische Partitionierung nach Device-Profilen.
171
+ 7. Profiling/Tracing + Benchmark-Suite; Ressourcenselektions-Heuristiken evaluieren.
172
+ 8. Stabilisierung: Tests/Performance-Regressions, deterministische Modi, BF16/FP16-Support; Persistenz von Tuning/Hyperstrategie-Entscheidungen.
173
+
174
+ ## Offene Fragen / Entscheidungen
175
+ - Mixed Precision Prioritaet: BF16 vs. FP16 Verfuegbarkeit auf Zielgeraeten?
176
+ - Autograd-Modell: nur Eager oder zusaetzlich Graph-basiert mit JIT-Fusion?
177
+ - Kommunikationspfad Multi-GPU: reicht Host-Relay oder braucht es P2P/OpenCL-Extensions?
178
+ - Zielgeraete: nur GPUs oder auch CPU/FPGA (beeinflusst Kernel-Optimierung und Workgroup-Strategie)?
@@ -0,0 +1,66 @@
1
+ # netcl – PyOpenCL Deep Learning Playground
2
+
3
+ `netcl` ist ein experimentelles Deep-Learning-Framework auf Basis von PyOpenCL. Es kombiniert low-level Kernel (Conv/Matmul/Elementwise) mit einer einfachen Autograd-Engine und einer High-Level API (Module, Trainer, Serializer), ohne Abhängigkeiten zu anderen DL-Frameworks.
4
+
5
+ ## Installation
6
+ ```bash
7
+ pip install .
8
+ ```
9
+ Voraussetzungen: Python ≥ 3.10, NumPy, PyOpenCL und ein verfügbares OpenCL-Gerät.
10
+
11
+ ## Schnelles Beispiel (MNIST-Mini-MLP)
12
+ ```python
13
+ import numpy as np
14
+ from netcl.core.device import manager
15
+ from netcl.nn.layers import Sequential, Flatten, Linear, ReLU
16
+ from netcl import autograd as ag
17
+ from netcl.optim import Adam
18
+ from netcl.core.tensor import Tensor
19
+
20
+ dev = manager.default()
21
+ q = dev.queue
22
+
23
+ model = Sequential(
24
+ Flatten(),
25
+ Linear(q, in_features=28*28, out_features=128),
26
+ ReLU(),
27
+ Linear(q, in_features=128, out_features=10),
28
+ )
29
+ opt = Adam(model.parameters(), lr=5e-3)
30
+
31
+ def one_hot(y, n=10):
32
+ oh = np.zeros((y.shape[0], n), dtype=np.float32)
33
+ oh[np.arange(y.shape[0]), y] = 1
34
+ return oh
35
+
36
+ xb = np.random.randn(32, 1, 28, 28).astype(np.float32)
37
+ yb = one_hot(np.random.randint(0, 10, size=(32,)))
38
+
39
+ tape = ag.Tape()
40
+ ag.set_current_tape(tape)
41
+ x = ag.tensor(Tensor.from_host(q, xb))
42
+ y = ag.tensor(Tensor.from_host(q, yb))
43
+ logits = model(x)
44
+ loss = ag.cross_entropy(logits, y)
45
+ tape.backward(loss)
46
+ opt.step(); opt.zero_grad()
47
+ ag.set_current_tape(None)
48
+ ```
49
+
50
+ ## Kernfeatures
51
+ - **Autograd**: Tape-basiert, elementare Ops (Matmul, Conv2d, Pooling, Elementwise) mit Backward.
52
+ - **Module/High-Level API**: `Linear`, `Conv2d`, `BatchNorm2d`, `Sequential`, `@model`-Dekorator, Trainer.
53
+ - **Optimierungen**: Conv-Algo-Heuristik/Autotuning, optional Mixed Precision, Buffer-Pool.
54
+ - **Serialization**: Speichert `Sequential`-Modelle als JSON (Architektur) + NPZ (Gewichte) via `netcl.io.serialization`.
55
+
56
+ ## Speichern & Laden eines Modells
57
+ ```python
58
+ from netcl.io.serialization import save_model, load_model
59
+ save_model(model, "checkpoints/mnist_mlp")
60
+ model2 = load_model("checkpoints/mnist_mlp") # queue auto="default"
61
+ ```
62
+
63
+ ## Hinweise
64
+ - Tests werden nicht mitinstalliert. Für lokale Entwicklung: `python -m pytest`.
65
+ - Für Performance: Batch-Größe erhöhen, Augment minimieren, optional Mixed Precision (`Trainer(..., mixed_precision=True)`).
66
+ - Conv-Algorithmen wählen automatisch optimierte Pfade; env-Flags wie `NETCL_CONV_AUTOTUNE=1` aktivieren Tuning.
@@ -0,0 +1,37 @@
1
+ """
2
+ netcl: PyOpenCL-based experimentation framework.
3
+ This package currently focuses on low-level kernel primitives and helpers.
4
+ """
5
+
6
+ from . import core, ops, autograd, distributed, runtime, profiling
7
+ from .ops import (
8
+ matmul,
9
+ build_matmul_kernel,
10
+ elementwise_binary,
11
+ relu,
12
+ bias_add,
13
+ reduce_sum,
14
+ softmax,
15
+ conv2d,
16
+ )
17
+ from . import nn, optim, io
18
+
19
+ __all__ = [
20
+ "core",
21
+ "ops",
22
+ "autograd",
23
+ "distributed",
24
+ "runtime",
25
+ "profiling",
26
+ "nn",
27
+ "optim",
28
+ "io",
29
+ "matmul",
30
+ "build_matmul_kernel",
31
+ "elementwise_binary",
32
+ "relu",
33
+ "bias_add",
34
+ "reduce_sum",
35
+ "softmax",
36
+ "conv2d",
37
+ ]
@@ -0,0 +1,147 @@
1
+ from __future__ import annotations
2
+
3
+ from dataclasses import dataclass
4
+ from typing import Optional, Sequence
5
+
6
+ try:
7
+ import numpy as np # type: ignore
8
+ except ImportError: # pragma: no cover
9
+ np = None
10
+
11
+ from netcl.core.tensor import Tensor
12
+ from netcl.core.tensor import _np_dtype # type: ignore
13
+
14
+ _AUTOCAST_ENABLED = False
15
+
16
+
17
+ @dataclass
18
+ class GradScaler:
19
+ init_scale: float = 2.0**16
20
+ growth_factor: float = 2.0
21
+ backoff_factor: float = 0.5
22
+ growth_interval: int = 2000
23
+ enabled: bool = True
24
+
25
+ def __post_init__(self):
26
+ self._scale = self.init_scale
27
+ self._growth_tracker = 0
28
+
29
+ @property
30
+ def scale(self) -> float:
31
+ return self._scale
32
+
33
+ def scale_loss(self, loss: Tensor) -> Tensor:
34
+ if not self.enabled:
35
+ return loss
36
+ from netcl.ops.elementwise import elementwise_binary
37
+
38
+ return elementwise_binary(loss, loss, expression=f"MUL(v0, {float(self._scale)})")
39
+
40
+ def unscale_grads(self, params: Sequence[Tensor]):
41
+ if not self.enabled:
42
+ return False
43
+ found_inf = False
44
+ for p in params:
45
+ if p.grad is None:
46
+ continue
47
+ g = p.grad.to_host()
48
+ if np.any(~np.isfinite(g)):
49
+ found_inf = True
50
+ break
51
+ if not found_inf:
52
+ inv_scale = 1.0 / self._scale
53
+ from netcl.ops.elementwise import elementwise_binary
54
+
55
+ for p in params:
56
+ if p.grad is None:
57
+ continue
58
+ p.grad = elementwise_binary(p.grad, p.grad, expression=f"MUL(v0, {inv_scale})")
59
+ return found_inf
60
+
61
+ def step(self, optimizer, params: Sequence[Tensor]):
62
+ if not self.enabled:
63
+ optimizer.step()
64
+ return
65
+ found_inf = self.unscale_grads(params)
66
+ if not found_inf:
67
+ optimizer.step()
68
+ self._growth_tracker += 1
69
+ if self._growth_tracker % self.growth_interval == 0:
70
+ self._scale *= self.growth_factor
71
+ else:
72
+ self._scale *= self.backoff_factor
73
+ self._growth_tracker = 0
74
+
75
+ def update(self):
76
+ # no-op kept for API compatibility
77
+ pass
78
+
79
+
80
+ def supports_fp16(queue) -> bool:
81
+ """
82
+ Check device extensions for cl_khr_fp16 support.
83
+ """
84
+ try:
85
+ return "cl_khr_fp16" in queue.device.extensions
86
+ except Exception:
87
+ return False
88
+
89
+
90
+ def autocast_enabled(profile_supports_fp16: bool) -> bool:
91
+ return profile_supports_fp16
92
+
93
+
94
+ class autocast:
95
+ """
96
+ Context manager for autocast. Enables casting only if underlying device supports fp16.
97
+ """
98
+
99
+ def __init__(self, enabled: bool = True, device_queue=None):
100
+ self.enabled = enabled
101
+ self.device_queue = device_queue
102
+ self.prev = False
103
+ self._capable = True
104
+
105
+ def __enter__(self):
106
+ global _AUTOCAST_ENABLED
107
+ self.prev = _AUTOCAST_ENABLED
108
+ if not self.enabled:
109
+ _AUTOCAST_ENABLED = False
110
+ return self
111
+ if self.device_queue is not None:
112
+ self._capable = supports_fp16(self.device_queue)
113
+ _AUTOCAST_ENABLED = self.enabled and self._capable
114
+ return self
115
+
116
+ def __exit__(self, exc_type, exc_val, exc_tb):
117
+ global _AUTOCAST_ENABLED
118
+ _AUTOCAST_ENABLED = self.prev
119
+ return False
120
+
121
+
122
+ def is_autocast_enabled() -> bool:
123
+ return _AUTOCAST_ENABLED
124
+
125
+
126
+ def maybe_cast_tensor(t: Tensor) -> Tensor:
127
+ if not _AUTOCAST_ENABLED:
128
+ return t
129
+ if t.dtype in ("float", "float32"):
130
+ # only cast if device can handle fp16
131
+ if supports_fp16(t.queue):
132
+ arr = t.to_host().astype(np.float16)
133
+ return Tensor.from_host(t.queue, arr, dtype="float16")
134
+ return t
135
+ return t
136
+
137
+
138
+ def master_param(param: Tensor) -> Tensor:
139
+ """
140
+ Keep master weights in FP32 for optimizers.
141
+ """
142
+ if param.dtype in ("float16", "half"):
143
+ master = Tensor.from_host(param.queue, param.to_host().astype(np.float32), dtype="float32")
144
+ setattr(master, "_model_param", param)
145
+ return master
146
+ setattr(param, "_model_param", param)
147
+ return param
@@ -0,0 +1,86 @@
1
+ """
2
+ Autograd: Node/Tape plus op wrappers.
3
+ """
4
+
5
+ from .engine import Node, Tape, apply_op, no_grad, set_current_tape, get_current_tape
6
+ from .debug import debug_tape
7
+ from .ops import (
8
+ tensor,
9
+ add,
10
+ relu,
11
+ bias_add,
12
+ matmul_op,
13
+ sub,
14
+ mse_loss,
15
+ sigmoid,
16
+ tanh,
17
+ leaky_relu,
18
+ gelu,
19
+ swish,
20
+ elu,
21
+ softplus,
22
+ hard_sigmoid,
23
+ hard_swish,
24
+ clamp,
25
+ hard_tanh,
26
+ prelu,
27
+ hinge_loss,
28
+ l1_loss,
29
+ l2_loss,
30
+ depthwise_conv2d,
31
+ batch_norm2d,
32
+ layer_norm,
33
+ pad2d,
34
+ group_norm,
35
+ global_avg_pool2d,
36
+ cross_entropy,
37
+ conv2d,
38
+ flatten,
39
+ max_pool2d,
40
+ dropout,
41
+ avg_pool2d,
42
+ )
43
+
44
+ __all__ = [
45
+ "Node",
46
+ "Tape",
47
+ "apply_op",
48
+ "no_grad",
49
+ "tensor",
50
+ "add",
51
+ "relu",
52
+ "bias_add",
53
+ "matmul_op",
54
+ "sub",
55
+ "mse_loss",
56
+ "sigmoid",
57
+ "tanh",
58
+ "leaky_relu",
59
+ "gelu",
60
+ "swish",
61
+ "elu",
62
+ "softplus",
63
+ "hard_sigmoid",
64
+ "hard_swish",
65
+ "clamp",
66
+ "hard_tanh",
67
+ "prelu",
68
+ "hinge_loss",
69
+ "l1_loss",
70
+ "l2_loss",
71
+ "depthwise_conv2d",
72
+ "batch_norm2d",
73
+ "layer_norm",
74
+ "pad2d",
75
+ "group_norm",
76
+ "global_avg_pool2d",
77
+ "cross_entropy",
78
+ "conv2d",
79
+ "flatten",
80
+ "max_pool2d",
81
+ "dropout",
82
+ "avg_pool2d",
83
+ "debug_tape",
84
+ "set_current_tape",
85
+ "get_current_tape",
86
+ ]
@@ -0,0 +1,12 @@
1
+ from __future__ import annotations
2
+
3
+ from contextlib import contextmanager
4
+ from typing import Iterator
5
+
6
+
7
+ @contextmanager
8
+ def debug_tape(tape):
9
+ """
10
+ Context manager to expose a tape for debugging/inspection.
11
+ """
12
+ yield tape