Compare commits
281 commits
master-bac
...
master
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
0f15c37c2e | ||
|
|
a7b9feaedc | ||
|
|
35a2297ab2 | ||
|
|
44bc283f4f | ||
|
|
822c60d839 | ||
|
|
0b279163de | ||
|
|
543534bf61 | ||
|
|
ba10834602 | ||
|
|
49c2cadb0a | ||
|
|
e10a494223 | ||
|
|
afad2c80e5 | ||
|
|
c41dc20132 | ||
|
|
03da5e41d6 | ||
|
|
b1ba1c2975 | ||
|
|
8c4ba37e59 | ||
|
|
c7496c7b42 | ||
|
|
96b293d1b5 | ||
|
|
e00dec67ba | ||
|
|
837d8dc507 | ||
|
|
d6025bc4e0 | ||
|
|
0ebbe75b6e | ||
|
|
5de5dbba23 | ||
|
|
c94f5144e7 | ||
|
|
a36386cc20 | ||
|
|
0b73f8037b | ||
|
|
9f9dcd5882 | ||
|
|
164359f6aa | ||
|
|
4b6e7da994 | ||
|
|
279cf58dff | ||
|
|
3f49ee11ae | ||
|
|
5e3f5594b8 | ||
|
|
860474654a | ||
|
|
3be2425665 | ||
|
|
3b27fe17c1 | ||
|
|
c3b563a032 | ||
|
|
aa141405c6 | ||
|
|
da6990ddc8 | ||
|
|
242cd93589 | ||
|
|
9cc4819524 | ||
|
|
fcd0209710 | ||
|
|
4a557d7e5c | ||
|
|
a55a5ec5cc | ||
|
|
c87e5a25d5 | ||
|
|
285ca80b4b | ||
|
|
5cc982fa00 | ||
|
|
2bc06cdd5a | ||
|
|
25236f82c3 | ||
|
|
22e6967ae2 | ||
|
|
aa7bf32940 | ||
|
|
8b54ca0216 | ||
|
|
351a5d842e | ||
|
|
39c3d88f7a | ||
|
|
5ac4d56d32 | ||
|
|
8bec5d1ab7 | ||
|
|
e32e5e77d1 | ||
|
|
938616d989 | ||
|
|
3bc43612ef | ||
|
|
5c90192c9f | ||
|
|
805c891557 | ||
|
|
3cc8dbc102 | ||
|
|
8bfe44b3cd | ||
|
|
bc29860385 | ||
|
|
b206e4444e | ||
|
|
60b5f08f65 | ||
|
|
1ec84044be | ||
|
|
6b77faced8 | ||
|
|
19f492dff1 | ||
|
|
0f8fb5c580 | ||
|
|
35cb553ecb | ||
|
|
1767b65c7e | ||
|
|
90244934d9 | ||
|
|
aa10424fbb | ||
|
|
0192d58fa4 | ||
|
|
db1a6b35ef | ||
|
|
92d8b04cf8 | ||
|
|
fc00a83f2e | ||
|
|
13bcbcb23f | ||
|
|
3148e2c020 | ||
|
|
4d381d62e4 | ||
|
|
715175085e | ||
|
|
714bdaef12 | ||
|
|
88b78d907a | ||
|
|
24f9d8acae | ||
|
|
cf3f8dbc9c | ||
|
|
ca1ae75b07 | ||
|
|
9e2e7f5809 | ||
|
|
c6260f7c48 | ||
|
|
f8c82b7e29 | ||
|
|
e78885d452 | ||
|
|
9d01ba2c8a | ||
|
|
89eec0e329 | ||
|
|
9054ed9f4a | ||
|
|
f10f04bac2 | ||
|
|
04f5ec30bc | ||
|
|
1756ca026d | ||
|
|
fa2d0aaa92 | ||
|
|
57d5591d4a | ||
|
|
26cf35807d | ||
|
|
e6e88193c2 | ||
|
|
9972960556 | ||
|
|
ee805fd3d7 | ||
|
|
ad6581cc18 | ||
|
|
9486cf0bee | ||
|
|
6d8c64ac33 | ||
|
|
689bee9afc | ||
|
|
8451c56e93 | ||
|
|
bfbdd0e33b | ||
|
|
5c18a10d11 | ||
|
|
a46a2167ba | ||
|
|
6d02137dca | ||
|
|
fb374e71e4 | ||
|
|
16af8dc809 | ||
|
|
25fd52294f | ||
|
|
84046e89be | ||
|
|
e331fc1a34 | ||
|
|
e0f92b32dc | ||
|
|
8eae09591d | ||
|
|
9fd3183961 | ||
|
|
e065dc736b | ||
|
|
cd8feaf2c0 | ||
|
|
1155067b26 | ||
|
|
3b389bdc17 | ||
|
|
2455f90550 | ||
|
|
f8c38a8a37 | ||
|
|
8866290d29 | ||
|
|
0eaf22cc46 | ||
|
|
69a17a609e | ||
|
|
afab59eb21 | ||
|
|
b8bcf58a29 | ||
|
|
79d018ffb4 | ||
|
|
5c7ee99d43 | ||
|
|
101ef375ef | ||
|
|
b56829ea26 | ||
|
|
0b3f780ec7 | ||
|
|
0494bf05af | ||
|
|
8cc5f2f9f7 | ||
|
|
69db2b82a4 | ||
|
|
72e034ca32 | ||
|
|
06f70f3d2f | ||
|
|
f5dbbc1330 | ||
|
|
d2dde03efb | ||
|
|
93266715c0 | ||
|
|
0f455dd33b | ||
|
|
3eadb0d726 | ||
|
|
6c92be58cd | ||
|
|
2484ea9d9c | ||
|
|
d4c85a3d86 | ||
|
|
87fb15ed13 | ||
|
|
b647271081 | ||
|
|
505b77da3f | ||
|
|
8dc73bc1d5 | ||
|
|
1293136343 | ||
|
|
8f87c3bc33 | ||
|
|
30d4f194ba | ||
|
|
aaeb6438a1 | ||
|
|
b2a1883369 | ||
|
|
7a685e0634 | ||
|
|
2ebf650381 | ||
|
|
b883f0029c | ||
|
|
70b6bf4d77 | ||
|
|
6279323a84 | ||
|
|
226c62f40b | ||
|
|
7121917a5d | ||
|
|
dbd53719b0 | ||
|
|
8f38095bec | ||
|
|
184f8dd1fe | ||
|
|
fb8202f385 | ||
|
|
56d63f2f18 | ||
|
|
b3e5bf0941 | ||
|
|
419ebb43d1 | ||
|
|
53b690dad9 | ||
|
|
aecad978ec | ||
|
|
b8f2380c60 | ||
|
|
73897f11df | ||
|
|
94d1bb7f41 | ||
|
|
782a041ba8 | ||
|
|
8955a02d05 | ||
|
|
36efa46848 | ||
|
|
5106cc3b71 | ||
|
|
466c0c36bd | ||
|
|
1a5d2934ae | ||
|
|
c34c41d0f5 | ||
|
|
0b63045503 | ||
|
|
b26310439d | ||
|
|
420bb37039 | ||
|
|
7660d58f26 | ||
|
|
1d48d390d3 | ||
|
|
5a3e07f4f3 | ||
|
|
d5a08acf6d | ||
|
|
cd451d1c2a | ||
|
|
cb09a6f5de | ||
|
|
98b5e4d182 | ||
|
|
b74c5bc5e5 | ||
|
|
a233b6a214 | ||
|
|
dd71eba0ec | ||
|
|
f6ba86aff8 | ||
|
|
fa72355799 | ||
|
|
ee8027055e | ||
|
|
4804e51ad7 | ||
|
|
90ce453b60 | ||
|
|
7e17b32a81 | ||
|
|
91fb72bd49 | ||
|
|
b4ae5dde77 | ||
|
|
e9daedd6ea | ||
|
|
97a99f84f5 | ||
|
|
15c5576273 | ||
|
|
4d00ef1296 | ||
|
|
77db3f4ab5 | ||
|
|
368ae81251 | ||
|
|
a84cfabd60 | ||
|
|
a3a79c87da | ||
|
|
a62e665623 | ||
|
|
bb2b0b926f | ||
|
|
d6c326b83d | ||
|
|
eb133745f9 | ||
|
|
b2fa4c4266 | ||
|
|
15b56a876a | ||
|
|
25b66804a4 | ||
|
|
74aaf9a0a1 | ||
|
|
be206950f0 | ||
|
|
7b276e1005 | ||
|
|
0e4f4228de | ||
|
|
16115b483a | ||
|
|
2c8151ec3e | ||
|
|
24d554abc3 | ||
|
|
ffb533ec9a | ||
|
|
d9ffb61712 | ||
|
|
f5e9b041cd | ||
|
|
259bf5a485 | ||
|
|
92e772cde1 | ||
|
|
a938bf9bb1 | ||
|
|
8feeb3d1c1 | ||
|
|
42ee676bc9 | ||
|
|
cef0db6fb1 | ||
|
|
4825d61486 | ||
|
|
64960c6aff | ||
|
|
17ad239692 | ||
|
|
f579a969ce | ||
|
|
3f4f2caf1f | ||
|
|
ab0edfc302 | ||
|
|
e0eb6e138d | ||
|
|
a679ab1c4b | ||
|
|
63029e6083 | ||
|
|
edf0548046 | ||
|
|
31e420b311 | ||
|
|
4a5877784b | ||
|
|
d3df3dde09 | ||
|
|
94057d2a66 | ||
|
|
0f639ba3b1 | ||
|
|
41f7d978a9 | ||
|
|
1e2ca13a15 | ||
|
|
8df79328cd | ||
|
|
c375472bbe | ||
|
|
aaa08e4495 | ||
|
|
f52b351cac | ||
|
|
98132ca2f5 | ||
|
|
e50cb9f0e2 | ||
|
|
8c600a1cdb | ||
|
|
f60e73fc32 | ||
|
|
58db6fe058 | ||
|
|
32c7512b69 | ||
|
|
038e6c58cf | ||
|
|
d5dfb1c304 | ||
|
|
bd1a6a44db | ||
|
|
f5cab30f21 | ||
|
|
3846b91662 | ||
|
|
e08f961707 | ||
|
|
29ab5fa8a6 | ||
|
|
54c44dbd6a | ||
|
|
53aa0e34a8 | ||
|
|
f91b45643d | ||
|
|
1aece0c617 | ||
|
|
6248c294b8 | ||
|
|
f676e84521 | ||
|
|
1310bb78ad | ||
|
|
0ec44ee2d1 | ||
|
|
ffa90323a4 | ||
|
|
f46ea7e0fb | ||
|
|
b7560534c1 | ||
|
|
eae8852832 | ||
|
|
2dff05d412 |
23 changed files with 797 additions and 19 deletions
6
.gitmodules
vendored
6
.gitmodules
vendored
|
|
@ -22,3 +22,9 @@
|
||||||
[submodule "Externals/implot"]
|
[submodule "Externals/implot"]
|
||||||
path = Externals/implot
|
path = Externals/implot
|
||||||
url = https://github.com/epezent/implot.git
|
url = https://github.com/epezent/implot.git
|
||||||
|
[submodule "Externals/googletest"]
|
||||||
|
path = Externals/googletest
|
||||||
|
url = https://github.com/google/googletest.git
|
||||||
|
[submodule "Externals/benchmark"]
|
||||||
|
path = Externals/benchmark
|
||||||
|
url = https://github.com/google/benchmark.git
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,7 @@
|
||||||
project(Containers)
|
project(Containers)
|
||||||
|
|
||||||
|
include(GoogleTest)
|
||||||
|
|
||||||
### ---------------------- Static Library --------------------- ###
|
### ---------------------- Static Library --------------------- ###
|
||||||
file(GLOB SOURCES "./private/*.cpp")
|
file(GLOB SOURCES "./private/*.cpp")
|
||||||
file(GLOB HEADERS "./public/*.hpp")
|
file(GLOB HEADERS "./public/*.hpp")
|
||||||
|
|
@ -16,6 +18,7 @@ file(GLOB TEST_SOURCES
|
||||||
./tests/ListTest.cpp
|
./tests/ListTest.cpp
|
||||||
./tests/MapTest.cpp
|
./tests/MapTest.cpp
|
||||||
./tests/TreeTest.cpp
|
./tests/TreeTest.cpp
|
||||||
|
./tests/RingBufferByte.cpp
|
||||||
./tests/Tests.cpp
|
./tests/Tests.cpp
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
@ -24,5 +27,10 @@ target_link_libraries(Tests${PROJECT_NAME} ${PROJECT_NAME} UnitTest++)
|
||||||
add_test(NAME Tests${PROJECT_NAME} COMMAND Tests${PROJECT_NAME})
|
add_test(NAME Tests${PROJECT_NAME} COMMAND Tests${PROJECT_NAME})
|
||||||
|
|
||||||
|
|
||||||
|
add_executable(testLinearRingBuffer ./tests/testLinearRingBuffer.cpp)
|
||||||
|
target_link_libraries(testLinearRingBuffer ${PROJECT_NAME} gtest)
|
||||||
|
gtest_discover_tests(testLinearRingBuffer)
|
||||||
|
|
||||||
|
|
||||||
add_executable(AVLTreeSpeedTest ./tests/AVLTreeProfiling.cpp)
|
add_executable(AVLTreeSpeedTest ./tests/AVLTreeProfiling.cpp)
|
||||||
target_link_libraries(AVLTreeSpeedTest ${PROJECT_NAME})
|
target_link_libraries(AVLTreeSpeedTest ${PROJECT_NAME})
|
||||||
65
Containers/private/linear_ring.cpp
Normal file
65
Containers/private/linear_ring.cpp
Normal file
|
|
@ -0,0 +1,65 @@
|
||||||
|
#include <cstdint>
|
||||||
|
#include <sys/mman.h>
|
||||||
|
#include <sys/syscall.h>
|
||||||
|
#include <unistd.h>
|
||||||
|
#include <fcntl.h>
|
||||||
|
#include <stdexcept>
|
||||||
|
#include <cstring>
|
||||||
|
|
||||||
|
namespace lrbm {
|
||||||
|
static int create_memfd(const char* name) {
|
||||||
|
int fd = syscall(SYS_memfd_create, name, 0);
|
||||||
|
if (fd == -1) throw std::runtime_error("memfd_create failed");
|
||||||
|
return fd;
|
||||||
|
}
|
||||||
|
|
||||||
|
std::pair<void*, size_t> create_linear_ring(size_t size) {
|
||||||
|
const size_t page = sysconf(_SC_PAGESIZE);
|
||||||
|
|
||||||
|
size_t aligned = (size + page - 1) & ~(page - 1);
|
||||||
|
|
||||||
|
// Create RAM-backed file descriptor
|
||||||
|
int fd = create_memfd("linear_ring");
|
||||||
|
if (ftruncate(fd, aligned) != 0) throw std::runtime_error("ftruncate failed");
|
||||||
|
|
||||||
|
// Reserve 2× VA space
|
||||||
|
uint8_t* base = (uint8_t*) mmap(nullptr, aligned * 2, PROT_NONE, MAP_PRIVATE | MAP_ANONYMOUS, -1, 0);
|
||||||
|
if (base == MAP_FAILED) throw std::runtime_error("mmap reserve failed");
|
||||||
|
|
||||||
|
// First mapping
|
||||||
|
void* p1 = mmap(base, aligned, PROT_READ | PROT_WRITE, MAP_FIXED | MAP_SHARED, fd, 0);
|
||||||
|
if (p1 != base) throw std::runtime_error("first mmap failed");
|
||||||
|
|
||||||
|
// Mirror mapping
|
||||||
|
void* p2 = mmap(base + aligned, aligned, PROT_READ | PROT_WRITE, MAP_FIXED | MAP_SHARED, fd, 0);
|
||||||
|
if (p2 != base + aligned) throw std::runtime_error("mirror mmap failed");
|
||||||
|
|
||||||
|
close(fd);
|
||||||
|
return { base, aligned }; // linear region [buf][buf]
|
||||||
|
}
|
||||||
|
|
||||||
|
void destroy_linear_ring(void* base, size_t size) { munmap(base, size); }
|
||||||
|
|
||||||
|
// void test() {
|
||||||
|
// const size_t RING_SIZE = 4096;
|
||||||
|
// uint8_t* ring = (uint8_t*) create_linear_ring(RING_SIZE);
|
||||||
|
|
||||||
|
// printf("Linear ring created at %p (size = %zu)\n", ring, RING_SIZE);
|
||||||
|
|
||||||
|
// const char* msg = "HELLO_LINEAR_RING";
|
||||||
|
// size_t msg_len = strlen(msg);
|
||||||
|
|
||||||
|
// size_t head = RING_SIZE - 4; // force boundary crossing
|
||||||
|
// std::memcpy(ring + head, msg, msg_len);
|
||||||
|
|
||||||
|
// char out[64];
|
||||||
|
// std::memcpy(out, ring + head, msg_len);
|
||||||
|
// out[msg_len] = 0;
|
||||||
|
|
||||||
|
// printf("Expected: %s\n", msg);
|
||||||
|
// printf("Readback: %s\n", out);
|
||||||
|
|
||||||
|
// if (std::strcmp(msg, out) == 0) printf("SUCCESS: Linear-address ring works!\n");
|
||||||
|
// else printf("FAILURE: Ring broken!\n");
|
||||||
|
// }
|
||||||
|
}
|
||||||
54
Containers/public/LinearRingBuffer.hpp
Normal file
54
Containers/public/LinearRingBuffer.hpp
Normal file
|
|
@ -0,0 +1,54 @@
|
||||||
|
|
||||||
|
#include <cstddef>
|
||||||
|
#include <cstdint>
|
||||||
|
#include <sys/mman.h>
|
||||||
|
|
||||||
|
#include "liniar_ring.hpp"
|
||||||
|
|
||||||
|
class LinearRingBuffer {
|
||||||
|
public:
|
||||||
|
LinearRingBuffer(size_t size, size_t history) {
|
||||||
|
const auto& [mem, aligned_size] = lrbm::create_linear_ring(size);
|
||||||
|
|
||||||
|
mem_ = (uint8_t*) mem;
|
||||||
|
memSize_ = aligned_size;
|
||||||
|
bufferSize_ = size;
|
||||||
|
historySize_ = history;
|
||||||
|
|
||||||
|
write_ptr_ = mem_;
|
||||||
|
read_ptr_ = mem_;
|
||||||
|
}
|
||||||
|
|
||||||
|
~LinearRingBuffer() { lrbm::destroy_linear_ring((void*) mem_, memSize_ * 2); }
|
||||||
|
|
||||||
|
uint8_t* write_data() { return write_ptr_; }
|
||||||
|
uint8_t* read_data() { return read_ptr_; }
|
||||||
|
|
||||||
|
void write_advance(size_t bytes) { write_ptr_ = advancePointer(write_ptr_, bytes); }
|
||||||
|
void read_advance(size_t bytes) { read_ptr_ = advancePointer(read_ptr_, bytes); }
|
||||||
|
|
||||||
|
void read_reset_with_history() {
|
||||||
|
const auto offset = size_t(write_ptr_ - mem_);
|
||||||
|
|
||||||
|
if (historySize_ < offset) {
|
||||||
|
read_ptr_ = write_ptr_ - historySize_;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
read_ptr_ = mem_ + (memSize_ + offset - historySize_);
|
||||||
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
inline uint8_t* advancePointer(const uint8_t* ptr, size_t bytes) {
|
||||||
|
return mem_ + (size_t(ptr - mem_) + bytes) % memSize_;
|
||||||
|
}
|
||||||
|
|
||||||
|
size_t bufferSize_ = 0;
|
||||||
|
size_t historySize_ = 0;
|
||||||
|
size_t memSize_ = 0;
|
||||||
|
|
||||||
|
uint8_t* mem_ = nullptr;
|
||||||
|
|
||||||
|
uint8_t* read_ptr_ = 0;
|
||||||
|
uint8_t* write_ptr_ = 0;
|
||||||
|
};
|
||||||
127
Containers/public/RingBufferByte.hpp
Normal file
127
Containers/public/RingBufferByte.hpp
Normal file
|
|
@ -0,0 +1,127 @@
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include <cstddef>
|
||||||
|
#include <cstdint>
|
||||||
|
#include <cstdio>
|
||||||
|
#include <cassert>
|
||||||
|
#include <cstring>
|
||||||
|
#include <stdexcept>
|
||||||
|
#include <vector>
|
||||||
|
|
||||||
|
template <bool ALLOW_BUFFER_OVERRIDE>
|
||||||
|
class RingBufferByte {
|
||||||
|
public:
|
||||||
|
explicit RingBufferByte(size_t maxCapacity) { buffer_.resize(maxCapacity); }
|
||||||
|
|
||||||
|
~RingBufferByte() = default;
|
||||||
|
|
||||||
|
void pushBack(const uint8_t* buffer, size_t size) {
|
||||||
|
const auto REQUIRED_SIZE = size + sizeof(size);
|
||||||
|
const auto DEPOSIT = static_cast<int>(freeSpace()) - static_cast<int>(REQUIRED_SIZE);
|
||||||
|
|
||||||
|
if (DEPOSIT < 0) {
|
||||||
|
if (ALLOW_BUFFER_OVERRIDE) {
|
||||||
|
freeupSpace(static_cast<size_t>(-DEPOSIT));
|
||||||
|
} else {
|
||||||
|
throw std::runtime_error("ring buffer overflow");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
push(reinterpret_cast<const uint8_t*>(&size), sizeof(size));
|
||||||
|
push(buffer, size);
|
||||||
|
}
|
||||||
|
|
||||||
|
[[nodiscard]] auto frontSize() const -> size_t {
|
||||||
|
size_t size = 0;
|
||||||
|
|
||||||
|
if (dataSize() < sizeof(size)) {
|
||||||
|
throw std::runtime_error("no data in the buffer");
|
||||||
|
}
|
||||||
|
|
||||||
|
peek(reinterpret_cast<uint8_t*>(&size), sizeof(size));
|
||||||
|
|
||||||
|
return size;
|
||||||
|
}
|
||||||
|
|
||||||
|
auto popFront(uint8_t* buffer) -> size_t {
|
||||||
|
size_t size = 0;
|
||||||
|
|
||||||
|
if (dataSize() < sizeof(size)) {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
pop(reinterpret_cast<uint8_t*>(&size), sizeof(size));
|
||||||
|
pop(buffer, size);
|
||||||
|
|
||||||
|
return size;
|
||||||
|
}
|
||||||
|
|
||||||
|
void clear() {
|
||||||
|
end_ = 0;
|
||||||
|
start_ = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
[[nodiscard]] bool empty() const { return start_ == end_; }
|
||||||
|
|
||||||
|
private:
|
||||||
|
void push(const uint8_t* buffer, size_t size) {
|
||||||
|
for (size_t simpleIdx = 0; simpleIdx < size; simpleIdx++) {
|
||||||
|
buffer_[end_++] = buffer == nullptr ? 0 : buffer[simpleIdx];
|
||||||
|
|
||||||
|
if (end_ == buffer_.size()) {
|
||||||
|
end_ = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void pop(uint8_t* buffer, size_t size) {
|
||||||
|
for (size_t sampleIdx = 0; sampleIdx < size; sampleIdx++) {
|
||||||
|
if (buffer != nullptr) {
|
||||||
|
buffer[sampleIdx] = buffer_[start_];
|
||||||
|
}
|
||||||
|
|
||||||
|
start_++;
|
||||||
|
|
||||||
|
if (start_ == buffer_.size()) {
|
||||||
|
start_ = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void peek(uint8_t* buffer, size_t size) const {
|
||||||
|
auto iter = start_;
|
||||||
|
for (size_t sampleIdx = 0; sampleIdx < size; sampleIdx++) {
|
||||||
|
buffer[sampleIdx] = buffer_[iter++];
|
||||||
|
|
||||||
|
if (iter == buffer_.size()) {
|
||||||
|
iter = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void freeupSpace(size_t additionalRequiredSpace) {
|
||||||
|
const auto CURRENT_DEPOSIT = freeSpace();
|
||||||
|
|
||||||
|
while (CURRENT_DEPOSIT + additionalRequiredSpace >= freeSpace()) {
|
||||||
|
popFront(nullptr);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
[[nodiscard]] size_t freeSpace() const {
|
||||||
|
if (start_ > end_) {
|
||||||
|
return start_ - end_;
|
||||||
|
}
|
||||||
|
|
||||||
|
const auto OUT = buffer_.size() - (end_ - start_);
|
||||||
|
return OUT;
|
||||||
|
}
|
||||||
|
|
||||||
|
[[nodiscard]] size_t dataSize() const { return buffer_.size() - freeSpace(); }
|
||||||
|
|
||||||
|
[[nodiscard]] bool hasSpace(unsigned int length) const { return freeSpace() > length; }
|
||||||
|
|
||||||
|
std::vector<uint8_t> buffer_;
|
||||||
|
|
||||||
|
size_t end_ = 0;
|
||||||
|
size_t start_ = 0;
|
||||||
|
};
|
||||||
9
Containers/public/liniar_ring.hpp
Normal file
9
Containers/public/liniar_ring.hpp
Normal file
|
|
@ -0,0 +1,9 @@
|
||||||
|
|
||||||
|
#include <cstddef>
|
||||||
|
#include <utility>
|
||||||
|
|
||||||
|
namespace lrbm {
|
||||||
|
std::pair<void*, size_t> create_linear_ring(size_t size);
|
||||||
|
void destroy_linear_ring(void* base, size_t size);
|
||||||
|
void test();
|
||||||
|
}
|
||||||
69
Containers/tests/RingBufferByte.cpp
Normal file
69
Containers/tests/RingBufferByte.cpp
Normal file
|
|
@ -0,0 +1,69 @@
|
||||||
|
|
||||||
|
#include "Tests.hpp"
|
||||||
|
#include "RingBufferByte.hpp"
|
||||||
|
|
||||||
|
SUITE(RingBufferBytes) {
|
||||||
|
TEST(Simple) {
|
||||||
|
|
||||||
|
using Data = std::vector<uint8_t>;
|
||||||
|
using DataStorage = std::vector<Data>;
|
||||||
|
|
||||||
|
constexpr auto BUFFER_SIZE = 395;
|
||||||
|
constexpr auto MAX_MSG_SIZE = 31;
|
||||||
|
constexpr auto ITERATIONS = 100000;
|
||||||
|
|
||||||
|
DataStorage pushed;
|
||||||
|
DataStorage popped;
|
||||||
|
|
||||||
|
RingBufferByte<true> buffer(BUFFER_SIZE);
|
||||||
|
|
||||||
|
Data randomSamples(MAX_MSG_SIZE);
|
||||||
|
|
||||||
|
for (auto idx = 0; idx < MAX_MSG_SIZE; idx++) {
|
||||||
|
randomSamples[idx] = (idx + 5 * 31) % 13;
|
||||||
|
}
|
||||||
|
|
||||||
|
const auto PUSH = [&](RingBufferByte<true>& buffer, DataStorage* storage) {
|
||||||
|
const Data& pushedSample = randomSamples;
|
||||||
|
|
||||||
|
buffer.pushBack(pushedSample.data(), pushedSample.size());
|
||||||
|
|
||||||
|
if (storage) {
|
||||||
|
storage->push_back(pushedSample);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
const auto POP = [](RingBufferByte<true>& buffer, DataStorage* storage) {
|
||||||
|
const auto poppedSampleSize = buffer.frontSize();
|
||||||
|
|
||||||
|
Data poppedSample(poppedSampleSize);
|
||||||
|
|
||||||
|
const auto SIZE = buffer.popFront(poppedSample.data());
|
||||||
|
|
||||||
|
CHECK(poppedSample.size() == SIZE);
|
||||||
|
|
||||||
|
if (storage) {
|
||||||
|
storage->push_back(poppedSample);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
for (auto iteration = 0; iteration < ITERATIONS; iteration++) {
|
||||||
|
PUSH(buffer, nullptr);
|
||||||
|
}
|
||||||
|
|
||||||
|
while (!buffer.empty()) {
|
||||||
|
POP(buffer, nullptr);
|
||||||
|
}
|
||||||
|
|
||||||
|
for (auto iteration = 0; iteration < ITERATIONS; iteration++) {
|
||||||
|
PUSH(buffer, &pushed);
|
||||||
|
POP(buffer, &popped);
|
||||||
|
}
|
||||||
|
|
||||||
|
CHECK(pushed.size() == popped.size());
|
||||||
|
|
||||||
|
for (auto idx = 0; idx < popped.size(); idx++) {
|
||||||
|
CHECK(pushed[idx] == popped[idx]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
188
Containers/tests/benchLinearRingBuffer.cpp
Normal file
188
Containers/tests/benchLinearRingBuffer.cpp
Normal file
|
|
@ -0,0 +1,188 @@
|
||||||
|
#include "LinearRingBuffer.hpp"
|
||||||
|
|
||||||
|
#include <gtest/gtest.h>
|
||||||
|
|
||||||
|
#include <cstring>
|
||||||
|
#include <cstdint>
|
||||||
|
#include <random>
|
||||||
|
|
||||||
|
static void fill(void* ptr, size_t n, uint8_t value) { std::memset(ptr, value, n); }
|
||||||
|
|
||||||
|
static bool check(const void* ptr, size_t n, uint8_t value) {
|
||||||
|
const uint8_t* p = static_cast<const uint8_t*>(ptr);
|
||||||
|
for (size_t i = 0; i < n; ++i) {
|
||||||
|
if (p[i] != value) return false;
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
static bool expect_mem_eq(const void* ptr, size_t n, uint8_t value) {
|
||||||
|
const uint8_t* p = static_cast<const uint8_t*>(ptr);
|
||||||
|
for (size_t i = 0; i < n; ++i) {
|
||||||
|
if (p[i] != value) return false;
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
using Data = std::vector<uint8_t>;
|
||||||
|
using DataStorage = std::vector<Data>;
|
||||||
|
|
||||||
|
typedef ::testing::Types<
|
||||||
|
std::integral_constant<size_t, 64>,
|
||||||
|
std::integral_constant<size_t, 128>,
|
||||||
|
std::integral_constant<size_t, 1000>,
|
||||||
|
std::integral_constant<size_t, 4096>,
|
||||||
|
std::integral_constant<size_t, 4096 * 2>>
|
||||||
|
BufferSizes;
|
||||||
|
|
||||||
|
template <typename TypeParam>
|
||||||
|
class LinearRingBufferTest : public ::testing::Test {
|
||||||
|
protected:
|
||||||
|
LinearRingBuffer rb;
|
||||||
|
|
||||||
|
LinearRingBufferTest() :
|
||||||
|
historySize_(10),
|
||||||
|
rb(size_t(TypeParam::value), size_t(historySize_)) {}
|
||||||
|
|
||||||
|
static constexpr auto ITERATIONS = TypeParam::value * 10;
|
||||||
|
|
||||||
|
size_t messagesPushed_ = 0;
|
||||||
|
size_t historySize_ = 0;
|
||||||
|
|
||||||
|
auto iterations() { return ITERATIONS; }
|
||||||
|
|
||||||
|
auto historySize() { return historySize_; }
|
||||||
|
|
||||||
|
size_t randomSize() {
|
||||||
|
static std::random_device rnd;
|
||||||
|
std::uniform_int_distribution<size_t> dist(0, 1000);
|
||||||
|
return dist(rnd);
|
||||||
|
}
|
||||||
|
|
||||||
|
auto write_and_advance(size_t messageSize, DataStorage* storage) {
|
||||||
|
Data pushedSample(messageSize);
|
||||||
|
|
||||||
|
for (auto idx = 0; idx < messageSize; idx++) {
|
||||||
|
pushedSample[idx] = (idx + messagesPushed_++ * 53) % 321;
|
||||||
|
}
|
||||||
|
|
||||||
|
std::memcpy(this->rb.write_data(), pushedSample.data(), pushedSample.size());
|
||||||
|
this->rb.write_advance(pushedSample.size());
|
||||||
|
|
||||||
|
if (storage) {
|
||||||
|
storage->push_back(pushedSample);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
auto read_and_advance(size_t messageSize, DataStorage* storage) {
|
||||||
|
Data poppedSample(messageSize);
|
||||||
|
|
||||||
|
std::memcpy(poppedSample.data(), this->rb.read_data(), poppedSample.size());
|
||||||
|
|
||||||
|
this->rb.read_advance(poppedSample.size());
|
||||||
|
|
||||||
|
if (storage) {
|
||||||
|
storage->push_back(poppedSample);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
auto reset_with_history() { this->rb.read_reset_with_history(); };
|
||||||
|
|
||||||
|
auto read_with_history(size_t messageSize, DataStorage* storage) {
|
||||||
|
Data poppedSample(messageSize);
|
||||||
|
|
||||||
|
std::memcpy(poppedSample.data(), this->rb.read_data(), poppedSample.size());
|
||||||
|
|
||||||
|
if (storage) {
|
||||||
|
storage->push_back(poppedSample);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
TYPED_TEST_SUITE(LinearRingBufferTest, BufferSizes);
|
||||||
|
|
||||||
|
TYPED_TEST(LinearRingBufferTest, LinearWriteAcrossBoundary) {
|
||||||
|
constexpr size_t N = TypeParam::value;
|
||||||
|
|
||||||
|
if (N % 4096 != 0) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
auto* base = this->rb.write_data();
|
||||||
|
|
||||||
|
size_t half = N - 16;
|
||||||
|
fill(base, half, 0xAA);
|
||||||
|
fill(base + half, 32, 0xBB);
|
||||||
|
|
||||||
|
EXPECT_EQ(expect_mem_eq(base, 16, 0xBB), true);
|
||||||
|
EXPECT_EQ(expect_mem_eq(base + 16, half - 16, 0xAA), true);
|
||||||
|
EXPECT_EQ(expect_mem_eq(base + half, 32, 0xBB), true);
|
||||||
|
}
|
||||||
|
|
||||||
|
TYPED_TEST(LinearRingBufferTest, Chase) {
|
||||||
|
|
||||||
|
DataStorage pushed;
|
||||||
|
DataStorage popped;
|
||||||
|
|
||||||
|
static constexpr auto MSG_SIZE = 31;
|
||||||
|
|
||||||
|
for (auto iteration = 0; iteration < this->iterations(); iteration++) {
|
||||||
|
this->write_and_advance(MSG_SIZE, &pushed);
|
||||||
|
this->read_and_advance(MSG_SIZE, &popped);
|
||||||
|
}
|
||||||
|
|
||||||
|
ASSERT_EQ(pushed.size(), popped.size());
|
||||||
|
|
||||||
|
for (auto idx = 0; idx < popped.size(); idx++) {
|
||||||
|
ASSERT_EQ(pushed[idx], popped[idx]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Data makeMessageWithHistory(const Data& prev, const Data& current, size_t historySize) {
|
||||||
|
if (historySize > prev.size()) historySize = prev.size();
|
||||||
|
|
||||||
|
std::vector<uint8_t> result;
|
||||||
|
|
||||||
|
result.reserve(historySize + current.size());
|
||||||
|
|
||||||
|
result.insert(result.end(), prev.end() - historySize, prev.end());
|
||||||
|
result.insert(result.end(), current.begin(), current.end());
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
TYPED_TEST(LinearRingBufferTest, History) {
|
||||||
|
|
||||||
|
DataStorage pushed;
|
||||||
|
DataStorage popped;
|
||||||
|
|
||||||
|
pushed.push_back(Data(this->historySize()));
|
||||||
|
|
||||||
|
static constexpr auto MAX_MSG_SIZE = 111;
|
||||||
|
|
||||||
|
for (auto iteration = 0; iteration < this->iterations(); iteration++) {
|
||||||
|
|
||||||
|
const auto MSG_SIZE = this->historySize() + this->randomSize() % MAX_MSG_SIZE;
|
||||||
|
|
||||||
|
auto prevPushed = pushed.back();
|
||||||
|
pushed.clear();
|
||||||
|
|
||||||
|
this->reset_with_history();
|
||||||
|
|
||||||
|
this->write_and_advance(MSG_SIZE, &pushed);
|
||||||
|
auto currentPushed = pushed.back();
|
||||||
|
|
||||||
|
this->read_with_history(this->historySize() + MSG_SIZE, &popped);
|
||||||
|
auto poppedWithHistory = popped.back();
|
||||||
|
popped.clear();
|
||||||
|
|
||||||
|
auto correctResult = makeMessageWithHistory(prevPushed, currentPushed, this->historySize());
|
||||||
|
|
||||||
|
ASSERT_EQ(correctResult, poppedWithHistory);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
int main(int argc, char** argv) {
|
||||||
|
::testing::InitGoogleTest(&argc, argv);
|
||||||
|
return RUN_ALL_TESTS();
|
||||||
|
}
|
||||||
188
Containers/tests/testLinearRingBuffer.cpp
Normal file
188
Containers/tests/testLinearRingBuffer.cpp
Normal file
|
|
@ -0,0 +1,188 @@
|
||||||
|
#include "LinearRingBuffer.hpp"
|
||||||
|
|
||||||
|
#include <gtest/gtest.h>
|
||||||
|
|
||||||
|
#include <cstring>
|
||||||
|
#include <cstdint>
|
||||||
|
#include <random>
|
||||||
|
|
||||||
|
static void fill(void* ptr, size_t n, uint8_t value) { std::memset(ptr, value, n); }
|
||||||
|
|
||||||
|
static bool check(const void* ptr, size_t n, uint8_t value) {
|
||||||
|
const uint8_t* p = static_cast<const uint8_t*>(ptr);
|
||||||
|
for (size_t i = 0; i < n; ++i) {
|
||||||
|
if (p[i] != value) return false;
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
static bool expect_mem_eq(const void* ptr, size_t n, uint8_t value) {
|
||||||
|
const uint8_t* p = static_cast<const uint8_t*>(ptr);
|
||||||
|
for (size_t i = 0; i < n; ++i) {
|
||||||
|
if (p[i] != value) return false;
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
using Data = std::vector<uint8_t>;
|
||||||
|
using DataStorage = std::vector<Data>;
|
||||||
|
|
||||||
|
typedef ::testing::Types<
|
||||||
|
std::integral_constant<size_t, 64>,
|
||||||
|
std::integral_constant<size_t, 128>,
|
||||||
|
std::integral_constant<size_t, 1000>,
|
||||||
|
std::integral_constant<size_t, 4096>,
|
||||||
|
std::integral_constant<size_t, 4096 * 2>>
|
||||||
|
BufferSizes;
|
||||||
|
|
||||||
|
template <typename TypeParam>
|
||||||
|
class LinearRingBufferTest : public ::testing::Test {
|
||||||
|
protected:
|
||||||
|
LinearRingBuffer rb;
|
||||||
|
|
||||||
|
LinearRingBufferTest() :
|
||||||
|
historySize_(10),
|
||||||
|
rb(size_t(TypeParam::value), size_t(historySize_)) {}
|
||||||
|
|
||||||
|
static constexpr auto ITERATIONS = TypeParam::value * 10;
|
||||||
|
|
||||||
|
size_t messagesPushed_ = 0;
|
||||||
|
size_t historySize_ = 0;
|
||||||
|
|
||||||
|
auto iterations() { return ITERATIONS; }
|
||||||
|
|
||||||
|
auto historySize() { return historySize_; }
|
||||||
|
|
||||||
|
size_t randomSize() {
|
||||||
|
static std::random_device rnd;
|
||||||
|
std::uniform_int_distribution<size_t> dist(0, 1000);
|
||||||
|
return dist(rnd);
|
||||||
|
}
|
||||||
|
|
||||||
|
auto write_and_advance(size_t messageSize, DataStorage* storage) {
|
||||||
|
Data pushedSample(messageSize);
|
||||||
|
|
||||||
|
for (auto idx = 0; idx < messageSize; idx++) {
|
||||||
|
pushedSample[idx] = (idx + messagesPushed_++ * 53) % 321;
|
||||||
|
}
|
||||||
|
|
||||||
|
std::memcpy(this->rb.write_data(), pushedSample.data(), pushedSample.size());
|
||||||
|
this->rb.write_advance(pushedSample.size());
|
||||||
|
|
||||||
|
if (storage) {
|
||||||
|
storage->push_back(pushedSample);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
auto read_and_advance(size_t messageSize, DataStorage* storage) {
|
||||||
|
Data poppedSample(messageSize);
|
||||||
|
|
||||||
|
std::memcpy(poppedSample.data(), this->rb.read_data(), poppedSample.size());
|
||||||
|
|
||||||
|
this->rb.read_advance(poppedSample.size());
|
||||||
|
|
||||||
|
if (storage) {
|
||||||
|
storage->push_back(poppedSample);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
auto reset_with_history() { this->rb.read_reset_with_history(); };
|
||||||
|
|
||||||
|
auto read_with_history(size_t messageSize, DataStorage* storage) {
|
||||||
|
Data poppedSample(messageSize);
|
||||||
|
|
||||||
|
std::memcpy(poppedSample.data(), this->rb.read_data(), poppedSample.size());
|
||||||
|
|
||||||
|
if (storage) {
|
||||||
|
storage->push_back(poppedSample);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
TYPED_TEST_SUITE(LinearRingBufferTest, BufferSizes);
|
||||||
|
|
||||||
|
TYPED_TEST(LinearRingBufferTest, LinearWriteAcrossBoundary) {
|
||||||
|
constexpr size_t N = TypeParam::value;
|
||||||
|
|
||||||
|
if (N % 4096 != 0) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
auto* base = this->rb.write_data();
|
||||||
|
|
||||||
|
size_t half = N - 16;
|
||||||
|
fill(base, half, 0xAA);
|
||||||
|
fill(base + half, 32, 0xBB);
|
||||||
|
|
||||||
|
EXPECT_EQ(expect_mem_eq(base, 16, 0xBB), true);
|
||||||
|
EXPECT_EQ(expect_mem_eq(base + 16, half - 16, 0xAA), true);
|
||||||
|
EXPECT_EQ(expect_mem_eq(base + half, 32, 0xBB), true);
|
||||||
|
}
|
||||||
|
|
||||||
|
TYPED_TEST(LinearRingBufferTest, Chase) {
|
||||||
|
|
||||||
|
DataStorage pushed;
|
||||||
|
DataStorage popped;
|
||||||
|
|
||||||
|
static constexpr auto MSG_SIZE = 31;
|
||||||
|
|
||||||
|
for (auto iteration = 0; iteration < this->iterations(); iteration++) {
|
||||||
|
this->write_and_advance(MSG_SIZE, &pushed);
|
||||||
|
this->read_and_advance(MSG_SIZE, &popped);
|
||||||
|
}
|
||||||
|
|
||||||
|
ASSERT_EQ(pushed.size(), popped.size());
|
||||||
|
|
||||||
|
for (auto idx = 0; idx < popped.size(); idx++) {
|
||||||
|
ASSERT_EQ(pushed[idx], popped[idx]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Data makeMessageWithHistory(const Data& prev, const Data& current, size_t historySize) {
|
||||||
|
if (historySize > prev.size()) historySize = prev.size();
|
||||||
|
|
||||||
|
std::vector<uint8_t> result;
|
||||||
|
|
||||||
|
result.reserve(historySize + current.size());
|
||||||
|
|
||||||
|
result.insert(result.end(), prev.end() - historySize, prev.end());
|
||||||
|
result.insert(result.end(), current.begin(), current.end());
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
TYPED_TEST(LinearRingBufferTest, History) {
|
||||||
|
|
||||||
|
DataStorage pushed;
|
||||||
|
DataStorage popped;
|
||||||
|
|
||||||
|
pushed.push_back(Data(this->historySize()));
|
||||||
|
|
||||||
|
static constexpr auto MAX_MSG_SIZE = 111;
|
||||||
|
|
||||||
|
for (auto iteration = 0; iteration < this->iterations(); iteration++) {
|
||||||
|
|
||||||
|
const auto MSG_SIZE = this->historySize() + this->randomSize() % MAX_MSG_SIZE;
|
||||||
|
|
||||||
|
auto prevPushed = pushed.back();
|
||||||
|
pushed.clear();
|
||||||
|
|
||||||
|
this->reset_with_history();
|
||||||
|
|
||||||
|
this->write_and_advance(MSG_SIZE, &pushed);
|
||||||
|
auto currentPushed = pushed.back();
|
||||||
|
|
||||||
|
this->read_with_history(this->historySize() + MSG_SIZE, &popped);
|
||||||
|
auto poppedWithHistory = popped.back();
|
||||||
|
popped.clear();
|
||||||
|
|
||||||
|
auto correctResult = makeMessageWithHistory(prevPushed, currentPushed, this->historySize());
|
||||||
|
|
||||||
|
ASSERT_EQ(correctResult, poppedWithHistory);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
int main(int argc, char** argv) {
|
||||||
|
::testing::InitGoogleTest(&argc, argv);
|
||||||
|
return RUN_ALL_TESTS();
|
||||||
|
}
|
||||||
|
|
@ -10,6 +10,8 @@
|
||||||
|
|
||||||
using namespace tp;
|
using namespace tp;
|
||||||
|
|
||||||
|
#include <filesystem>
|
||||||
|
|
||||||
void loadImage(Buffer<halnf>& output, const char* name) {
|
void loadImage(Buffer<halnf>& output, const char* name) {
|
||||||
int x, y, channels_in_file;
|
int x, y, channels_in_file;
|
||||||
unsigned char* loadedImage = stbi_load(name, &x, &y, &channels_in_file, 4);
|
unsigned char* loadedImage = stbi_load(name, &x, &y, &channels_in_file, 4);
|
||||||
|
|
@ -28,7 +30,9 @@ void loadImage(Buffer<halnf>& output, const char* name) {
|
||||||
void loadNN(FCNN& nn) {
|
void loadNN(FCNN& nn) {
|
||||||
ArchiverLocalConnection<true> archiver;
|
ArchiverLocalConnection<true> archiver;
|
||||||
|
|
||||||
archiver.connection.connect(LocalConnection::Location("NumRec.wb"), LocalConnection::Type(true));
|
if (std::filesystem::exists(std::filesystem::path("NumRec.wb"))) {
|
||||||
|
archiver.connection.connect(LocalConnection::Location("NumRec.wb"), LocalConnection::Type(true));
|
||||||
|
}
|
||||||
|
|
||||||
if (archiver.connection.getConnectionStatus().isOpened()) {
|
if (archiver.connection.getConnectionStatus().isOpened()) {
|
||||||
archiver % nn;
|
archiver % nn;
|
||||||
|
|
@ -56,7 +60,7 @@ void executeCmd(const char* imageName) {
|
||||||
}
|
}
|
||||||
|
|
||||||
int main(int argc, char** argv) {
|
int main(int argc, char** argv) {
|
||||||
const char* imageName = "digit.png";
|
const char* imageName = "tmp2.png";
|
||||||
|
|
||||||
if (argc == 2) {
|
if (argc == 2) {
|
||||||
imageName = argv[1];
|
imageName = argv[1];
|
||||||
|
|
|
||||||
|
|
@ -1,3 +1,4 @@
|
||||||
|
#include <filesystem>
|
||||||
#include "FCNN.hpp"
|
#include "FCNN.hpp"
|
||||||
#include "LocalConnection.hpp"
|
#include "LocalConnection.hpp"
|
||||||
|
|
||||||
|
|
@ -71,7 +72,9 @@ struct NumberRec {
|
||||||
{
|
{
|
||||||
ArchiverLocalConnection<true> archiver;
|
ArchiverLocalConnection<true> archiver;
|
||||||
|
|
||||||
archiver.connection.connect(LocalConnection::Location("NumRec.wb"), LocalConnection::Type(true));
|
if (std::filesystem::exists(std::filesystem::path("NumRec.wb"))) {
|
||||||
|
archiver.connection.connect(LocalConnection::Location("NumRec.wb"), LocalConnection::Type(true));
|
||||||
|
}
|
||||||
|
|
||||||
if (archiver.connection.getConnectionStatus().isOpened()) {
|
if (archiver.connection.getConnectionStatus().isOpened()) {
|
||||||
archiver % nn;
|
archiver % nn;
|
||||||
|
|
@ -215,7 +218,7 @@ int main() {
|
||||||
|
|
||||||
auto batchSize = trainRange.idxDiff() / numBatches;
|
auto batchSize = trainRange.idxDiff() / numBatches;
|
||||||
|
|
||||||
for (auto epoch : IterRange(1)) {
|
for (auto epoch : IterRange(10)) {
|
||||||
printf("Epoch %i\n", epoch.index());
|
printf("Epoch %i\n", epoch.index());
|
||||||
|
|
||||||
for (auto batchIdx : IterRange(trainRange.idxDiff() / batchSize)) {
|
for (auto batchIdx : IterRange(trainRange.idxDiff() / batchSize)) {
|
||||||
|
|
@ -241,5 +244,5 @@ int main() {
|
||||||
// app.displayImage(i);
|
// app.displayImage(i);
|
||||||
}
|
}
|
||||||
|
|
||||||
printf("\n\nIncorrect - %i out of %i (%f)\n\n", errors, testRange.idxDiff(), (halnf) errors / (halnf) testRange.idxDiff());
|
printf("\n\nIncorrect - %i out of %i error percentage (%f)\n\n", errors, testRange.idxDiff(), (halnf) errors / (halnf) testRange.idxDiff());
|
||||||
}
|
}
|
||||||
2
Externals/CMakeLists.txt
vendored
2
Externals/CMakeLists.txt
vendored
|
|
@ -54,3 +54,5 @@ add_library(${PROJECT_NAME} INTERFACE)
|
||||||
target_include_directories(${PROJECT_NAME} INTERFACE ./imageIO/)
|
target_include_directories(${PROJECT_NAME} INTERFACE ./imageIO/)
|
||||||
|
|
||||||
add_subdirectory(lalr)
|
add_subdirectory(lalr)
|
||||||
|
|
||||||
|
add_subdirectory(googletest)
|
||||||
|
|
|
||||||
1
Externals/benchmark
vendored
Submodule
1
Externals/benchmark
vendored
Submodule
|
|
@ -0,0 +1 @@
|
||||||
|
Subproject commit c3f86578bb2081b52cee9d51615912ca4aa52fe4
|
||||||
1
Externals/googletest
vendored
Submodule
1
Externals/googletest
vendored
Submodule
|
|
@ -0,0 +1 @@
|
||||||
|
Subproject commit 1b96fa13f549387b7549cc89e1a785cf143a1a50
|
||||||
2
Externals/lalr
vendored
2
Externals/lalr
vendored
|
|
@ -1 +1 @@
|
||||||
Subproject commit 6d16a6bb60490a2ee4e86f689c86e647b300c7fb
|
Subproject commit 498612239713a6dbbf9f26b8e412e985538a0650
|
||||||
|
|
@ -82,6 +82,19 @@ void Canvas::frame(RectF rec, const RGBA& col, halnf round) {
|
||||||
// nvgFill(mContext->vg);
|
// nvgFill(mContext->vg);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void Canvas::line(Vec2F start, Vec2F end, const RGBA& col, halnf thickness) {
|
||||||
|
start += mOrigin;
|
||||||
|
end += mOrigin;
|
||||||
|
|
||||||
|
nvgBeginPath(mContext->vg);
|
||||||
|
nvgFillColor(mContext->vg, { col.r, col.g, col.b, col.a});
|
||||||
|
nvgMoveTo(mContext->vg, start.x, start.y);
|
||||||
|
nvgLineTo(mContext->vg, end.x, end.y);
|
||||||
|
nvgStrokeWidth(mContext->vg, thickness);
|
||||||
|
nvgStrokeColor(mContext->vg, { col.r, col.g, col.b, col.a });
|
||||||
|
nvgStroke(mContext->vg);
|
||||||
|
}
|
||||||
|
|
||||||
void Canvas::circle(Vec2F pos, halnf size, const RGBA& col) {
|
void Canvas::circle(Vec2F pos, halnf size, const RGBA& col) {
|
||||||
pos += mOrigin;
|
pos += mOrigin;
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -75,6 +75,7 @@ namespace tp {
|
||||||
void circle(Vec2F pos, halnf size, const RGBA& col);
|
void circle(Vec2F pos, halnf size, const RGBA& col);
|
||||||
void text(const char*, const RectF&, halnf size, Align, halnf padding, const RGBA&);
|
void text(const char*, const RectF&, halnf size, Align, halnf padding, const RGBA&);
|
||||||
void colorWheel(const RectF& rec, const ColorWheel& colorWheel);
|
void colorWheel(const RectF& rec, const ColorWheel& colorWheel);
|
||||||
|
void line(Vec2F start, Vec2F end, const RGBA& col, halnf thickness);
|
||||||
|
|
||||||
ImageHandle createImageFromTextId(ualni id, Vec2F size);
|
ImageHandle createImageFromTextId(ualni id, Vec2F size);
|
||||||
void updateTextureID(ImageHandle handle, ualni id);
|
void updateTextureID(ImageHandle handle, ualni id);
|
||||||
|
|
|
||||||
|
|
@ -15,7 +15,7 @@ target_link_libraries(${PROJECT_NAME} PUBLIC Graphics Connection Widgets)
|
||||||
target_link_libraries(${PROJECT_NAME} PUBLIC ${BINDINGS_LIBS})
|
target_link_libraries(${PROJECT_NAME} PUBLIC ${BINDINGS_LIBS})
|
||||||
|
|
||||||
file(COPY "library" DESTINATION "${CMAKE_BINARY_DIR}/${PROJECT_NAME}")
|
file(COPY "library" DESTINATION "${CMAKE_BINARY_DIR}/${PROJECT_NAME}")
|
||||||
file(COPY "applications/Font.ttf" DESTINATION "${CMAKE_BINARY_DIR}/${PROJECT_NAME}/")
|
file(COPY "applications/Font.ttf" DESTINATION "${CMAKE_BINARY_DIR}/${PROJECT_NAME}/rsc/")
|
||||||
|
|
||||||
### -------------------------- Applications -------------------------- ###
|
### -------------------------- Applications -------------------------- ###
|
||||||
add_executable(libView ./applications/Entry.cpp)
|
add_executable(libView ./applications/Entry.cpp)
|
||||||
|
|
|
||||||
|
|
@ -465,8 +465,15 @@ namespace tp {
|
||||||
}
|
}
|
||||||
|
|
||||||
// Matrix Properties
|
// Matrix Properties
|
||||||
|
MVec toGlobal(const MVec &in) const { return i * in.x + j * in.y; }
|
||||||
|
|
||||||
|
Mat toGlobal(const Mat &in) const { return {toGlobal(in.i), toGlobal(in.j)}; }
|
||||||
|
|
||||||
|
MVec toLocal(const MVec &in) const { return transform(in); }
|
||||||
|
|
||||||
MVec transform(const MVec& in) const { return MVec(i.x * in.x + i.y * in.y, j.x * in.x + j.y * in.y); }
|
MVec transform(const MVec& in) const { return MVec(i.x * in.x + i.y * in.y, j.x * in.x + j.y * in.y); }
|
||||||
|
|
||||||
|
// ???
|
||||||
Mat transform(const Mat& in) const {
|
Mat transform(const Mat& in) const {
|
||||||
Mat out;
|
Mat out;
|
||||||
out.i.x = i.x * in.i.x + j.x * in.i.y;
|
out.i.x = i.x * in.i.x + j.x * in.i.y;
|
||||||
|
|
|
||||||
|
|
@ -70,6 +70,29 @@ namespace tp {
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Rect<Type>& adjust(tp::halnf left, tp::halnf bottom, tp::halnf right, tp::halnf top) {
|
||||||
|
x += left;
|
||||||
|
y += bottom;
|
||||||
|
size.x += -left + right;
|
||||||
|
size.y += -bottom + top;
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
|
Rect<Type> adjusted(tp::halnf left, tp::halnf bottom, tp::halnf right, tp::halnf top) const {
|
||||||
|
return Rect<Type>(*this).adjust(left, bottom, right, top);
|
||||||
|
}
|
||||||
|
|
||||||
|
[[nodiscard]] halnf left() const { return x; }
|
||||||
|
[[nodiscard]] halnf bottom() { return y; }
|
||||||
|
[[nodiscard]] halnf top() { return y + size.y; }
|
||||||
|
[[nodiscard]] halnf right() { return x + size.x; }
|
||||||
|
|
||||||
|
static Rect fromPoints(const Vec2<Type>& p1, const Vec2<Type>& p2) {
|
||||||
|
tp::Vec2F min = {tp::min(p1.x, p2.x), tp::min(p1.y, p2.y)};
|
||||||
|
tp::Vec2F max = {tp::max(p1.x, p2.x), tp::max(p1.y, p2.y)};
|
||||||
|
return { min, max - min };
|
||||||
|
}
|
||||||
|
|
||||||
bool operator==(const Rect<Type>& rect) const { return (pos == rect.pos && size == rect.size); }
|
bool operator==(const Rect<Type>& rect) const { return (pos == rect.pos && size == rect.size); }
|
||||||
|
|
||||||
bool isEnclosedIn(const Rect<Type>& rect, bool aParent = false) const {
|
bool isEnclosedIn(const Rect<Type>& rect, bool aParent = false) const {
|
||||||
|
|
@ -184,13 +207,23 @@ namespace tp {
|
||||||
}
|
}
|
||||||
|
|
||||||
void expand(const Vec2<Type>& point) {
|
void expand(const Vec2<Type>& point) {
|
||||||
pos.x = min(point.x, pos.x);
|
if (point.x < x) {
|
||||||
pos.y = min(point.y, pos.y);
|
size.x += x - point.x;
|
||||||
|
x = point.x;
|
||||||
|
}
|
||||||
|
|
||||||
auto p = pos + size;
|
if (point.y < y) {
|
||||||
p.x = max(point.x, p.x);
|
size.y += y - point.y;
|
||||||
p.y = max(point.y, p.y);
|
y = point.y;
|
||||||
size = p - pos;
|
}
|
||||||
|
|
||||||
|
if (point.x > x + size.x) {
|
||||||
|
size.x = point.x - x;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (point.y > y + size.y) {
|
||||||
|
size.y = point.y - y;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void expand(const Rect<Type>& rect) {
|
void expand(const Rect<Type>& rect) {
|
||||||
|
|
|
||||||
|
|
@ -19,4 +19,4 @@ add_executable(Sketch3DApp ./applications/Entry.cpp)
|
||||||
target_link_libraries(Sketch3DApp ${PROJECT_NAME})
|
target_link_libraries(Sketch3DApp ${PROJECT_NAME})
|
||||||
|
|
||||||
file(COPY "rsc" DESTINATION "${CMAKE_BINARY_DIR}/${PROJECT_NAME}/")
|
file(COPY "rsc" DESTINATION "${CMAKE_BINARY_DIR}/${PROJECT_NAME}/")
|
||||||
file(COPY "applications/Font.ttf" DESTINATION "${CMAKE_BINARY_DIR}/${PROJECT_NAME}/")
|
file(COPY "applications/Font.ttf" DESTINATION "${CMAKE_BINARY_DIR}/${PROJECT_NAME}/rsc")
|
||||||
|
|
|
||||||
|
|
@ -14,4 +14,4 @@ add_executable(WidgetsExample examples/Example.cpp)
|
||||||
target_link_libraries(WidgetsExample ${PROJECT_NAME} ${GLEW_LIB})
|
target_link_libraries(WidgetsExample ${PROJECT_NAME} ${GLEW_LIB})
|
||||||
target_include_directories(WidgetsExample PUBLIC ../Externals/glfw/include ${GLEW_INCLUDE_DIR})
|
target_include_directories(WidgetsExample PUBLIC ../Externals/glfw/include ${GLEW_INCLUDE_DIR})
|
||||||
|
|
||||||
file(COPY "examples/Font.ttf" DESTINATION "${CMAKE_BINARY_DIR}/${PROJECT_NAME}/")
|
file(COPY "examples/Font.ttf" DESTINATION "${CMAKE_BINARY_DIR}/${PROJECT_NAME}/rsc")
|
||||||
|
|
|
||||||
|
|
@ -10,6 +10,7 @@ namespace tp {
|
||||||
WidgetApplication() = default;
|
WidgetApplication() = default;
|
||||||
|
|
||||||
void setRoot(Widget* widget);
|
void setRoot(Widget* widget);
|
||||||
|
virtual void debugUI();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
void processFrame(EventHandler* eventHandler, halnf deltaTime) override;
|
void processFrame(EventHandler* eventHandler, halnf deltaTime) override;
|
||||||
|
|
@ -17,8 +18,6 @@ namespace tp {
|
||||||
void drawFrame(Canvas* canvas) override;
|
void drawFrame(Canvas* canvas) override;
|
||||||
bool forceNewFrame() override ;
|
bool forceNewFrame() override ;
|
||||||
|
|
||||||
private:
|
|
||||||
void debugUI();
|
|
||||||
|
|
||||||
private:
|
private:
|
||||||
halnf mDebugSplitFactor = 0.7;
|
halnf mDebugSplitFactor = 0.7;
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue