Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions .clang-format
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
# .clang-format
BasedOnStyle: Google
IndentWidth: 4
28 changes: 28 additions & 0 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
# .github/workflows/ci.yml
name: C/C++ CI

on:
pull_request:
branches:
- main

jobs:
build:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v2

- name: Install build tools and linter
run: sudo apt-get update && sudo apt-get install -y clang-format cppcheck

- name: Check code formatting
run: |
mkdir -p ../temp_repo
cp -r . ../temp_repo
find ../temp_repo -name "*.c" -o -name "*.h" | xargs clang-format -i --style=Google
diff -u -r ../temp_repo .

- name: Run static code analysis
run: |
# The suppress flag tells cppcheck to ignore unused function warnings.
cppcheck --enable=all -I nn/include --suppress=missingIncludeSystem --suppress=unusedFunction --inconclusive --error-exitcode=1 .
16 changes: 8 additions & 8 deletions nn/include/linalg.h
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@

// _matrix is used to avoid confusion if the struct is self referencing
// 1D array used, this is way more performant than a 2D array is
typedef struct _Matrix{
typedef struct _Matrix {
double* matrix_data;
int rows;
int cols;
Expand Down Expand Up @@ -30,18 +30,18 @@ void print_matrix(Matrix* m);
void save_matrix(Matrix* m);
int matrix_argmax(Matrix* m);


//============================
// Functions for Matrix Operations
//============================
Matrix* identity_matrix(int n);
Matrix* add_matrix(Matrix *a, Matrix *b);
Matrix* add_matrix(Matrix* a, Matrix* b);
Matrix* subtract_matrix(Matrix* a, Matrix* b);
Matrix* multiply_matrix(Matrix* a, Matrix* b);
Matrix* apply_onto_matrix(double* (* func)(double), Matrix* m); // Apply our own stuff onto the matrix items, useful for activation
Matrix* add_scalar_to_matrix(Matrix *m, double n);
Matrix* apply_onto_matrix(double* (*func)(double),
Matrix* m); // Apply our own stuff onto the matrix
// items, useful for activation
Matrix* add_scalar_to_matrix(Matrix* m, double n);
Matrix* dot_matrix(Matrix* a, Matrix* b);
Matrix* transpose_matrix(Matrix* m);
Matrix* scale_matrix(double n, Matrix* m); // matrix can be scaled to non integer values


Matrix* scale_matrix(double n,
Matrix* m); // matrix can be scaled to non integer values
39 changes: 20 additions & 19 deletions nn/include/utils.h
Original file line number Diff line number Diff line change
@@ -1,40 +1,41 @@
#pragma once

#include <errno.h>
#include <stdio.h>
#include <stdlib.h>
#include <errno.h>
#include <time.h>

// Set up log levels
typedef enum {
LOG_LEVEL_DEBUG,
LOG_LEVEL_INFO,
LOG_LEVEL_WARN,
LOG_LEVEL_ERROR
LOG_LEVEL_DEBUG,
LOG_LEVEL_INFO,
LOG_LEVEL_WARN,
LOG_LEVEL_ERROR
} LogLevel;

// Set the minimum log level to display. Change this to filter output.
#define MIN_LOG_LEVEL LOG_LEVEL_INFO

// Assert macro, it'll be useful for checking matrix properties
#define ASSERT(condition, message) \
do { \
if (!(condition)) { \
fprintf(stderr, "Assertion failed in %s at line %d: %s\n", \
__FILE__, __LINE__, message); \
exit(EXIT_FAILURE); \
} \
} while (0)
#define ASSERT(condition, message) \
do { \
if (!(condition)) { \
fprintf(stderr, "Assertion failed in %s at line %d: %s\n", __FILE__, \
__LINE__, message); \
exit(EXIT_FAILURE); \
} \
} while (0)

// For safe malloc allocations
#define CHECK_MALLOC(ptr, message) \
ASSERT((ptr) != NULL, message);\
#define CHECK_MALLOC(ptr, message) ASSERT((ptr) != NULL, message);

// Function prototypes for logging
void log_message(LogLevel level, const char* format, ...);

// Convenience macros for easier logging
#define LOG_DEBUG(format, ...) log_message(LOG_LEVEL_DEBUG, format, ##__VA_ARGS__)
#define LOG_INFO(format, ...) log_message(LOG_LEVEL_INFO, format, ##__VA_ARGS__)
#define LOG_WARN(format, ...) log_message(LOG_LEVEL_WARN, format, ##__VA_ARGS__)
#define LOG_ERROR(format, ...) log_message(LOG_LEVEL_ERROR, format, ##__VA_ARGS__)
#define LOG_DEBUG(format, ...) \
log_message(LOG_LEVEL_DEBUG, format, ##__VA_ARGS__)
#define LOG_INFO(format, ...) log_message(LOG_LEVEL_INFO, format, ##__VA_ARGS__)
#define LOG_WARN(format, ...) log_message(LOG_LEVEL_WARN, format, ##__VA_ARGS__)
#define LOG_ERROR(format, ...) \
log_message(LOG_LEVEL_ERROR, format, ##__VA_ARGS__)
6 changes: 3 additions & 3 deletions nn/src/main.c
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
#include <stdio.h>

int main(){
printf("NN Program");
return 0;
int main() {
printf("NN Program");
return 0;
}
58 changes: 31 additions & 27 deletions nn/src/utils.c
Original file line number Diff line number Diff line change
Expand Up @@ -4,35 +4,39 @@
#include <string.h>

const char* get_log_level_string(LogLevel level) {
switch (level) {
case LOG_LEVEL_DEBUG: return "DEBUG";
case LOG_LEVEL_INFO: return "INFO";
case LOG_LEVEL_WARN: return "WARN";
case LOG_LEVEL_ERROR: return "ERROR";
default: return "UNKNOWN";
}
switch (level) {
case LOG_LEVEL_DEBUG:
return "DEBUG";
case LOG_LEVEL_INFO:
return "INFO";
case LOG_LEVEL_WARN:
return "WARN";
case LOG_LEVEL_ERROR:
return "ERROR";
default:
return "UNKNOWN";
}
}

void log_message(LogLevel level, const char* format, ...) {
if (level < MIN_LOG_LEVEL) {
return;
}

if (level < MIN_LOG_LEVEL) {
return;
}

// include time
time_t now = time(NULL);
struct tm* t = localtime(&now);
char time_str[20];
strftime(time_str, sizeof(time_str), "%Y-%m-%d %H:%M:%S", t);

FILE* stream = (level >= LOG_LEVEL_WARN) ? stderr : stdout;

va_list args;
va_start(args, format); // sets pointer to the beginning of our args

fprintf(stream, "[%s] [%s] ", time_str, get_log_level_string(level));
vfprintf(stream, format, args);
fprintf(stream, "\n");

va_end(args); // cleans up va args memory
// include time
time_t now = time(NULL);
const struct tm* t = localtime(&now);
char time_str[20];
strftime(time_str, sizeof(time_str), "%Y-%m-%d %H:%M:%S", t);

FILE* stream = (level >= LOG_LEVEL_WARN) ? stderr : stdout;

va_list args;
va_start(args, format); // sets pointer to the beginning of our args

fprintf(stream, "[%s] [%s] ", time_str, get_log_level_string(level));
vfprintf(stream, format, args);
fprintf(stream, "\n");

va_end(args); // cleans up va args memory
}