Added NDArray, did some light header and CMake restructuring

This commit is contained in:
NaifBanana
2026-10-30 02:19:05 -05:00
parent 97aed4e5ca
commit de7d435ccb
13 changed files with 287 additions and 170 deletions
+135
View File
@@ -0,0 +1,135 @@
#pragma once
#ifndef _NB_DATA_TYPES
#define _NB_DATA_TYPES
#include <algorithm>
#include <array>
#include <cstring>
#include <NBCore/Errors.hpp>
namespace nb {
/*!
* @brief A multidimensional array template class
*
* */
template<typename T, unsigned int N>
class NDArray {
public:
using Coordinate = std::array<unsigned int, N>;
private:
template<unsigned int M>
static Coordinate ProjectDimensions(const std::array<unsigned int, M>& dims) {
Coordinate p;
unsigned int i=0;
if constexpr (M > N) {
std::for_each(dims.begin(), dims.end(), [&](unsigned int x){
if (i < N) {
p[i] = x;
} else {
if (x != 1) {
THROW(Error(Error<>::VALUE_ERROR,
"Higher dimensions must have a size of 1"
));
}
}
i++;
});
} else if constexpr (M < N) {
p.fill(1);
std::for_each(dims.begin(), dims.end(), [&](unsigned int x) {p[i] = x; i++;});
} else { p = dims; }
return p;
}
protected:
T* _data;
static unsigned int CalculateTotalSize(const std::array<unsigned int, N>& dims) {
unsigned int ret = 1;
std::for_each(dims.begin(), dims.end(), [&](unsigned int n){
ret *= n;
});
return ret;
}
public:
template<typename U, unsigned int M>
friend class NDArray;
static NDArray&& MemoryToNDArray(const Coordinate& dimensions_, T* data_) {
auto ret = NDArray(dimensions_);
ret._data = data_;
return std::move(ret);
}
const Coordinate dimensions;
const unsigned int totalSize;
NDArray(const Coordinate& dimensions_, T* data_=nullptr) :
dimensions(dimensions_),
totalSize(CalculateTotalSize(dimensions_))
{
if (data_) { data(data_); }
}
NDArray(NDArray&& arr) :
dimensions(arr.dimensions),
totalSize(arr.totalSize),
_data(std::move(arr._data)) {}
NDArray(const NDArray& arr)=delete;
template<unsigned int M>
NDArray(NDArray<T, M>&& arr) :
dimensions(ProjectDimensions<M>(arr.dimensions)),
totalSize(arr.totalSize),
_data(std::move(arr._data)){}
NDArray& operator=(const NDArray& arr) = delete;
NDArray& operator=(NDArray&& arr) = delete;
~NDArray() {
if (_data) { delete[] _data; }
};
unsigned int coordinateToIndex(const Coordinate& coord) const {
unsigned int blockSize = 1;
unsigned int ret = 0;
for (auto i = 0; i < dimensions.size(); ++i) {
ret += coord[i] * blockSize;
blockSize *= dimensions[i];
}
return ret;
}
inline NDArray& copy() const {
return NDArray(dimensions, _data);
}
inline const T& at(const Coordinate& coord) const {
return operator[](coord);
}
inline const T* data() const { return _data; }
inline const T& operator[](const Coordinate& coord) const {
return _data[coordinateToIndex(coord)];
}
inline T& at(const Coordinate& coord) {
return _data[coordinateToIndex(coord)];
}
inline T* data(const T* data_) {
if (!_data) { _data = new T[totalSize]; }
std::memcpy(_data, data_, totalSize * sizeof(T));
return _data;
}
inline T& operator[](const Coordinate& coord) {
return _data[coordinateToIndex(coord)];
}
}; // class NDArray<type, int>
} // namespace nb
#endif // _NB_DATA_TYPES
@@ -0,0 +1,37 @@
#pragma once
#ifndef _NB_CORE_TYPES
#define _NB_CORE_TYPES
#include <memory>
#include <unordered_map>
#include <vector>
namespace nb {
template<typename T>
using SharedVector = std::vector<std::shared_ptr<T>>;
template<typename T>
using RValueVector = std::vector<T&&>;
using ByteVector = std::vector<uint8_t>;
template<typename A, typename B>
class ConstantMap : public std::unordered_map<A, B> {
using Base = std::unordered_map<A, B>;
public:
using Base::Base;
using Base::at;
const B& operator[](const A& key) const {
return at(key);
}
};
enum TypeCodes {
UINT8, UINT16, UINT32, UINT64, INT8, INT16, INT32, INT64,
FLOAT16, FLOAT32, DOUBLE64, BOOL, NONE
};
}; // namespace nb
#endif // _NB_NB_CORE_TYPES
@@ -1,71 +0,0 @@
#pragma once
#include <cstring>
#ifndef _NB_DATA_TYPES
#define _NB_DATA_TYPES
#include <algorithm>
#include <array>
#include <memory>
namespace nb {
template<typename T, unsigned int N>
class NDArray {
protected:
std::unique_ptr<T[]> _data;
static unsigned int calculateTotalSize(const std::array<unsigned int, N>& dims) {
unsigned int ret = 1;
std::for_each(dims.begin(), dims.end(), [&](unsigned int n){
ret *= n;
});
return ret;
}
public:
const std::array<unsigned int, N> dimensions;
const unsigned int totalSize;
static constexpr unsigned int NumberDimensions = N;
NDArray(
const std::array<unsigned int, N>& dimensions_,
T* data_=nullptr
) :
dimensions(dimensions_),
totalSize(calculateTotalSize(dimensions_))
{
if (data_) { data(data_); }
}
NDArray(
const std::array<unsigned int, N>& dimensions_,
const T* data_
) : NDArray(dimensions_) { data(data_); }
unsigned int coordinateToIndex(const std::array<T, N>& coord) const {
unsigned int blockSize = 1;
unsigned int ret = 0;
for (auto i = 0; i < dimensions.size(); ++i) {
ret += coord[i] * blockSize;
blockSize *= dimensions[i];
}
return ret;
}
inline const T& at(const std::array<T, N>& coord) const {
return _data[coordinateToIndex(coord)];
}
inline std::shared_ptr<T> data() const { return _data; }
inline T& at(const std::array<T, N>& coord) {
return _data[coordinateToIndex(coord)];
}
inline T* data(const T* data_) {
_data = std::make_unique<T[]>(totalSize);
std::memcpy(_data.get(), data_, totalSize * sizeof(T));
return _data.get();
}
}; // namespace nb
}
#endif // _NB_DATA_TYPES
+2 -2
View File
@@ -8,7 +8,7 @@
#include <type_traits>
#include <NBCore/StringUtils.hpp>
#include <NBCore/Utils.hpp>
#include <NBCore/CoreTypes.hpp>
namespace nb {
@@ -168,4 +168,4 @@ Error(Args...) -> Error<NoneType>;
} // namespace nb
#endif // _NB_ERRORS_IMPL
#endif // _NB_ERRORS_IMPL
+3 -6
View File
@@ -5,6 +5,8 @@
#include <type_traits>
#include <utility>
#include <NBCore/CoreTypes.hpp>
namespace nb {
namespace detail {
@@ -33,11 +35,6 @@ namespace detail {
template<typename K, typename V>
std::pair<K, V> KeyVal(K key, V val) { return std::pair(key, val); }
enum TypeCodes {
UINT8, UINT16, UINT32, UINT64, INT8, INT16, INT32, INT64,
FLOAT16, FLOAT32, DOUBLE64, BOOL, NONE
};
template<typename T>
static constexpr TypeCodes GetTypeEnum = NONE;
@@ -137,4 +134,4 @@ struct Find<T, U> {
} // namespace nb
#endif // _NB_TYPE_TRAITS
#endif // _NB_TYPE_TRAITS
+5 -27
View File
@@ -2,34 +2,13 @@
#ifndef _NB_UTILTIES
#define _NB_UTILTIES
#include <memory>
#include <unordered_map>
#include <vector>
// #include <NBCore/Errors.hpp>
#include <NBCore/CoreTypes.hpp>
#include <NBCore/Errors.hpp>
namespace nb {
template<typename A, typename B>
class ConstantMap : public std::unordered_map<A, B> {
using Base = std::unordered_map<A, B>;
public:
using Base::Base;
using Base::at;
const B& operator[](const A& key) const {
return at(key);
}
};
template<typename T>
using SharedVector = std::vector<std::shared_ptr<T>>;
template<typename T>
using RValueVector = std::vector<T&&>;
using ByteVector = std::vector<uint8_t>;
/* class ObjectManagerError : public Error<ObjectManagerError> {
using Base = Error<ObjectManagerError>;
@@ -67,11 +46,10 @@ ByteVector concatVectorBytes(const std::vector<T>& vec1, const std::vector<S>& v
template<typename T>
std::vector<T> bytesToVector(const ByteVector& vec) {
if (vec.size() % sizeof(T) != 0) {
/* THROW(Error<NoneType>(
THROW(Error(
std::runtime_error("Data size does not align to std::vector<" + std::string(typeid(T).name()) + ">.")
)); */
throw "byyyyeeee";
}
));
}
unsigned int num_elmts = vec.size() / sizeof(T);
std::vector<T> ret(num_elmts);
memcpy(ret.data(), vec.data(), vec.size());