Skip to content

Commit a1e0733

Browse files
committed
backup
1 parent acf7c95 commit a1e0733

File tree

7 files changed

+57
-41
lines changed

7 files changed

+57
-41
lines changed

.vscode/launch.json

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
{
2+
// Use IntelliSense to learn about possible attributes.
3+
// Hover to view descriptions of existing attributes.
4+
// For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387
5+
"version": "0.2.0",
6+
"configurations": [
7+
{
8+
"type": "lldb",
9+
"request": "launch",
10+
"name": "Debug",
11+
"program": "${workspaceFolder}/main",
12+
"args": [],
13+
"cwd": "${workspaceFolder}"
14+
}
15+
]
16+
}

include/cten.h

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33
#include <assert.h>
44
#include <stdbool.h>
55
#include <stddef.h>
6+
#include <stdint.h>
67

78
typedef int TensorShape[4];
89
typedef struct GradNode GradNode;
@@ -71,7 +72,7 @@ Tensor Tensor_mean(Tensor self);
7172
Tensor Tensor_max(Tensor self);
7273
Tensor Tensor_min(Tensor self);
7374

74-
int* Tensor_argmax(Tensor self, int dim);
75+
void Tensor_argmax(Tensor self, int* out);
7576

7677
/* Neural Networks */
7778
Tensor nn_log(Tensor self);
@@ -90,7 +91,7 @@ Tensor nn_softmax(Tensor input);
9091
Tensor nn_crossentropy(Tensor y_true, Tensor y_pred);
9192

9293
/* Memory Management */
93-
typedef int PoolId;
94+
typedef int64_t PoolId;
9495

9596
void cten_begin_malloc(PoolId id);
9697
void cten_end_malloc();

src/basic.c

