Repository files navigation

CppNet

CppNet Logo

CppNet is a high-performance C++17 deep learning library for building and training neural networks from scratch.
Built on Eigen for fast tensor operations, OpenMP for CPU parallelism, and CUDA for GPU acceleration.

C++17CMakeMIT LicenseCUDAWebsite


Table of Contents


Features

  • High Performance — Vectorized tensor operations via Eigen, multi-threaded with OpenMP, full CUDA GPU backend for all layers, activations, losses, and optimizers.
  • Rich Layer Library — Linear, Conv2D, MaxPool2D, RNN, LSTM, GRU, Multi-Head Attention, Dropout, BatchNorm, Embedding, Residual, GlobalPool, MeanPool1D, Flatten.
  • Multiple Backends — Per-layer compute backend selection: "cpu-eigen" (Eigen contractions), "cpu" (OpenMP loops), "gpu" (CUDA kernels).
  • Complete CUDA Coverage — 41 CUDA kernel files covering all layers, activations, losses, and optimizers for end-to-end GPU training.
  • Modular Architecture — Clean separation of layers, activations, losses, optimizers, metrics, regularizations, and utilities.
  • Training Utilities — DataLoader with batching & shuffling, learning rate schedulers, early stopping callbacks, gradient clipping, model serialization.
  • Visualization — Built-in TrainingLogger for tracking metrics and exporting training history to CSV.
  • Extensible — Abstract base classes for layers, losses, and optimizers make it straightforward to add custom components.
  • Single-Header Access#include <CppNet/CppNet.hpp> brings in the entire library.

Installation

Prerequisites

DependencyVersionRequired
C++ compiler (GCC, Clang, MSVC)C++17 supportYes
CMake≥ 3.18Yes
Eigen3≥ 3.3Yes
OpenMPanyOptional (CPU parallelism)
CUDA ToolkitanyOptional (GPU acceleration)

Build from Source

git clone https://github.com/LoqmanSamani/CppNet.git
cd CppNet
mkdir build &&cd build
cmake .. -DCMAKE_BUILD_TYPE=Release
make -j$(nproc)

Install System-Wide

sudo make install

This installs headers to /usr/local/include/CppNet/ and the static library to /usr/local/lib/.

Use in Your CMake Project

find_package(CppNetREQUIRED)
target_link_libraries(your_targetPRIVATECppNet::CppNet)

Quick Start

A minimal binary classification example:

#include<CppNet/CppNet.hpp>
#include<iostream>intmain() {
// Define layers
CppNet::Layers::Linear layer1(30, 64, "fc1", true, true, "cpu-eigen", "xavier");
CppNet::Layers::Linear layer2(64, 1, "fc2", true, true, "cpu-eigen", "xavier");
CppNet::Activations::ReLU relu("cpu-eigen");
CppNet::Activations::Sigmoid sigmoid;
// Loss & optimizer
CppNet::Losses::BinaryCrossEntropy loss_fn("mean");
CppNet::Optimizers::Adam optimizer;
float lr = 0.001;
// Training loopfor (int epoch = 0; epoch < 100; ++epoch) {
auto h = relu.forward(layer1.forward(X_train));
auto pred = sigmoid.forward(layer2.forward(h));
float loss = loss_fn.forward(pred, Y_train);
auto grad = loss_fn.backward(pred, Y_train);
grad = layer2.backward(sigmoid.backward(grad));
layer1.backward(relu.backward(grad));
layer2.step(optimizer, lr);
layer1.step(optimizer, lr);
std::cout << "Epoch " << epoch << " — Loss: " << loss << std::endl;
}
return0;
}

API Overview

Layers

All layers inherit from CppNet::Layers::Layer and implement forward(), backward(), step(), freeze(), unfreeze(), and print_layer_info().

LayerDescriptionKey Parameters
LinearFully connected layerin_size, out_size, bias, device, weight_init
Conv2D2D convolutionin_channels, out_channels, kernel_size, stride, padding
MaxPool2D2D max poolingkernel_size, stride
FlattenReshape to 2D
RNNVanilla recurrent layerinput_size, hidden_size
LSTMLong Short-Term Memoryinput_size, hidden_size
GRUGated Recurrent Unitinput_size, hidden_size
MultiHeadAttentionScaled dot-product multi-head attentionembed_dim, num_heads
DropoutDropout regularizationdrop_rate
BatchNormBatch normalizationnum_features
EmbeddingEmbedding lookup tablevocab_size, embed_dim
ResidualResidual (skip) connection wrapper
GlobalPoolGlobal average/max pooling
MeanPool1DMean pooling over sequence dimension

Activations

ActivationFunction
ReLU$\max(0, x)$
LeakyReLU$\max(\alpha x, x)$
Sigmoid$\sigma(x) = \frac{1}{1 + e^{-x}}$
Tanh$\tanh(x)$
Softmax$\frac{e^{x_i}}{\sum_j e^{x_j}}$

All activations support both 2D and 4D tensor inputs and run on all three backends (cpu-eigen, cpu, gpu).

Losses

LossTypical Use
MSERegression
MAERegression
HuberRobust regression
BinaryCrossEntropyBinary classification
CategoricalCrossEntropyMulti-class classification
SoftmaxCrossEntropyMulti-class (fused softmax + CE)

All support configurable reduction modes ("mean", "sum") and CUDA GPU acceleration.

Optimizers

OptimizerDescription
SGDStochastic Gradient Descent
AdamAdaptive Moment Estimation (default: $\beta_1=0.9$, $\beta_2=0.999$, $\epsilon=10^{-8}$)
AdagradAdaptive gradient accumulation
MomentumSGD with momentum
RMSPropRoot Mean Square Propagation

All optimizers have dedicated CUDA kernels for GPU-side weight updates.

Metrics

CppNet::Metrics::accuracy(predictions, targets);
CppNet::Metrics::binary_accuracy(predictions, targets, 0.5);
CppNet::Metrics::precision(predictions, targets, 0.5);
CppNet::Metrics::recall(predictions, targets, 0.5);
CppNet::Metrics::f1_score(predictions, targets, 0.5);

Regularizations

CppNet::Regularizations::l1_penalty(weights, lambda);
CppNet::Regularizations::l2_penalty(weights, lambda);
CppNet::Regularizations::elastic_net_penalty(weights, lambda, l1_ratio);
// Corresponding gradient functions: l1_gradient, l2_gradient, elastic_net_gradient

Utilities

UtilityDescription
DataLoaderBatched iteration with shuffling. Supports range-based for loops.
Weight InitXavier (uniform/normal), He (uniform/normal), constant, custom.
Gradient Clippingclip_by_value() and clip_by_norm().
Serializationsave_model() / load_model() for full model persistence; tensor-level binary I/O.
LR SchedulersStepLR, ExponentialLR, CosineAnnealingLR.
CallbacksEarlyStopping with configurable patience, delta, and mode.
Elapsed TimeTraining duration measurement.

DataLoader example:

CppNet::Utils::DataLoader loader(X, Y, /*batch_size=*/32, /*shuffle=*/true);
for (auto& [x_batch, y_batch] : loader) {
// forward / backward / step
}
loader.reset(); // re-shuffle for next epoch

Learning rate scheduler example:

CppNet::Schedulers::CosineAnnealingLR scheduler(/*initial_lr=*/0.01, /*T_max=*/100);
for (int epoch = 0; epoch < 100; ++epoch) {
float lr = scheduler.step();
// ... train with lr
}

Visualization

CppNet::Visualizations::TrainingLogger logger;
// Inside training loop:
logger.log("train_loss", loss);
logger.log("val_accuracy", val_acc);
logger.next_epoch();
// After training:
logger.print_epoch_summary();
logger.export_csv("training_history.csv");

Examples

The examples/ directory contains complete, self-contained deep learning programs that train on synthetic data — no downloads required. Each example generates its own dataset, trains a model, and reports final metrics.

ExampleArchitectureDatasetKey ComponentsResult
mlp_classification.cppLinear→ReLU→Linear→ReLU→Linear3-class spiral (600 samples, 2D)ReLU, SoftmaxCrossEntropy, Adam~75% accuracy
cnn_image_classification.cppConv2D→ReLU→MaxPool2D→Flatten→Linear8×8 stripe images (400 samples)Conv2D, MaxPool2D, SoftmaxCrossEntropy, Adam100% accuracy
rnn_sequence_prediction.cppLSTM(1,16)→Linear(16,1)Sine-wave sequences (400 samples)LSTM, MSE, AdamMSE ≈ 0.00001
gru_sequence_prediction.cppGRU(1,16)→Linear(16,1)Sine-wave sequences (400 samples)GRU, MAE, MomentumMAE ≈ 0.010
transformer_classifier.cppEmbedding→Attention+skip→ReLU→LinearToken sequences (400 samples)Embedding, MultiHeadAttention, MeanPool1D100% accuracy
resnet_classifier.cppLinear→ReLU→ResBlock(32)→Linear→SigmoidConcentric circles (600 samples)Residual, GradientClip, He init~99% accuracy
regularized_cnn.cppConv2D→LeakyReLU→Pool→BN→Dropout→FC8×8 pattern images (600 samples, 3 classes)BatchNorm, Dropout, LeakyReLU, CategoricalCrossEntropy, Adagrad100% accuracy
optimizer_comparison.cppLinear→Tanh→Linear→Tanh→LinearRegression: y = sin(x₀)·cos(x₁) (500 samples)SGD, Momentum, Adagrad, RMSProp, Adam, Tanh, Huberloss ≈ 0.002

Build and run:

cd build
cmake .. -DCMAKE_BUILD_TYPE=Release -DBUILD_EXAMPLES=ON
make -j$(nproc)
./examples/mlp_classification
./examples/cnn_image_classification
./examples/rnn_sequence_prediction
./examples/gru_sequence_prediction
./examples/transformer_classifier
./examples/resnet_classifier
./examples/regularized_cnn
./examples/optimizer_comparison

GPU Acceleration

CppNet provides full CUDA GPU support across all layers, activations, losses, and optimizers. When CUDA is detected at build time, layers can target the GPU backend:

CppNet::Layers::Linear layer(784, 256, "fc1", true, true, "gpu", "xavier");

CUDA Kernel Coverage (41 kernels)

CategoryCUDA Kernels
Linear algebramatmul, matmul_grad_input, matmul_grad_weight, add_bias, bias_grad, elementwise
Convolutionconv2d_forward, conv2d_backward, maxpool2d_forward, maxpool2d_backward
Recurrentrnn_cell, lstm_cell, gru_cell
Attentionattention_scores (scale, softmax, backward), embedding_forward, embedding_backward
Normalizationbatch_norm_forward, batch_norm_backward, dropout
Poolingglobal_avg_pool2d, global_max_pool2d, mean_pool1d
Activationsrelu, relu_grad, leaky_relu, leaky_relu_grad, sigmoid, sigmoid_grad, tanh_activation, tanh_activation_grad
Lossesmse, mae, huber, bce, categorical_ce, softmax_ce
Optimizerssgd_step, momentum_step, adagrad_step, rmsprop_step, adam_step

To force a CPU-only build even when CUDA is present:

cmake .. -DCUDAToolkit_ROOT=/nonexistent

Benchmarks

Five benchmarks compare three compute backends — cpu-eigen (Eigen SIMD contractions), cpu (OpenMP loops), and gpu (CUDA kernels) — across different architectures and model sizes. All benchmarks are reproducible via the scripts in the benchmarks/ directory.

Summary of GPU Speedups

ArchitectureModel SizeGPU Speedup vs cpu-eigenKey Observation
MLPSmall (4.5K params)2.0xGPU overhead limits gains for small matmuls
Medium (66K params)6.9x
Large (660K params)14.3x
XLarge (2.6M params)25.3xSub-linear GPU time scaling with params
CNNSmall (Conv16→32)28.8xConvolution is highly GPU-parallel
Medium (Conv32→64→FC128)42.0xHighest CNN speedup
RNN/LSTM/GRUSmall (H=64)2.2–5.2xGRU benefits most from GPU
Medium (H=128)4.7–15.5x
Large (H=256)12.2–56.4xGRU Large achieves 56.4x — highest overall
TransformerSmall (d=32, h=2)0.5x (slower)GPU overhead dominates at small scale
Medium (d=64, h=4)1.0x (break-even)
Large (d=128, h=8)1.2xModest gain; hybrid CPU/GPU attention
ResNetSmall (W=64, D=2)1.6xDepth amplifies GPU advantage
Medium (W=128, D=4)6.7x
Large (W=256, D=6)9.0xSkip connections add negligible overhead

Key Findings

  • GPU advantage grows with model size. Across all architectures, larger models see dramatically higher GPU speedups as matrix sizes better saturate GPU cores.
  • CNNs and recurrent layers benefit most from GPU. Convolution achieves up to 42x speedup; GRU achieves up to 56.4x — the highest across all benchmarks.
  • Transformers show modest GPU gains at tested scales due to mixed operations (embedding lookups, attention softmax, multiple small projections) and a hybrid CPU/GPU attention path.
  • Eigen (cpu-eigen) consistently outperforms OpenMP (cpu) for all architectures, leveraging SIMD vectorization and cache-optimal memory layouts.
  • Numerical consistency is verified across all backends — all devices converge to equivalent loss and accuracy values.

Average GPU Speedups by Architecture

ArchitectureAvg GPU SpeedupBest GPU SpeedupBest Config
MLP12.1x25.3xXLarge (2.6M params)
CNN35.4x42.0xMedium (Conv32→64→FC128)
Sequence (RNN/LSTM/GRU)13.7x56.4xGRU Large (H=256, seq=50)
Transformer0.9x1.2xLarge (d=128, h=8)
ResNet5.8x9.0xLarge (W=256, D=6)

How to Reproduce

cd build
cmake .. -DCMAKE_BUILD_TYPE=Release -DBUILD_BENCHMARKS=ON
make -j$(nproc)
./benchmarks/mlp_benchmark
./benchmarks/cnn_benchmark
./benchmarks/sequence_benchmark
./benchmarks/transformer_benchmark
./benchmarks/residual_benchmark

See benchmarks/benchmarks.md for full per-epoch results, detailed speedup analysis, and methodology.


Testing

CppNet has 41 unit tests with 377 test cases covering every module:

cd build
cmake .. -DBUILD_TESTS=ON
make -j$(nproc)
ctest --output-on-failure
CategoryTestsTest Cases
Layers (13)Linear, Conv2D, Flatten, MaxPool2D, RNN, Attention, BatchNorm, Dropout, Embedding, GlobalPool, GRU, LSTM, Residual123
Activations (5)ReLU, Sigmoid, Softmax, Tanh, LeakyReLU55
Losses (6)BinaryCrossEntropy, CategoricalCrossEntropy, MSE, MAE, Huber, SoftmaxCrossEntropy52
Optimizers (5)SGD, Adam, Momentum, Adagrad, RMSProp34
Utilities (7)Metrics, Regularizations, Callbacks, DataLoader, ElapsedTime, GradientClip, Init65
GPU Kernels (1)GPU matmul via Linear layer (forward, backward, step, CPU/GPU comparison)7
Other (4)Schedulers, Utils, Models, Visualizations41

Each test validates forward pass, backward pass (gradient shapes & values), parameter updates, and GPU/CPU numerical consistency where applicable.


Project Structure

CppNet/
├── CMakeLists.txt # Top-level build configuration
├── cmake/ # CMake package config templates
├── include/CppNet/ # Public headers
│ ├── CppNet.hpp # Single-include entry point
│ ├── activations/ # ReLU, Sigmoid, Softmax, Tanh, LeakyReLU
│ ├── layers/ # Linear, Conv2D, RNN, LSTM, GRU, Attention, ...
│ ├── losses/ # MSE, MAE, Huber, BCE, CCE, SoftmaxCE
│ ├── optimizers/ # SGD, Adam, Adagrad, Momentum, RMSProp
│ ├── models/ # SequentialModel
│ ├── metrics/ # Accuracy, Precision, Recall, F1
│ ├── regularizations/ # L1, L2, Elastic Net
│ ├── kernels/gpu/ # CUDA kernel declarations
│ ├── utils/ # DataLoader, Init, Schedulers, Serialization, ...
│ └── visualizations/ # TrainingLogger
├── src/CppNet/ # Implementation files (.cpp / .cu)
│ └── kernels/gpu/ # 41 CUDA kernel implementations
├── tests/ # 41 unit tests (377 test cases)
├── examples/ # 8 deep learning examples
├── benchmarks/ # 5 device benchmarks (CPU vs GPU)
└── docs/ # Additional documentation

Roadmap

  • Core layer library (Linear, Conv2D, Pooling, RNN, LSTM, GRU, Attention, BatchNorm, Dropout, Embedding, Residual)
  • Activation functions (ReLU, Sigmoid, Tanh, Softmax, LeakyReLU)
  • Loss functions (MSE, MAE, Huber, BCE, CCE, SoftmaxCE)
  • Optimizers (SGD, Adam, Adagrad, Momentum, RMSProp)
  • DataLoader, LR schedulers, early stopping, gradient clipping
  • Model serialization (save/load)
  • Full CUDA GPU backend — 41 kernels covering all layers, activations, losses, and optimizers
  • OpenMP CPU parallelism
  • Comprehensive test suite (41 tests, 377 test cases)
  • Deep learning examples (MLP, CNN, RNN/LSTM, GRU, Transformer, ResNet, Regularized CNN, Optimizer Comparison)
  • Device benchmarks (MLP, CNN, Sequence, Transformer, ResNet)
  • Add Trainer abstraction with built-in training loop
  • Additional examples (GANs, Reinforcement Learning, NLP pipelines)
  • Python bindings (pybind11)
  • Comprehensive API reference documentation

Contributing

Contributions are welcome! To get started:

  1. Fork the repository and create a feature branch.
  2. Follow the existing coding style — headers in include/CppNet/, implementations in src/CppNet/.
  3. Add tests for new functionality in tests/.
  4. Make sure all tests pass: cd build && ctest --output-on-failure.
  5. Open a pull request with a clear description of your changes.

License

CppNet is released under the MIT License.

Copyright © 2025 Loghman Samani

About

A high-performance C++ deep learning library for building and training neural networks

Resources

Stars

7 stars

Watchers

1 watching

Forks

Releases

Packages

Contributors

Languages

, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Add copy buttons to all
 blocks\n(function() {\n function addCopyButtons() {\n document.querySelectorAll('pre code').forEach(function(codeBlock) {\n if (codeBlock.parentElement.hasAttribute('data-copy-added')) return;\n codeBlock.parentElement.setAttribute('data-copy-added', 'true');\n \n var btn = document.createElement('button');\n btn.textContent = 'Copy';\n btn.style.cssText = 'position:absolute;top:4px;right:4px;padding:2px 8px;font-size:11px;background:#4ecdc4;border:none;border-radius:4px;color:#1a1a2e;cursor:pointer;opacity:0.7;transition:opacity 0.2s;';\n btn.onmouseover = function() { this.style.opacity = '1'; };\n btn.onmouseout = function() { this.style.opacity = '0.7'; };\n btn.onclick = function() {\n navigator.clipboard.writeText(codeBlock.textContent).then(function() {\n btn.textContent = 'Copied!';\n setTimeout(function() { btn.textContent = 'Copy'; }, 1500);\n });\n };\n codeBlock.parentElement.style.position = 'relative';\n codeBlock.parentElement.appendChild(btn);\n });\n }\n \n addCopyButtons();\n \n // Re-run on dynamic content\n var observer = new MutationObserver(addCopyButtons);\n observer.observe(document.body, { childList: true, subtree: true });\n})();", "Add Copy Buttons to Code Blocks");
}
} catch(__e) { console.warn('[Userscript:Add Copy Buttons to Code Blocks]', __e); }
})();
(function(){
try {
var __m = "github.com";
var __re = new RegExp('^' + "github\\.com" + '
Skip to content

Repository files navigation

CppNet

CppNet Logo

CppNet is a high-performance C++17 deep learning library for building and training neural networks from scratch.
Built on Eigen for fast tensor operations, OpenMP for CPU parallelism, and CUDA for GPU acceleration.

C++17CMakeMIT LicenseCUDAWebsite


Table of Contents


Features

  • High Performance — Vectorized tensor operations via Eigen, multi-threaded with OpenMP, full CUDA GPU backend for all layers, activations, losses, and optimizers.
  • Rich Layer Library — Linear, Conv2D, MaxPool2D, RNN, LSTM, GRU, Multi-Head Attention, Dropout, BatchNorm, Embedding, Residual, GlobalPool, MeanPool1D, Flatten.
  • Multiple Backends — Per-layer compute backend selection: "cpu-eigen" (Eigen contractions), "cpu" (OpenMP loops), "gpu" (CUDA kernels).
  • Complete CUDA Coverage — 41 CUDA kernel files covering all layers, activations, losses, and optimizers for end-to-end GPU training.
  • Modular Architecture — Clean separation of layers, activations, losses, optimizers, metrics, regularizations, and utilities.
  • Training Utilities — DataLoader with batching & shuffling, learning rate schedulers, early stopping callbacks, gradient clipping, model serialization.
  • Visualization — Built-in TrainingLogger for tracking metrics and exporting training history to CSV.
  • Extensible — Abstract base classes for layers, losses, and optimizers make it straightforward to add custom components.
  • Single-Header Access#include <CppNet/CppNet.hpp> brings in the entire library.

Installation

Prerequisites

DependencyVersionRequired
C++ compiler (GCC, Clang, MSVC)C++17 supportYes
CMake≥ 3.18Yes
Eigen3≥ 3.3Yes
OpenMPanyOptional (CPU parallelism)
CUDA ToolkitanyOptional (GPU acceleration)

Build from Source

git clone https://github.com/LoqmanSamani/CppNet.git
cd CppNet
mkdir build &&cd build
cmake .. -DCMAKE_BUILD_TYPE=Release
make -j$(nproc)

Install System-Wide

sudo make install

This installs headers to /usr/local/include/CppNet/ and the static library to /usr/local/lib/.

Use in Your CMake Project

find_package(CppNetREQUIRED)
target_link_libraries(your_targetPRIVATECppNet::CppNet)

Quick Start

A minimal binary classification example:

#include<CppNet/CppNet.hpp>
#include<iostream>intmain() {
// Define layers
CppNet::Layers::Linear layer1(30, 64, "fc1", true, true, "cpu-eigen", "xavier");
CppNet::Layers::Linear layer2(64, 1, "fc2", true, true, "cpu-eigen", "xavier");
CppNet::Activations::ReLU relu("cpu-eigen");
CppNet::Activations::Sigmoid sigmoid;
// Loss & optimizer
CppNet::Losses::BinaryCrossEntropy loss_fn("mean");
CppNet::Optimizers::Adam optimizer;
float lr = 0.001;
// Training loopfor (int epoch = 0; epoch < 100; ++epoch) {
auto h = relu.forward(layer1.forward(X_train));
auto pred = sigmoid.forward(layer2.forward(h));
float loss = loss_fn.forward(pred, Y_train);
auto grad = loss_fn.backward(pred, Y_train);
grad = layer2.backward(sigmoid.backward(grad));
layer1.backward(relu.backward(grad));
layer2.step(optimizer, lr);
layer1.step(optimizer, lr);
std::cout << "Epoch " << epoch << " — Loss: " << loss << std::endl;
}
return0;
}

API Overview

Layers

All layers inherit from CppNet::Layers::Layer and implement forward(), backward(), step(), freeze(), unfreeze(), and print_layer_info().

LayerDescriptionKey Parameters
LinearFully connected layerin_size, out_size, bias, device, weight_init
Conv2D2D convolutionin_channels, out_channels, kernel_size, stride, padding
MaxPool2D2D max poolingkernel_size, stride
FlattenReshape to 2D
RNNVanilla recurrent layerinput_size, hidden_size
LSTMLong Short-Term Memoryinput_size, hidden_size
GRUGated Recurrent Unitinput_size, hidden_size
MultiHeadAttentionScaled dot-product multi-head attentionembed_dim, num_heads
DropoutDropout regularizationdrop_rate
BatchNormBatch normalizationnum_features
EmbeddingEmbedding lookup tablevocab_size, embed_dim
ResidualResidual (skip) connection wrapper
GlobalPoolGlobal average/max pooling
MeanPool1DMean pooling over sequence dimension

Activations

ActivationFunction
ReLU$\max(0, x)$
LeakyReLU$\max(\alpha x, x)$
Sigmoid$\sigma(x) = \frac{1}{1 + e^{-x}}$
Tanh$\tanh(x)$
Softmax$\frac{e^{x_i}}{\sum_j e^{x_j}}$

All activations support both 2D and 4D tensor inputs and run on all three backends (cpu-eigen, cpu, gpu).

Losses

LossTypical Use
MSERegression
MAERegression
HuberRobust regression
BinaryCrossEntropyBinary classification
CategoricalCrossEntropyMulti-class classification
SoftmaxCrossEntropyMulti-class (fused softmax + CE)

All support configurable reduction modes ("mean", "sum") and CUDA GPU acceleration.

Optimizers

OptimizerDescription
SGDStochastic Gradient Descent
AdamAdaptive Moment Estimation (default: $\beta_1=0.9$, $\beta_2=0.999$, $\epsilon=10^{-8}$)
AdagradAdaptive gradient accumulation
MomentumSGD with momentum
RMSPropRoot Mean Square Propagation

All optimizers have dedicated CUDA kernels for GPU-side weight updates.

Metrics

CppNet::Metrics::accuracy(predictions, targets);
CppNet::Metrics::binary_accuracy(predictions, targets, 0.5);
CppNet::Metrics::precision(predictions, targets, 0.5);
CppNet::Metrics::recall(predictions, targets, 0.5);
CppNet::Metrics::f1_score(predictions, targets, 0.5);

Regularizations

CppNet::Regularizations::l1_penalty(weights, lambda);
CppNet::Regularizations::l2_penalty(weights, lambda);
CppNet::Regularizations::elastic_net_penalty(weights, lambda, l1_ratio);
// Corresponding gradient functions: l1_gradient, l2_gradient, elastic_net_gradient

Utilities

UtilityDescription
DataLoaderBatched iteration with shuffling. Supports range-based for loops.
Weight InitXavier (uniform/normal), He (uniform/normal), constant, custom.
Gradient Clippingclip_by_value() and clip_by_norm().
Serializationsave_model() / load_model() for full model persistence; tensor-level binary I/O.
LR SchedulersStepLR, ExponentialLR, CosineAnnealingLR.
CallbacksEarlyStopping with configurable patience, delta, and mode.
Elapsed TimeTraining duration measurement.

DataLoader example:

CppNet::Utils::DataLoader loader(X, Y, /*batch_size=*/32, /*shuffle=*/true);
for (auto& [x_batch, y_batch] : loader) {
// forward / backward / step
}
loader.reset(); // re-shuffle for next epoch

Learning rate scheduler example:

CppNet::Schedulers::CosineAnnealingLR scheduler(/*initial_lr=*/0.01, /*T_max=*/100);
for (int epoch = 0; epoch < 100; ++epoch) {
float lr = scheduler.step();
// ... train with lr
}

Visualization

CppNet::Visualizations::TrainingLogger logger;
// Inside training loop:
logger.log("train_loss", loss);
logger.log("val_accuracy", val_acc);
logger.next_epoch();
// After training:
logger.print_epoch_summary();
logger.export_csv("training_history.csv");

Examples

The examples/ directory contains complete, self-contained deep learning programs that train on synthetic data — no downloads required. Each example generates its own dataset, trains a model, and reports final metrics.

ExampleArchitectureDatasetKey ComponentsResult
mlp_classification.cppLinear→ReLU→Linear→ReLU→Linear3-class spiral (600 samples, 2D)ReLU, SoftmaxCrossEntropy, Adam~75% accuracy
cnn_image_classification.cppConv2D→ReLU→MaxPool2D→Flatten→Linear8×8 stripe images (400 samples)Conv2D, MaxPool2D, SoftmaxCrossEntropy, Adam100% accuracy
rnn_sequence_prediction.cppLSTM(1,16)→Linear(16,1)Sine-wave sequences (400 samples)LSTM, MSE, AdamMSE ≈ 0.00001
gru_sequence_prediction.cppGRU(1,16)→Linear(16,1)Sine-wave sequences (400 samples)GRU, MAE, MomentumMAE ≈ 0.010
transformer_classifier.cppEmbedding→Attention+skip→ReLU→LinearToken sequences (400 samples)Embedding, MultiHeadAttention, MeanPool1D100% accuracy
resnet_classifier.cppLinear→ReLU→ResBlock(32)→Linear→SigmoidConcentric circles (600 samples)Residual, GradientClip, He init~99% accuracy
regularized_cnn.cppConv2D→LeakyReLU→Pool→BN→Dropout→FC8×8 pattern images (600 samples, 3 classes)BatchNorm, Dropout, LeakyReLU, CategoricalCrossEntropy, Adagrad100% accuracy
optimizer_comparison.cppLinear→Tanh→Linear→Tanh→LinearRegression: y = sin(x₀)·cos(x₁) (500 samples)SGD, Momentum, Adagrad, RMSProp, Adam, Tanh, Huberloss ≈ 0.002

Build and run:

cd build
cmake .. -DCMAKE_BUILD_TYPE=Release -DBUILD_EXAMPLES=ON
make -j$(nproc)
./examples/mlp_classification
./examples/cnn_image_classification
./examples/rnn_sequence_prediction
./examples/gru_sequence_prediction
./examples/transformer_classifier
./examples/resnet_classifier
./examples/regularized_cnn
./examples/optimizer_comparison

GPU Acceleration

CppNet provides full CUDA GPU support across all layers, activations, losses, and optimizers. When CUDA is detected at build time, layers can target the GPU backend:

CppNet::Layers::Linear layer(784, 256, "fc1", true, true, "gpu", "xavier");

CUDA Kernel Coverage (41 kernels)

CategoryCUDA Kernels
Linear algebramatmul, matmul_grad_input, matmul_grad_weight, add_bias, bias_grad, elementwise
Convolutionconv2d_forward, conv2d_backward, maxpool2d_forward, maxpool2d_backward
Recurrentrnn_cell, lstm_cell, gru_cell
Attentionattention_scores (scale, softmax, backward), embedding_forward, embedding_backward
Normalizationbatch_norm_forward, batch_norm_backward, dropout
Poolingglobal_avg_pool2d, global_max_pool2d, mean_pool1d
Activationsrelu, relu_grad, leaky_relu, leaky_relu_grad, sigmoid, sigmoid_grad, tanh_activation, tanh_activation_grad
Lossesmse, mae, huber, bce, categorical_ce, softmax_ce
Optimizerssgd_step, momentum_step, adagrad_step, rmsprop_step, adam_step

To force a CPU-only build even when CUDA is present:

cmake .. -DCUDAToolkit_ROOT=/nonexistent

Benchmarks

Five benchmarks compare three compute backends — cpu-eigen (Eigen SIMD contractions), cpu (OpenMP loops), and gpu (CUDA kernels) — across different architectures and model sizes. All benchmarks are reproducible via the scripts in the benchmarks/ directory.

Summary of GPU Speedups

ArchitectureModel SizeGPU Speedup vs cpu-eigenKey Observation
MLPSmall (4.5K params)2.0xGPU overhead limits gains for small matmuls
Medium (66K params)6.9x
Large (660K params)14.3x
XLarge (2.6M params)25.3xSub-linear GPU time scaling with params
CNNSmall (Conv16→32)28.8xConvolution is highly GPU-parallel
Medium (Conv32→64→FC128)42.0xHighest CNN speedup
RNN/LSTM/GRUSmall (H=64)2.2–5.2xGRU benefits most from GPU
Medium (H=128)4.7–15.5x
Large (H=256)12.2–56.4xGRU Large achieves 56.4x — highest overall
TransformerSmall (d=32, h=2)0.5x (slower)GPU overhead dominates at small scale
Medium (d=64, h=4)1.0x (break-even)
Large (d=128, h=8)1.2xModest gain; hybrid CPU/GPU attention
ResNetSmall (W=64, D=2)1.6xDepth amplifies GPU advantage
Medium (W=128, D=4)6.7x
Large (W=256, D=6)9.0xSkip connections add negligible overhead

Key Findings

  • GPU advantage grows with model size. Across all architectures, larger models see dramatically higher GPU speedups as matrix sizes better saturate GPU cores.
  • CNNs and recurrent layers benefit most from GPU. Convolution achieves up to 42x speedup; GRU achieves up to 56.4x — the highest across all benchmarks.
  • Transformers show modest GPU gains at tested scales due to mixed operations (embedding lookups, attention softmax, multiple small projections) and a hybrid CPU/GPU attention path.
  • Eigen (cpu-eigen) consistently outperforms OpenMP (cpu) for all architectures, leveraging SIMD vectorization and cache-optimal memory layouts.
  • Numerical consistency is verified across all backends — all devices converge to equivalent loss and accuracy values.

Average GPU Speedups by Architecture

ArchitectureAvg GPU SpeedupBest GPU SpeedupBest Config
MLP12.1x25.3xXLarge (2.6M params)
CNN35.4x42.0xMedium (Conv32→64→FC128)
Sequence (RNN/LSTM/GRU)13.7x56.4xGRU Large (H=256, seq=50)
Transformer0.9x1.2xLarge (d=128, h=8)
ResNet5.8x9.0xLarge (W=256, D=6)

How to Reproduce

cd build
cmake .. -DCMAKE_BUILD_TYPE=Release -DBUILD_BENCHMARKS=ON
make -j$(nproc)
./benchmarks/mlp_benchmark
./benchmarks/cnn_benchmark
./benchmarks/sequence_benchmark
./benchmarks/transformer_benchmark
./benchmarks/residual_benchmark

See benchmarks/benchmarks.md for full per-epoch results, detailed speedup analysis, and methodology.


Testing

CppNet has 41 unit tests with 377 test cases covering every module:

cd build
cmake .. -DBUILD_TESTS=ON
make -j$(nproc)
ctest --output-on-failure
CategoryTestsTest Cases
Layers (13)Linear, Conv2D, Flatten, MaxPool2D, RNN, Attention, BatchNorm, Dropout, Embedding, GlobalPool, GRU, LSTM, Residual123
Activations (5)ReLU, Sigmoid, Softmax, Tanh, LeakyReLU55
Losses (6)BinaryCrossEntropy, CategoricalCrossEntropy, MSE, MAE, Huber, SoftmaxCrossEntropy52
Optimizers (5)SGD, Adam, Momentum, Adagrad, RMSProp34
Utilities (7)Metrics, Regularizations, Callbacks, DataLoader, ElapsedTime, GradientClip, Init65
GPU Kernels (1)GPU matmul via Linear layer (forward, backward, step, CPU/GPU comparison)7
Other (4)Schedulers, Utils, Models, Visualizations41

Each test validates forward pass, backward pass (gradient shapes & values), parameter updates, and GPU/CPU numerical consistency where applicable.


Project Structure

CppNet/
├── CMakeLists.txt # Top-level build configuration
├── cmake/ # CMake package config templates
├── include/CppNet/ # Public headers
│ ├── CppNet.hpp # Single-include entry point
│ ├── activations/ # ReLU, Sigmoid, Softmax, Tanh, LeakyReLU
│ ├── layers/ # Linear, Conv2D, RNN, LSTM, GRU, Attention, ...
│ ├── losses/ # MSE, MAE, Huber, BCE, CCE, SoftmaxCE
│ ├── optimizers/ # SGD, Adam, Adagrad, Momentum, RMSProp
│ ├── models/ # SequentialModel
│ ├── metrics/ # Accuracy, Precision, Recall, F1
│ ├── regularizations/ # L1, L2, Elastic Net
│ ├── kernels/gpu/ # CUDA kernel declarations
│ ├── utils/ # DataLoader, Init, Schedulers, Serialization, ...
│ └── visualizations/ # TrainingLogger
├── src/CppNet/ # Implementation files (.cpp / .cu)
│ └── kernels/gpu/ # 41 CUDA kernel implementations
├── tests/ # 41 unit tests (377 test cases)
├── examples/ # 8 deep learning examples
├── benchmarks/ # 5 device benchmarks (CPU vs GPU)
└── docs/ # Additional documentation

Roadmap

  • Core layer library (Linear, Conv2D, Pooling, RNN, LSTM, GRU, Attention, BatchNorm, Dropout, Embedding, Residual)
  • Activation functions (ReLU, Sigmoid, Tanh, Softmax, LeakyReLU)
  • Loss functions (MSE, MAE, Huber, BCE, CCE, SoftmaxCE)
  • Optimizers (SGD, Adam, Adagrad, Momentum, RMSProp)
  • DataLoader, LR schedulers, early stopping, gradient clipping
  • Model serialization (save/load)
  • Full CUDA GPU backend — 41 kernels covering all layers, activations, losses, and optimizers
  • OpenMP CPU parallelism
  • Comprehensive test suite (41 tests, 377 test cases)
  • Deep learning examples (MLP, CNN, RNN/LSTM, GRU, Transformer, ResNet, Regularized CNN, Optimizer Comparison)
  • Device benchmarks (MLP, CNN, Sequence, Transformer, ResNet)
  • Add Trainer abstraction with built-in training loop
  • Additional examples (GANs, Reinforcement Learning, NLP pipelines)
  • Python bindings (pybind11)
  • Comprehensive API reference documentation

Contributing

Contributions are welcome! To get started:

  1. Fork the repository and create a feature branch.
  2. Follow the existing coding style — headers in include/CppNet/, implementations in src/CppNet/.
  3. Add tests for new functionality in tests/.
  4. Make sure all tests pass: cd build && ctest --output-on-failure.
  5. Open a pull request with a clear description of your changes.

License

CppNet is released under the MIT License.

Copyright © 2025 Loghman Samani

About

A high-performance C++ deep learning library for building and training neural networks

Resources

Stars

7 stars

Watchers

1 watching

Forks

Releases

Packages

Contributors

Languages

, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Force GitHub README to respect dark mode\n(function() {\n var style = document.createElement('style');\n style.textContent = '\n .markdown-body {\n color-scheme: dark light;\n }\n .markdown-body pre { background: #161b22 !important; }\n .markdown-body code { background: rgba(110, 118, 129, 0.4) !important; }\n .markdown-body table th, .markdown-body table td { border-color: #30363d !important; }\n .markdown-body img { background: #0d1117; }\n .markdown-body blockquote { border-left-color: #8b949e; }\n .markdown-body hr { border-color: #30363d; }\n ';\n document.head.appendChild(style);\n})();", "GitHub Dark Mode README Fix"); } } catch(__e) { console.warn('[Userscript:GitHub Dark Mode README Fix]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + '
Skip to content

Repository files navigation

CppNet

CppNet Logo

CppNet is a high-performance C++17 deep learning library for building and training neural networks from scratch.
Built on Eigen for fast tensor operations, OpenMP for CPU parallelism, and CUDA for GPU acceleration.

C++17CMakeMIT LicenseCUDAWebsite


Table of Contents


Features

  • High Performance — Vectorized tensor operations via Eigen, multi-threaded with OpenMP, full CUDA GPU backend for all layers, activations, losses, and optimizers.
  • Rich Layer Library — Linear, Conv2D, MaxPool2D, RNN, LSTM, GRU, Multi-Head Attention, Dropout, BatchNorm, Embedding, Residual, GlobalPool, MeanPool1D, Flatten.
  • Multiple Backends — Per-layer compute backend selection: "cpu-eigen" (Eigen contractions), "cpu" (OpenMP loops), "gpu" (CUDA kernels).
  • Complete CUDA Coverage — 41 CUDA kernel files covering all layers, activations, losses, and optimizers for end-to-end GPU training.
  • Modular Architecture — Clean separation of layers, activations, losses, optimizers, metrics, regularizations, and utilities.
  • Training Utilities — DataLoader with batching & shuffling, learning rate schedulers, early stopping callbacks, gradient clipping, model serialization.
  • Visualization — Built-in TrainingLogger for tracking metrics and exporting training history to CSV.
  • Extensible — Abstract base classes for layers, losses, and optimizers make it straightforward to add custom components.
  • Single-Header Access#include <CppNet/CppNet.hpp> brings in the entire library.

Installation

Prerequisites

DependencyVersionRequired
C++ compiler (GCC, Clang, MSVC)C++17 supportYes
CMake≥ 3.18Yes
Eigen3≥ 3.3Yes
OpenMPanyOptional (CPU parallelism)
CUDA ToolkitanyOptional (GPU acceleration)

Build from Source

git clone https://github.com/LoqmanSamani/CppNet.git
cd CppNet
mkdir build &&cd build
cmake .. -DCMAKE_BUILD_TYPE=Release
make -j$(nproc)

Install System-Wide

sudo make install

This installs headers to /usr/local/include/CppNet/ and the static library to /usr/local/lib/.

Use in Your CMake Project

find_package(CppNetREQUIRED)
target_link_libraries(your_targetPRIVATECppNet::CppNet)

Quick Start

A minimal binary classification example:

#include<CppNet/CppNet.hpp>
#include<iostream>intmain() {
// Define layers
CppNet::Layers::Linear layer1(30, 64, "fc1", true, true, "cpu-eigen", "xavier");
CppNet::Layers::Linear layer2(64, 1, "fc2", true, true, "cpu-eigen", "xavier");
CppNet::Activations::ReLU relu("cpu-eigen");
CppNet::Activations::Sigmoid sigmoid;
// Loss & optimizer
CppNet::Losses::BinaryCrossEntropy loss_fn("mean");
CppNet::Optimizers::Adam optimizer;
float lr = 0.001;
// Training loopfor (int epoch = 0; epoch < 100; ++epoch) {
auto h = relu.forward(layer1.forward(X_train));
auto pred = sigmoid.forward(layer2.forward(h));
float loss = loss_fn.forward(pred, Y_train);
auto grad = loss_fn.backward(pred, Y_train);
grad = layer2.backward(sigmoid.backward(grad));
layer1.backward(relu.backward(grad));
layer2.step(optimizer, lr);
layer1.step(optimizer, lr);
std::cout << "Epoch " << epoch << " — Loss: " << loss << std::endl;
}
return0;
}

