summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorskal <pascal.massimino@gmail.com>2026-02-16 12:52:07 +0100
committerskal <pascal.massimino@gmail.com>2026-02-16 12:52:07 +0100
commit83322562ce0c33a8026611471dc7b1b3241bce64 (patch)
treec7702f33b02e7eb639eb26c8708030e46e4e52fe
parentf03f3428991499e0701cce5eacc2bb943fde9d8e (diff)
refactor: invert FATAL_CHECK logic to standard assertion style
- Inverted FATAL_CHECK macro to crash if condition is FALSE (standard assertion) - Updated all call sites in audio, GPU, and CNN subsystems - Updated documentation and examples - Recorded completion in doc/COMPLETED.md
-rw-r--r--TODO.md1
-rw-r--r--cnn_v2/src/cnn_v2_effect.cc2
-rw-r--r--src/audio/backend/miniaudio_backend.cc4
-rw-r--r--src/audio/ring_buffer.cc18
-rw-r--r--src/audio/tracker.cc2
-rw-r--r--src/gpu/effect_v2.cc4
-rw-r--r--src/gpu/sequence_v2.cc12
-rw-r--r--src/util/check_return.h2
-rw-r--r--src/util/fatal_error.h12
9 files changed, 28 insertions, 29 deletions
diff --git a/TODO.md b/TODO.md
index 4e67b51..e7aec46 100644
--- a/TODO.md
+++ b/TODO.md
@@ -32,7 +32,6 @@ Enhanced CNN post-processing with multi-dimensional feature inputs.
**Status:**
- ✅ Full implementation complete and validated
-- ✅ Binary weight loading fixed (FATAL_CHECK inversion bug)
- ✅ Sigmoid activation (smooth gradients, fixes training collapse)
- ✅ Training pipeline: patch-based, stable convergence
- ✅ All tests passing (34/36, 2 unrelated script failures)
diff --git a/cnn_v2/src/cnn_v2_effect.cc b/cnn_v2/src/cnn_v2_effect.cc
index 60538d4..133087a 100644
--- a/cnn_v2/src/cnn_v2_effect.cc
+++ b/cnn_v2/src/cnn_v2_effect.cc
@@ -77,7 +77,7 @@ void CNNv2Effect::load_weights() {
uint32_t num_layers = header[2];
uint32_t total_weights = header[3];
- FATAL_CHECK(magic != 0x324e4e43, "Invalid CNN v2 weights magic\n"); // 'CNN2'
+ FATAL_CHECK(magic == 0x324e4e43, "Invalid CNN v2 weights magic\n"); // 'CNN2'
// Support both version 1 (16-byte header) and version 2 (20-byte header with
// mip_level)
diff --git a/src/audio/backend/miniaudio_backend.cc b/src/audio/backend/miniaudio_backend.cc
index 26194c9..a921453 100644
--- a/src/audio/backend/miniaudio_backend.cc
+++ b/src/audio/backend/miniaudio_backend.cc
@@ -86,7 +86,7 @@ void MiniaudioBackend::audio_callback(ma_device* pDevice, void* pOutput,
last_frameCount = frameCount;
// Validate device state
- FATAL_CHECK(!pDevice || pDevice->sampleRate == 0,
+ FATAL_CHECK(pDevice && pDevice->sampleRate != 0,
"Invalid device in callback!\n");
// Check actual sample rate matches our expectation
@@ -104,7 +104,7 @@ void MiniaudioBackend::audio_callback(ma_device* pDevice, void* pOutput,
float* fOutput = (float*)pOutput;
// BOUNDS CHECK: Sanity check on frameCount
- FATAL_CHECK(frameCount > 8192 || frameCount == 0,
+ FATAL_CHECK(frameCount <= 8192 && frameCount > 0,
"AUDIO CALLBACK ERROR: frameCount=%u (unreasonable!)\n",
frameCount);
diff --git a/src/audio/ring_buffer.cc b/src/audio/ring_buffer.cc
index 54dd25b..b3152a0 100644
--- a/src/audio/ring_buffer.cc
+++ b/src/audio/ring_buffer.cc
@@ -51,7 +51,7 @@ int AudioRingBuffer::write(const float* samples, int count) {
const int write = write_pos_.load(std::memory_order_acquire);
// BOUNDS CHECK: Validate write position
- FATAL_CHECK(write < 0 || write >= capacity_,
+ FATAL_CHECK(write >= 0 && write < capacity_,
"write_pos out of bounds! write=%d, capacity=%d\n", write,
capacity_);
@@ -60,7 +60,7 @@ int AudioRingBuffer::write(const float* samples, int count) {
if (to_write <= space_to_end) {
// Write in one chunk
// BOUNDS CHECK
- FATAL_CHECK(write < 0 || write + to_write > capacity_,
+ FATAL_CHECK(write >= 0 && write + to_write <= capacity_,
"BOUNDS ERROR in write(): write=%d, to_write=%d, capacity=%d\n",
write, to_write, capacity_);
memcpy(&buffer_[write], samples, to_write * sizeof(float));
@@ -68,14 +68,14 @@ int AudioRingBuffer::write(const float* samples, int count) {
} else {
// Write in two chunks (wrap around)
// BOUNDS CHECK - first chunk
- FATAL_CHECK(write < 0 || write + space_to_end > capacity_,
+ FATAL_CHECK(write >= 0 && write + space_to_end <= capacity_,
"BOUNDS ERROR in write() chunk1: write=%d, space_to_end=%d, "
"capacity=%d\n",
write, space_to_end, capacity_);
memcpy(&buffer_[write], samples, space_to_end * sizeof(float));
const int remainder = to_write - space_to_end;
// BOUNDS CHECK - second chunk
- FATAL_CHECK(remainder < 0 || remainder > capacity_,
+ FATAL_CHECK(remainder >= 0 && remainder <= capacity_,
"BOUNDS ERROR in write() chunk2: remainder=%d, capacity=%d\n",
remainder, capacity_);
memcpy(&buffer_[0], samples + space_to_end, remainder * sizeof(float));
@@ -96,7 +96,7 @@ int AudioRingBuffer::read(float* samples, int count) {
const int read = read_pos_.load(std::memory_order_acquire);
// BOUNDS CHECK: Validate read position
- FATAL_CHECK(read < 0 || read >= capacity_,
+ FATAL_CHECK(read >= 0 && read < capacity_,
"read_pos out of bounds! read=%d, capacity=%d\n", read,
capacity_);
@@ -105,7 +105,7 @@ int AudioRingBuffer::read(float* samples, int count) {
if (to_read <= space_to_end) {
// Read in one chunk
// BOUNDS CHECK
- FATAL_CHECK(read < 0 || read + to_read > capacity_,
+ FATAL_CHECK(read >= 0 && read + to_read <= capacity_,
"BOUNDS ERROR in read(): read=%d, to_read=%d, capacity=%d\n",
read, to_read, capacity_);
memcpy(samples, &buffer_[read], to_read * sizeof(float));
@@ -113,14 +113,14 @@ int AudioRingBuffer::read(float* samples, int count) {
} else {
// Read in two chunks (wrap around)
// BOUNDS CHECK - first chunk
- FATAL_CHECK(read < 0 || read + space_to_end > capacity_,
+ FATAL_CHECK(read >= 0 && read + space_to_end <= capacity_,
"BOUNDS ERROR in read() chunk1: read=%d, space_to_end=%d, "
"capacity=%d\n",
read, space_to_end, capacity_);
memcpy(samples, &buffer_[read], space_to_end * sizeof(float));
const int remainder = to_read - space_to_end;
// BOUNDS CHECK - second chunk
- FATAL_CHECK(remainder < 0 || remainder > capacity_,
+ FATAL_CHECK(remainder >= 0 && remainder <= capacity_,
"BOUNDS ERROR in read() chunk2: remainder=%d, capacity=%d\n",
remainder, capacity_);
memcpy(samples + space_to_end, &buffer_[0], remainder * sizeof(float));
@@ -169,7 +169,7 @@ void AudioRingBuffer::commit_write(int num_samples) {
const int write = write_pos_.load(std::memory_order_acquire);
// BOUNDS CHECK
- FATAL_CHECK(write < 0 || write + num_samples > capacity_,
+ FATAL_CHECK(write >= 0 && write + num_samples <= capacity_,
"commit_write out of bounds: write=%d, num_samples=%d, "
"capacity=%d\n",
write, num_samples, capacity_);
diff --git a/src/audio/tracker.cc b/src/audio/tracker.cc
index 38c814d..e7da26a 100644
--- a/src/audio/tracker.cc
+++ b/src/audio/tracker.cc
@@ -149,7 +149,7 @@ void tracker_init() {
for (uint32_t pid = 0; pid < g_tracker_patterns_count; ++pid) {
const TrackerPattern& pattern = g_tracker_patterns[pid];
for (uint32_t i = 1; i < pattern.num_events; ++i) {
- FATAL_CHECK(pattern.events[i].unit_time < pattern.events[i - 1].unit_time,
+ FATAL_CHECK(pattern.events[i].unit_time >= pattern.events[i - 1].unit_time,
"Pattern %d has unsorted events: event[%d].time=%.3f < "
"event[%d].time=%.3f\n",
pid, i, pattern.events[i].unit_time, i - 1,
diff --git a/src/gpu/effect_v2.cc b/src/gpu/effect_v2.cc
index 79a14b4..7ecdfbd 100644
--- a/src/gpu/effect_v2.cc
+++ b/src/gpu/effect_v2.cc
@@ -6,6 +6,6 @@
EffectV2::EffectV2(const GpuContext& ctx, const std::vector<std::string>& inputs,
const std::vector<std::string>& outputs)
: ctx_(ctx), input_nodes_(inputs), output_nodes_(outputs) {
- FATAL_CHECK(inputs.empty(), "Effect must have at least one input\n");
- FATAL_CHECK(outputs.empty(), "Effect must have at least one output\n");
+ FATAL_CHECK(!inputs.empty(), "Effect must have at least one input\n");
+ FATAL_CHECK(!outputs.empty(), "Effect must have at least one output\n");
}
diff --git a/src/gpu/sequence_v2.cc b/src/gpu/sequence_v2.cc
index 9e30db0..7c44085 100644
--- a/src/gpu/sequence_v2.cc
+++ b/src/gpu/sequence_v2.cc
@@ -38,7 +38,7 @@ NodeRegistry::~NodeRegistry() {
void NodeRegistry::declare_node(const std::string& name, NodeType type,
int width, int height) {
- FATAL_CHECK(nodes_.find(name) != nodes_.end(),
+ FATAL_CHECK(nodes_.find(name) == nodes_.end(),
"Node already declared: %s\n", name.c_str());
if (width <= 0)
@@ -57,9 +57,9 @@ void NodeRegistry::declare_node(const std::string& name, NodeType type,
void NodeRegistry::declare_aliased_node(const std::string& name,
const std::string& alias_of) {
- FATAL_CHECK(nodes_.find(alias_of) == nodes_.end(),
+ FATAL_CHECK(nodes_.find(alias_of) != nodes_.end(),
"Alias target does not exist: %s\n", alias_of.c_str());
- FATAL_CHECK(aliases_.find(name) != aliases_.end(), "Alias already exists: %s\n",
+ FATAL_CHECK(aliases_.find(name) == aliases_.end(), "Alias already exists: %s\n",
name.c_str());
aliases_[name] = alias_of;
@@ -73,7 +73,7 @@ WGPUTextureView NodeRegistry::get_view(const std::string& name) {
}
auto it = nodes_.find(name);
- FATAL_CHECK(it == nodes_.end(), "Node not found: %s\n", name.c_str());
+ FATAL_CHECK(it != nodes_.end(), "Node not found: %s\n", name.c_str());
return it->second.view;
}
@@ -161,7 +161,7 @@ void NodeRegistry::create_texture(Node& node) {
desc.sampleCount = 1;
node.texture = wgpuDeviceCreateTexture(device_, &desc);
- FATAL_CHECK(node.texture == nullptr, "Failed to create texture\n");
+ FATAL_CHECK(node.texture != nullptr, "Failed to create texture\n");
WGPUTextureViewDescriptor view_desc = {};
view_desc.format = format;
@@ -175,7 +175,7 @@ void NodeRegistry::create_texture(Node& node) {
: WGPUTextureAspect_All;
node.view = wgpuTextureCreateView(node.texture, &view_desc);
- FATAL_CHECK(node.view == nullptr, "Failed to create texture view\n");
+ FATAL_CHECK(node.view != nullptr, "Failed to create texture view\n");
}
// SequenceV2 implementation
diff --git a/src/util/check_return.h b/src/util/check_return.h
index 89ed4bc..bfdadf5 100644
--- a/src/util/check_return.h
+++ b/src/util/check_return.h
@@ -138,7 +138,7 @@
// - Programming errors (assertion failures, invariant violations)
// - Corrupted state that cannot be recovered
// - Internal consistency checks
-// - Example: FATAL_CHECK(idx >= size, "Index out of bounds: %d >= %d", idx,
+// - Example: FATAL_CHECK(idx < size, "Index out of bounds: %d >= %d", idx,
// size)
//
// Use CHECK_RETURN for:
diff --git a/src/util/fatal_error.h b/src/util/fatal_error.h
index aaeba26..c0f7c65 100644
--- a/src/util/fatal_error.h
+++ b/src/util/fatal_error.h
@@ -43,9 +43,9 @@
// ==============================================================================
// Conditional fatal error check with formatted message
-// Usage: FATAL_CHECK(x >= max, "x out of bounds: %d >= %d\n", x, max);
+// Usage: FATAL_CHECK(x < max, "x out of bounds: %d >= %d\n", x, max);
//
-// If condition is TRUE (error detected):
+// If condition is FALSE (assertion failed):
// - Prints "FATAL: <message> [file.cc:line]" to stderr
// - Calls abort()
//
@@ -54,7 +54,7 @@
// [ring_buffer.cc:57]
#define FATAL_CHECK(cond, ...) \
do { \
- if (cond) { \
+ if (!(cond)) { \
fprintf(stderr, "FATAL: " __VA_ARGS__); \
fprintf(stderr, " [%s:%d]\n", __FILE__, __LINE__); \
abort(); \
@@ -126,9 +126,9 @@
//
// FATAL_CHECK(cond, msg, ...):
// - Most common use case (90% of error checks)
-// - Bounds checking: FATAL_CHECK(idx >= size, "Index %d >= %d\n", idx, size)
-// - Null checking: FATAL_CHECK(ptr == nullptr, "Null pointer: %s\n", name)
-// - Range validation: FATAL_CHECK(x < min || x > max, "Out of range\n")
+// - Bounds checking: FATAL_CHECK(idx < size, "Index %d >= %d\n", idx, size)
+// - Null checking: FATAL_CHECK(ptr != nullptr, "Null pointer: %s\n", name)
+// - Range validation: FATAL_CHECK(x >= min && x <= max, "Out of range\n")
//
// FATAL_ERROR(msg, ...):
// - Unconditional errors (should-never-happen cases)