Lines changed: 11 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -39,7 +39,7 @@ Tensor Tensor_new(TensorShape shape, bool requires_grad) {
3939
int numel = TensorShape_numel(shape);
4040
self.data = _cten_malloc(sizeof(FloatBuffer) + sizeof(float) * numel);
4141
self.data->numel = numel;
42-
if(requires_grad && !cten_is_eval()) {
42+
if(requires_grad) {
4343
self.node = _cten_malloc(sizeof(GradNode));
4444
memset(self.node, 0, sizeof(GradNode));
4545
} else {
@@ -63,19 +63,19 @@ Tensor Tensor_ones(TensorShape shape, bool requires_grad) {
6363
}
6464

6565
float Tensor_get(Tensor self, int i, int j, int k, int l) {
66-
assert(i >= 0 && i < self.shape[0]);
67-
assert(j >= 0 && j < self.shape[1]);
68-
assert(k >= 0 && k < self.shape[2]);
69-
assert(l >= 0 && l < self.shape[3]);
66+
assert((self.shape[0] == 0 && i == 0) || (i >= 0 && i < self.shape[0]));
67+
assert((self.shape[1] == 0 && j == 0) || (j >= 0 && j < self.shape[1]));
68+
assert((self.shape[2] == 0 && k == 0) || (k >= 0 && k < self.shape[2]));
69+
assert((self.shape[3] == 0 && l == 0) || (l >= 0 && l < self.shape[3]));
7070
return self.data->flex[i * self.shape[1] * self.shape[2] * self.shape[3] +
7171
j * self.shape[2] * self.shape[3] + k * self.shape[3] + l];
7272
}
7373

7474
void Tensor_set(Tensor self, int i, int j, int k, int l, float value) {
75-
assert(i >= 0 && i < self.shape[0]);
76-
assert(j >= 0 && j < self.shape[1]);
77-
assert(k >= 0 && k < self.shape[2]);
78-
assert(l >= 0 && l < self.shape[3]);
75+
assert((self.shape[0] == 0 && i == 0) || (i >= 0 && i < self.shape[0]));
76+
assert((self.shape[1] == 0 && j == 0) || (j >= 0 && j < self.shape[1]));
77+
assert((self.shape[2] == 0 && k == 0) || (k >= 0 && k < self.shape[2]));
78+
assert((self.shape[3] == 0 && l == 0) || (l >= 0 && l < self.shape[3]));
7979
self.data->flex[i * self.shape[1] * self.shape[2] * self.shape[3] +
8080
j * self.shape[2] * self.shape[3] + k * self.shape[3] + l] = value;
8181
}
@@ -146,14 +146,7 @@ void Tensor_print(Tensor self) {
146146
void _cten_zero_grad(Tensor* params, int n_params) {
147147
for(int i = 0; i < n_params; i++) {
148148
Tensor t = params[i];
149-
if(t.node != NULL) {
150-
if(t.node->grad.data != NULL) {
151-
for(int j = 0; j < t.node->grad.data->numel; j++) {
152-
t.node->grad.data->flex[j] = 0;
153-
}
154-
} else {
155-
t.node->grad = Tensor_zeros(t.shape, false);
156-
}
157-
}
149+
if(t.node == NULL) continue;
150+
t.node->grad = Tensor_zeros(t.shape, false);
158151
}
159152
}

src/operator.c

Lines changed: 20 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -21,12 +21,12 @@ Tensor Tensor_add(Tensor self, Tensor other) {
2121
if(!cten_elemwise_broadcast(&self, &other)) {
2222
cten_assert_shape("Tensor_add() cannot broadcast", self.shape, other.shape);
2323
}
24-
bool require_grad = self.node != NULL || other.node != NULL;
25-
Tensor res = Tensor_new(self.shape, require_grad);
24+
bool requires_grad = !cten_is_eval() && (self.node != NULL || other.node != NULL);
25+
Tensor res = Tensor_new(self.shape, requires_grad);
2626
for(int i = 0; i < self.data->numel; i++) {
2727
res.data->flex[i] = self.data->flex[i] + other.data->flex[i];
2828
}
29-
if(require_grad) {
29+
if(requires_grad) {
3030
res.node->grad_fn = GradFn_add;
3131
res.node->inputs[0] = self;
3232
res.node->inputs[1] = other;
@@ -36,12 +36,12 @@ Tensor Tensor_add(Tensor self, Tensor other) {
3636
}
3737

3838
Tensor Tensor_mul(Tensor self, Tensor other) {
39-
bool require_grad = self.node != NULL || other.node != NULL;
40-
Tensor res = Tensor_new(self.shape, require_grad);
39+
bool requires_grad = !cten_is_eval() && (self.node != NULL || other.node != NULL);
40+
Tensor res = Tensor_new(self.shape, requires_grad);
4141
for(int i = 0; i < self.data->numel; i++) {
4242
res.data->flex[i] = self.data->flex[i] * other.data->flex[i];
4343
}
44-
if(require_grad) {
44+
if(requires_grad) {
4545
res.node->grad_fn = GradFn_mul;
4646
res.node->inputs[0] = self;
4747
res.node->inputs[1] = other;
@@ -59,18 +59,22 @@ Tensor Tensor_mulf(Tensor self, float other) {
5959
return res;
6060
}
6161

62-
int* Tensor_argmax(Tensor self, int dim) {
63-
dim = TensorShape_asdim(self.shape, dim);
64-
int* res = (int*)malloc(sizeof(int) * self.shape[dim]);
65-
for(int i = 0; i < self.shape[dim]; i++) {
66-
res[i] = 0;
67-
for(int j = 0; j < self.shape[dim]; j++) {
68-
float _0 = self.data->flex[res[i] * self.shape[dim] + i];
69-
float _1 = self.data->flex[j * self.shape[dim] + i];
70-
if(_0 < _1) res[i] = j;
62+
void Tensor_argmax(Tensor self, int* out) {
63+
// reduce last dim
64+
int last_dim = self.shape[TensorShape_dim(self.shape) - 1];
65+
int n = TensorShape_numel(self.shape) / last_dim;
66+
for(int i = 0; i < n; i++) {
67+
float* p = self.data->flex + i * last_dim;
68+
float max_val = p[0];
69+
int max_idx = 0;
70+
for(int j = 1; j < last_dim; j++) {
71+
if(p[j] > max_val) {
72+
max_val = p[j];
73+
max_idx = j;
74+
}
7175
}
76+
out[i] = max_idx;
7277
}
73-
return res;
7478
}
7579

7680
static Tensor GradFn_mean(Tensor self, int i) {

src/optimizer/sgd.c

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -30,10 +30,10 @@ void optim_sgd_config(optim_sgd* self, float lr, float momentum) {
3030
void optim_sgd_zerograd(optim_sgd* self) { _cten_zero_grad(self->params, self->n_params); }
3131

3232
void optim_sgd_step(optim_sgd* self) {
33+
assert(self->momentum == 0);
3334
for(int i = 0; i < self->n_params; i++) {
3435
Tensor t = self->params[i];
35-
assert(self->momentum == 0);
36-
assert(t.node != NULL);
36+
if(t.node == NULL) continue;
3737
assert(t.node->grad.data != NULL);
3838
// step
3939
for(int j = 0; j < t.data->numel; j++) {

src/utils.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@ void cten_assert(bool cond, const char* fmt, ...) {
1313
vfprintf(stderr, fmt, args);
1414
fprintf(stderr, "\n");
1515
va_end(args);
16-
exit(1);
16+
abort();
1717
}
1818
}
1919

src2/main.c

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -57,7 +57,9 @@ int main() {
5757
// train model
5858
int batch_size = 8;
5959
for(int epoch = 0; epoch < 3; epoch++) {
60+
printf("==> epoch: %d\n", epoch);
6061
for(int i = 0; i < n_train_samples; i += batch_size) {
62+
printf(" batch: %d/%d samples\n", i, n_train_samples);
6163
cten_begin_malloc(PoolId_Default);
6264
// prepare input and target
6365
Tensor input = Tensor_new((TensorShape){batch_size, n_features}, false);
@@ -102,9 +104,9 @@ int main() {
102104
Tensor y_pred = Model_forward(&model, input);
103105
Tensor loss = nn_crossentropy(y_true, y_pred);
104106
// calculate accuracy
105-
int* pred_classes = Tensor_argmax(y_pred, -1);
107+
int pred_classes[1];
108+
Tensor_argmax(y_pred, pred_classes);
106109
if(pred_classes[0] == y[i]) correct++;
107-
free(pred_classes);
108110
cten_end_malloc();
109111
// free temporary tensors
110112
cten_free(PoolId_Default);

0 commit comments

Comments
 (0)