Skip to content

Commit a4eb580

Browse files
committed
Added cmake for building in Windows, have confirmed that it works for -G'NMake Makefiles'
1 parent ba10aae commit a4eb580

File tree

7 files changed

+139
-35
lines changed

7 files changed

+139
-35
lines changed

CMakeLists.txt

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
cmake_minimum_required (VERSION 2.6)
2+
add_compile_definitions(WINDOWS)
3+
add_compile_definitions(_CRT_SECURE_NO_WARNINGS)
4+
project (net)
5+
add_executable(net main.c layers.c lstm.c set.c utilities.c)

layers.c

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,10 @@
3434

3535
#include "layers.h"
3636

37+
#ifdef WINDOWS
38+
#include <stdio.h>
39+
#endif
40+
3741
// Y = AX + b &Y, A, X, B, Rows (for A), Columns (for A)
3842
void fully_connected_forward(double* Y, double* A, double* X, double* b, int R, int C)
3943
{
@@ -97,7 +101,19 @@ void softmax_layers_forward(double* P, double* Y, int F, double temperature)
97101
{
98102
int f = 0;
99103
double sum = 0;
104+
#ifdef WINDOWS
105+
// MSVC is not a C99 compiler, and does not support variable length arrays
106+
// MSVC is documented as conforming to C90
107+
double *cache = malloc(sizeof(double)*F);
108+
109+
if ( cache == NULL ) {
110+
fprintf(stderr, "%s.%s.%d malloc(%zu) failed\r\n",
111+
__FILE__, __func__, __LINE__, sizeof(double)*F);
112+
exit(1);
113+
}
114+
#else
100115
double cache[F];
116+
#endif
101117

102118
while ( f < F ) {
103119
cache[f] = exp(Y[f] / temperature);
@@ -110,6 +126,10 @@ void softmax_layers_forward(double* P, double* Y, int F, double temperature)
110126
P[f] = cache[f] / sum;
111127
++f;
112128
}
129+
130+
#ifdef WINDOWS
131+
free(cache);
132+
#endif
113133
}
114134
// P, c, &dldh, rows
115135
void softmax_loss_layer_backward(double* P, int c, double* dldh, int R)

lstm.c

Lines changed: 88 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -594,7 +594,18 @@ void lstm_forward_propagate(lstm_model_t* model, double * input, lstm_values_cac
594594
F = model->F;
595595
S = model->S;
596596

597-
double tmp[N]; // VLA must be supported.. May cause portability problems.. If so use init_zeros_vector (will be slower).
597+
#ifdef WINDOWS
598+
// MSVC is not a C99 compiler, and does not support variable length arrays
599+
// MSVC is documented as conforming to C90
600+
double *tmp;
601+
if ( init_zero_vector(&tmp, N) ) {
602+
fprintf(stderr, "%s.%s.%d init_zero_vector(.., %d) failed\r\n",
603+
__FILE__, __func__, __LINE__, N);
604+
exit(1);
605+
}
606+
#else
607+
double tmp[N]; // VLA must be supported.. May cause portability problems.. If so use init_zero_vector (will be slower).
608+
#endif
598609

599610
copy_vector(cache_out->h_old, h_old, N);
600611
copy_vector(cache_out->c_old, c_old, N);
@@ -650,6 +661,10 @@ void lstm_forward_propagate(lstm_model_t* model, double * input, lstm_values_cac
650661

651662
copy_vector(cache_out->X, X_one_hot, S);
652663

664+
#ifdef WINDOWS
665+
free_vector(&tmp);
666+
#endif
667+
653668
}
654669
// model, y_probabilities, y_correct, the next deltas, state and cache values, &gradients, &the next deltas
655670
void lstm_backward_propagate(lstm_model_t* model, double* y_probabilities, int y_correct, lstm_values_next_cache_t* d_next, lstm_values_cache_t* cache_in, lstm_model_t* gradients, lstm_values_next_cache_t* cache_out)
@@ -925,14 +940,28 @@ void lstm_output_string_layers_to_file(FILE * fp,lstm_model_t ** model_layers, s
925940
{
926941
lstm_values_cache_t ***caches_layer;
927942
int i = 0, count, index, p = 0, b = 0;
928-
char input = set_char_to_indx(char_index_mapping, first);
943+
int input = set_indx_to_char(char_index_mapping, first);
929944
int F = model_layers[0]->F;
930945
int N = model_layers[0]->N;
946+
#ifdef WINDOWS
947+
double *first_layer_input;
948+
#else
931949
double first_layer_input[F];
950+
#endif
932951

933952
if ( fp == NULL )
934953
return;
935954

955+
#ifdef WINDOWS
956+
first_layer_input = malloc(F*sizeof(double));
957+
958+
if ( first_layer_input == NULL ) {
959+
fprintf(stderr, "%s.%s.%d malloc(%zu) failed\r\n",
960+
__FILE__, __func__, __LINE__, F*sizeof(double));
961+
exit(1);
962+
}
963+
#endif
964+
936965
caches_layer = calloc(layers, sizeof(lstm_values_cache_t**));
937966

938967
if ( caches_layer == NULL )
@@ -996,17 +1025,35 @@ void lstm_output_string_layers_to_file(FILE * fp,lstm_model_t ** model_layers, s
9961025
}
9971026

9981027
free(caches_layer);
1028+
#ifdef WINDOWS
1029+
free(first_layer_input);
1030+
#endif
1031+
9991032
}
10001033

10011034

10021035
void lstm_output_string_layers(lstm_model_t ** model_layers, set_T* char_index_mapping, int first, int numbers_to_display, int layers)
10031036
{
10041037
lstm_values_cache_t ***caches_layer;
10051038
int i = 0, count, index, p = 0, b = 0;
1006-
char input = set_char_to_indx(char_index_mapping, first);
1039+
int input = set_indx_to_char(char_index_mapping, first);
10071040
int F = model_layers[0]->F;
10081041
int N = model_layers[0]->N;
1009-
double first_layer_input[F];
1042+
#ifdef WINDOWS
1043+
double *first_layer_input;
1044+
#else
1045+
double first_layer_input[F];
1046+
#endif
1047+
1048+
#ifdef WINDOWS
1049+
first_layer_input = malloc(F*sizeof(double));
1050+
1051+
if ( first_layer_input == NULL ) {
1052+
fprintf(stderr, "%s.%s.%d malloc(%zu) failed\r\n",
1053+
__FILE__, __func__, __LINE__, F*sizeof(double));
1054+
exit(1);
1055+
}
1056+
#endif
10101057

10111058
caches_layer = calloc(layers, sizeof(lstm_values_cache_t**));
10121059

@@ -1037,6 +1084,11 @@ void lstm_output_string_layers(lstm_model_t ** model_layers, set_T* char_index_m
10371084
++count;
10381085
}
10391086

1087+
if ( index < 0 ) {
1088+
index = 0;
1089+
printf("%s.%s unexpected input char: '%c', (%d)\r\n", __FILE__, __func__, input, input);
1090+
}
1091+
10401092
first_layer_input[index] = 1.0;
10411093

10421094
p = layers - 1;
@@ -1071,6 +1123,9 @@ void lstm_output_string_layers(lstm_model_t ** model_layers, set_T* char_index_m
10711123
}
10721124

10731125
free(caches_layer);
1126+
#ifdef WINDOWS
1127+
free(first_layer_input);
1128+
#endif
10741129
}
10751130

10761131
void lstm_output_string_from_string_layers(lstm_model_t **model_layers, set_T* char_index_mapping, char * input_string, int layers, int out_length)
@@ -1082,6 +1137,18 @@ void lstm_output_string_from_string_layers(lstm_model_t **model_layers, set_T* c
10821137

10831138
int p = 0;
10841139

1140+
#ifdef WINDOWS
1141+
double *first_layer_input = malloc(F*sizeof(double));
1142+
1143+
if ( first_layer_input == NULL ) {
1144+
fprintf(stderr, "%s.%s.%d malloc(%zu) failed\r\n",
1145+
__FILE__, __func__, __LINE__, F*sizeof(double));
1146+
exit(1);
1147+
}
1148+
#else
1149+
double first_layer_input[F];
1150+
#endif
1151+
10851152
caches_layers = calloc(layers, sizeof(lstm_values_cache_t**));
10861153

10871154
if ( caches_layers == NULL ) {
@@ -1101,8 +1168,6 @@ void lstm_output_string_from_string_layers(lstm_model_t **model_layers, set_T* c
11011168
++p;
11021169
}
11031170

1104-
double first_layer_input[F];
1105-
11061171
in_len = strlen(input_string);
11071172
i = 0;
11081173

@@ -1180,6 +1245,9 @@ void lstm_output_string_from_string_layers(lstm_model_t **model_layers, set_T* c
11801245
}
11811246

11821247
free(caches_layers);
1248+
#ifdef WINDOWS
1249+
free(first_layer_input);
1250+
#endif
11831251
}
11841252

11851253
void lstm_store_progress(const char* filename, unsigned int n, double loss)
@@ -1245,7 +1313,17 @@ void lstm_train(lstm_model_t** model_layers, lstm_model_parameters_t *params, se
12451313
F = model_layers[0]->F;
12461314
S = model_layers[0]->S;
12471315

1248-
double first_layer_input[F];
1316+
#ifdef WINDOWS
1317+
double *first_layer_input = malloc(F*sizeof(double));
1318+
1319+
if ( first_layer_input == NULL ) {
1320+
fprintf(stderr, "%s.%s.%d malloc(%zu) failed\r\n",
1321+
__FILE__, __func__, __LINE__, F*sizeof(double));
1322+
exit(1);
1323+
}
1324+
#else
1325+
double first_layer_input[F];
1326+
#endif
12491327

12501328
if ( stateful ) {
12511329
stateful_d_next = calloc(layers, sizeof(lstm_values_state_t*));
@@ -1580,17 +1658,7 @@ to continue refining the weights.\n", params->store_network_name_raw);
15801658
free(gradient_layers);
15811659
free(M_layers);
15821660
free(R_layers);
1583-
1661+
#ifdef WINDOWS
1662+
free(first_layer_input);
1663+
#endif
15841664
}
1585-
1586-
1587-
1588-
1589-
1590-
1591-
1592-
1593-
1594-
1595-
1596-

lstm.h

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,13 @@
2424
#define LSTM_H
2525

2626
#include <stdlib.h>
27+
28+
#ifdef WINDOWS
29+
30+
#else
2731
#include <unistd.h>
32+
#endif
33+
2834
#include <stdio.h>
2935
#include <string.h>
3036
#include <time.h>

main.c

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,12 @@
22
#include <stdlib.h>
33
#include <string.h>
44
#include <signal.h>
5+
6+
#ifdef WINDOWS
7+
8+
#else
59
#include <unistd.h>
10+
#endif
611

712
#include "lstm.h"
813
#include "set.h"

set.c

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -54,8 +54,9 @@ set_insert_symbol(set_T * set, char c)
5454
char
5555
set_indx_to_char(set_T* set, int indx)
5656
{
57-
if ( indx >= SET_MAX_CHARS )
57+
if ( indx >= SET_MAX_CHARS ){
5858
return '\0';
59+
}
5960
return (char) set->values[indx];
6061
}
6162

@@ -68,6 +69,7 @@ set_char_to_indx(set_T* set, char c)
6869
return i;
6970
++i;
7071
}
72+
7173
return -1;
7274
}
7375

utilities.c

Lines changed: 12 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -456,14 +456,14 @@ void matrix_store(double ** A, int R, int C, FILE * fp)
456456
{
457457
int r = 0, c = 0;
458458
size_t i = 0;
459-
void * p;
459+
char *p;
460460

461461
while ( r < R ) {
462462
c = 0;
463463
while ( c < C ) {
464-
i = 0; p = &A[r][c];
464+
i = 0; p = (char*)&A[r][c];
465465
while ( i < sizeof(double) ) {
466-
fputc(*((char*)p), fp);
466+
fputc(*(p), fp);
467467
++i; ++p;
468468
}
469469
++c;
@@ -492,15 +492,15 @@ void matrix_read(double ** A, int R, int C, FILE * fp)
492492
{
493493
int r = 0, c = 0;
494494
size_t i = 0;
495-
void * p;
495+
char *p;
496496
double value;
497497

498498
while ( r < R ) {
499499
c = 0;
500500
while ( c < C ) {
501-
i = 0; p = &value;
501+
i = 0; p = (char*)&value;
502502
while ( i < sizeof(double) ) {
503-
*((char *)p) = fgetc(fp);
503+
*(p) = fgetc(fp);
504504
++i; ++p;
505505
}
506506
A[r][c] = value;
@@ -515,12 +515,12 @@ void vector_store(double* V, int L, FILE * fp)
515515
{
516516
int l = 0;
517517
size_t i = 0;
518-
void * p;
518+
char *p;
519519

520520
while ( l < L ){
521-
i = 0; p = &V[l];
521+
i = 0; p = (char*)&V[l];
522522
while ( i < sizeof(double)) {
523-
fputc(*((char*)p), fp);
523+
fputc(*(p), fp);
524524
++i; ++p;
525525
}
526526
++l;
@@ -531,13 +531,13 @@ void vector_read(double * V, int L, FILE * fp)
531531
{
532532
int l = 0;
533533
size_t i = 0;
534-
void * p;
534+
char *p;
535535
double value;
536536

537537
while ( l < L ) {
538-
i = 0; p = &value;
538+
i = 0; p = (char*)&value;
539539
while ( i < sizeof(double) ) {
540-
*((char *)p) = fgetc(fp);
540+
*(p) = fgetc(fp);
541541
++i; ++p;
542542
}
543543
V[l] = value;
@@ -554,7 +554,6 @@ void vector_store_as_matrix_json(double* V, int R, int C, FILE * fp)
554554
{
555555
int r = 0, c = 0;
556556
size_t i = 0;
557-
void * p;
558557

559558
if ( fp == NULL )
560559
return; // No file, nothing to do.
@@ -598,7 +597,6 @@ void vector_store_json(double* V, int L, FILE * fp)
598597
{
599598
int l = 0;
600599
size_t i = 0;
601-
void * p;
602600

603601
if ( fp == NULL )
604602
return; // No file, nothing to do.

0 commit comments

Comments
 (0)