Skip to content

Commit ad7b4a5

Browse files
authored
Merge pull request #1 from danbarua/bugfix-example-segfault
[WIP] Bugfix: nn_training_example segfault
2 parents c94e2ea + 31d7407 commit ad7b4a5

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

65 files changed

+1096
-418
lines changed

.gitignore

+52
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,52 @@
1+
# Prerequisites
2+
*.d
3+
4+
# Object files
5+
*.o
6+
*.ko
7+
*.obj
8+
*.elf
9+
10+
# Linker output
11+
*.ilk
12+
*.map
13+
*.exp
14+
15+
# Precompiled Headers
16+
*.gch
17+
*.pch
18+
19+
# Libraries
20+
*.lib
21+
*.a
22+
*.la
23+
*.lo
24+
25+
# Shared objects (inc. Windows DLLs)
26+
*.dll
27+
*.so
28+
*.so.*
29+
*.dylib
30+
31+
# Executables
32+
*.exe
33+
*.out
34+
*.app
35+
*.i*86
36+
*.x86_64
37+
*.hex
38+
39+
# Debug files
40+
*.dSYM/
41+
*.su
42+
*.idb
43+
*.pdb
44+
45+
# VSCode
46+
.VSCode
47+
48+
# Project-specific Artefacts
49+
examples_bin/**
50+
test_bin/**
51+
bin/**
52+
lib/**

Makefile

+148-43
Original file line numberDiff line numberDiff line change
@@ -1,69 +1,174 @@
1-
CC = gcc
2-
CFLAGS = -g -Wall -MMD -lm -Iinclude
3-
SRC = src
4-
OBJ = obj
5-
BINDIR = bin
6-
LIB = libmylib.a
7-
TEST_BIN_DIR = test_bin
8-
EXAMPLES_DIR = examples
9-
EXAMPLES_BIN_DIR = examples_bin
10-
11-
SRCS = $(wildcard $(SRC)/**/*.c) main.c
12-
OBJS = $(patsubst $(SRC)/%.c, $(OBJ)/%.o, $(filter $(SRC)%,$(SRCS))) \
13-
$(patsubst %.c, $(OBJ)/%.o, $(filter main.c,$(SRCS)))
14-
LIB_OBJS = $(filter-out $(OBJ)/main.o, $(OBJS))
15-
DEPS = $(OBJS:.o=.d)
16-
17-
TEST_SRCS = $(wildcard test/**/*.c)
18-
EXAMPLES_SRCS = $(wildcard $(EXAMPLES_DIR)/*.c)
19-
EXAMPLES = $(patsubst $(EXAMPLES_DIR)/%.c, $(EXAMPLES_BIN_DIR)/%, $(EXAMPLES_SRCS))
20-
21-
all: $(BINDIR)/main
22-
23-
release: CFLAGS = -Wall -O2 -DNDEBUG -MMD
1+
################################################################################
2+
# C-ML Machine Learning Library Makefile
3+
################################################################################
4+
5+
# Compiler and flags
6+
CC := gcc
7+
CFLAGS := -g -Wall -MMD -Iinclude
8+
LDFLAGS :=
9+
10+
# Project structure
11+
SRC_DIR := src
12+
INCLUDE_DIR := include
13+
OBJ_DIR := obj
14+
BIN_DIR := bin
15+
LIB_DIR := lib
16+
TEST_DIR := test
17+
TEST_BIN_DIR := test_bin
18+
EXAMPLES_DIR := examples
19+
EXAMPLES_BIN_DIR := examples_bin
20+
21+
# Library configuration
22+
LIB_NAME := c_ml
23+
LIB_VERSION := 1.0.0
24+
STATIC_LIB := $(LIB_DIR)/lib$(LIB_NAME).a
25+
26+
# Find all source files
27+
SRC_FILES := $(shell find $(SRC_DIR) -name "*.c")
28+
MAIN_FILE := main.c
29+
ALL_SRCS := $(SRC_FILES) $(MAIN_FILE)
30+
31+
# Generate object file paths
32+
OBJ_FILES := $(patsubst $(SRC_DIR)/%.c,$(OBJ_DIR)/%.o,$(SRC_FILES))
33+
MAIN_OBJ := $(OBJ_DIR)/main.o
34+
ALL_OBJS := $(OBJ_FILES) $(MAIN_OBJ)
35+
LIB_OBJS := $(OBJ_FILES)
36+
37+
# Find all test files
38+
TEST_FILES := $(shell find $(TEST_DIR) -name "*.c")
39+
40+
# Find all example files
41+
EXAMPLE_FILES := $(wildcard $(EXAMPLES_DIR)/*.c)
42+
EXAMPLES := $(patsubst $(EXAMPLES_DIR)/%.c,$(EXAMPLES_BIN_DIR)/%,$(EXAMPLE_FILES))
43+
44+
# Dependencies
45+
DEPS := $(ALL_OBJS:.o=.d)
46+
47+
################################################################################
48+
# Main targets
49+
################################################################################
50+
51+
# Default target
52+
.PHONY: all
53+
all: $(BIN_DIR)/main
54+
55+
# Build the main executable
56+
$(BIN_DIR)/main: $(ALL_OBJS)
57+
@mkdir -p $(BIN_DIR)
58+
$(CC) $(CFLAGS) $(LDFLAGS) $^ -o $@
59+
@echo "Built main executable: $@"
60+
61+
# Build the static library
62+
.PHONY: lib
63+
lib: $(STATIC_LIB)
64+
65+
$(STATIC_LIB): $(LIB_OBJS)
66+
@mkdir -p $(LIB_DIR)
67+
ar rcs $@ $^
68+
@echo "Built static library: $@"
69+
70+
# Release build with optimizations
71+
.PHONY: release
72+
release: CFLAGS := -Wall -O2 -DNDEBUG -MMD
2473
release: clean all
74+
@echo "Built release version"
2575

26-
$(BINDIR)/main: $(OBJS)
27-
@mkdir -p $(BINDIR)
28-
$(CC) $(CFLAGS) $(OBJS) -o $@ -lm
76+
# Debug build with sanitizers
77+
.PHONY: debug
78+
debug: CFLAGS += -fsanitize=address -fsanitize=undefined
79+
debug: all
80+
@echo "Built debug version with sanitizers"
2981

30-
$(OBJ)/%.o: $(SRC)/%.c
82+
################################################################################
83+
# Object file compilation
84+
################################################################################
85+
86+
# Compile source files
87+
$(OBJ_DIR)/%.o: $(SRC_DIR)/%.c
3188
@mkdir -p $(@D)
3289
$(CC) $(CFLAGS) -c $< -o $@
3390

34-
$(OBJ)/main.o: main.c
35-
@mkdir -p $(OBJ)
91+
# Compile main file
92+
$(OBJ_DIR)/main.o: $(MAIN_FILE)
93+
@mkdir -p $(OBJ_DIR)
3694
$(CC) $(CFLAGS) -c $< -o $@
3795

38-
$(LIB): $(LIB_OBJS)
39-
ar rcs $@ $^
96+
################################################################################
97+
# Examples
98+
################################################################################
4099

41100
.PHONY: examples
42-
examples: $(LIB) $(EXAMPLES)
101+
examples: $(STATIC_LIB) $(EXAMPLES)
102+
@echo "Built all examples"
43103

44-
$(EXAMPLES_BIN_DIR)/%: $(EXAMPLES_DIR)/%.c
104+
$(EXAMPLES_BIN_DIR)/%: $(EXAMPLES_DIR)/%.c $(STATIC_LIB)
45105
@mkdir -p $(EXAMPLES_BIN_DIR)
46-
$(CC) $(CFLAGS) $< -L. -lmylib -lm -o $@
106+
$(CC) $(CFLAGS) $< -L$(LIB_DIR) -l$(LIB_NAME) -o $@
107+
@echo "Built example: $@"
108+
109+
# Debug version of examples with sanitizers
110+
.PHONY: debug_examples
111+
debug_examples: EXAMPLE_FLAGS := -fsanitize=address -fsanitize=undefined
112+
debug_examples: $(STATIC_LIB)
113+
@mkdir -p $(EXAMPLES_BIN_DIR)
114+
@for example_src in $(EXAMPLE_FILES); do \
115+
example_bin=$$(basename $$example_src .c); \
116+
echo "Compiling $$example_bin with debug flags..."; \
117+
$(CC) $(CFLAGS) $(EXAMPLE_FLAGS) $$example_src -L$(LIB_DIR) -l$(LIB_NAME) \
118+
-o $(EXAMPLES_BIN_DIR)/$$example_bin; \
119+
done
120+
@echo "Built all examples with debug flags"
121+
122+
# Neural network training example (special case)
123+
.PHONY: nn_example
124+
nn_example: $(STATIC_LIB)
125+
@mkdir -p $(EXAMPLES_BIN_DIR)
126+
$(CC) $(CFLAGS) $(EXAMPLES_DIR)/nn_training_example.c -L$(LIB_DIR) -l$(LIB_NAME) -o $(EXAMPLES_BIN_DIR)/nn_training_example
127+
./$(EXAMPLES_BIN_DIR)/nn_training_example
128+
129+
# Debug version of neural network example
130+
.PHONY: debug_nn_example
131+
debug_nn_example: EXAMPLE_FLAGS := -fsanitize=address -fsanitize=undefined
132+
debug_nn_example: $(STATIC_LIB)
133+
@mkdir -p $(EXAMPLES_BIN_DIR)
134+
$(CC) $(CFLAGS) $(EXAMPLE_FLAGS) $(EXAMPLES_DIR)/nn_training_example.c -L$(LIB_DIR) -l$(LIB_NAME) -o $(EXAMPLES_BIN_DIR)/nn_training_example
135+
./$(EXAMPLES_BIN_DIR)/nn_training_example
136+
137+
################################################################################
138+
# Tests
139+
################################################################################
47140

48141
.PHONY: test
49-
test: $(LIB)
142+
test: $(STATIC_LIB)
50143
@mkdir -p $(TEST_BIN_DIR)
51144
@echo "Running tests..."
52-
@for test_src in $(TEST_SRCS); do \
145+
@for test_src in $(TEST_FILES); do \
53146
test_bin=$$(basename $$test_src .c); \
54147
src_file=$$(echo $$test_src | sed 's|^test/|src/|; s|test_||'); \
55148
echo "\nCompiling and running $$test_bin..."; \
56-
$(CC) $(CFLAGS) $$test_src $$src_file -L. -lmylib -lm -o $(TEST_BIN_DIR)/$$test_bin && ./$(TEST_BIN_DIR)/$$test_bin || exit 1; \
149+
$(CC) $(CFLAGS) $$test_src $$src_file -L$(LIB_DIR) -l$(LIB_NAME) \
150+
-o $(TEST_BIN_DIR)/$$test_bin -fsanitize=address -fsanitize=undefined && \
151+
ASAN_OPTIONS=allocator_may_return_null=1 ./$(TEST_BIN_DIR)/$$test_bin || exit 1; \
57152
done
58153
@echo "\nALL TESTS PASSED"
59154

60-
.PHONY: nn_example
61-
nn_example: $(LIB)
62-
@mkdir -p $(EXAMPLES_BIN_DIR)
63-
$(CC) $(CFLAGS) $(EXAMPLES_DIR)/nn_training_example.c -L. -lmylib -lm -o $(EXAMPLES_BIN_DIR)/nn_training_example
64-
./$(EXAMPLES_BIN_DIR)/nn_training_example
155+
# Test logging system specifically
156+
.PHONY: test_logging
157+
test_logging: $(STATIC_LIB)
158+
@mkdir -p $(TEST_BIN_DIR)
159+
@echo "Running logging tests..."
160+
$(CC) $(CFLAGS) test/Core/test_logging.c src/Core/logging.c -o $(TEST_BIN_DIR)/test_logging
161+
./$(TEST_BIN_DIR)/test_logging
162+
163+
################################################################################
164+
# Utility targets
165+
################################################################################
65166

167+
# Clean build artifacts
168+
.PHONY: clean
66169
clean:
67-
rm -rf $(BINDIR) $(OBJ) $(TEST_BIN_DIR) $(EXAMPLES_BIN_DIR) $(LIB) a.out
170+
rm -rf $(BIN_DIR) $(OBJ_DIR) $(TEST_BIN_DIR) $(EXAMPLES_BIN_DIR) $(LIB_DIR) a.out
171+
@echo "Cleaned all build artifacts"
68172

173+
# Include dependency files
69174
-include $(DEPS)

docs/DesignGuide.md

+28-13
Original file line numberDiff line numberDiff line change
@@ -103,25 +103,40 @@ void polling_layer_free(PollingLayer *layer);
103103
## 5. Debugging Conventions
104104
105105
### 5.1 Debug Logging
106-
- **Enable/disable logs**: Use the `DEBUG_LOGGING` macro to toggle debug logs.
106+
- **Enable/disable logs**: Use the `set_log_level(LOG_LEVEL_*)` macro to configure the global log level.
107107
```c
108-
#define DEBUG_LOGGING 1 // Set to 0 to disable debug logs
108+
#include "include/logging.h"
109+
110+
set_log_level(LOG_LEVEL_DEBUG);
111+
set_log_level(LOG_LEVEL_INFO);
112+
set_log_level(LOG_LEVEL_WARNING);
113+
set_log_level(LOG_LEVEL_ERROR);
109114
```
110115

111-
- **Wrap debug logs**: Use `#if DEBUG_LOGGING` to conditionally compile debug messages.
116+
- **Log appropriately**: Use the `#LOG_*` macros to conditionally log messages.
112117
```c
113-
#if DEBUG_LOGGING
114-
printf("[function_name] Debug: %s\n", message);
115-
#endif
118+
LOG_DEBUG("%s is a debug message.", message);
119+
LOG_INFO("Count is %d.", count);
120+
LOG_WARNING("Tensor Bloat is %d unreasonable.", bloat_factor);
121+
LOG_ERROR("NeuralNetwork is NULL.");
116122
```
117123
118124
### 5.2 Error Messages
119-
- **Error messages**: Include the function name and relevant parameter values.
125+
- **Error messages**: Use the `LOG_ERROR` macro. Include relevant parameter values.
120126
```c
121-
fprintf(stderr, "[function_name] Error: Invalid parameter (%d).\n", param);
127+
LOG_ERROR("Invalid parameter (%d).", param);
122128
```
123129

124-
130+
### 5.3 Log Message Formatting
131+
- Log messages are automatically formatted for you when you use the `LOG_*` macros.
132+
```plaintext
133+
Compiling and running test_logging...
134+
Running logging tests...
135+
2025-04-07 03:37:33 [DEBUG] test/Core/test_logging.c:18 main(): This is a debug message: 42
136+
2025-04-07 03:37:33 [INFO] test/Core/test_logging.c:19 main(): This is an info message: hello
137+
2025-04-07 03:37:33 [WARNING] test/Core/test_logging.c:20 main(): This is a warning message: 3.14
138+
2025-04-07 03:37:33 [ERROR] test/Core/test_logging.c:21 main(): This is an error message: X
139+
```
125140

126141
## 6. File Organization
127142

@@ -169,7 +184,7 @@ void polling_layer_free(PollingLayer *layer);
169184
Before submitting a pull request:
170185
1. Code follows the naming and formatting conventions.
171186
2. Functions are properly documented with Doxygen-style comments.
172-
3. Debug logs are wrapped in `#if DEBUG_LOGGING` blocks.
187+
3. Logs use `LOG_DEBUG`, `LOG_INFO`, `LOG_WARNING` or `LOG_ERROR` appropriately.
173188
4. Error handling is implemented and tested.
174189
5. Unit tests are written and pass successfully.
175190
@@ -185,7 +200,7 @@ int main() {
185200
// Create polling layer
186201
PollingLayer *layer = polling_layer_create(2, 2);
187202
if (!layer) {
188-
fprintf(stderr, "Failed to create polling layer.\n");
203+
LOG_ERROR("Failed to create polling layer.\n");
189204
return CM_NULL_POINTER_ERROR;
190205
}
191206
@@ -195,14 +210,14 @@ int main() {
195210
int output_size = polling_layer_forward(layer, input, output, 4);
196211
197212
if (output_size < 0) {
198-
fprintf(stderr, "Error during forward pass.\n");
213+
LOG_ERROR("Error during forward pass.\n");
199214
polling_layer_free(layer);
200215
return output_size;
201216
}
202217
203218
// Print output
204219
for (int i = 0; i < output_size; i++) {
205-
printf("Output[%d]: %f\n", i, output[i]);
220+
LOG_INFO("$2");Output[%d]: %f\n", i, output[i]);
206221
}
207222
208223
// Free resources

0 commit comments

Comments
 (0)