API Overview

Layers

All layers inherit from CppNet::Layers::Layer and implement forward(), backward(), step(), freeze(), unfreeze(), and print_layer_info().

LayerDescriptionKey Parameters
LinearFully connected layerin_size, out_size, bias, device, weight_init
Conv2D2D convolutionin_channels, out_channels, kernel_size, stride, padding
MaxPool2D2D max poolingkernel_size, stride
FlattenReshape to 2D
RNNVanilla recurrent layerinput_size, hidden_size
LSTMLong Short-Term Memoryinput_size, hidden_size
GRUGated Recurrent Unitinput_size, hidden_size
MultiHeadAttentionScaled dot-product multi-head attentionembed_dim, num_heads
DropoutDropout regularizationdrop_rate
BatchNormBatch normalizationnum_features
EmbeddingEmbedding lookup tablevocab_size, embed_dim
ResidualResidual (skip) connection wrapper
GlobalPoolGlobal average/max pooling
MeanPool1DMean pooling over sequence dimension

Activations

ActivationFunction
ReLU$\max(0, x)$
LeakyReLU$\max(\alpha x, x)$
Sigmoid$\sigma(x) = \frac{1}{1 + e^{-x}}$
Tanh$\tanh(x)$
Softmax$\frac{e^{x_i}}{\sum_j e^{x_j}}$

All activations support both 2D and 4D tensor inputs and run on all three backends (cpu-eigen, cpu, gpu).

Losses

LossTypical Use
MSERegression
MAERegression
HuberRobust regression
BinaryCrossEntropyBinary classification
CategoricalCrossEntropyMulti-class classification
SoftmaxCrossEntropyMulti-class (fused softmax + CE)

All support configurable reduction modes ("mean", "sum") and CUDA GPU acceleration.

Optimizers

OptimizerDescription
SGDStochastic Gradient Descent
AdamAdaptive Moment Estimation (default: $\beta_1=0.9$, $\beta_2=0.999$, $\epsilon=10^{-8}$)
AdagradAdaptive gradient accumulation
MomentumSGD with momentum
RMSPropRoot Mean Square Propagation

All optimizers have dedicated CUDA kernels for GPU-side weight updates.

Metrics

CppNet::Metrics::accuracy(predictions, targets);
CppNet::Metrics::binary_accuracy(predictions, targets, 0.5);
CppNet::Metrics::precision(predictions, targets, 0.5);
CppNet::Metrics::recall(predictions, targets, 0.5);
CppNet::Metrics::f1_score(predictions, targets, 0.5);

Regularizations

CppNet::Regularizations::l1_penalty(weights, lambda);
CppNet::Regularizations::l2_penalty(weights, lambda);
CppNet::Regularizations::elastic_net_penalty(weights, lambda, l1_ratio);
// Corresponding gradient functions: l1_gradient, l2_gradient, elastic_net_gradient

Utilities

UtilityDescription
DataLoaderBatched iteration with shuffling. Supports range-based for loops.
Weight InitXavier (uniform/normal), He (uniform/normal), constant, custom.
Gradient Clippingclip_by_value() and clip_by_norm().
Serializationsave_model() / load_model() for full model persistence; tensor-level binary I/O.
LR SchedulersStepLR, ExponentialLR, CosineAnnealingLR.
CallbacksEarlyStopping with configurable patience, delta, and mode.
Elapsed TimeTraining duration measurement.

DataLoader example:

CppNet::Utils::DataLoader loader(X, Y, /*batch_size=*/32, /*shuffle=*/true);
for (auto& [x_batch, y_batch] : loader) {
// forward / backward / step
}
loader.reset(); // re-shuffle for next epoch

Learning rate scheduler example:

CppNet::Schedulers::CosineAnnealingLR scheduler(/*initial_lr=*/0.01, /*T_max=*/100);
for (int epoch = 0; epoch < 100; ++epoch) {
float lr = scheduler.step();
// ... train with lr
}

Visualization

CppNet::Visualizations::TrainingLogger logger;
// Inside training loop:
logger.log("train_loss", loss);
logger.log("val_accuracy", val_acc);
logger.next_epoch();
// After training:
logger.print_epoch_summary();
logger.export_csv("training_history.csv");

Examples

The examples/ directory contains complete, self-contained deep learning programs that train on synthetic data — no downloads required. Each example generates its own dataset, trains a model, and reports final metrics.

ExampleArchitectureDatasetKey ComponentsResult
mlp_classification.cppLinear→ReLU→Linear→ReLU→Linear3-class spiral (600 samples, 2D)ReLU, SoftmaxCrossEntropy, Adam~75% accuracy
cnn_image_classification.cppConv2D→ReLU→MaxPool2D→Flatten→Linear8×8 stripe images (400 samples)Conv2D, MaxPool2D, SoftmaxCrossEntropy, Adam100% accuracy
rnn_sequence_prediction.cppLSTM(1,16)→Linear(16,1)Sine-wave sequences (400 samples)LSTM, MSE, AdamMSE ≈ 0.00001
gru_sequence_prediction.cppGRU(1,16)→Linear(16,1)Sine-wave sequences (400 samples)GRU, MAE, MomentumMAE ≈ 0.010
transformer_classifier.cppEmbedding→Attention+skip→ReLU→LinearToken sequences (400 samples)Embedding, MultiHeadAttention, MeanPool1D100% accuracy
resnet_classifier.cppLinear→ReLU→ResBlock(32)→Linear→SigmoidConcentric circles (600 samples)Residual, GradientClip, He init~99% accuracy
regularized_cnn.cppConv2D→LeakyReLU→Pool→BN→Dropout→FC8×8 pattern images (600 samples, 3 classes)BatchNorm, Dropout, LeakyReLU, CategoricalCrossEntropy, Adagrad100% accuracy
optimizer_comparison.cppLinear→Tanh→Linear→Tanh→LinearRegression: y = sin(x₀)·cos(x₁) (500 samples)SGD, Momentum, Adagrad, RMSProp, Adam, Tanh, Huberloss ≈ 0.002

Build and run:

cd build
cmake .. -DCMAKE_BUILD_TYPE=Release -DBUILD_EXAMPLES=ON
make -j$(nproc)
./examples/mlp_classification
./examples/cnn_image_classification
./examples/rnn_sequence_prediction
./examples/gru_sequence_prediction
./examples/transformer_classifier
./examples/resnet_classifier
./examples/regularized_cnn
./examples/optimizer_comparison

GPU Acceleration

CppNet provides full CUDA GPU support across all layers, activations, losses, and optimizers. When CUDA is detected at build time, layers can target the GPU backend:

CppNet::Layers::Linear layer(784, 256, "fc1", true, true, "gpu", "xavier");

CUDA Kernel Coverage (41 kernels)

CategoryCUDA Kernels
Linear algebramatmul, matmul_grad_input, matmul_grad_weight, add_bias, bias_grad, elementwise
Convolutionconv2d_forward, conv2d_backward, maxpool2d_forward, maxpool2d_backward
Recurrentrnn_cell, lstm_cell, gru_cell
Attentionattention_scores (scale, softmax, backward), embedding_forward, embedding_backward
Normalizationbatch_norm_forward, batch_norm_backward, dropout
Poolingglobal_avg_pool2d, global_max_pool2d, mean_pool1d
Activationsrelu, relu_grad, leaky_relu, leaky_relu_grad, sigmoid, sigmoid_grad, tanh_activation, tanh_activation_grad
Lossesmse, mae, huber, bce, categorical_ce, softmax_ce
Optimizerssgd_step, momentum_step, adagrad_step, rmsprop_step, adam_step

To force a CPU-only build even when CUDA is present:

cmake .. -DCUDAToolkit_ROOT=/nonexistent

Benchmarks

Five benchmarks compare three compute backends — cpu-eigen (Eigen SIMD contractions), cpu (OpenMP loops), and gpu (CUDA kernels) — across different architectures and model sizes. All benchmarks are reproducible via the scripts in the benchmarks/ directory.

Summary of GPU Speedups

ArchitectureModel SizeGPU Speedup vs cpu-eigenKey Observation
MLPSmall (4.5K params)2.0xGPU overhead limits gains for small matmuls
Medium (66K params)6.9x
Large (660K params)14.3x
XLarge (2.6M params)25.3xSub-linear GPU time scaling with params
CNNSmall (Conv16→32)28.8xConvolution is highly GPU-parallel
Medium (Conv32→64→FC128)42.0xHighest CNN speedup
RNN/LSTM/GRUSmall (H=64)2.2–5.2xGRU benefits most from GPU
Medium (H=128)4.7–15.5x
Large (H=256)12.2–56.4xGRU Large achieves 56.4x — highest overall
TransformerSmall (d=32, h=2)0.5x (slower)GPU overhead dominates at small scale
Medium (d=64, h=4)1.0x (break-even)
Large (d=128, h=8)1.2xModest gain; hybrid CPU/GPU attention
ResNetSmall (W=64, D=2)1.6xDepth amplifies GPU advantage
Medium (W=128, D=4)6.7x
Large (W=256, D=6)9.0xSkip connections add negligible overhead

Key Findings

  • GPU advantage grows with model size. Across all architectures, larger models see dramatically higher GPU speedups as matrix sizes better saturate GPU cores.
  • CNNs and recurrent layers benefit most from GPU. Convolution achieves up to 42x speedup; GRU achieves up to 56.4x — the highest across all benchmarks.
  • Transformers show modest GPU gains at tested scales due to mixed operations (embedding lookups, attention softmax, multiple small projections) and a hybrid CPU/GPU attention path.
  • Eigen (cpu-eigen) consistently outperforms OpenMP (cpu) for all architectures, leveraging SIMD vectorization and cache-optimal memory layouts.
  • Numerical consistency is verified across all backends — all devices converge to equivalent loss and accuracy values.

Average GPU Speedups by Architecture

ArchitectureAvg GPU SpeedupBest GPU SpeedupBest Config
MLP12.1x25.3xXLarge (2.6M params)
CNN35.4x42.0xMedium (Conv32→64→FC128)
Sequence (RNN/LSTM/GRU)13.7x56.4xGRU Large (H=256, seq=50)
Transformer0.9x1.2xLarge (d=128, h=8)
ResNet5.8x9.0xLarge (W=256, D=6)

How to Reproduce

cd build
cmake .. -DCMAKE_BUILD_TYPE=Release -DBUILD_BENCHMARKS=ON
make -j$(nproc)
./benchmarks/mlp_benchmark
./benchmarks/cnn_benchmark
./benchmarks/sequence_benchmark
./benchmarks/transformer_benchmark
./benchmarks/residual_benchmark

See benchmarks/benchmarks.md for full per-epoch results, detailed speedup analysis, and methodology.


Testing

CppNet has 41 unit tests with 377 test cases covering every module:

cd build
cmake .. -DBUILD_TESTS=ON
make -j$(nproc)
ctest --output-on-failure
CategoryTestsTest Cases
Layers (13)Linear, Conv2D, Flatten, MaxPool2D, RNN, Attention, BatchNorm, Dropout, Embedding, GlobalPool, GRU, LSTM, Residual123
Activations (5)ReLU, Sigmoid, Softmax, Tanh, LeakyReLU55
Losses (6)BinaryCrossEntropy, CategoricalCrossEntropy, MSE, MAE, Huber, SoftmaxCrossEntropy52
Optimizers (5)SGD, Adam, Momentum, Adagrad, RMSProp34
Utilities (7)Metrics, Regularizations, Callbacks, DataLoader, ElapsedTime, GradientClip, Init65
GPU Kernels (1)GPU matmul via Linear layer (forward, backward, step, CPU/GPU comparison)7
Other (4)Schedulers, Utils, Models, Visualizations41

Each test validates forward pass, backward pass (gradient shapes & values), parameter updates, and GPU/CPU numerical consistency where applicable.


Project Structure

CppNet/
├── CMakeLists.txt # Top-level build configuration
├── cmake/ # CMake package config templates
├── include/CppNet/ # Public headers
│ ├── CppNet.hpp # Single-include entry point
│ ├── activations/ # ReLU, Sigmoid, Softmax, Tanh, LeakyReLU
│ ├── layers/ # Linear, Conv2D, RNN, LSTM, GRU, Attention, ...
│ ├── losses/ # MSE, MAE, Huber, BCE, CCE, SoftmaxCE
│ ├── optimizers/ # SGD, Adam, Adagrad, Momentum, RMSProp
│ ├── models/ # SequentialModel
│ ├── metrics/ # Accuracy, Precision, Recall, F1
│ ├── regularizations/ # L1, L2, Elastic Net
│ ├── kernels/gpu/ # CUDA kernel declarations
│ ├── utils/ # DataLoader, Init, Schedulers, Serialization, ...
│ └── visualizations/ # TrainingLogger
├── src/CppNet/ # Implementation files (.cpp / .cu)
│ └── kernels/gpu/ # 41 CUDA kernel implementations
├── tests/ # 41 unit tests (377 test cases)
├── examples/ # 8 deep learning examples
├── benchmarks/ # 5 device benchmarks (CPU vs GPU)
└── docs/ # Additional documentation

Roadmap

  • Core layer library (Linear, Conv2D, Pooling, RNN, LSTM, GRU, Attention, BatchNorm, Dropout, Embedding, Residual)
  • Activation functions (ReLU, Sigmoid, Tanh, Softmax, LeakyReLU)
  • Loss functions (MSE, MAE, Huber, BCE, CCE, SoftmaxCE)
  • Optimizers (SGD, Adam, Adagrad, Momentum, RMSProp)
  • DataLoader, LR schedulers, early stopping, gradient clipping
  • Model serialization (save/load)
  • Full CUDA GPU backend — 41 kernels covering all layers, activations, losses, and optimizers
  • OpenMP CPU parallelism
  • Comprehensive test suite (41 tests, 377 test cases)
  • Deep learning examples (MLP, CNN, RNN/LSTM, GRU, Transformer, ResNet, Regularized CNN, Optimizer Comparison)
  • Device benchmarks (MLP, CNN, Sequence, Transformer, ResNet)
  • Add Trainer abstraction with built-in training loop
  • Additional examples (GANs, Reinforcement Learning, NLP pipelines)
  • Python bindings (pybind11)
  • Comprehensive API reference documentation

Contributing

Contributions are welcome! To get started:

  1. Fork the repository and create a feature branch.
  2. Follow the existing coding style — headers in include/CppNet/, implementations in src/CppNet/.
  3. Add tests for new functionality in tests/.
  4. Make sure all tests pass: cd build && ctest --output-on-failure.
  5. Open a pull request with a clear description of your changes.

License

CppNet is released under the MIT License.

Copyright © 2025 Loghman Samani

About

A high-performance C++ deep learning library for building and training neural networks

Resources

Stars

7 stars

Watchers

1 watching

Forks

Releases

Packages

Contributors

Languages

, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Highlight search terms from Google/DuckDuckGo/Bing referrer\n(function() {\n var ref = document.referrer;\n var terms = [];\n \n if (ref.includes('google.com') || ref.includes('duckduckgo.com') || ref.includes('bing.com')) {\n var url = new URL(ref);\n var q = url.searchParams.get('q') || url.searchParams.get('p');\n if (q) {\n terms = q.split(/\\s+/).filter(function(t) { return t.length > 2; });\n }\n }\n \n if (terms.length === 0) return;\n \n var style = document.createElement('style');\n style.textContent = '.userscript-highlight { background: #fbbf24; color: #1a1a2e; padding: 1px 3px; border-radius: 2px; }';\n document.head.appendChild(style);\n \n function highlight(node) {\n if (node.nodeType === 3) { // text node\n var text = node.textContent;\n var found = false;\n terms.forEach(function(term) {\n var regex = new RegExp('(' + term.replace(/[.*+?^${}()|[\\]\\\\]/g, '\\\\') + ')', 'gi');\n if (regex.test(text)) {\n found = true;\n var frag = document.createDocumentFragment();\n var parts = text.split(regex);\n parts.forEach(function(part, i) {\n if (i % 2 === 0) {\n frag.appendChild(document.createTextNode(part));\n } else {\n var span = document.createElement('span');\n span.className = 'userscript-highlight';\n span.textContent = part;\n frag.appendChild(span);\n }\n });\n node.parentNode.replaceChild(frag, node);\n }\n });\n } else if (node.nodeType === 1 && node.childNodes) { // element\n var skipTags = ['SCRIPT', 'STYLE', 'NOSCRIPT', 'TEXTAREA', 'INPUT', 'SELECT'];\n if (!skipTags.includes(node.tagName)) {\n Array.from(node.childNodes).forEach(highlight);\n }\n }\n }\n \n highlight(document.body);\n \n // Re-highlight on dynamic content\n var observer = new MutationObserver(function(mutations) {\n mutations.forEach(function(m) {\n m.addedNodes.forEach(function(node) {\n if (node.nodeType === 1 || node.nodeType === 3) highlight(node);\n });\n });\n });\n observer.observe(document.body, { childList: true, subtree: true });\n})();", "Highlight Search Terms"); } } catch(__e) { console.warn('[Userscript:Highlight Search Terms]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + '
Skip to content

Repository files navigation

CppNet

CppNet Logo

CppNet is a high-performance C++17 deep learning library for building and training neural networks from scratch.
Built on Eigen for fast tensor operations, OpenMP for CPU parallelism, and CUDA for GPU acceleration.

C++17CMakeMIT LicenseCUDAWebsite


Table of Contents


Features

  • High Performance — Vectorized tensor operations via Eigen, multi-threaded with OpenMP, full CUDA GPU backend for all layers, activations, losses, and optimizers.
  • Rich Layer Library — Linear, Conv2D, MaxPool2D, RNN, LSTM, GRU, Multi-Head Attention, Dropout, BatchNorm, Embedding, Residual, GlobalPool, MeanPool1D, Flatten.
  • Multiple Backends — Per-layer compute backend selection: "cpu-eigen" (Eigen contractions), "cpu" (OpenMP loops), "gpu" (CUDA kernels).
  • Complete CUDA Coverage — 41 CUDA kernel files covering all layers, activations, losses, and optimizers for end-to-end GPU training.
  • Modular Architecture — Clean separation of layers, activations, losses, optimizers, metrics, regularizations, and utilities.
  • Training Utilities — DataLoader with batching & shuffling, learning rate schedulers, early stopping callbacks, gradient clipping, model serialization.
  • Visualization — Built-in TrainingLogger for tracking metrics and exporting training history to CSV.
  • Extensible — Abstract base classes for layers, losses, and optimizers make it straightforward to add custom components.
  • Single-Header Access#include <CppNet/CppNet.hpp> brings in the entire library.

Installation

Prerequisites

DependencyVersionRequired
C++ compiler (GCC, Clang, MSVC)C++17 supportYes
CMake≥ 3.18Yes
Eigen3≥ 3.3Yes
OpenMPanyOptional (CPU parallelism)
CUDA ToolkitanyOptional (GPU acceleration)

Build from Source

git clone https://github.com/LoqmanSamani/CppNet.git
cd CppNet
mkdir build &&cd build
cmake .. -DCMAKE_BUILD_TYPE=Release
make -j$(nproc)

Install System-Wide

sudo make install

This installs headers to /usr/local/include/CppNet/ and the static library to /usr/local/lib/.

Use in Your CMake Project

find_package(CppNetREQUIRED)
target_link_libraries(your_targetPRIVATECppNet::CppNet)

Quick Start

A minimal binary classification example:

#include<CppNet/CppNet.hpp>
#include<iostream>intmain() {
// Define layers
CppNet::Layers::Linear layer1(30, 64, "fc1", true, true, "cpu-eigen", "xavier");
CppNet::Layers::Linear layer2(64, 1, "fc2", true, true, "cpu-eigen", "xavier");
CppNet::Activations::ReLU relu("cpu-eigen");
CppNet::Activations::Sigmoid sigmoid;
// Loss & optimizer
CppNet::Losses::BinaryCrossEntropy loss_fn("mean");
CppNet::Optimizers::Adam optimizer;
float lr = 0.001;
// Training loopfor (int epoch = 0; epoch < 100; ++epoch) {
auto h = relu.forward(layer1.forward(X_train));
auto pred = sigmoid.forward(layer2.forward(h));
float loss = loss_fn.forward(pred, Y_train);
auto grad = loss_fn.backward(pred, Y_train);
grad = layer2.backward(sigmoid.backward(grad));
layer1.backward(relu.backward(grad));
layer2.step(optimizer, lr);
layer1.step(optimizer, lr);
std::cout << "Epoch " << epoch << " — Loss: " << loss << std::endl;
}
return0;
}

API Overview

Layers

All layers inherit from CppNet::Layers::Layer and implement forward(), backward(), step(), freeze(), unfreeze(), and print_layer_info().

LayerDescriptionKey Parameters
LinearFully connected layerin_size, out_size, bias, device, weight_init
Conv2D2D convolutionin_channels, out_channels, kernel_size, stride, padding
MaxPool2D2D max poolingkernel_size, stride
FlattenReshape to 2D
RNNVanilla recurrent layerinput_size, hidden_size
LSTMLong Short-Term Memoryinput_size, hidden_size
GRUGated Recurrent Unitinput_size, hidden_size
MultiHeadAttentionScaled dot-product multi-head attentionembed_dim, num_heads
DropoutDropout regularizationdrop_rate
BatchNormBatch normalizationnum_features
EmbeddingEmbedding lookup tablevocab_size, embed_dim
ResidualResidual (skip) connection wrapper
GlobalPoolGlobal average/max pooling
MeanPool1DMean pooling over sequence dimension

Activations

ActivationFunction
ReLU$\max(0, x)$
LeakyReLU$\max(\alpha x, x)$
Sigmoid$\sigma(x) = \frac{1}{1 + e^{-x}}$
Tanh$\tanh(x)$
Softmax$\frac{e^{x_i}}{\sum_j e^{x_j}}$

All activations support both 2D and 4D tensor inputs and run on all three backends (cpu-eigen, cpu, gpu).

Losses

LossTypical Use
MSERegression
MAERegression
HuberRobust regression
BinaryCrossEntropyBinary classification
CategoricalCrossEntropyMulti-class classification
SoftmaxCrossEntropyMulti-class (fused softmax + CE)

All support configurable reduction modes ("mean", "sum") and CUDA GPU acceleration.

Optimizers

OptimizerDescription
SGDStochastic Gradient Descent
AdamAdaptive Moment Estimation (default: $\beta_1=0.9$, $\beta_2=0.999$, $\epsilon=10^{-8}$)
AdagradAdaptive gradient accumulation
MomentumSGD with momentum
RMSPropRoot Mean Square Propagation

All optimizers have dedicated CUDA kernels for GPU-side weight updates.

Metrics

CppNet::Metrics::accuracy(predictions, targets);
CppNet::Metrics::binary_accuracy(predictions, targets, 0.5);
CppNet::Metrics::precision(predictions, targets, 0.5);
CppNet::Metrics::recall(predictions, targets, 0.5);
CppNet::Metrics::f1_score(predictions, targets, 0.5);

Regularizations

CppNet::Regularizations::l1_penalty(weights, lambda);
CppNet::Regularizations::l2_penalty(weights, lambda);
CppNet::Regularizations::elastic_net_penalty(weights, lambda, l1_ratio);
// Corresponding gradient functions: l1_gradient, l2_gradient, elastic_net_gradient

Utilities

UtilityDescription
DataLoaderBatched iteration with shuffling. Supports range-based for loops.
Weight InitXavier (uniform/normal), He (uniform/normal), constant, custom.
Gradient Clippingclip_by_value() and clip_by_norm().
Serializationsave_model() / load_model() for full model persistence; tensor-level binary I/O.
LR SchedulersStepLR, ExponentialLR, CosineAnnealingLR.
CallbacksEarlyStopping with configurable patience, delta, and mode.
Elapsed TimeTraining duration measurement.

DataLoader example:

CppNet::Utils::DataLoader loader(X, Y, /*batch_size=*/32, /*shuffle=*/true);
for (auto& [x_batch, y_batch] : loader) {
// forward / backward / step
}
loader.reset(); // re-shuffle for next epoch

Learning rate scheduler example:

CppNet::Schedulers::CosineAnnealingLR scheduler(/*initial_lr=*/0.01, /*T_max=*/100);
for (int epoch = 0; epoch < 100; ++epoch) {
float lr = scheduler.step();
// ... train with lr
}

Visualization

CppNet::Visualizations::TrainingLogger logger;
// Inside training loop:
logger.log("train_loss", loss);
logger.log("val_accuracy", val_acc);
logger.next_epoch();
// After training:
logger.print_epoch_summary();
logger.export_csv("training_history.csv");

Examples

The examples/ directory contains complete, self-contained deep learning programs that train on synthetic data — no downloads required. Each example generates its own dataset, trains a model, and reports final metrics.

ExampleArchitectureDatasetKey ComponentsResult
mlp_classification.cppLinear→ReLU→Linear→ReLU→Linear3-class spiral (600 samples, 2D)ReLU, SoftmaxCrossEntropy, Adam~75% accuracy
cnn_image_classification.cppConv2D→ReLU→MaxPool2D→Flatten→Linear8×8 stripe images (400 samples)Conv2D, MaxPool2D, SoftmaxCrossEntropy, Adam100% accuracy
rnn_sequence_prediction.cppLSTM(1,16)→Linear(16,1)Sine-wave sequences (400 samples)LSTM, MSE, AdamMSE ≈ 0.00001
gru_sequence_prediction.cppGRU(1,16)→Linear(16,1)Sine-wave sequences (400 samples)GRU, MAE, MomentumMAE ≈ 0.010
transformer_classifier.cppEmbedding→Attention+skip→ReLU→LinearToken sequences (400 samples)Embedding, MultiHeadAttention, MeanPool1D100% accuracy
resnet_classifier.cppLinear→ReLU→ResBlock(32)→Linear→SigmoidConcentric circles (600 samples)Residual, GradientClip, He init~99% accuracy
regularized_cnn.cppConv2D→LeakyReLU→Pool→BN→Dropout→FC8×8 pattern images (600 samples, 3 classes)BatchNorm, Dropout, LeakyReLU, CategoricalCrossEntropy, Adagrad100% accuracy
optimizer_comparison.cppLinear→Tanh→Linear→Tanh→LinearRegression: y = sin(x₀)·cos(x₁) (500 samples)SGD, Momentum, Adagrad, RMSProp, Adam, Tanh, Huberloss ≈ 0.002

Build and run:

cd build
cmake .. -DCMAKE_BUILD_TYPE=Release -DBUILD_EXAMPLES=ON
make -j$(nproc)
./examples/mlp_classification
./examples/cnn_image_classification
./examples/rnn_sequence_prediction
./examples/gru_sequence_prediction
./examples/transformer_classifier
./examples/resnet_classifier
./examples/regularized_cnn
./examples/optimizer_comparison

GPU Acceleration

CppNet provides full CUDA GPU support across all layers, activations, losses, and optimizers. When CUDA is detected at build time, layers can target the GPU backend:

CppNet::Layers::Linear layer(784, 256, "fc1", true, true, "gpu", "xavier");

CUDA Kernel Coverage (41 kernels)

CategoryCUDA Kernels
Linear algebramatmul, matmul_grad_input, matmul_grad_weight, add_bias, bias_grad, elementwise
Convolutionconv2d_forward, conv2d_backward, maxpool2d_forward, maxpool2d_backward
Recurrentrnn_cell, lstm_cell, gru_cell
Attentionattention_scores (scale, softmax, backward), embedding_forward, embedding_backward
Normalizationbatch_norm_forward, batch_norm_backward, dropout
Poolingglobal_avg_pool2d, global_max_pool2d, mean_pool1d
Activationsrelu, relu_grad, leaky_relu, leaky_relu_grad, sigmoid, sigmoid_grad, tanh_activation, tanh_activation_grad
Lossesmse, mae, huber, bce, categorical_ce, softmax_ce
Optimizerssgd_step, momentum_step, adagrad_step, rmsprop_step, adam_step

To force a CPU-only build even when CUDA is present:

cmake .. -DCUDAToolkit_ROOT=/nonexistent

Benchmarks

Five benchmarks compare three compute backends — cpu-eigen (Eigen SIMD contractions), cpu (OpenMP loops), and gpu (CUDA kernels) — across different architectures and model sizes. All benchmarks are reproducible via the scripts in the benchmarks/ directory.

Summary of GPU Speedups

ArchitectureModel SizeGPU Speedup vs cpu-eigenKey Observation
MLPSmall (4.5K params)2.0xGPU overhead limits gains for small matmuls
Medium (66K params)6.9x
Large (660K params)14.3x
XLarge (2.6M params)25.3xSub-linear GPU time scaling with params
CNNSmall (Conv16→32)28.8xConvolution is highly GPU-parallel
Medium (Conv32→64→FC128)42.0xHighest CNN speedup
RNN/LSTM/GRUSmall (H=64)2.2–5.2xGRU benefits most from GPU
Medium (H=128)4.7–15.5x
Large (H=256)12.2–56.4xGRU Large achieves 56.4x — highest overall
TransformerSmall (d=32, h=2)0.5x (slower)GPU overhead dominates at small scale
Medium (d=64, h=4)1.0x (break-even)
Large (d=128, h=8)1.2xModest gain; hybrid CPU/GPU attention
ResNetSmall (W=64, D=2)1.6xDepth amplifies GPU advantage
Medium (W=128, D=4)6.7x
Large (W=256, D=6)9.0xSkip connections add negligible overhead

Key Findings

  • GPU advantage grows with model size. Across all architectures, larger models see dramatically higher GPU speedups as matrix sizes better saturate GPU cores.
  • CNNs and recurrent layers benefit most from GPU. Convolution achieves up to 42x speedup; GRU achieves up to 56.4x — the highest across all benchmarks.
  • Transformers show modest GPU gains at tested scales due to mixed operations (embedding lookups, attention softmax, multiple small projections) and a hybrid CPU/GPU attention path.
  • Eigen (cpu-eigen) consistently outperforms OpenMP (cpu) for all architectures, leveraging SIMD vectorization and cache-optimal memory layouts.
  • Numerical consistency is verified across all backends — all devices converge to equivalent loss and accuracy values.

Average GPU Speedups by Architecture

ArchitectureAvg GPU SpeedupBest GPU SpeedupBest Config
MLP12.1x25.3xXLarge (2.6M params)
CNN35.4x42.0xMedium (Conv32→64→FC128)
Sequence (RNN/LSTM/GRU)13.7x56.4xGRU Large (H=256, seq=50)
Transformer0.9x1.2xLarge (d=128, h=8)
ResNet5.8x9.0xLarge (W=256, D=6)

How to Reproduce

cd build
cmake .. -DCMAKE_BUILD_TYPE=Release -DBUILD_BENCHMARKS=ON
make -j$(nproc)
./benchmarks/mlp_benchmark
./benchmarks/cnn_benchmark
./benchmarks/sequence_benchmark
./benchmarks/transformer_benchmark
./benchmarks/residual_benchmark

See benchmarks/benchmarks.md for full per-epoch results, detailed speedup analysis, and methodology.


Testing

CppNet has 41 unit tests with 377 test cases covering every module:

cd build
cmake .. -DBUILD_TESTS=ON
make -j$(nproc)
ctest --output-on-failure
CategoryTestsTest Cases
Layers (13)Linear, Conv2D, Flatten, MaxPool2D, RNN, Attention, BatchNorm, Dropout, Embedding, GlobalPool, GRU, LSTM, Residual123
Activations (5)ReLU, Sigmoid, Softmax, Tanh, LeakyReLU55
Losses (6)BinaryCrossEntropy, CategoricalCrossEntropy, MSE, MAE, Huber, SoftmaxCrossEntropy52
Optimizers (5)SGD, Adam, Momentum, Adagrad, RMSProp34
Utilities (7)Metrics, Regularizations, Callbacks, DataLoader, ElapsedTime, GradientClip, Init65
GPU Kernels (1)GPU matmul via Linear layer (forward, backward, step, CPU/GPU comparison)7
Other (4)Schedulers, Utils, Models, Visualizations41

Each test validates forward pass, backward pass (gradient shapes & values), parameter updates, and GPU/CPU numerical consistency where applicable.


Project Structure

CppNet/
├── CMakeLists.txt # Top-level build configuration
├── cmake/ # CMake package config templates
├── include/CppNet/ # Public headers
│ ├── CppNet.hpp # Single-include entry point
│ ├── activations/ # ReLU, Sigmoid, Softmax, Tanh, LeakyReLU
│ ├── layers/ # Linear, Conv2D, RNN, LSTM, GRU, Attention, ...
│ ├── losses/ # MSE, MAE, Huber, BCE, CCE, SoftmaxCE
│ ├── optimizers/ # SGD, Adam, Adagrad, Momentum, RMSProp
│ ├── models/ # SequentialModel
│ ├── metrics/ # Accuracy, Precision, Recall, F1
│ ├── regularizations/ # L1, L2, Elastic Net
│ ├── kernels/gpu/ # CUDA kernel declarations
│ ├── utils/ # DataLoader, Init, Schedulers, Serialization, ...
│ └── visualizations/ # TrainingLogger
├── src/CppNet/ # Implementation files (.cpp / .cu)
│ └── kernels/gpu/ # 41 CUDA kernel implementations
├── tests/ # 41 unit tests (377 test cases)
├── examples/ # 8 deep learning examples
├── benchmarks/ # 5 device benchmarks (CPU vs GPU)
└── docs/ # Additional documentation

Roadmap

  • Core layer library (Linear, Conv2D, Pooling, RNN, LSTM, GRU, Attention, BatchNorm, Dropout, Embedding, Residual)
  • Activation functions (ReLU, Sigmoid, Tanh, Softmax, LeakyReLU)
  • Loss functions (MSE, MAE, Huber, BCE, CCE, SoftmaxCE)
  • Optimizers (SGD, Adam, Adagrad, Momentum, RMSProp)
  • DataLoader, LR schedulers, early stopping, gradient clipping
  • Model serialization (save/load)
  • Full CUDA GPU backend — 41 kernels covering all layers, activations, losses, and optimizers
  • OpenMP CPU parallelism
  • Comprehensive test suite (41 tests, 377 test cases)
  • Deep learning examples (MLP, CNN, RNN/LSTM, GRU, Transformer, ResNet, Regularized CNN, Optimizer Comparison)
  • Device benchmarks (MLP, CNN, Sequence, Transformer, ResNet)
  • Add Trainer abstraction with built-in training loop
  • Additional examples (GANs, Reinforcement Learning, NLP pipelines)
  • Python bindings (pybind11)
  • Comprehensive API reference documentation

Contributing

Contributions are welcome! To get started:

  1. Fork the repository and create a feature branch.
  2. Follow the existing coding style — headers in include/CppNet/, implementations in src/CppNet/.
  3. Add tests for new functionality in tests/.
  4. Make sure all tests pass: cd build && ctest --output-on-failure.
  5. Open a pull request with a clear description of your changes.

License

CppNet is released under the MIT License.

Copyright © 2025 Loghman Samani

About

A high-performance C++ deep learning library for building and training neural networks

Resources

Stars

7 stars

Watchers

1 watching

Forks

Releases

Packages

Contributors

Languages

, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Strip utm_, fbclid, gclid, etc. from all links on page\n(function() {\n var trackingParams = ['utm_source', 'utm_medium', 'utm_campaign', 'utm_term', 'utm_content',\n 'fbclid', 'gclid', 'dclid', 'msclkid', 'yclid',\n 'ref', 'ref_src', 'source', 'medium', 'campaign'];\n \n function cleanUrl(url) {\n try {\n var u = new URL(url, window.location.origin);\n var changed = false;\n trackingParams.forEach(function(p) {\n if (u.searchParams.has(p)) {\n u.searchParams.delete(p);\n changed = true;\n }\n });\n return changed ? u.toString() : url;\n } catch (e) {\n return url;\n }\n }\n \n function cleanLinks() {\n document.querySelectorAll('a[href]').forEach(function(a) {\n var clean = cleanUrl(a.href);\n if (clean !== a.href) a.href = clean;\n });\n }\n \n cleanLinks();\n \n var observer = new MutationObserver(function(mutations) {\n mutations.forEach(function(m) {\n m.addedNodes.forEach(function(node) {\n if (node.nodeType === 1) {\n if (node.tagName === 'A') cleanLinks();\n node.querySelectorAll('a[href]').forEach(function(a) {\n var clean = cleanUrl(a.href);\n if (clean !== a.href) a.href = clean;\n });\n }\n });\n });\n });\n observer.observe(document.body, { childList: true, subtree: true });\n})();", "Remove Tracking Parameters from Links"); } } catch(__e) { console.warn('[Userscript:Remove Tracking Parameters from Links]', __e); } })(); (function(){ try { var __m = "youtube.com"; var __re = new RegExp('^' + "youtube\\.com" + '
Skip to content

Repository files navigation

CppNet

CppNet Logo

CppNet is a high-performance C++17 deep learning library for building and training neural networks from scratch.
Built on Eigen for fast tensor operations, OpenMP for CPU parallelism, and CUDA for GPU acceleration.

C++17CMakeMIT LicenseCUDAWebsite


Table of Contents


Features

  • High Performance — Vectorized tensor operations via Eigen, multi-threaded with OpenMP, full CUDA GPU backend for all layers, activations, losses, and optimizers.
  • Rich Layer Library — Linear, Conv2D, MaxPool2D, RNN, LSTM, GRU, Multi-Head Attention, Dropout, BatchNorm, Embedding, Residual, GlobalPool, MeanPool1D, Flatten.
  • Multiple Backends — Per-layer compute backend selection: "cpu-eigen" (Eigen contractions), "cpu" (OpenMP loops), "gpu" (CUDA kernels).
  • Complete CUDA Coverage — 41 CUDA kernel files covering all layers, activations, losses, and optimizers for end-to-end GPU training.
  • Modular Architecture — Clean separation of layers, activations, losses, optimizers, metrics, regularizations, and utilities.
  • Training Utilities — DataLoader with batching & shuffling, learning rate schedulers, early stopping callbacks, gradient clipping, model serialization.
  • Visualization — Built-in TrainingLogger for tracking metrics and exporting training history to CSV.
  • Extensible — Abstract base classes for layers, losses, and optimizers make it straightforward to add custom components.
  • Single-Header Access#include <CppNet/CppNet.hpp> brings in the entire library.

Installation

Prerequisites

DependencyVersionRequired
C++ compiler (GCC, Clang, MSVC)C++17 supportYes
CMake≥ 3.18Yes
Eigen3≥ 3.3Yes
OpenMPanyOptional (CPU parallelism)
CUDA ToolkitanyOptional (GPU acceleration)

Build from Source

git clone https://github.com/LoqmanSamani/CppNet.git
cd CppNet
mkdir build &&cd build
cmake .. -DCMAKE_BUILD_TYPE=Release
make -j$(nproc)

Install System-Wide

sudo make install

This installs headers to /usr/local/include/CppNet/ and the static library to /usr/local/lib/.

Use in Your CMake Project

find_package(CppNetREQUIRED)
target_link_libraries(your_targetPRIVATECppNet::CppNet)

Quick Start

A minimal binary classification example:

#include<CppNet/CppNet.hpp>
#include<iostream>intmain() {
// Define layers
CppNet::Layers::Linear layer1(30, 64, "fc1", true, true, "cpu-eigen", "xavier");
CppNet::Layers::Linear layer2(64, 1, "fc2", true, true, "cpu-eigen", "xavier");
CppNet::Activations::ReLU relu("cpu-eigen");
CppNet::Activations::Sigmoid sigmoid;
// Loss & optimizer
CppNet::Losses::BinaryCrossEntropy loss_fn("mean");
CppNet::Optimizers::Adam optimizer;
float lr = 0.001;
// Training loopfor (int epoch = 0; epoch < 100; ++epoch) {
auto h = relu.forward(layer1.forward(X_train));
auto pred = sigmoid.forward(layer2.forward(h));
float loss = loss_fn.forward(pred, Y_train);
auto grad = loss_fn.backward(pred, Y_train);
grad = layer2.backward(sigmoid.backward(grad));
layer1.backward(relu.backward(grad));
layer2.step(optimizer, lr);
layer1.step(optimizer, lr);
std::cout << "Epoch " << epoch << " — Loss: " << loss << std::endl;
}
return0;
}

