T
thomas.luce
Hi all,
I was wondering if I could get some people to take a look at some code.
I have narrowed down where the problem is, just not what the problem
is. I haven't coded in C in quite some time, so I'm re-learning a lot.
Basically, I get a seg fault on the Data_Get_Struct when net_update is
called. I figured it has something to do with the stuff in net_new.
Heres the code:
<code>
typedef struct NN
{
//Activations of each of those layers
float *ai;
float *ah;
float *ao;
// We are making pointers to arrays, not arrays of pointers.
//float *nodes;
float **wi;
float **wo;
//Change in weights used for momentum calculations
float **ci;
float **co;
//Number of nodes in each layer
int ni;
int nh;
int no;
} NN;
static VALUE
net_new(VALUE self, VALUE ni, VALUE nh, VALUE no)
{
//TODO: something about the way I am allocating net is causing it to
crap out on me in update.
NN *net;
VALUE obj = Data_Make_Struct(self,NN,NULL,net_free,net);
//Set layer sizes
net->ni = NUM2INT(ni) + 1;
net->nh = NUM2INT(nh);
net->no = NUM2INT(no);
//Set activations
net->ai = calloc(NUM2INT(ni)+1, sizeof(float));
net->ah = calloc(NUM2INT(nh), sizeof(float));
net->ao = calloc(NUM2INT(no), sizeof(float));
if(net->ai == NULL || net->ah == NULL || net->ao == NULL)
rb_raise(rb_eRuntimeError, "could not allocate activations");
//Build and randomize the link weights
net->wi = malloc((net->ni+ 1) * sizeof(float));
net->wo = malloc(net->nh * sizeof(float));
if(net->wi == NULL || net->wo == NULL)
rb_raise(rb_eRuntimeError, "could not allocate weight tables [1]");
int i;
int y;
for(i = 0; i < NUM2INT(nh); i++)
{
net->wi = malloc(NUM2INT(nh) * sizeof(float));
if(net->wi == NULL)
rb_raise(rb_eRuntimeError, "could not allocate weight
tables[2]");
for(y = 0; y < net->nh; y++)
{
net->wi[y] = -1.0 + (float)rand()/RAND_MAX;
}
}
for(i = 0; i < NUM2INT(no); i++)
{
net->wo = malloc(NUM2INT(no) * sizeof(float));
if(net->wo == NULL)
rb_raise(rb_eRuntimeError, "could not allocate weight
tables[3]");
for(y = 0; y < net->no; y++)
{
net->wo[y] = -1.0 + (float)rand()/RAND_MAX;
}
}
//Build our change in weight (momentum) arrays
net->ci = malloc(sizeof(float)*(NUM2INT(ni)+1));
net->co = malloc(sizeof(float)*NUM2INT(nh));
if(net->ci == NULL || net->co == NULL)
rb_raise(rb_eRuntimeError, "could not allocate change tables[1]");
for(i = 0; i < NUM2INT(nh); i++)
{
net->ci = calloc(NUM2INT(nh), sizeof(float));
if(net->ci == NULL || net->co == NULL)
rb_raise(rb_eRuntimeError, "could not allocate change
tables[2]");
}
for(i = 0; i < NUM2INT(no); i++)
{
net->co = calloc(NUM2INT(no), sizeof(float));
if(net->co == NULL || net->co == NULL)
rb_raise(rb_eRuntimeError, "could not allocate change
tables[3]");
}
return obj;
}
static VALUE
net_update(VALUE self, VALUE input)
{
NN *net;
Data_Get_Struct(self,NN,net);
int i;
int y;
//Inputs
for(i = 0; i < net->ni - 1; i++)
{
net->ai = (float)NUM2DBL(rb_ary_entry(input,i));
}
//Hidden
float sum = 0.0;
for(i = 0; i < net->nh; i++)
{
sum = 0.0;
for(y = 0; y < net->ni; y++)
{
sum = sum + net->ai[y] * net->wi[y];
}
net->ah = sigmoid(sum);
}
//Outputs
for(i = 0; i < net->no; i++)
{
sum = 0.0;
for(y = 0; y < net->nh; y++)
{
sum = sum + net->ah[y] * net->wo[y];
}
net->ao = sigmoid(sum);
}
//Now, stuff it all in an array, and throw it back.
VALUE ary = rb_ary_new();
for(i = 0; i < net->no; i++)
{
rb_ary_push(ary, rb_float_new(net->ao));
}
return ary;
}
</code>
Thanks to anyone that can offer any insight.
-Thomas
I was wondering if I could get some people to take a look at some code.
I have narrowed down where the problem is, just not what the problem
is. I haven't coded in C in quite some time, so I'm re-learning a lot.
Basically, I get a seg fault on the Data_Get_Struct when net_update is
called. I figured it has something to do with the stuff in net_new.
Heres the code:
<code>
typedef struct NN
{
//Activations of each of those layers
float *ai;
float *ah;
float *ao;
// We are making pointers to arrays, not arrays of pointers.
//float *nodes;
float **wi;
float **wo;
//Change in weights used for momentum calculations
float **ci;
float **co;
//Number of nodes in each layer
int ni;
int nh;
int no;
} NN;
static VALUE
net_new(VALUE self, VALUE ni, VALUE nh, VALUE no)
{
//TODO: something about the way I am allocating net is causing it to
crap out on me in update.
NN *net;
VALUE obj = Data_Make_Struct(self,NN,NULL,net_free,net);
//Set layer sizes
net->ni = NUM2INT(ni) + 1;
net->nh = NUM2INT(nh);
net->no = NUM2INT(no);
//Set activations
net->ai = calloc(NUM2INT(ni)+1, sizeof(float));
net->ah = calloc(NUM2INT(nh), sizeof(float));
net->ao = calloc(NUM2INT(no), sizeof(float));
if(net->ai == NULL || net->ah == NULL || net->ao == NULL)
rb_raise(rb_eRuntimeError, "could not allocate activations");
//Build and randomize the link weights
net->wi = malloc((net->ni+ 1) * sizeof(float));
net->wo = malloc(net->nh * sizeof(float));
if(net->wi == NULL || net->wo == NULL)
rb_raise(rb_eRuntimeError, "could not allocate weight tables [1]");
int i;
int y;
for(i = 0; i < NUM2INT(nh); i++)
{
net->wi = malloc(NUM2INT(nh) * sizeof(float));
if(net->wi == NULL)
rb_raise(rb_eRuntimeError, "could not allocate weight
tables[2]");
for(y = 0; y < net->nh; y++)
{
net->wi[y] = -1.0 + (float)rand()/RAND_MAX;
}
}
for(i = 0; i < NUM2INT(no); i++)
{
net->wo = malloc(NUM2INT(no) * sizeof(float));
if(net->wo == NULL)
rb_raise(rb_eRuntimeError, "could not allocate weight
tables[3]");
for(y = 0; y < net->no; y++)
{
net->wo[y] = -1.0 + (float)rand()/RAND_MAX;
}
}
//Build our change in weight (momentum) arrays
net->ci = malloc(sizeof(float)*(NUM2INT(ni)+1));
net->co = malloc(sizeof(float)*NUM2INT(nh));
if(net->ci == NULL || net->co == NULL)
rb_raise(rb_eRuntimeError, "could not allocate change tables[1]");
for(i = 0; i < NUM2INT(nh); i++)
{
net->ci = calloc(NUM2INT(nh), sizeof(float));
if(net->ci == NULL || net->co == NULL)
rb_raise(rb_eRuntimeError, "could not allocate change
tables[2]");
}
for(i = 0; i < NUM2INT(no); i++)
{
net->co = calloc(NUM2INT(no), sizeof(float));
if(net->co == NULL || net->co == NULL)
rb_raise(rb_eRuntimeError, "could not allocate change
tables[3]");
}
return obj;
}
static VALUE
net_update(VALUE self, VALUE input)
{
NN *net;
Data_Get_Struct(self,NN,net);
int i;
int y;
//Inputs
for(i = 0; i < net->ni - 1; i++)
{
net->ai = (float)NUM2DBL(rb_ary_entry(input,i));
}
//Hidden
float sum = 0.0;
for(i = 0; i < net->nh; i++)
{
sum = 0.0;
for(y = 0; y < net->ni; y++)
{
sum = sum + net->ai[y] * net->wi[y];
}
net->ah = sigmoid(sum);
}
//Outputs
for(i = 0; i < net->no; i++)
{
sum = 0.0;
for(y = 0; y < net->nh; y++)
{
sum = sum + net->ah[y] * net->wo[y];
}
net->ao = sigmoid(sum);
}
//Now, stuff it all in an array, and throw it back.
VALUE ary = rb_ary_new();
for(i = 0; i < net->no; i++)
{
rb_ary_push(ary, rb_float_new(net->ao));
}
return ary;
}
</code>
Thanks to anyone that can offer any insight.
-Thomas