Memory management tweaks
There are no memory leaks, yet, I discover, with my steady course, thru my small valgrind peeks, that nvidia are a bunch of stupid a-holes.
This commit is contained in:
parent
68d3d4b692
commit
c2b9dfdd29
6 changed files with 113 additions and 30 deletions
|
@ -32,6 +32,7 @@ typedef struct _cx_gl_ctx {
|
||||||
GLFWwindow *window;
|
GLFWwindow *window;
|
||||||
ModelRegistry *mr;
|
ModelRegistry *mr;
|
||||||
GLuint *VertexArrayIDs;
|
GLuint *VertexArrayIDs;
|
||||||
|
void (*free)(void *self);
|
||||||
size_t VertexArray_count;
|
size_t VertexArray_count;
|
||||||
size_t VertexArray_size;
|
size_t VertexArray_size;
|
||||||
GLuint *programIDs;
|
GLuint *programIDs;
|
||||||
|
@ -43,6 +44,7 @@ typedef struct _cx_nn_ctx {
|
||||||
Neural_Network *nn;
|
Neural_Network *nn;
|
||||||
float *input_buffer;
|
float *input_buffer;
|
||||||
float *output_buffer;
|
float *output_buffer;
|
||||||
|
void (*free)(void *self);
|
||||||
} CX_NN_CTX;
|
} CX_NN_CTX;
|
||||||
|
|
||||||
typedef struct _cx_ctx {
|
typedef struct _cx_ctx {
|
||||||
|
@ -55,7 +57,7 @@ typedef struct _cx_ctx {
|
||||||
|
|
||||||
CX_Context *cx_context_new(void);
|
CX_Context *cx_context_new(void);
|
||||||
|
|
||||||
int cx_glinit(GLFWwindow **);
|
int cx_glinit(CX_GL_CTX **);
|
||||||
int cx_nninit(Neural_Network **);
|
int cx_nninit(Neural_Network **);
|
||||||
int cx_init(CX_Context **);
|
int cx_init(CX_Context **);
|
||||||
|
|
||||||
|
|
|
@ -14,6 +14,7 @@ typedef struct _cx_thrgr {
|
||||||
} CX_ThreadGroup;
|
} CX_ThreadGroup;
|
||||||
|
|
||||||
CX_ThreadGroup *cx_threadGroup_new(void *(*)(void *), void *);
|
CX_ThreadGroup *cx_threadGroup_new(void *(*)(void *), void *);
|
||||||
|
void cx_threadGroup_free(CX_ThreadGroup *);
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
|
@ -26,6 +26,7 @@ typedef struct _neural_data {
|
||||||
} Neural_Data;
|
} Neural_Data;
|
||||||
|
|
||||||
Neural_Network *neural_new(size_t, size_t, size_t);
|
Neural_Network *neural_new(size_t, size_t, size_t);
|
||||||
|
void neural_free(Neural_Network *);
|
||||||
void neural_randomize(Neural_Network *);
|
void neural_randomize(Neural_Network *);
|
||||||
float *neural_process(Neural_Network *, float *);
|
float *neural_process(Neural_Network *, float *);
|
||||||
Neural_Data *neural_getData(Neural_Network *, size_t);
|
Neural_Data *neural_getData(Neural_Network *, size_t);
|
||||||
|
|
96
src/cx.c
96
src/cx.c
|
@ -80,13 +80,58 @@ cx_loadShaders(GLuint *VertexArrayID, GLuint *programID) {
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
gl_ctx_free(void *self) {
|
||||||
|
CX_GL_CTX *gl_ctx;
|
||||||
|
|
||||||
|
gl_ctx = self;
|
||||||
|
|
||||||
|
if (gl_ctx) {
|
||||||
|
free(gl_ctx->VertexArrayIDs);
|
||||||
|
free(gl_ctx->programIDs);
|
||||||
|
modelRegistry_free(gl_ctx->mr);
|
||||||
|
}
|
||||||
|
free(gl_ctx);
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
nn_ctx_free(void *self) {
|
||||||
|
CX_NN_CTX *nn_ctx;
|
||||||
|
|
||||||
|
nn_ctx = self;
|
||||||
|
|
||||||
|
if (nn_ctx) {
|
||||||
|
free(nn_ctx->input_buffer);
|
||||||
|
free(nn_ctx->output_buffer);
|
||||||
|
neural_free(nn_ctx->nn);
|
||||||
|
}
|
||||||
|
free(nn_ctx);
|
||||||
|
}
|
||||||
|
|
||||||
int
|
int
|
||||||
cx_glinit(GLFWwindow **window) {
|
cx_glinit(CX_GL_CTX **gl_ctx) {
|
||||||
|
// Initialize OpenGL context
|
||||||
|
|
||||||
|
(*gl_ctx)->VertexArrayIDs = calloc(1, sizeof(GLuint));
|
||||||
|
if (!(*gl_ctx)->VertexArrayIDs) {
|
||||||
|
goto err;
|
||||||
|
}
|
||||||
|
(*gl_ctx)->VertexArray_count = 0;
|
||||||
|
(*gl_ctx)->VertexArray_size = 1;
|
||||||
|
(*gl_ctx)->programIDs = calloc(1, sizeof(GLuint));
|
||||||
|
if (!(*gl_ctx)->programIDs) {
|
||||||
|
goto err;
|
||||||
|
}
|
||||||
|
(*gl_ctx)->ProgramID_count = 0;
|
||||||
|
(*gl_ctx)->ProgramID_size = 1;
|
||||||
|
|
||||||
|
(*gl_ctx)->free = &gl_ctx_free;
|
||||||
|
|
||||||
// Initialise GLFW
|
// Initialise GLFW
|
||||||
printf("Initializing OpenGL.\n");
|
printf("Initializing OpenGL.\n");
|
||||||
if(!glfwInit()) {
|
if(!glfwInit()) {
|
||||||
fprintf(stderr, "Failed to initialize GLFW\n");
|
fprintf(stderr, "Failed to initialize GLFW\n");
|
||||||
return -1;
|
goto err;
|
||||||
}
|
}
|
||||||
|
|
||||||
glfwWindowHint(GLFW_SAMPLES, 4);
|
glfwWindowHint(GLFW_SAMPLES, 4);
|
||||||
|
@ -98,30 +143,33 @@ cx_glinit(GLFWwindow **window) {
|
||||||
glfwWindowHint(GLFW_OPENGL_FORWARD_COMPAT, GL_TRUE);
|
glfwWindowHint(GLFW_OPENGL_FORWARD_COMPAT, GL_TRUE);
|
||||||
|
|
||||||
// Open a window and create its OpenGL context
|
// Open a window and create its OpenGL context
|
||||||
*window = glfwCreateWindow(1280, 720, "C-X", NULL, NULL);
|
(*gl_ctx)->window = glfwCreateWindow(1280, 720, "C-X", NULL, NULL);
|
||||||
if (*window == NULL) {
|
if ((*gl_ctx)->window == NULL) {
|
||||||
fprintf(stderr, "Failed to open GLFW window.\n");
|
fprintf(stderr, "Failed to open GLFW window.\n");
|
||||||
glfwTerminate();
|
glfwTerminate();
|
||||||
return -1;
|
goto err;
|
||||||
}
|
}
|
||||||
printf("Window created.\n");
|
printf("Window created.\n");
|
||||||
|
|
||||||
glfwMakeContextCurrent(*window);
|
glfwMakeContextCurrent((*gl_ctx)->window);
|
||||||
|
|
||||||
// Initialize GLEW
|
// Initialize GLEW
|
||||||
if (glewInit() != GLEW_OK) {
|
if (glewInit() != GLEW_OK) {
|
||||||
fprintf(stderr, "Failed to initialize GLEW\n");
|
fprintf(stderr, "Failed to initialize GLEW\n");
|
||||||
glfwTerminate();
|
glfwTerminate();
|
||||||
return -1;
|
goto err;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Ensure we can capture the escape key being pressed below
|
// Ensure we can capture the escape key being pressed below
|
||||||
glfwSetInputMode(*window, GLFW_STICKY_KEYS, GL_TRUE);
|
glfwSetInputMode((*gl_ctx)->window, GLFW_STICKY_KEYS, GL_TRUE);
|
||||||
|
|
||||||
// Dark grey background
|
// Dark grey background
|
||||||
glClearColor(0.15f, 0.15f, 0.15f, 0.0f);
|
glClearColor(0.15f, 0.15f, 0.15f, 0.0f);
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
|
err:
|
||||||
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
int
|
int
|
||||||
|
@ -147,27 +195,11 @@ cx_init(CX_Context **cx_ctx) {
|
||||||
|
|
||||||
printf("Initializing CX.\n");
|
printf("Initializing CX.\n");
|
||||||
|
|
||||||
gl_ctx = calloc(1, sizeof(CX_GL_CTX));
|
|
||||||
|
|
||||||
gl_ctx->VertexArrayIDs = calloc(1, sizeof(GLuint));
|
|
||||||
if (!gl_ctx->VertexArrayIDs) {
|
|
||||||
goto err;
|
|
||||||
}
|
|
||||||
gl_ctx->VertexArray_count = 0;
|
|
||||||
gl_ctx->VertexArray_size = 1;
|
|
||||||
gl_ctx->programIDs = calloc(1, sizeof(GLuint));
|
|
||||||
if (!gl_ctx->programIDs) {
|
|
||||||
goto err;
|
|
||||||
}
|
|
||||||
gl_ctx->ProgramID_count = 0;
|
|
||||||
gl_ctx->ProgramID_size = 1;
|
|
||||||
|
|
||||||
// Establish a model registry
|
|
||||||
gl_ctx->mr = modelRegistry_new();
|
|
||||||
|
|
||||||
nn_ctx = calloc(1, sizeof(CX_NN_CTX));
|
nn_ctx = calloc(1, sizeof(CX_NN_CTX));
|
||||||
|
nn_ctx->free = &nn_ctx_free;
|
||||||
|
|
||||||
*cx_ctx = calloc(1, sizeof(CX_Context));
|
*cx_ctx = calloc(1, sizeof(CX_Context));
|
||||||
|
gl_ctx = calloc(1, sizeof(CX_GL_CTX));
|
||||||
|
|
||||||
(*cx_ctx)->gl_ctx = gl_ctx;
|
(*cx_ctx)->gl_ctx = gl_ctx;
|
||||||
(*cx_ctx)->nn_ctx = nn_ctx;
|
(*cx_ctx)->nn_ctx = nn_ctx;
|
||||||
|
@ -228,7 +260,7 @@ cx_glthread(void *self) {
|
||||||
CX_Thread *self_t = self;
|
CX_Thread *self_t = self;
|
||||||
CX_GL_CTX *gl_ctx = self_t->ctx;
|
CX_GL_CTX *gl_ctx = self_t->ctx;
|
||||||
|
|
||||||
cx_glinit(&gl_ctx->window);
|
cx_glinit(&gl_ctx);
|
||||||
|
|
||||||
if (cx_loadShaders(gl_ctx->VertexArrayIDs, gl_ctx->programIDs)) {
|
if (cx_loadShaders(gl_ctx->VertexArrayIDs, gl_ctx->programIDs)) {
|
||||||
return NULL;
|
return NULL;
|
||||||
|
@ -253,6 +285,9 @@ int
|
||||||
cx_run(CX_Context *ctx) {
|
cx_run(CX_Context *ctx) {
|
||||||
CX_ThreadGroup *tg[2];
|
CX_ThreadGroup *tg[2];
|
||||||
|
|
||||||
|
// Establish a model registry
|
||||||
|
ctx->gl_ctx->mr = modelRegistry_new();
|
||||||
|
|
||||||
tg[1] = cx_threadGroup_new(&cx_nnthread, ctx->nn_ctx);
|
tg[1] = cx_threadGroup_new(&cx_nnthread, ctx->nn_ctx);
|
||||||
|
|
||||||
pthread_join(tg[1]->group_manager->thread, NULL);
|
pthread_join(tg[1]->group_manager->thread, NULL);
|
||||||
|
@ -263,7 +298,12 @@ cx_run(CX_Context *ctx) {
|
||||||
|
|
||||||
pthread_join(tg[0]->group_manager->thread, NULL);
|
pthread_join(tg[0]->group_manager->thread, NULL);
|
||||||
|
|
||||||
modelRegistry_free(ctx->gl_ctx->mr);
|
|
||||||
|
cx_threadGroup_free(tg[0]);
|
||||||
|
cx_threadGroup_free(tg[1]);
|
||||||
|
|
||||||
|
free(ctx->threads);
|
||||||
|
free(ctx);
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
|
@ -23,6 +23,20 @@ err:
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
cx_thread_free(CX_Thread *self) {
|
||||||
|
if (self) {
|
||||||
|
/* TODO */
|
||||||
|
/* This is naive in its current form and will shatter
|
||||||
|
* sooner or later.
|
||||||
|
* Fix the context structures so that this call
|
||||||
|
* is guaranteed not to touch invalid memory.
|
||||||
|
*/
|
||||||
|
((CX_GL_CTX *)self->ctx)->free(self->ctx);
|
||||||
|
}
|
||||||
|
free(self);
|
||||||
|
}
|
||||||
|
|
||||||
CX_ThreadGroup *
|
CX_ThreadGroup *
|
||||||
cx_threadGroup_new(void *(*target)(void *),
|
cx_threadGroup_new(void *(*target)(void *),
|
||||||
void *ctx) {
|
void *ctx) {
|
||||||
|
@ -39,3 +53,12 @@ cx_threadGroup_new(void *(*target)(void *),
|
||||||
return self;
|
return self;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
cx_threadGroup_free(CX_ThreadGroup *self) {
|
||||||
|
if (self) {
|
||||||
|
cx_thread_free(self->group_manager);
|
||||||
|
free(self->workers);
|
||||||
|
}
|
||||||
|
free(self);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
16
src/neural.c
16
src/neural.c
|
@ -17,7 +17,12 @@ nl_new(size_t layer_size, size_t layer_size_next) {
|
||||||
|
|
||||||
static void
|
static void
|
||||||
nl_free(Neural_Layer *self) {
|
nl_free(Neural_Layer *self) {
|
||||||
|
if (self) {
|
||||||
|
for (int i = 0; i < self->layer_size; i++) {
|
||||||
|
free(self->neurons[i].synapses);
|
||||||
|
}
|
||||||
free(self->neurons);
|
free(self->neurons);
|
||||||
|
}
|
||||||
free(self);
|
free(self);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -51,6 +56,17 @@ neural_new(size_t input_size, size_t output_size, size_t layer_count) {
|
||||||
return self;
|
return self;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
neural_free(Neural_Network *self) {
|
||||||
|
if (self) {
|
||||||
|
for (int i = 0; i < self->layer_count; i++) {
|
||||||
|
nl_free(self->layers[i]);
|
||||||
|
}
|
||||||
|
free(self->layers);
|
||||||
|
}
|
||||||
|
free(self);
|
||||||
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
neural_randomize(Neural_Network *self) {
|
neural_randomize(Neural_Network *self) {
|
||||||
FILE *f;
|
FILE *f;
|
||||||
|
|
Loading…
Reference in a new issue