API Overview

Layers

All layers inherit from CppNet::Layers::Layer and implement forward(), backward(), step(), freeze(), unfreeze(), and print_layer_info().

LayerDescriptionKey Parameters
LinearFully connected layerin_size, out_size, bias, device, weight_init
Conv2D2D convolutionin_channels, out_channels, kernel_size, stride, padding
MaxPool2D2D max poolingkernel_size, stride
FlattenReshape to 2D
RNNVanilla recurrent layerinput_size, hidden_size
LSTMLong Short-Term Memoryinput_size, hidden_size
GRUGated Recurrent Unitinput_size, hidden_size
MultiHeadAttentionScaled dot-product multi-head attentionembed_dim, num_heads
DropoutDropout regularizationdrop_rate
BatchNormBatch normalizationnum_features
EmbeddingEmbedding lookup tablevocab_size, embed_dim
ResidualResidual (skip) connection wrapper
GlobalPoolGlobal average/max pooling
MeanPool1DMean pooling over sequence dimension

Activations

ActivationFunction
ReLU$\max(0, x)$
LeakyReLU$\max(\alpha x, x)$
Sigmoid$\sigma(x) = \frac{1}{1 + e^{-x}}$
Tanh$\tanh(x)$
Softmax$\frac{e^{x_i}}{\sum_j e^{x_j}}$

All activations support both 2D and 4D tensor inputs and run on all three backends (cpu-eigen, cpu, gpu).

Losses

LossTypical Use
MSERegression
MAERegression
HuberRobust regression
BinaryCrossEntropyBinary classification
CategoricalCrossEntropyMulti-class classification
SoftmaxCrossEntropyMulti-class (fused softmax + CE)

All support configurable reduction modes ("mean", "sum") and CUDA GPU acceleration.

Optimizers

OptimizerDescription
SGDStochastic Gradient Descent
AdamAdaptive Moment Estimation (default: $\beta_1=0.9$, $\beta_2=0.999$, $\epsilon=10^{-8}$)
AdagradAdaptive gradient accumulation
MomentumSGD with momentum
RMSPropRoot Mean Square Propagation

All optimizers have dedicated CUDA kernels for GPU-side weight updates.

Metrics

CppNet::Metrics::accuracy(predictions, targets);
CppNet::Metrics::binary_accuracy(predictions, targets, 0.5);
CppNet::Metrics::precision(predictions, targets, 0.5);
CppNet::Metrics::recall(predictions, targets, 0.5);
CppNet::Metrics::f1_score(predictions, targets, 0.5);

Regularizations

CppNet::Regularizations::l1_penalty(weights, lambda);
CppNet::Regularizations::l2_penalty(weights, lambda);
CppNet::Regularizations::elastic_net_penalty(weights, lambda, l1_ratio);
// Corresponding gradient functions: l1_gradient, l2_gradient, elastic_net_gradient

Utilities

UtilityDescription
DataLoaderBatched iteration with shuffling. Supports range-based for loops.
Weight InitXavier (uniform/normal), He (uniform/normal), constant, custom.
Gradient Clippingclip_by_value() and clip_by_norm().
Serializationsave_model() / load_model() for full model persistence; tensor-level binary I/O.
LR SchedulersStepLR, ExponentialLR, CosineAnnealingLR.
CallbacksEarlyStopping with configurable patience, delta, and mode.
Elapsed TimeTraining duration measurement.

DataLoader example:

CppNet::Utils::DataLoader loader(X, Y, /*batch_size=*/32, /*shuffle=*/true);
for (auto& [x_batch, y_batch] : loader) {
// forward / backward / step
}
loader.reset(); // re-shuffle for next epoch

Learning rate scheduler example:

CppNet::Schedulers::CosineAnnealingLR scheduler(/*initial_lr=*/0.01, /*T_max=*/100);
for (int epoch = 0; epoch < 100; ++epoch) {
float lr = scheduler.step();
// ... train with lr
}

Visualization

CppNet::Visualizations::TrainingLogger logger;
// Inside training loop:
logger.log("train_loss", loss);
logger.log("val_accuracy", val_acc);
logger.next_epoch();
// After training:
logger.print_epoch_summary();
logger.export_csv("training_history.csv");

Examples

The examples/ directory contains complete, self-contained deep learning programs that train on synthetic data — no downloads required. Each example generates its own dataset, trains a model, and reports final metrics.

ExampleArchitectureDatasetKey ComponentsResult
mlp_classification.cppLinear→ReLU→Linear→ReLU→Linear3-class spiral (600 samples, 2D)ReLU, SoftmaxCrossEntropy, Adam~75% accuracy
cnn_image_classification.cppConv2D→ReLU→MaxPool2D→Flatten→Linear8×8 stripe images (400 samples)Conv2D, MaxPool2D, SoftmaxCrossEntropy, Adam100% accuracy
rnn_sequence_prediction.cppLSTM(1,16)→Linear(16,1)Sine-wave sequences (400 samples)LSTM, MSE, AdamMSE ≈ 0.00001
gru_sequence_prediction.cppGRU(1,16)→Linear(16,1)Sine-wave sequences (400 samples)GRU, MAE, MomentumMAE ≈ 0.010
transformer_classifier.cppEmbedding→Attention+skip→ReLU→LinearToken sequences (400 samples)Embedding, MultiHeadAttention, MeanPool1D100% accuracy
resnet_classifier.cppLinear→ReLU→ResBlock(32)→Linear→SigmoidConcentric circles (600 samples)Residual, GradientClip, He init~99% accuracy
regularized_cnn.cppConv2D→LeakyReLU→Pool→BN→Dropout→FC8×8 pattern images (600 samples, 3 classes)BatchNorm, Dropout, LeakyReLU, CategoricalCrossEntropy, Adagrad100% accuracy
optimizer_comparison.cppLinear→Tanh→Linear→Tanh→LinearRegression: y = sin(x₀)·cos(x₁) (500 samples)SGD, Momentum, Adagrad, RMSProp, Adam, Tanh, Huberloss ≈ 0.002

Build and run:

cd build
cmake .. -DCMAKE_BUILD_TYPE=Release -DBUILD_EXAMPLES=ON
make -j$(nproc)
./examples/mlp_classification
./examples/cnn_image_classification
./examples/rnn_sequence_prediction
./examples/gru_sequence_prediction
./examples/transformer_classifier
./examples/resnet_classifier
./examples/regularized_cnn
./examples/optimizer_comparison

GPU Acceleration

CppNet provides full CUDA GPU support across all layers, activations, losses, and optimizers. When CUDA is detected at build time, layers can target the GPU backend:

CppNet::Layers::Linear layer(784, 256, "fc1", true, true, "gpu", "xavier");

CUDA Kernel Coverage (41 kernels)

CategoryCUDA Kernels
Linear algebramatmul, matmul_grad_input, matmul_grad_weight, add_bias, bias_grad, elementwise
Convolutionconv2d_forward, conv2d_backward, maxpool2d_forward, maxpool2d_backward
Recurrentrnn_cell, lstm_cell, gru_cell
Attentionattention_scores (scale, softmax, backward), embedding_forward, embedding_backward
Normalizationbatch_norm_forward, batch_norm_backward, dropout
Poolingglobal_avg_pool2d, global_max_pool2d, mean_pool1d
Activationsrelu, relu_grad, leaky_relu, leaky_relu_grad, sigmoid, sigmoid_grad, tanh_activation, tanh_activation_grad
Lossesmse, mae, huber, bce, categorical_ce, softmax_ce
Optimizerssgd_step, momentum_step, adagrad_step, rmsprop_step, adam_step

To force a CPU-only build even when CUDA is present:

cmake .. -DCUDAToolkit_ROOT=/nonexistent

Benchmarks

Five benchmarks compare three compute backends — cpu-eigen (Eigen SIMD contractions), cpu (OpenMP loops), and gpu (CUDA kernels) — across different architectures and model sizes. All benchmarks are reproducible via the scripts in the benchmarks/ directory.

Summary of GPU Speedups

ArchitectureModel SizeGPU Speedup vs cpu-eigenKey Observation
MLPSmall (4.5K params)2.0xGPU overhead limits gains for small matmuls
Medium (66K params)6.9x
Large (660K params)14.3x
XLarge (2.6M params)25.3xSub-linear GPU time scaling with params
CNNSmall (Conv16→32)28.8xConvolution is highly GPU-parallel
Medium (Conv32→64→FC128)42.0xHighest CNN speedup
RNN/LSTM/GRUSmall (H=64)2.2–5.2xGRU benefits most from GPU
Medium (H=128)4.7–15.5x
Large (H=256)12.2–56.4xGRU Large achieves 56.4x — highest overall
TransformerSmall (d=32, h=2)0.5x (slower)GPU overhead dominates at small scale
Medium (d=64, h=4)1.0x (break-even)
Large (d=128, h=8)1.2xModest gain; hybrid CPU/GPU attention
ResNetSmall (W=64, D=2)1.6xDepth amplifies GPU advantage
Medium (W=128, D=4)6.7x
Large (W=256, D=6)9.0xSkip connections add negligible overhead

Key Findings

  • GPU advantage grows with model size. Across all architectures, larger models see dramatically higher GPU speedups as matrix sizes better saturate GPU cores.
  • CNNs and recurrent layers benefit most from GPU. Convolution achieves up to 42x speedup; GRU achieves up to 56.4x — the highest across all benchmarks.
  • Transformers show modest GPU gains at tested scales due to mixed operations (embedding lookups, attention softmax, multiple small projections) and a hybrid CPU/GPU attention path.
  • Eigen (cpu-eigen) consistently outperforms OpenMP (cpu) for all architectures, leveraging SIMD vectorization and cache-optimal memory layouts.
  • Numerical consistency is verified across all backends — all devices converge to equivalent loss and accuracy values.

Average GPU Speedups by Architecture

ArchitectureAvg GPU SpeedupBest GPU SpeedupBest Config
MLP12.1x25.3xXLarge (2.6M params)
CNN35.4x42.0xMedium (Conv32→64→FC128)
Sequence (RNN/LSTM/GRU)13.7x56.4xGRU Large (H=256, seq=50)
Transformer0.9x1.2xLarge (d=128, h=8)
ResNet5.8x9.0xLarge (W=256, D=6)

How to Reproduce

cd build
cmake .. -DCMAKE_BUILD_TYPE=Release -DBUILD_BENCHMARKS=ON
make -j$(nproc)
./benchmarks/mlp_benchmark
./benchmarks/cnn_benchmark
./benchmarks/sequence_benchmark
./benchmarks/transformer_benchmark
./benchmarks/residual_benchmark

See benchmarks/benchmarks.md for full per-epoch results, detailed speedup analysis, and methodology.


Testing

CppNet has 41 unit tests with 377 test cases covering every module:

cd build
cmake .. -DBUILD_TESTS=ON
make -j$(nproc)
ctest --output-on-failure
CategoryTestsTest Cases
Layers (13)Linear, Conv2D, Flatten, MaxPool2D, RNN, Attention, BatchNorm, Dropout, Embedding, GlobalPool, GRU, LSTM, Residual123
Activations (5)ReLU, Sigmoid, Softmax, Tanh, LeakyReLU55
Losses (6)BinaryCrossEntropy, CategoricalCrossEntropy, MSE, MAE, Huber, SoftmaxCrossEntropy52
Optimizers (5)SGD, Adam, Momentum, Adagrad, RMSProp34
Utilities (7)Metrics, Regularizations, Callbacks, DataLoader, ElapsedTime, GradientClip, Init65
GPU Kernels (1)GPU matmul via Linear layer (forward, backward, step, CPU/GPU comparison)7
Other (4)Schedulers, Utils, Models, Visualizations41

Each test validates forward pass, backward pass (gradient shapes & values), parameter updates, and GPU/CPU numerical consistency where applicable.


Project Structure

CppNet/
├── CMakeLists.txt # Top-level build configuration
├── cmake/ # CMake package config templates
├── include/CppNet/ # Public headers
│ ├── CppNet.hpp # Single-include entry point
│ ├── activations/ # ReLU, Sigmoid, Softmax, Tanh, LeakyReLU
│ ├── layers/ # Linear, Conv2D, RNN, LSTM, GRU, Attention, ...
│ ├── losses/ # MSE, MAE, Huber, BCE, CCE, SoftmaxCE
│ ├── optimizers/ # SGD, Adam, Adagrad, Momentum, RMSProp
│ ├── models/ # SequentialModel
│ ├── metrics/ # Accuracy, Precision, Recall, F1
│ ├── regularizations/ # L1, L2, Elastic Net
│ ├── kernels/gpu/ # CUDA kernel declarations
│ ├── utils/ # DataLoader, Init, Schedulers, Serialization, ...
│ └── visualizations/ # TrainingLogger
├── src/CppNet/ # Implementation files (.cpp / .cu)
│ └── kernels/gpu/ # 41 CUDA kernel implementations
├── tests/ # 41 unit tests (377 test cases)
├── examples/ # 8 deep learning examples
├── benchmarks/ # 5 device benchmarks (CPU vs GPU)
└── docs/ # Additional documentation

Roadmap

  • Core layer library (Linear, Conv2D, Pooling, RNN, LSTM, GRU, Attention, BatchNorm, Dropout, Embedding, Residual)
  • Activation functions (ReLU, Sigmoid, Tanh, Softmax, LeakyReLU)
  • Loss functions (MSE, MAE, Huber, BCE, CCE, SoftmaxCE)
  • Optimizers (SGD, Adam, Adagrad, Momentum, RMSProp)
  • DataLoader, LR schedulers, early stopping, gradient clipping
  • Model serialization (save/load)
  • Full CUDA GPU backend — 41 kernels covering all layers, activations, losses, and optimizers
  • OpenMP CPU parallelism
  • Comprehensive test suite (41 tests, 377 test cases)
  • Deep learning examples (MLP, CNN, RNN/LSTM, GRU, Transformer, ResNet, Regularized CNN, Optimizer Comparison)
  • Device benchmarks (MLP, CNN, Sequence, Transformer, ResNet)
  • Add Trainer abstraction with built-in training loop
  • Additional examples (GANs, Reinforcement Learning, NLP pipelines)
  • Python bindings (pybind11)
  • Comprehensive API reference documentation

Contributing

Contributions are welcome! To get started:

  1. Fork the repository and create a feature branch.
  2. Follow the existing coding style — headers in include/CppNet/, implementations in src/CppNet/.
  3. Add tests for new functionality in tests/.
  4. Make sure all tests pass: cd build && ctest --output-on-failure.
  5. Open a pull request with a clear description of your changes.

License

CppNet is released under the MIT License.

Copyright © 2025 Loghman Samani

About

A high-performance C++ deep learning library for building and training neural networks

Resources

Stars

7 stars

Watchers

1 watching

Forks

Releases

Packages

Contributors

Languages

, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Auto-enable theater mode on YouTube\n(function() {\n function tryTheater() {\n var btn = document.querySelector('button[aria-label=\"Theater mode\"], ytd-player #player button[title=\"Theater mode\"]');\n if (btn && !btn.classList.contains('activated')) {\n btn.click();\n }\n }\n \n // Try immediately\n tryTheater();\n \n // Try after navigation (SPA)\n var lastUrl = location.href;\n setInterval(function() {\n if (location.href !== lastUrl) {\n lastUrl = location.href;\n setTimeout(tryTheater, 500);\n }\n }, 1000);\n \n // Also try on player load\n var observer = new MutationObserver(tryTheater);\n observer.observe(document.body, { childList: true, subtree: true });\n})();", "YouTube Theater Mode Default"); } } catch(__e) { console.warn('[Userscript:YouTube Theater Mode Default]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + '
Skip to content

Repository files navigation

CppNet

CppNet Logo

CppNet is a high-performance C++17 deep learning library for building and training neural networks from scratch.
Built on Eigen for fast tensor operations, OpenMP for CPU parallelism, and CUDA for GPU acceleration.

C++17CMakeMIT LicenseCUDAWebsite


Table of Contents


Features

  • High Performance — Vectorized tensor operations via Eigen, multi-threaded with OpenMP, full CUDA GPU backend for all layers, activations, losses, and optimizers.
  • Rich Layer Library — Linear, Conv2D, MaxPool2D, RNN, LSTM, GRU, Multi-Head Attention, Dropout, BatchNorm, Embedding, Residual, GlobalPool, MeanPool1D, Flatten.
  • Multiple Backends — Per-layer compute backend selection: "cpu-eigen" (Eigen contractions), "cpu" (OpenMP loops), "gpu" (CUDA kernels).
  • Complete CUDA Coverage — 41 CUDA kernel files covering all layers, activations, losses, and optimizers for end-to-end GPU training.
  • Modular Architecture — Clean separation of layers, activations, losses, optimizers, metrics, regularizations, and utilities.
  • Training Utilities — DataLoader with batching & shuffling, learning rate schedulers, early stopping callbacks, gradient clipping, model serialization.
  • Visualization — Built-in TrainingLogger for tracking metrics and exporting training history to CSV.
  • Extensible — Abstract base classes for layers, losses, and optimizers make it straightforward to add custom components.
  • Single-Header Access#include <CppNet/CppNet.hpp> brings in the entire library.

Installation

Prerequisites

DependencyVersionRequired
C++ compiler (GCC, Clang, MSVC)C++17 supportYes
CMake≥ 3.18Yes
Eigen3≥ 3.3Yes
OpenMPanyOptional (CPU parallelism)
CUDA ToolkitanyOptional (GPU acceleration)

Build from Source

git clone https://github.com/LoqmanSamani/CppNet.git
cd CppNet
mkdir build &&cd build
cmake .. -DCMAKE_BUILD_TYPE=Release
make -j$(nproc)

Install System-Wide

sudo make install

This installs headers to /usr/local/include/CppNet/ and the static library to /usr/local/lib/.

Use in Your CMake Project

find_package(CppNetREQUIRED)
target_link_libraries(your_targetPRIVATECppNet::CppNet)

Quick Start

A minimal binary classification example:

#include<CppNet/CppNet.hpp>
#include<iostream>intmain() {
// Define layers
CppNet::Layers::Linear layer1(30, 64, "fc1", true, true, "cpu-eigen", "xavier");
CppNet::Layers::Linear layer2(64, 1, "fc2", true, true, "cpu-eigen", "xavier");
CppNet::Activations::ReLU relu("cpu-eigen");
CppNet::Activations::Sigmoid sigmoid;
// Loss & optimizer
CppNet::Losses::BinaryCrossEntropy loss_fn("mean");
CppNet::Optimizers::Adam optimizer;
float lr = 0.001;
// Training loopfor (int epoch = 0; epoch < 100; ++epoch) {
auto h = relu.forward(layer1.forward(X_train));
auto pred = sigmoid.forward(layer2.forward(h));
float loss = loss_fn.forward(pred, Y_train);
auto grad = loss_fn.backward(pred, Y_train);
grad = layer2.backward(sigmoid.backward(grad));
layer1.backward(relu.backward(grad));
layer2.step(optimizer, lr);
layer1.step(optimizer, lr);
std::cout << "Epoch " << epoch << " — Loss: " << loss << std::endl;
}
return0;
}

API Overview

Layers

All layers inherit from CppNet::Layers::Layer and implement forward(), backward(), step(), freeze(), unfreeze(), and print_layer_info().

LayerDescriptionKey Parameters
LinearFully connected layerin_size, out_size, bias, device, weight_init
Conv2D2D convolutionin_channels, out_channels, kernel_size, stride, padding
MaxPool2D2D max poolingkernel_size, stride
FlattenReshape to 2D
RNNVanilla recurrent layerinput_size, hidden_size
LSTMLong Short-Term Memoryinput_size, hidden_size
GRUGated Recurrent Unitinput_size, hidden_size
MultiHeadAttentionScaled dot-product multi-head attentionembed_dim, num_heads
DropoutDropout regularizationdrop_rate
BatchNormBatch normalizationnum_features
EmbeddingEmbedding lookup tablevocab_size, embed_dim
ResidualResidual (skip) connection wrapper
GlobalPoolGlobal average/max pooling
MeanPool1DMean pooling over sequence dimension

Activations

ActivationFunction
ReLU$\max(0, x)$
LeakyReLU$\max(\alpha x, x)$
Sigmoid$\sigma(x) = \frac{1}{1 + e^{-x}}$
Tanh$\tanh(x)$
Softmax$\frac{e^{x_i}}{\sum_j e^{x_j}}$

All activations support both 2D and 4D tensor inputs and run on all three backends (cpu-eigen, cpu, gpu).

Losses

LossTypical Use
MSERegression
MAERegression
HuberRobust regression
BinaryCrossEntropyBinary classification
CategoricalCrossEntropyMulti-class classification
SoftmaxCrossEntropyMulti-class (fused softmax + CE)

All support configurable reduction modes ("mean", "sum") and CUDA GPU acceleration.

Optimizers

OptimizerDescription
SGDStochastic Gradient Descent
AdamAdaptive Moment Estimation (default: $\beta_1=0.9$, $\beta_2=0.999$, $\epsilon=10^{-8}$)
AdagradAdaptive gradient accumulation
MomentumSGD with momentum
RMSPropRoot Mean Square Propagation

All optimizers have dedicated CUDA kernels for GPU-side weight updates.

Metrics

CppNet::Metrics::accuracy(predictions, targets);
CppNet::Metrics::binary_accuracy(predictions, targets, 0.5);
CppNet::Metrics::precision(predictions, targets, 0.5);
CppNet::Metrics::recall(predictions, targets, 0.5);
CppNet::Metrics::f1_score(predictions, targets, 0.5);

Regularizations

CppNet::Regularizations::l1_penalty(weights, lambda);
CppNet::Regularizations::l2_penalty(weights, lambda);
CppNet::Regularizations::elastic_net_penalty(weights, lambda, l1_ratio);
// Corresponding gradient functions: l1_gradient, l2_gradient, elastic_net_gradient

Utilities

UtilityDescription
DataLoaderBatched iteration with shuffling. Supports range-based for loops.
Weight InitXavier (uniform/normal), He (uniform/normal), constant, custom.
Gradient Clippingclip_by_value() and clip_by_norm().
Serializationsave_model() / load_model() for full model persistence; tensor-level binary I/O.
LR SchedulersStepLR, ExponentialLR, CosineAnnealingLR.
CallbacksEarlyStopping with configurable patience, delta, and mode.
Elapsed TimeTraining duration measurement.

DataLoader example:

CppNet::Utils::DataLoader loader(X, Y, /*batch_size=*/32, /*shuffle=*/true);
for (auto& [x_batch, y_batch] : loader) {
// forward / backward / step
}
loader.reset(); // re-shuffle for next epoch

Learning rate scheduler example:

CppNet::Schedulers::CosineAnnealingLR scheduler(/*initial_lr=*/0.01, /*T_max=*/100);
for (int epoch = 0; epoch < 100; ++epoch) {
float lr = scheduler.step();
// ... train with lr
}

Visualization

CppNet::Visualizations::TrainingLogger logger;
// Inside training loop:
logger.log("train_loss", loss);
logger.log("val_accuracy", val_acc);
logger.next_epoch();
// After training:
logger.print_epoch_summary();
logger.export_csv("training_history.csv");

Examples

The examples/ directory contains complete, self-contained deep learning programs that train on synthetic data — no downloads required. Each example generates its own dataset, trains a model, and reports final metrics.

ExampleArchitectureDatasetKey ComponentsResult
mlp_classification.cppLinear→ReLU→Linear→ReLU→Linear3-class spiral (600 samples, 2D)ReLU, SoftmaxCrossEntropy, Adam~75% accuracy
cnn_image_classification.cppConv2D→ReLU→MaxPool2D→Flatten→Linear8×8 stripe images (400 samples)Conv2D, MaxPool2D, SoftmaxCrossEntropy, Adam100% accuracy
rnn_sequence_prediction.cppLSTM(1,16)→Linear(16,1)Sine-wave sequences (400 samples)LSTM, MSE, AdamMSE ≈ 0.00001
gru_sequence_prediction.cppGRU(1,16)→Linear(16,1)Sine-wave sequences (400 samples)GRU, MAE, MomentumMAE ≈ 0.010
transformer_classifier.cppEmbedding→Attention+skip→ReLU→LinearToken sequences (400 samples)Embedding, MultiHeadAttention, MeanPool1D100% accuracy
resnet_classifier.cppLinear→ReLU→ResBlock(32)→Linear→SigmoidConcentric circles (600 samples)Residual, GradientClip, He init~99% accuracy
regularized_cnn.cppConv2D→LeakyReLU→Pool→BN→Dropout→FC8×8 pattern images (600 samples, 3 classes)BatchNorm, Dropout, LeakyReLU, CategoricalCrossEntropy, Adagrad100% accuracy
optimizer_comparison.cppLinear→Tanh→Linear→Tanh→LinearRegression: y = sin(x₀)·cos(x₁) (500 samples)SGD, Momentum, Adagrad, RMSProp, Adam, Tanh, Huberloss ≈ 0.002

Build and run:

cd build
cmake .. -DCMAKE_BUILD_TYPE=Release -DBUILD_EXAMPLES=ON
make -j$(nproc)
./examples/mlp_classification
./examples/cnn_image_classification
./examples/rnn_sequence_prediction
./examples/gru_sequence_prediction
./examples/transformer_classifier
./examples/resnet_classifier
./examples/regularized_cnn
./examples/optimizer_comparison

GPU Acceleration

CppNet provides full CUDA GPU support across all layers, activations, losses, and optimizers. When CUDA is detected at build time, layers can target the GPU backend:

CppNet::Layers::Linear layer(784, 256, "fc1", true, true, "gpu", "xavier");

CUDA Kernel Coverage (41 kernels)

CategoryCUDA Kernels
Linear algebramatmul, matmul_grad_input, matmul_grad_weight, add_bias, bias_grad, elementwise
Convolutionconv2d_forward, conv2d_backward, maxpool2d_forward, maxpool2d_backward
Recurrentrnn_cell, lstm_cell, gru_cell
Attentionattention_scores (scale, softmax, backward), embedding_forward, embedding_backward
Normalizationbatch_norm_forward, batch_norm_backward, dropout
Poolingglobal_avg_pool2d, global_max_pool2d, mean_pool1d
Activationsrelu, relu_grad, leaky_relu, leaky_relu_grad, sigmoid, sigmoid_grad, tanh_activation, tanh_activation_grad
Lossesmse, mae, huber, bce, categorical_ce, softmax_ce
Optimizerssgd_step, momentum_step, adagrad_step, rmsprop_step, adam_step

To force a CPU-only build even when CUDA is present:

cmake .. -DCUDAToolkit_ROOT=/nonexistent

Benchmarks

Five benchmarks compare three compute backends — cpu-eigen (Eigen SIMD contractions), cpu (OpenMP loops), and gpu (CUDA kernels) — across different architectures and model sizes. All benchmarks are reproducible via the scripts in the benchmarks/ directory.

Summary of GPU Speedups

ArchitectureModel SizeGPU Speedup vs cpu-eigenKey Observation
MLPSmall (4.5K params)2.0xGPU overhead limits gains for small matmuls
Medium (66K params)6.9x
Large (660K params)14.3x
XLarge (2.6M params)25.3xSub-linear GPU time scaling with params
CNNSmall (Conv16→32)28.8xConvolution is highly GPU-parallel
Medium (Conv32→64→FC128)42.0xHighest CNN speedup
RNN/LSTM/GRUSmall (H=64)2.2–5.2xGRU benefits most from GPU
Medium (H=128)4.7–15.5x
Large (H=256)12.2–56.4xGRU Large achieves 56.4x — highest overall
TransformerSmall (d=32, h=2)0.5x (slower)GPU overhead dominates at small scale
Medium (d=64, h=4)1.0x (break-even)
Large (d=128, h=8)1.2xModest gain; hybrid CPU/GPU attention
ResNetSmall (W=64, D=2)1.6xDepth amplifies GPU advantage
Medium (W=128, D=4)6.7x
Large (W=256, D=6)9.0xSkip connections add negligible overhead

Key Findings

  • GPU advantage grows with model size. Across all architectures, larger models see dramatically higher GPU speedups as matrix sizes better saturate GPU cores.
  • CNNs and recurrent layers benefit most from GPU. Convolution achieves up to 42x speedup; GRU achieves up to 56.4x — the highest across all benchmarks.
  • Transformers show modest GPU gains at tested scales due to mixed operations (embedding lookups, attention softmax, multiple small projections) and a hybrid CPU/GPU attention path.
  • Eigen (cpu-eigen) consistently outperforms OpenMP (cpu) for all architectures, leveraging SIMD vectorization and cache-optimal memory layouts.
  • Numerical consistency is verified across all backends — all devices converge to equivalent loss and accuracy values.

Average GPU Speedups by Architecture

ArchitectureAvg GPU SpeedupBest GPU SpeedupBest Config
MLP12.1x25.3xXLarge (2.6M params)
CNN35.4x42.0xMedium (Conv32→64→FC128)
Sequence (RNN/LSTM/GRU)13.7x56.4xGRU Large (H=256, seq=50)
Transformer0.9x1.2xLarge (d=128, h=8)
ResNet5.8x9.0xLarge (W=256, D=6)

How to Reproduce

cd build
cmake .. -DCMAKE_BUILD_TYPE=Release -DBUILD_BENCHMARKS=ON
make -j$(nproc)
./benchmarks/mlp_benchmark
./benchmarks/cnn_benchmark
./benchmarks/sequence_benchmark
./benchmarks/transformer_benchmark
./benchmarks/residual_benchmark

See benchmarks/benchmarks.md for full per-epoch results, detailed speedup analysis, and methodology.


Testing

CppNet has 41 unit tests with 377 test cases covering every module:

cd build
cmake .. -DBUILD_TESTS=ON
make -j$(nproc)
ctest --output-on-failure
CategoryTestsTest Cases
Layers (13)Linear, Conv2D, Flatten, MaxPool2D, RNN, Attention, BatchNorm, Dropout, Embedding, GlobalPool, GRU, LSTM, Residual123
Activations (5)ReLU, Sigmoid, Softmax, Tanh, LeakyReLU55
Losses (6)BinaryCrossEntropy, CategoricalCrossEntropy, MSE, MAE, Huber, SoftmaxCrossEntropy52
Optimizers (5)SGD, Adam, Momentum, Adagrad, RMSProp34
Utilities (7)Metrics, Regularizations, Callbacks, DataLoader, ElapsedTime, GradientClip, Init65
GPU Kernels (1)GPU matmul via Linear layer (forward, backward, step, CPU/GPU comparison)7
Other (4)Schedulers, Utils, Models, Visualizations41

Each test validates forward pass, backward pass (gradient shapes & values), parameter updates, and GPU/CPU numerical consistency where applicable.


Project Structure

CppNet/
├── CMakeLists.txt # Top-level build configuration
├── cmake/ # CMake package config templates
├── include/CppNet/ # Public headers
│ ├── CppNet.hpp # Single-include entry point
│ ├── activations/ # ReLU, Sigmoid, Softmax, Tanh, LeakyReLU
│ ├── layers/ # Linear, Conv2D, RNN, LSTM, GRU, Attention, ...
│ ├── losses/ # MSE, MAE, Huber, BCE, CCE, SoftmaxCE
│ ├── optimizers/ # SGD, Adam, Adagrad, Momentum, RMSProp
│ ├── models/ # SequentialModel
│ ├── metrics/ # Accuracy, Precision, Recall, F1
│ ├── regularizations/ # L1, L2, Elastic Net
│ ├── kernels/gpu/ # CUDA kernel declarations
│ ├── utils/ # DataLoader, Init, Schedulers, Serialization, ...
│ └── visualizations/ # TrainingLogger
├── src/CppNet/ # Implementation files (.cpp / .cu)
│ └── kernels/gpu/ # 41 CUDA kernel implementations
├── tests/ # 41 unit tests (377 test cases)
├── examples/ # 8 deep learning examples
├── benchmarks/ # 5 device benchmarks (CPU vs GPU)
└── docs/ # Additional documentation

Roadmap

  • Core layer library (Linear, Conv2D, Pooling, RNN, LSTM, GRU, Attention, BatchNorm, Dropout, Embedding, Residual)
  • Activation functions (ReLU, Sigmoid, Tanh, Softmax, LeakyReLU)
  • Loss functions (MSE, MAE, Huber, BCE, CCE, SoftmaxCE)
  • Optimizers (SGD, Adam, Adagrad, Momentum, RMSProp)
  • DataLoader, LR schedulers, early stopping, gradient clipping
  • Model serialization (save/load)
  • Full CUDA GPU backend — 41 kernels covering all layers, activations, losses, and optimizers
  • OpenMP CPU parallelism
  • Comprehensive test suite (41 tests, 377 test cases)
  • Deep learning examples (MLP, CNN, RNN/LSTM, GRU, Transformer, ResNet, Regularized CNN, Optimizer Comparison)
  • Device benchmarks (MLP, CNN, Sequence, Transformer, ResNet)
  • Add Trainer abstraction with built-in training loop
  • Additional examples (GANs, Reinforcement Learning, NLP pipelines)
  • Python bindings (pybind11)
  • Comprehensive API reference documentation

Contributing

Contributions are welcome! To get started:

  1. Fork the repository and create a feature branch.
  2. Follow the existing coding style — headers in include/CppNet/, implementations in src/CppNet/.
  3. Add tests for new functionality in tests/.
  4. Make sure all tests pass: cd build && ctest --output-on-failure.
  5. Open a pull request with a clear description of your changes.

License

CppNet is released under the MIT License.

Copyright © 2025 Loghman Samani

About

A high-performance C++ deep learning library for building and training neural networks

Resources

Stars

7 stars

Watchers

1 watching

Forks

Releases

Packages

Contributors

Languages

, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Remove or un-stick sticky/fixed headers that block content\n(function() {\n function unstick() {\n document.querySelectorAll('header, nav, [role=\"banner\"], .header, .navbar, .sticky, .fixed-top, [style*=\"position: fixed\"], [style*=\"position:sticky\"]').forEach(function(el) {\n if (el.style.position === 'fixed' || el.style.position === 'sticky' || \n getComputedStyle(el).position === 'fixed' || getComputedStyle(el).position === 'sticky') {\n el.style.position = 'static';\n el.style.top = 'auto';\n el.style.zIndex = 'auto';\n }\n });\n }\n \n unstick();\n \n var observer = new MutationObserver(unstick);\n observer.observe(document.body, { childList: true, subtree: true, attributes: true, attributeFilter: ['style', 'class'] });\n})();", "Kill Sticky Headers"); } } catch(__e) { console.warn('[Userscript:Kill Sticky Headers]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + '
Skip to content

Repository files navigation

CppNet

CppNet Logo

CppNet is a high-performance C++17 deep learning library for building and training neural networks from scratch.
Built on Eigen for fast tensor operations, OpenMP for CPU parallelism, and CUDA for GPU acceleration.

