diff --git a/CMakeLists.txt b/CMakeLists.txt index e0332f3..355d287 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -10,8 +10,8 @@ set(SOURCE_DIR ${CMAKE_CURRENT_SOURCE_DIR}/src) set(HEADERS ${INCLUDE_DIR}/CaberNet.h ${INCLUDE_DIR}/CaberNet/tensor.h - ${INCLUDE_DIR}/CaberNet/tensor/tensor_float32.h - ${INCLUDE_DIR}/CaberNet/tensor/tensor_int16.h + ${INCLUDE_DIR}/CaberNet/tensor/tensor_float.h + ${INCLUDE_DIR}/CaberNet/tensor/tensor_int.h ${INCLUDE_DIR}/CaberNet/functions.h ${INCLUDE_DIR}/CaberNet/layers.h ${INCLUDE_DIR}/CaberNet/model.h @@ -20,8 +20,8 @@ set(HEADERS set(SOURCES ${SOURCE_DIR}/tensor.cpp - ${SOURCE_DIR}/tensor/tensor_float32.cpp - ${SOURCE_DIR}/tensor/tensor_int16.cpp + ${SOURCE_DIR}/tensor/tensor_float.cpp + ${SOURCE_DIR}/tensor/tensor_int.cpp ${SOURCE_DIR}/functions.cpp ${SOURCE_DIR}/layers.cpp ${SOURCE_DIR}/criterions.cpp diff --git a/LICENSE b/LICENSE index 13132be..23806ee 100644 --- a/LICENSE +++ b/LICENSE @@ -1,6 +1,6 @@ MIT License -Copyright (c) 2023 Jiahao Li +Copyright (c) 2023 Eric Cardozo Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal diff --git a/README.md b/README.md index bec00c4..3f0c9dc 100644 --- a/README.md +++ b/README.md @@ -2,7 +2,7 @@ ## Join the Discord: -https://discord.gg/5Z7Xfs8Q +https://discord.gg/QJsKT82a ## Description diff --git a/include/CaberNet/tensor.h b/include/CaberNet/tensor.h index 2197b56..ff78a48 100644 --- a/include/CaberNet/tensor.h +++ b/include/CaberNet/tensor.h @@ -4,25 +4,21 @@ #include #include -#include "tensor/tensor_float32.h" -#include "tensor/tensor_int16.h" +#include "tensor/tensor_float.h" +#include "tensor/tensor_int.h" namespace net { -template -class Tensor { - public: - Tensor() { throw std::runtime_error("Bad type or not implemented type."); } -}; +template class Tensor; template<> -struct Tensor : public TensorFloat32 { - using TensorFloat32::TensorFloat32; +struct Tensor : public TensorFloat { + using TensorFloat::TensorFloat; }; template<> -struct Tensor : public TensorInt16 { - using TensorInt16::TensorInt16; +struct Tensor : public TensorInt { + using TensorInt::TensorInt; }; std::ostream& operator<<(std::ostream& ostream, const Tensor& tensor); diff --git a/include/CaberNet/tensor/tensor_float32.h b/include/CaberNet/tensor/tensor_float.h similarity index 83% rename from include/CaberNet/tensor/tensor_float32.h rename to include/CaberNet/tensor/tensor_float.h index 0895da8..98d2adb 100644 --- a/include/CaberNet/tensor/tensor_float32.h +++ b/include/CaberNet/tensor/tensor_float.h @@ -12,7 +12,7 @@ namespace net { template class Tensor; -class TensorFloat32 { +class TensorFloat { public: using value_type = float; // Needed for GMock's built-in matches using pointer = value_type*; @@ -25,10 +25,10 @@ class TensorFloat32 { using iterator = storage_type::iterator; using const_iterator = storage_type::const_iterator; - TensorFloat32() = default; - TensorFloat32(std::shared_ptr tensor); - TensorFloat32(shape_type shape, bool gradient_requirement = false); - TensorFloat32(shape_type shape, requires_gradient gradient_requirement); + TensorFloat() = default; + TensorFloat(std::shared_ptr tensor); + TensorFloat(shape_type shape, bool gradient_requirement = false); + TensorFloat(shape_type shape, requires_gradient gradient_requirement); void reshape(shape_type shape); diff --git a/include/CaberNet/tensor/tensor_int16.h b/include/CaberNet/tensor/tensor_int.h similarity index 84% rename from include/CaberNet/tensor/tensor_int16.h rename to include/CaberNet/tensor/tensor_int.h index cd4e323..6953b6f 100644 --- a/include/CaberNet/tensor/tensor_int16.h +++ b/include/CaberNet/tensor/tensor_int.h @@ -9,9 +9,9 @@ namespace net { template class Tensor; -class TensorInt16 { +class TensorInt { public: - using value_type = int16_t; + using value_type = int; using pointer = value_type*; using const_pointer = const value_type*; @@ -21,9 +21,9 @@ class TensorInt16 { using iterator = std::vector::iterator; using const_iterator = std::vector::const_iterator; - TensorInt16() = default; - TensorInt16(std::shared_ptr> subscripts); - TensorInt16(shape_type shape); + TensorInt() = default; + TensorInt(std::shared_ptr> subscripts); + TensorInt(shape_type shape); void reshape(shape_type shape); void fill(value_type value); diff --git a/src/internals/config.h b/src/internals/config.h index 5390267..932edf6 100644 --- a/src/internals/config.h +++ b/src/internals/config.h @@ -1,4 +1,4 @@ -/** +/* Note: This file is used to configure the internal library. Eigen is used as the default backend for the library, and should be included only in the cpp files, not in the h or hpp files. @@ -6,7 +6,7 @@ in the cpp files, not in the h or hpp files. This is for making the implementation of the operations independent of the internal library. The internal library should be able to use any backend, and the user should be able to choose the backend when compiling the library. -**/ +*/ #ifndef INTERNAL_CONFIG_H #define INTERNAL_CONFIG_H diff --git a/src/internals/criterions/internal_criterions.hpp b/src/internals/criterions/internal_criterions.hpp index 2b29742..4c588e0 100644 --- a/src/internals/criterions/internal_criterions.hpp +++ b/src/internals/criterions/internal_criterions.hpp @@ -14,7 +14,7 @@ class Criterion { using shape_type = Tensor::shape_type; using scalar_type = Tensor::scalar_type; - Criterion(Tensor* output, Array* targets) { + Criterion(Tensor* output, Array* targets) { output_ = output; targets_ = targets; } @@ -23,20 +23,20 @@ class Criterion { virtual scalar_type loss() const = 0; Tensor* output() const { return output_; } - Array* targets() const { return targets_; } + Array* targets() const { return targets_; } size_type number_of_classes() const { return output()->size() / batch_size(); } size_type batch_size() const { return output()->shape().front(); } private: Tensor* output_; - Array* targets_; + Array* targets_; }; class NLLLoss : public Criterion { public: ~NLLLoss() final = default; - NLLLoss(Tensor* output, Array* targets) : Criterion(output, targets) {} + NLLLoss(Tensor* output, Array* targets) : Criterion(output, targets) {} scalar_type loss() const final; }; diff --git a/src/internals/internal_expression.hpp b/src/internals/internal_expression.hpp index ed33888..5afc64e 100644 --- a/src/internals/internal_expression.hpp +++ b/src/internals/internal_expression.hpp @@ -1,8 +1,6 @@ -/*************************************************************************************************\ - +/* This is just an interface class for the non-leaf nodes of the computational graph. - -/*************************************************************************************************/ +*/ #ifndef INTERNAL_EXPRESSION_HPP #define INTERNAL_EXPRESSION_HPP diff --git a/src/tensor/tensor_float.cpp b/src/tensor/tensor_float.cpp new file mode 100644 index 0000000..9d388c4 --- /dev/null +++ b/src/tensor/tensor_float.cpp @@ -0,0 +1,81 @@ +#include "../../include/CaberNet/tensor/tensor_float.h" +#include "../../include/CaberNet/tensor.h" + +#include "../internals/internal_tensor.hpp" +#include "../internals/internal_graph.hpp" +#include "../internals/operations/internal_operations.hpp" + +namespace net { + +TensorFloat::TensorFloat(std::shared_ptr tensor) { + tensor_ = tensor; + internal::Graph::add(tensor_); +} + +TensorFloat::TensorFloat(shape_type shape, bool gradient_requirement ) { + tensor_ = std::make_shared(shape); + tensor_-> requires_gradient(gradient_requirement); + internal::Graph::add(tensor_); +} + +TensorFloat::TensorFloat(shape_type shape, requires_gradient gradient_requirement ) { + tensor_ = std::make_shared(shape); + tensor_-> requires_gradient(static_cast(gradient_requirement)); + internal::Graph::add(tensor_); +} + +void TensorFloat::reshape(shape_type shape) { + if(tensor_ == nullptr) tensor_ = std::make_shared(shape, false, false); + tensor_-> reshape(shape); +} + +Tensor TensorFloat::gradient() const { + Tensor gradient = std::make_shared(shape(), false); + std::copy(tensor_->gradient()->begin(), tensor_->gradient()->end(), gradient.begin()); + return gradient; +} + +internal::Tensor* TensorFloat::internal() const {return tensor_.get(); } +internal::Tensor* TensorFloat::internal() { return tensor_.get(); } + +void TensorFloat::backward(const Tensor& gradient) { tensor_-> backward(gradient.internal()); } +void TensorFloat::perform() { tensor_-> forward(); } // TODO : this should have a return type. + +TensorFloat::iterator TensorFloat::begin() { return tensor_->begin(); } +TensorFloat::iterator TensorFloat::end() { return tensor_->end(); } +TensorFloat::const_iterator TensorFloat::begin() const { return tensor_->begin(); } +TensorFloat::const_iterator TensorFloat::end() const { return tensor_->end(); } +TensorFloat::const_iterator TensorFloat::cbegin() const { return tensor_->cbegin(); } +TensorFloat::const_iterator TensorFloat::cend() const { return tensor_->cend(); } + +TensorFloat::pointer TensorFloat::data() { return tensor_->data(); } +TensorFloat::const_pointer TensorFloat::data() const { return tensor_->data(); } +TensorFloat::shape_type TensorFloat::shape() const { return tensor_->shape(); } +TensorFloat::size_type TensorFloat::rank() const { return tensor_->rank(); } + +void TensorFloat::fill(initializer distribution) { + distribution::Distribution* filler = nullptr; + switch (distribution) { + case initializer::He : + filler = new distribution::Normal(0, std::sqrt(2.0 / shape().back())); + for (auto& element : *this) element = filler->generate(); + break; + + default : + throw std::runtime_error("Invalid initializer"); + break; + } + + delete filler; +} + +void TensorFloat::fill(value_type value) { + std::fill(tensor_->begin(), tensor_->end(), value); +} + +void TensorFloat::fill(std::vector values) { + std::move(values.begin(), values.end(), tensor_->begin()); +} + +} // namespace net + diff --git a/src/tensor/tensor_float32.cpp b/src/tensor/tensor_float32.cpp deleted file mode 100644 index 9a2fdd9..0000000 --- a/src/tensor/tensor_float32.cpp +++ /dev/null @@ -1,95 +0,0 @@ -#include "../../include/CaberNet/tensor/tensor_float32.h" -#include "../../include/CaberNet/tensor.h" - -#include "../internals/internal_tensor.hpp" -#include "../internals/internal_graph.hpp" -#include "../internals/operations/internal_operations.hpp" - -namespace net { - -TensorFloat32::TensorFloat32(std::shared_ptr tensor) { - tensor_ = tensor; - internal::Graph::add(tensor_); -} - -TensorFloat32::TensorFloat32(shape_type shape, bool gradient_requirement ) { - tensor_ = std::make_shared(shape); - tensor_-> requires_gradient(gradient_requirement); - internal::Graph::add(tensor_); -} - -TensorFloat32::TensorFloat32(shape_type shape, requires_gradient gradient_requirement ) { - tensor_ = std::make_shared(shape); - tensor_-> requires_gradient(static_cast(gradient_requirement)); - internal::Graph::add(tensor_); -} - -void TensorFloat32::reshape(shape_type shape) { - if(tensor_ == nullptr) tensor_ = std::make_shared(shape, false, false); - tensor_-> reshape(shape); -} - -Tensor TensorFloat32::gradient() const { - Tensor gradient = std::make_shared(shape(), false); - std::copy(tensor_->gradient()->begin(), tensor_->gradient()->end(), gradient.begin()); - return gradient; -} - -internal::Tensor* TensorFloat32::internal() const {return tensor_.get(); } -internal::Tensor* TensorFloat32::internal() { return tensor_.get(); } - -void TensorFloat32::backward(const Tensor& gradient) { tensor_-> backward(gradient.internal()); } -void TensorFloat32::perform() { tensor_-> forward(); } // TODO : this should have a return type. - -TensorFloat32::iterator TensorFloat32::begin() { return tensor_->begin(); } -TensorFloat32::iterator TensorFloat32::end() { return tensor_->end(); } -TensorFloat32::const_iterator TensorFloat32::begin() const { return tensor_->begin(); } -TensorFloat32::const_iterator TensorFloat32::end() const { return tensor_->end(); } -TensorFloat32::const_iterator TensorFloat32::cbegin() const { return tensor_->cbegin(); } -TensorFloat32::const_iterator TensorFloat32::cend() const { return tensor_->cend(); } - -TensorFloat32::pointer TensorFloat32::data() { return tensor_->data(); } -TensorFloat32::const_pointer TensorFloat32::data() const { return tensor_->data(); } -TensorFloat32::shape_type TensorFloat32::shape() const { return tensor_->shape(); } -TensorFloat32::size_type TensorFloat32::rank() const { return tensor_->rank(); } - -/* -Tensor operator + (const Tensor& first, const Tensor& second) { - return Tensor(std::make_shared( first.internal(), second.internal() )); -} - -Tensor operator * (const Tensor& first, const Tensor& second) { - return Tensor(std::make_shared( first.internal(), second.internal() )); -} - -Tensor matmul(const Tensor& first, const Tensor& second) { - return Tensor(std::make_shared( first.internal(), second.internal() )); -} -*/ - -void TensorFloat32::fill(initializer distribution) { - distribution::Distribution* filler = nullptr; - switch (distribution) { - case initializer::He : - filler = new distribution::Normal(0, std::sqrt(2.0 / shape().back())); - for (auto& element : *this) element = filler->generate(); - break; - - default : - throw std::runtime_error("Invalid initializer"); - break; - } - - delete filler; -} - -void TensorFloat32::fill(value_type value) { - std::fill(tensor_->begin(), tensor_->end(), value); -} - -void TensorFloat32::fill(std::vector values) { - std::move(values.begin(), values.end(), tensor_->begin()); -} - -} // namespace net - diff --git a/src/tensor/tensor_int.cpp b/src/tensor/tensor_int.cpp new file mode 100644 index 0000000..000e8a5 --- /dev/null +++ b/src/tensor/tensor_int.cpp @@ -0,0 +1,43 @@ +#include "../../include/CaberNet/tensor/tensor_int.h" +#include "../../include/CaberNet/tensor.h" + +#include "../internals/internal_array.hpp" + +namespace net { + +TensorInt::TensorInt(std::shared_ptr> subscripts) { + data_ = subscripts; +} + +TensorInt::TensorInt(shape_type shape) { + data_ = std::make_shared>(shape); +} + +void TensorInt::reshape(shape_type shape) { + data_->reshape(shape); +} + +void TensorInt::fill(value_type value) { + std::fill(data_->begin(), data_->end(), value); +} + +void TensorInt::fill(std::vector values) { + std::move(values.begin(), values.end(), data_->begin()); +} + +internal::Array* TensorInt::internal() const { return data_.get(); } +internal::Array* TensorInt::internal() { return data_.get(); } + +TensorInt::iterator TensorInt::begin() { return data_->begin(); } +TensorInt::iterator TensorInt::end() { return data_->end(); } +TensorInt::const_iterator TensorInt::begin() const { return data_->cbegin(); } +TensorInt::const_iterator TensorInt::end() const { return data_->cend(); } +TensorInt::const_iterator TensorInt::cbegin() const { return data_->cbegin(); } +TensorInt::const_iterator TensorInt::cend() const { return data_->cend(); } + +TensorInt::pointer TensorInt::data() { return data_->data(); } +TensorInt::const_pointer TensorInt::data() const { return data_->data(); } +TensorInt::shape_type TensorInt::shape() const { return data_->shape(); } +TensorInt::size_type TensorInt::rank() const { return data_->rank(); } + +} // namespace net \ No newline at end of file diff --git a/src/tensor/tensor_int16.cpp b/src/tensor/tensor_int16.cpp deleted file mode 100644 index 8efd489..0000000 --- a/src/tensor/tensor_int16.cpp +++ /dev/null @@ -1,43 +0,0 @@ -#include "../../include/CaberNet/tensor/tensor_int16.h" -#include "../../include/CaberNet/tensor.h" - -#include "../internals/internal_array.hpp" - -namespace net { - -TensorInt16::TensorInt16(std::shared_ptr> subscripts) { - data_ = subscripts; -} - -TensorInt16::TensorInt16(shape_type shape) { - data_ = std::make_shared>(shape); -} - -void TensorInt16::reshape(shape_type shape) { - data_->reshape(shape); -} - -void TensorInt16::fill(value_type value) { - std::fill(data_->begin(), data_->end(), value); -} - -void TensorInt16::fill(std::vector values) { - std::move(values.begin(), values.end(), data_->begin()); -} - -internal::Array* TensorInt16::internal() const { return data_.get(); } -internal::Array* TensorInt16::internal() { return data_.get(); } - -TensorInt16::iterator TensorInt16::begin() { return data_->begin(); } -TensorInt16::iterator TensorInt16::end() { return data_->end(); } -TensorInt16::const_iterator TensorInt16::begin() const { return data_->cbegin(); } -TensorInt16::const_iterator TensorInt16::end() const { return data_->cend(); } -TensorInt16::const_iterator TensorInt16::cbegin() const { return data_->cbegin(); } -TensorInt16::const_iterator TensorInt16::cend() const { return data_->cend(); } - -TensorInt16::pointer TensorInt16::data() { return data_->data(); } -TensorInt16::const_pointer TensorInt16::data() const { return data_->data(); } -TensorInt16::shape_type TensorInt16::shape() const { return data_->shape(); } -TensorInt16::size_type TensorInt16::rank() const { return data_->rank(); } - -} // namespace net \ No newline at end of file