C++17CMakeMIT LicenseCUDAWebsite


Table of Contents


Features

  • High Performance — Vectorized tensor operations via Eigen, multi-threaded with OpenMP, full CUDA GPU backend for all layers, activations, losses, and optimizers.
  • Rich Layer Library — Linear, Conv2D, MaxPool2D, RNN, LSTM, GRU, Multi-Head Attention, Dropout, BatchNorm, Embedding, Residual, GlobalPool, MeanPool1D, Flatten.
  • Multiple Backends — Per-layer compute backend selection: "cpu-eigen" (Eigen contractions), "cpu" (OpenMP loops), "gpu" (CUDA kernels).
  • Complete CUDA Coverage — 41 CUDA kernel files covering all layers, activations, losses, and optimizers for end-to-end GPU training.
  • Modular Architecture — Clean separation of layers, activations, losses, optimizers, metrics, regularizations, and utilities.
  • Training Utilities — DataLoader with batching & shuffling, learning rate schedulers, early stopping callbacks, gradient clipping, model serialization.
  • Visualization — Built-in TrainingLogger for tracking metrics and exporting training history to CSV.
  • Extensible — Abstract base classes for layers, losses, and optimizers make it straightforward to add custom components.
  • Single-Header Access#include <CppNet/CppNet.hpp> brings in the entire library.

Installation

Prerequisites

DependencyVersionRequired
C++ compiler (GCC, Clang, MSVC)C++17 supportYes
CMake≥ 3.18Yes
Eigen3≥ 3.3Yes
OpenMPanyOptional (CPU parallelism)
CUDA ToolkitanyOptional (GPU acceleration)

Build from Source

git clone https://github.com/LoqmanSamani/CppNet.git
cd CppNet
mkdir build &&cd build
cmake .. -DCMAKE_BUILD_TYPE=Release
make -j$(nproc)

Install System-Wide

sudo make install

This installs headers to /usr/local/include/CppNet/ and the static library to /usr/local/lib/.

Use in Your CMake Project

find_package(CppNetREQUIRED)
target_link_libraries(your_targetPRIVATECppNet::CppNet)

Quick Start

A minimal binary classification example:

#include<CppNet/CppNet.hpp>
#include<iostream>intmain() {
// Define layers
CppNet::Layers::Linear layer1(30, 64, "fc1", true, true, "cpu-eigen", "xavier");
CppNet::Layers::Linear layer2(64, 1, "fc2", true, true, "cpu-eigen", "xavier");
CppNet::Activations::ReLU relu("cpu-eigen");
CppNet::Activations::Sigmoid sigmoid;
// Loss & optimizer
CppNet::Losses::BinaryCrossEntropy loss_fn("mean");
CppNet::Optimizers::Adam optimizer;
float lr = 0.001;
// Training loopfor (int epoch = 0; epoch < 100; ++epoch) {
auto h = relu.forward(layer1.forward(X_train));
auto pred = sigmoid.forward(layer2.forward(h));
float loss = loss_fn.forward(pred, Y_train);
auto grad = loss_fn.backward(pred, Y_train);
grad = layer2.backward(sigmoid.backward(grad));
layer1.backward(relu.backward(grad));
layer2.step(optimizer, lr);
layer1.step(optimizer, lr);
std::cout << "Epoch " << epoch << " — Loss: " << loss << std::endl;
}
return0;
}

API Overview

Layers

All layers inherit from CppNet::Layers::Layer and implement forward(), backward(), step(), freeze(), unfreeze(), and print_layer_info().

LayerDescriptionKey Parameters
LinearFully connected layerin_size, out_size, bias, device, weight_init
Conv2D2D convolutionin_channels, out_channels, kernel_size, stride, padding
MaxPool2D2D max poolingkernel_size, stride
FlattenReshape to 2D
RNNVanilla recurrent layerinput_size, hidden_size
LSTMLong Short-Term Memoryinput_size, hidden_size
GRUGated Recurrent Unitinput_size, hidden_size
MultiHeadAttentionScaled dot-product multi-head attentionembed_dim, num_heads
DropoutDropout regularizationdrop_rate
BatchNormBatch normalizationnum_features
EmbeddingEmbedding lookup tablevocab_size, embed_dim
ResidualResidual (skip) connection wrapper
GlobalPoolGlobal average/max pooling
MeanPool1DMean pooling over sequence dimension

Activations

ActivationFunction
ReLU$\max(0, x)$
LeakyReLU$\max(\alpha x, x)$
Sigmoid$\sigma(x) = \frac{1}{1 + e^{-x}}$
Tanh$\tanh(x)$
Softmax$\frac{e^{x_i}}{\sum_j e^{x_j}}$

All activations support both 2D and 4D tensor inputs and run on all three backends (cpu-eigen, cpu, gpu).

Losses

LossTypical Use
MSERegression
MAERegression
HuberRobust regression
BinaryCrossEntropyBinary classification
CategoricalCrossEntropyMulti-class classification
SoftmaxCrossEntropyMulti-class (fused softmax + CE)

All support configurable reduction modes ("mean", "sum") and CUDA GPU acceleration.

Optimizers

OptimizerDescription
SGDStochastic Gradient Descent
AdamAdaptive Moment Estimation (default: $\beta_1=0.9$, $\beta_2=0.999$, $\epsilon=10^{-8}$)
AdagradAdaptive gradient accumulation
MomentumSGD with momentum
RMSPropRoot Mean Square Propagation

All optimizers have dedicated CUDA kernels for GPU-side weight updates.

Metrics

CppNet::Metrics::accuracy(predictions, targets);
CppNet::Metrics::binary_accuracy(predictions, targets, 0.5);
CppNet::Metrics::precision(predictions, targets, 0.5);
CppNet::Metrics::recall(predictions, targets, 0.5);
CppNet::Metrics::f1_score(predictions, targets, 0.5);

Regularizations

CppNet::Regularizations::l1_penalty(weights, lambda);
CppNet::Regularizations::l2_penalty(weights, lambda);
CppNet::Regularizations::elastic_net_penalty(weights, lambda, l1_ratio);
// Corresponding gradient functions: l1_gradient, l2_gradient, elastic_net_gradient

Utilities

UtilityDescription
DataLoaderBatched iteration with shuffling. Supports range-based for loops.
Weight InitXavier (uniform/normal), He (uniform/normal), constant, custom.
Gradient Clippingclip_by_value() and clip_by_norm().
Serializationsave_model() / load_model() for full model persistence; tensor-level binary I/O.
LR SchedulersStepLR, ExponentialLR, CosineAnnealingLR.
CallbacksEarlyStopping with configurable patience, delta, and mode.
Elapsed TimeTraining duration measurement.

DataLoader example:

CppNet::Utils::DataLoader loader(X, Y, /*batch_size=*/32, /*shuffle=*/true);
for (auto& [x_batch, y_batch] : loader) {
// forward / backward / step
}
loader.reset(); // re-shuffle for next epoch

Learning rate scheduler example:

CppNet::Schedulers::CosineAnnealingLR scheduler(/*initial_lr=*/0.01, /*T_max=*/100);
for (int epoch = 0; epoch < 100; ++epoch) {
float lr = scheduler.step();
// ... train with lr
}

Visualization

CppNet::Visualizations::TrainingLogger logger;
// Inside training loop:
logger.log("train_loss", loss);
logger.log("val_accuracy", val_acc);
logger.next_epoch();
// After training:
logger.print_epoch_summary();
logger.export_csv("training_history.csv");

Examples

The examples/ directory contains complete, self-contained deep learning programs that train on synthetic data — no downloads required. Each example generates its own dataset, trains a model, and reports final metrics.

ExampleArchitectureDatasetKey ComponentsResult
mlp_classification.cppLinear→ReLU→Linear→ReLU→Linear3-class spiral (600 samples, 2D)ReLU, SoftmaxCrossEntropy, Adam~75% accuracy
cnn_image_classification.cppConv2D→ReLU→MaxPool2D→Flatten→Linear8×8 stripe images (400 samples)Conv2D, MaxPool2D, SoftmaxCrossEntropy, Adam100% accuracy
rnn_sequence_prediction.cppLSTM(1,16)→Linear(16,1)Sine-wave sequences (400 samples)LSTM, MSE, AdamMSE ≈ 0.00001
gru_sequence_prediction.cppGRU(1,16)→Linear(16,1)Sine-wave sequences (400 samples)GRU, MAE, MomentumMAE ≈ 0.010
transformer_classifier.cppEmbedding→Attention+skip→ReLU→LinearToken sequences (400 samples)Embedding, MultiHeadAttention, MeanPool1D100% accuracy
resnet_classifier.cppLinear→ReLU→ResBlock(32)→Linear→SigmoidConcentric circles (600 samples)Residual, GradientClip, He init~99% accuracy
regularized_cnn.cppConv2D→LeakyReLU→Pool→BN→Dropout→FC8×8 pattern images (600 samples, 3 classes)BatchNorm, Dropout, LeakyReLU, CategoricalCrossEntropy, Adagrad100% accuracy
optimizer_comparison.cppLinear→Tanh→Linear→Tanh→LinearRegression: y = sin(x₀)·cos(x₁) (500 samples)SGD, Momentum, Adagrad, RMSProp, Adam, Tanh, Huberloss ≈ 0.002

Build and run:

cd build
cmake .. -DCMAKE_BUILD_TYPE=Release -DBUILD_EXAMPLES=ON
make -j$(nproc)
./examples/mlp_classification
./examples/cnn_image_classification
./examples/rnn_sequence_prediction
./examples/gru_sequence_prediction
./examples/transformer_classifier
./examples/resnet_classifier
./examples/regularized_cnn
./examples/optimizer_comparison

GPU Acceleration

CppNet provides full CUDA GPU support across all layers, activations, losses, and optimizers. When CUDA is detected at build time, layers can target the GPU backend:

CppNet::Layers::Linear layer(784, 256, "fc1", true, true, "gpu", "xavier");

CUDA Kernel Coverage (41 kernels)

CategoryCUDA Kernels
Linear algebramatmul, matmul_grad_input, matmul_grad_weight, add_bias, bias_grad, elementwise
Convolutionconv2d_forward, conv2d_backward, maxpool2d_forward, maxpool2d_backward
Recurrentrnn_cell, lstm_cell, gru_cell
Attentionattention_scores (scale, softmax, backward), embedding_forward, embedding_backward
Normalizationbatch_norm_forward, batch_norm_backward, dropout
Poolingglobal_avg_pool2d, global_max_pool2d, mean_pool1d
Activationsrelu, relu_grad, leaky_relu, leaky_relu_grad, sigmoid, sigmoid_grad, tanh_activation, tanh_activation_grad
Lossesmse, mae, huber, bce, categorical_ce, softmax_ce
Optimizerssgd_step, momentum_step, adagrad_step, rmsprop_step, adam_step

To force a CPU-only build even when CUDA is present:

cmake .. -DCUDAToolkit_ROOT=/nonexistent

Benchmarks

Five benchmarks compare three compute backends — cpu-eigen (Eigen SIMD contractions), cpu (OpenMP loops), and gpu (CUDA kernels) — across different architectures and model sizes. All benchmarks are reproducible via the scripts in the benchmarks/ directory.

Summary of GPU Speedups

ArchitectureModel SizeGPU Speedup vs cpu-eigenKey Observation
MLPSmall (4.5K params)2.0xGPU overhead limits gains for small matmuls
Medium (66K params)6.9x
Large (660K params)14.3x
XLarge (2.6M params)25.3xSub-linear GPU time scaling with params
CNNSmall (Conv16→32)28.8xConvolution is highly GPU-parallel
Medium (Conv32→64→FC128)42.0xHighest CNN speedup
RNN/LSTM/GRUSmall (H=64)2.2–5.2xGRU benefits most from GPU
Medium (H=128)4.7–15.5x
Large (H=256)12.2–56.4xGRU Large achieves 56.4x — highest overall
TransformerSmall (d=32, h=2)0.5x (slower)GPU overhead dominates at small scale
Medium (d=64, h=4)1.0x (break-even)
Large (d=128, h=8)1.2xModest gain; hybrid CPU/GPU attention
ResNetSmall (W=64, D=2)1.6xDepth amplifies GPU advantage
Medium (W=128, D=4)6.7x
Large (W=256, D=6)9.0xSkip connections add negligible overhead

Key Findings

  • GPU advantage grows with model size. Across all architectures, larger models see dramatically higher GPU speedups as matrix sizes better saturate GPU cores.
  • CNNs and recurrent layers benefit most from GPU. Convolution achieves up to 42x speedup; GRU achieves up to 56.4x — the highest across all benchmarks.
  • Transformers show modest GPU gains at tested scales due to mixed operations (embedding lookups, attention softmax, multiple small projections) and a hybrid CPU/GPU attention path.
  • Eigen (cpu-eigen) consistently outperforms OpenMP (cpu) for all architectures, leveraging SIMD vectorization and cache-optimal memory layouts.
  • Numerical consistency is verified across all backends — all devices converge to equivalent loss and accuracy values.

Average GPU Speedups by Architecture

ArchitectureAvg GPU SpeedupBest GPU SpeedupBest Config
MLP12.1x25.3xXLarge (2.6M params)
CNN35.4x42.0xMedium (Conv32→64→FC128)
Sequence (RNN/LSTM/GRU)13.7x56.4xGRU Large (H=256, seq=50)
Transformer0.9x1.2xLarge (d=128, h=8)
ResNet5.8x9.0xLarge (W=256, D=6)

How to Reproduce

cd build
cmake .. -DCMAKE_BUILD_TYPE=Release -DBUILD_BENCHMARKS=ON
make -j$(nproc)
./benchmarks/mlp_benchmark
./benchmarks/cnn_benchmark
./benchmarks/sequence_benchmark
./benchmarks/transformer_benchmark
./benchmarks/residual_benchmark

See benchmarks/benchmarks.md for full per-epoch results, detailed speedup analysis, and methodology.


Testing

CppNet has 41 unit tests with 377 test cases covering every module:

cd build
cmake .. -DBUILD_TESTS=ON
make -j$(nproc)
ctest --output-on-failure
CategoryTestsTest Cases
Layers (13)Linear, Conv2D, Flatten, MaxPool2D, RNN, Attention, BatchNorm, Dropout, Embedding, GlobalPool, GRU, LSTM, Residual123
Activations (5)ReLU, Sigmoid, Softmax, Tanh, LeakyReLU55
Losses (6)BinaryCrossEntropy, CategoricalCrossEntropy, MSE, MAE, Huber, SoftmaxCrossEntropy52
Optimizers (5)SGD, Adam, Momentum, Adagrad, RMSProp34
Utilities (7)Metrics, Regularizations, Callbacks, DataLoader, ElapsedTime, GradientClip, Init65
GPU Kernels (1)GPU matmul via Linear layer (forward, backward, step, CPU/GPU comparison)7
Other (4)Schedulers, Utils, Models, Visualizations41

Each test validates forward pass, backward pass (gradient shapes & values), parameter updates, and GPU/CPU numerical consistency where applicable.


Project Structure

CppNet/
├── CMakeLists.txt # Top-level build configuration
├── cmake/ # CMake package config templates
├── include/CppNet/ # Public headers
│ ├── CppNet.hpp # Single-include entry point
│ ├── activations/ # ReLU, Sigmoid, Softmax, Tanh, LeakyReLU
│ ├── layers/ # Linear, Conv2D, RNN, LSTM, GRU, Attention, ...
│ ├── losses/ # MSE, MAE, Huber, BCE, CCE, SoftmaxCE
│ ├── optimizers/ # SGD, Adam, Adagrad, Momentum, RMSProp
│ ├── models/ # SequentialModel
│ ├── metrics/ # Accuracy, Precision, Recall, F1
│ ├── regularizations/ # L1, L2, Elastic Net
│ ├── kernels/gpu/ # CUDA kernel declarations
│ ├── utils/ # DataLoader, Init, Schedulers, Serialization, ...
│ └── visualizations/ # TrainingLogger
├── src/CppNet/ # Implementation files (.cpp / .cu)
│ └── kernels/gpu/ # 41 CUDA kernel implementations
├── tests/ # 41 unit tests (377 test cases)
├── examples/ # 8 deep learning examples
├── benchmarks/ # 5 device benchmarks (CPU vs GPU)
└── docs/ # Additional documentation

Roadmap

  • Core layer library (Linear, Conv2D, Pooling, RNN, LSTM, GRU, Attention, BatchNorm, Dropout, Embedding, Residual)
  • Activation functions (ReLU, Sigmoid, Tanh, Softmax, LeakyReLU)
  • Loss functions (MSE, MAE, Huber, BCE, CCE, SoftmaxCE)
  • Optimizers (SGD, Adam, Adagrad, Momentum, RMSProp)
  • DataLoader, LR schedulers, early stopping, gradient clipping
  • Model serialization (save/load)
  • Full CUDA GPU backend — 41 kernels covering all layers, activations, losses, and optimizers
  • OpenMP CPU parallelism
  • Comprehensive test suite (41 tests, 377 test cases)
  • Deep learning examples (MLP, CNN, RNN/LSTM, GRU, Transformer, ResNet, Regularized CNN, Optimizer Comparison)
  • Device benchmarks (MLP, CNN, Sequence, Transformer, ResNet)
  • Add Trainer abstraction with built-in training loop
  • Additional examples (GANs, Reinforcement Learning, NLP pipelines)
  • Python bindings (pybind11)
  • Comprehensive API reference documentation

Contributing

Contributions are welcome! To get started:

  1. Fork the repository and create a feature branch.
  2. Follow the existing coding style — headers in include/CppNet/, implementations in src/CppNet/.
  3. Add tests for new functionality in tests/.
  4. Make sure all tests pass: cd build && ctest --output-on-failure.
  5. Open a pull request with a clear description of your changes.

License

CppNet is released under the MIT License.

Copyright © 2025 Loghman Samani

About

A high-performance C++ deep learning library for building and training neural networks

Resources

Stars

7 stars

Watchers

1 watching

Forks

Releases

Packages

Contributors

Languages

, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Universal Dark Mode - works on any site\n(function() {\n var enabled = true;\n \n function applyDarkMode() {\n if (!enabled) return;\n \n // Create style element if it doesn't exist\n var style = document.getElementById('universal-dark-mode-style');\n if (!style) {\n style = document.createElement('style');\n style.id = 'universal-dark-mode-style';\n document.head.appendChild(style);\n }\n \n // Dark mode CSS - inverts colors but preserves images/video\n style.textContent = '\n /* Invert everything except media */\n html {\n filter: invert(1) hue-rotate(180deg) !important;\n background: #1a1a2e !important;\n }\n \n /* Restore images, videos, iframes, canvas */\n img, video, iframe, canvas, svg, picture, [style*=\"background-image\"] {\n filter: invert(1) hue-rotate(180deg) !important;\n }\n \n /* Preserve specific elements that should not be inverted */\n .no-dark-mode, .no-dark-mode *,\n [data-theme=\"light\"], [data-theme=\"light\"],\n .ace_editor, .ace_editor *,\n .CodeMirror, .CodeMirror *,\n .monaco-editor, .monaco-editor *,\n .markdown-body pre, .markdown-body pre *,\n .highlight, .highlight *,\n pre code, pre code * {\n filter: none !important;\n }\n \n /* Fix common UI elements */\n .modal, .popup, .dropdown-menu, .tooltip, .popover {\n filter: invert(1) hue-rotate(180deg) !important;\n background: #2d2d44 !important;\n border-color: #444 !important;\n }\n \n /* Scrollbars */\n ::-webkit-scrollbar { background: #1a1a2e !important; }\n ::-webkit-scrollbar-thumb { background: #444 !important; }\n ::-webkit-scrollbar-thumb:hover { background: #555 !important; }\n \n /* Selection */\n ::selection { background: #4ecdc4 !important; color: #1a1a2e !important; }\n ::-moz-selection { background: #4ecdc4 !important; color: #1a1a2e !important; }\n ';\n }\n \n function removeDarkMode() {\n var style = document.getElementById('universal-dark-mode-style');\n if (style) style.remove();\n }\n \n // Toggle with Alt+Shift+D\n document.addEventListener('keydown', function(e) {\n if (e.altKey && e.shiftKey && e.key === 'D') {\n e.preventDefault();\n enabled = !enabled;\n if (enabled) {\n applyDarkMode();\n console.log('[Universal Dark Mode] Enabled');\n } else {\n removeDarkMode();\n console.log('[Universal Dark Mode] Disabled');\n }\n }\n });\n \n // Apply on load\n applyDarkMode();\n \n // Re-apply on dynamic content\n var observer = new MutationObserver(function(mutations) {\n if (enabled && !document.getElementById('universal-dark-mode-style')) {\n applyDarkMode();\n }\n });\n observer.observe(document.head, { childList: true });\n \n console.log('[Universal Dark Mode] Loaded - Press Alt+Shift+D to toggle');\n})();", "Universal Dark Mode"); } } catch(__e) { console.warn('[Userscript:Universal Dark Mode]', __e); } })(); })();
Skip to content

Repository files navigation

CppNet

CppNet Logo

CppNet is a high-performance C++17 deep learning library for building and training neural networks from scratch.
Built on Eigen for fast tensor operations, OpenMP for CPU parallelism, and CUDA for GPU acceleration.

C++17CMakeMIT LicenseCUDAWebsite


Table of Contents


Features

  • High Performance — Vectorized tensor operations via Eigen, multi-threaded with OpenMP, full CUDA GPU backend for all layers, activations, losses, and optimizers.
  • Rich Layer Library — Linear, Conv2D, MaxPool2D, RNN, LSTM, GRU, Multi-Head Attention, Dropout, BatchNorm, Embedding, Residual, GlobalPool, MeanPool1D, Flatten.
  • Multiple Backends — Per-layer compute backend selection: "cpu-eigen" (Eigen contractions), "cpu" (OpenMP loops), "gpu" (CUDA kernels).
  • Complete CUDA Coverage — 41 CUDA kernel files covering all layers, activations, losses, and optimizers for end-to-end GPU training.
  • Modular Architecture — Clean separation of layers, activations, losses, optimizers, metrics, regularizations, and utilities.
  • Training Utilities — DataLoader with batching & shuffling, learning rate schedulers, early stopping callbacks, gradient clipping, model serialization.
  • Visualization — Built-in TrainingLogger for tracking metrics and exporting training history to CSV.
  • Extensible — Abstract base classes for layers, losses, and optimizers make it straightforward to add custom components.
  • Single-Header Access#include <CppNet/CppNet.hpp> brings in the entire library.

Installation

Prerequisites

DependencyVersionRequired
C++ compiler (GCC, Clang, MSVC)C++17 supportYes
CMake≥ 3.18Yes
Eigen3≥ 3.3Yes
OpenMPanyOptional (CPU parallelism)
CUDA ToolkitanyOptional (GPU acceleration)

Build from Source

git clone https://github.com/LoqmanSamani/CppNet.git
cd CppNet
mkdir build &&cd build
cmake .. -DCMAKE_BUILD_TYPE=Release
make -j$(nproc)

Install System-Wide

sudo make install

This installs headers to /usr/local/include/CppNet/ and the static library to /usr/local/lib/.

Use in Your CMake Project

find_package(CppNetREQUIRED)
target_link_libraries(your_targetPRIVATECppNet::CppNet)

Quick Start

A minimal binary classification example:

#include<CppNet/CppNet.hpp>
#include<iostream>intmain() {
// Define layers
CppNet::Layers::Linear layer1(30, 64, "fc1", true, true, "cpu-eigen", "xavier");
CppNet::Layers::Linear layer2(64, 1, "fc2", true, true, "cpu-eigen", "xavier");
CppNet::Activations::ReLU relu("cpu-eigen");
CppNet::Activations::Sigmoid sigmoid;
// Loss & optimizer
CppNet::Losses::BinaryCrossEntropy loss_fn("mean");
CppNet::Optimizers::Adam optimizer;
float lr = 0.001;
// Training loopfor (int epoch = 0; epoch < 100; ++epoch) {
auto h = relu.forward(layer1.forward(X_train));
auto pred = sigmoid.forward(layer2.forward(h));
float loss = loss_fn.forward(pred, Y_train);
auto grad = loss_fn.backward(pred, Y_train);
grad = layer2.backward(sigmoid.backward(grad));
layer1.backward(relu.backward(grad));
layer2.step(optimizer, lr);
layer1.step(optimizer, lr);
std::cout << "Epoch " << epoch << " — Loss: " << loss << std::endl;
}
return0;
}

API Overview

Layers

All layers inherit from CppNet::Layers::Layer and implement forward(), backward(), step(), freeze(), unfreeze(), and print_layer_info().

LayerDescriptionKey Parameters
LinearFully connected layerin_size, out_size, bias, device, weight_init
Conv2D2D convolutionin_channels, out_channels, kernel_size, stride, padding
MaxPool2D2D max poolingkernel_size, stride
FlattenReshape to 2D
RNNVanilla recurrent layerinput_size, hidden_size
LSTMLong Short-Term Memoryinput_size, hidden_size
GRUGated Recurrent Unitinput_size, hidden_size
MultiHeadAttentionScaled dot-product multi-head attentionembed_dim, num_heads
DropoutDropout regularizationdrop_rate
BatchNormBatch normalizationnum_features
EmbeddingEmbedding lookup tablevocab_size, embed_dim
ResidualResidual (skip) connection wrapper
GlobalPoolGlobal average/max pooling
MeanPool1DMean pooling over sequence dimension

Activations

ActivationFunction
ReLU$\max(0, x)$
LeakyReLU$\max(\alpha x, x)$
Sigmoid$\sigma(x) = \frac{1}{1 + e^{-x}}$
Tanh$\tanh(x)$
Softmax$\frac{e^{x_i}}{\sum_j e^{x_j}}$

All activations support both 2D and 4D tensor inputs and run on all three backends (cpu-eigen, cpu, gpu).

Losses

LossTypical Use
MSERegression
MAERegression
HuberRobust regression
BinaryCrossEntropyBinary classification
CategoricalCrossEntropyMulti-class classification
SoftmaxCrossEntropyMulti-class (fused softmax + CE)

All support configurable reduction modes ("mean", "sum") and CUDA GPU acceleration.

Optimizers

OptimizerDescription
SGDStochastic Gradient Descent
AdamAdaptive Moment Estimation (default: $\beta_1=0.9$, $\beta_2=0.999$, $\epsilon=10^{-8}$)
AdagradAdaptive gradient accumulation
MomentumSGD with momentum
RMSPropRoot Mean Square Propagation

All optimizers have dedicated CUDA kernels for GPU-side weight updates.

Metrics

CppNet::Metrics::accuracy(predictions, targets);
CppNet::Metrics::binary_accuracy(predictions, targets, 0.5);
CppNet::Metrics::precision(predictions, targets, 0.5);
CppNet::Metrics::recall(predictions, targets, 0.5);
CppNet::Metrics::f1_score(predictions, targets, 0.5);

Regularizations

CppNet::Regularizations::l1_penalty(weights, lambda);
CppNet::Regularizations::l2_penalty(weights, lambda);
CppNet::Regularizations::elastic_net_penalty(weights, lambda, l1_ratio);
// Corresponding gradient functions: l1_gradient, l2_gradient, elastic_net_gradient

Utilities

UtilityDescription
DataLoaderBatched iteration with shuffling. Supports range-based for loops.
Weight InitXavier (uniform/normal), He (uniform/normal), constant, custom.
Gradient Clippingclip_by_value() and clip_by_norm().
Serializationsave_model() / load_model() for full model persistence; tensor-level binary I/O.
LR SchedulersStepLR, ExponentialLR, CosineAnnealingLR.
CallbacksEarlyStopping with configurable patience, delta, and mode.
Elapsed TimeTraining duration measurement.

DataLoader example:

CppNet::Utils::DataLoader loader(X, Y, /*batch_size=*/32, /*shuffle=*/true);
for (auto& [x_batch, y_batch] : loader) {
// forward / backward / step
}
loader.reset(); // re-shuffle for next epoch

Learning rate scheduler example:

CppNet::Schedulers::CosineAnnealingLR scheduler(/*initial_lr=*/0.01, /*T_max=*/100);
for (int epoch = 0; epoch < 100; ++epoch) {
float lr = scheduler.step();
// ... train with lr
}

Visualization

CppNet::Visualizations::TrainingLogger logger;
// Inside training loop:
logger.log("train_loss", loss);
logger.log("val_accuracy", val_acc);
logger.next_epoch();
// After training:
logger.print_epoch_summary();
logger.export_csv("training_history.csv");

Examples

The examples/ directory contains complete, self-contained deep learning programs that train on synthetic data — no downloads required. Each example generates its own dataset, trains a model, and reports final metrics.

ExampleArchitectureDatasetKey ComponentsResult
mlp_classification.cppLinear→ReLU→Linear→ReLU→Linear3-class spiral (600 samples, 2D)ReLU, SoftmaxCrossEntropy, Adam~75% accuracy
cnn_image_classification.cppConv2D→ReLU→MaxPool2D→Flatten→Linear8×8 stripe images (400 samples)Conv2D, MaxPool2D, SoftmaxCrossEntropy, Adam100% accuracy
rnn_sequence_prediction.cppLSTM(1,16)→Linear(16,1)Sine-wave sequences (400 samples)LSTM, MSE, AdamMSE ≈ 0.00001
gru_sequence_prediction.cppGRU(1,16)→Linear(16,1)Sine-wave sequences (400 samples)GRU, MAE, MomentumMAE ≈ 0.010
transformer_classifier.cppEmbedding→Attention+skip→ReLU→LinearToken sequences (400 samples)Embedding, MultiHeadAttention, MeanPool1D100% accuracy
resnet_classifier.cppLinear→ReLU→ResBlock(32)→Linear→SigmoidConcentric circles (600 samples)Residual, GradientClip, He init~99% accuracy
regularized_cnn.cppConv2D→LeakyReLU→Pool→BN→Dropout→FC8×8 pattern images (600 samples, 3 classes)BatchNorm, Dropout, LeakyReLU, CategoricalCrossEntropy, Adagrad100% accuracy
optimizer_comparison.cppLinear→Tanh→Linear→Tanh→LinearRegression: y = sin(x₀)·cos(x₁) (500 samples)SGD, Momentum, Adagrad, RMSProp, Adam, Tanh, Huberloss ≈ 0.002

Build and run:

cd build
cmake .. -DCMAKE_BUILD_TYPE=Release -DBUILD_EXAMPLES=ON
make -j$(nproc)
./examples/mlp_classification
./examples/cnn_image_classification
./examples/rnn_sequence_prediction
./examples/gru_sequence_prediction
./examples/transformer_classifier
./examples/resnet_classifier
./examples/regularized_cnn
./examples/optimizer_comparison

GPU Acceleration

CppNet provides full CUDA GPU support across all layers, activations, losses, and optimizers. When CUDA is detected at build time, layers can target the GPU backend:

CppNet::Layers::Linear layer(784, 256, "fc1", true, true, "gpu", "xavier");

CUDA Kernel Coverage (41 kernels)

CategoryCUDA Kernels
Linear algebramatmul, matmul_grad_input, matmul_grad_weight, add_bias, bias_grad, elementwise
Convolutionconv2d_forward, conv2d_backward, maxpool2d_forward, maxpool2d_backward
Recurrentrnn_cell, lstm_cell, gru_cell
Attentionattention_scores (scale, softmax, backward), embedding_forward, embedding_backward
Normalizationbatch_norm_forward, batch_norm_backward, dropout
Poolingglobal_avg_pool2d, global_max_pool2d, mean_pool1d
Activationsrelu, relu_grad, leaky_relu, leaky_relu_grad, sigmoid, sigmoid_grad, tanh_activation, tanh_activation_grad
Lossesmse, mae, huber, bce, categorical_ce, softmax_ce
Optimizerssgd_step, momentum_step, adagrad_step, rmsprop_step, adam_step

To force a CPU-only build even when CUDA is present:

cmake .. -DCUDAToolkit_ROOT=/nonexistent

Benchmarks

Five benchmarks compare three compute backends — cpu-eigen (Eigen SIMD contractions), cpu (OpenMP loops), and gpu (CUDA kernels) — across different architectures and model sizes. All benchmarks are reproducible via the scripts in the benchmarks/ directory.

Summary of GPU Speedups

ArchitectureModel SizeGPU Speedup vs cpu-eigenKey Observation
MLPSmall (4.5K params)2.0xGPU overhead limits gains for small matmuls
Medium (66K params)6.9x
Large (660K params)14.3x
XLarge (2.6M params)25.3xSub-linear GPU time scaling with params
CNNSmall (Conv16→32)28.8xConvolution is highly GPU-parallel
Medium (Conv32→64→FC128)42.0xHighest CNN speedup
RNN/LSTM/GRUSmall (H=64)2.2–5.2xGRU benefits most from GPU
Medium (H=128)4.7–15.5x
Large (H=256)12.2–56.4xGRU Large achieves 56.4x — highest overall
TransformerSmall (d=32, h=2)0.5x (slower)GPU overhead dominates at small scale
Medium (d=64, h=4)1.0x (break-even)
Large (d=128, h=8)1.2xModest gain; hybrid CPU/GPU attention
ResNetSmall (W=64, D=2)1.6xDepth amplifies GPU advantage
Medium (W=128, D=4)6.7x
Large (W=256, D=6)9.0xSkip connections add negligible overhead

Key Findings

  • GPU advantage grows with model size. Across all architectures, larger models see dramatically higher GPU speedups as matrix sizes better saturate GPU cores.
  • CNNs and recurrent layers benefit most from GPU. Convolution achieves up to 42x speedup; GRU achieves up to 56.4x — the highest across all benchmarks.
  • Transformers show modest GPU gains at tested scales due to mixed operations (embedding lookups, attention softmax, multiple small projections) and a hybrid CPU/GPU attention path.
  • Eigen (cpu-eigen) consistently outperforms OpenMP (cpu) for all architectures, leveraging SIMD vectorization and cache-optimal memory layouts.
  • Numerical consistency is verified across all backends — all devices converge to equivalent loss and accuracy values.

Average GPU Speedups by Architecture

ArchitectureAvg GPU SpeedupBest GPU SpeedupBest Config
MLP12.1x25.3xXLarge (2.6M params)
CNN35.4x42.0xMedium (Conv32→64→FC128)
Sequence (RNN/LSTM/GRU)13.7x56.4xGRU Large (H=256, seq=50)
Transformer0.9x1.2xLarge (d=128, h=8)
ResNet5.8x9.0xLarge (W=256, D=6)

How to Reproduce

cd build
cmake .. -DCMAKE_BUILD_TYPE=Release -DBUILD_BENCHMARKS=ON
make -j$(nproc)
./benchmarks/mlp_benchmark
./benchmarks/cnn_benchmark
./benchmarks/sequence_benchmark
./benchmarks/transformer_benchmark
./benchmarks/residual_benchmark

See benchmarks/benchmarks.md for full per-epoch results, detailed speedup analysis, and methodology.


Testing

CppNet has 41 unit tests with 377 test cases covering every module:

cd build
cmake .. -DBUILD_TESTS=ON
make -j$(nproc)
ctest --output-on-failure
CategoryTestsTest Cases
Layers (13)Linear, Conv2D, Flatten, MaxPool2D, RNN, Attention, BatchNorm, Dropout, Embedding, GlobalPool, GRU, LSTM, Residual123
Activations (5)ReLU, Sigmoid, Softmax, Tanh, LeakyReLU55
Losses (6)BinaryCrossEntropy, CategoricalCrossEntropy, MSE, MAE, Huber, SoftmaxCrossEntropy52
Optimizers (5)SGD, Adam, Momentum, Adagrad, RMSProp34
Utilities (7)Metrics, Regularizations, Callbacks, DataLoader, ElapsedTime, GradientClip, Init65
GPU Kernels (1)GPU matmul via Linear layer (forward, backward, step, CPU/GPU comparison)7
Other (4)Schedulers, Utils, Models, Visualizations41

Each test validates forward pass, backward pass (gradient shapes & values), parameter updates, and GPU/CPU numerical consistency where applicable.


Project Structure

CppNet/
├── CMakeLists.txt # Top-level build configuration
├── cmake/ # CMake package config templates
├── include/CppNet/ # Public headers
│ ├── CppNet.hpp # Single-include entry point
│ ├── activations/ # ReLU, Sigmoid, Softmax, Tanh, LeakyReLU
│ ├── layers/ # Linear, Conv2D, RNN, LSTM, GRU, Attention, ...
│ ├── losses/ # MSE, MAE, Huber, BCE, CCE, SoftmaxCE
│ ├── optimizers/ # SGD, Adam, Adagrad, Momentum, RMSProp
│ ├── models/ # SequentialModel
│ ├── metrics/ # Accuracy, Precision, Recall, F1
│ ├── regularizations/ # L1, L2, Elastic Net
│ ├── kernels/gpu/ # CUDA kernel declarations
│ ├── utils/ # DataLoader, Init, Schedulers, Serialization, ...
│ └── visualizations/ # TrainingLogger
├── src/CppNet/ # Implementation files (.cpp / .cu)
│ └── kernels/gpu/ # 41 CUDA kernel implementations
├── tests/ # 41 unit tests (377 test cases)
├── examples/ # 8 deep learning examples
├── benchmarks/ # 5 device benchmarks (CPU vs GPU)
└── docs/ # Additional documentation

Roadmap

  • Core layer library (Linear, Conv2D, Pooling, RNN, LSTM, GRU, Attention, BatchNorm, Dropout, Embedding, Residual)
  • Activation functions (ReLU, Sigmoid, Tanh, Softmax, LeakyReLU)
  • Loss functions (MSE, MAE, Huber, BCE, CCE, SoftmaxCE)
  • Optimizers (SGD, Adam, Adagrad, Momentum, RMSProp)
  • DataLoader, LR schedulers, early stopping, gradient clipping
  • Model serialization (save/load)
  • Full CUDA GPU backend — 41 kernels covering all layers, activations, losses, and optimizers
  • OpenMP CPU parallelism
  • Comprehensive test suite (41 tests, 377 test cases)
  • Deep learning examples (MLP, CNN, RNN/LSTM, GRU, Transformer, ResNet, Regularized CNN, Optimizer Comparison)
  • Device benchmarks (MLP, CNN, Sequence, Transformer, ResNet)
  • Add Trainer abstraction with built-in training loop
  • Additional examples (GANs, Reinforcement Learning, NLP pipelines)
  • Python bindings (pybind11)
  • Comprehensive API reference documentation

Contributing

Contributions are welcome! To get started:

  1. Fork the repository and create a feature branch.
  2. Follow the existing coding style — headers in include/CppNet/, implementations in src/CppNet/.
  3. Add tests for new functionality in tests/.
  4. Make sure all tests pass: cd build && ctest --output-on-failure.
  5. Open a pull request with a clear description of your changes.

License

CppNet is released under the MIT License.

Copyright © 2025 Loghman Samani

About

A high-performance C++ deep learning library for building and training neural networks

Resources

Stars

7 stars

Watchers

1 watching

Forks

Releases

Packages

Contributors

Languages