00001 #include <stdio.h>
00002 #include <string.h>
00003 #include <unistd.h>
00004 #include <sys/types.h>
00005 #include <sys/socket.h>
00006 #include <netinet/in.h>
00007 #include <netdb.h>
00008 #include <pthread.h>
00009 #include <time.h>
00010
00011 #include "mini_blas.h"
00012 #include "utils.h"
00013 #include "parser.h"
00014 #include "server.h"
00015 #include "connected_layer.h"
00016 #include "convolutional_layer.h"
00017
00018 #define SERVER_PORT 9423
00019 #define STR(x) #x
00020
00021 int socket_setup(int server)
00022 {
00023 int fd = 0;
00024 struct sockaddr_in me;
00025
00026
00027
00028 if ((fd = socket(AF_INET, SOCK_STREAM, 0)) < 0) {
00029 error("cannot create socket");
00030 }
00031
00032
00033 if (server == 1){
00034 bzero((char *) &me, sizeof(me));
00035 me.sin_family = AF_INET;
00036 me.sin_addr.s_addr = htonl(INADDR_ANY);
00037 me.sin_port = htons(SERVER_PORT);
00038
00039 if (bind(fd, (struct sockaddr *)&me, sizeof(me)) < 0) {
00040 error("bind failed");
00041 }
00042 }
00043
00044 return fd;
00045 }
00046
00047 typedef struct{
00048 int fd;
00049 int counter;
00050 network net;
00051 } connection_info;
00052
00053 void read_and_add_into(int fd, float *a, int n)
00054 {
00055 float *buff = calloc(n, sizeof(float));
00056 read_all(fd, (char*) buff, n*sizeof(float));
00057 axpy_cpu(n, 1, buff, 1, a, 1);
00058 free(buff);
00059 }
00060
00061 void handle_connection(void *pointer)
00062 {
00063 connection_info info = *(connection_info *) pointer;
00064 free(pointer);
00065
00066 if(info.counter%100==0){
00067 char buff[256];
00068 sprintf(buff, "unikitty/net_%d.part", info.counter);
00069 save_network(info.net, buff);
00070 }
00071 int fd = info.fd;
00072 network net = info.net;
00073 int i;
00074 for(i = 0; i < net.n; ++i){
00075 if(net.types[i] == CONVOLUTIONAL){
00076 convolutional_layer layer = *(convolutional_layer *) net.layers[i];
00077
00078 read_and_add_into(fd, layer.bias_updates, layer.n);
00079 int num = layer.n*layer.c*layer.size*layer.size;
00080 read_and_add_into(fd, layer.filter_updates, num);
00081 }
00082 if(net.types[i] == CONNECTED){
00083 connected_layer layer = *(connected_layer *) net.layers[i];
00084
00085 read_and_add_into(fd, layer.bias_updates, layer.outputs);
00086 read_and_add_into(fd, layer.weight_updates, layer.inputs*layer.outputs);
00087 }
00088 }
00089 for(i = 0; i < net.n; ++i){
00090 if(net.types[i] == CONVOLUTIONAL){
00091 convolutional_layer layer = *(convolutional_layer *) net.layers[i];
00092 update_convolutional_layer(layer);
00093
00094 write_all(fd, (char*) layer.biases, layer.n*sizeof(float));
00095 int num = layer.n*layer.c*layer.size*layer.size;
00096 write_all(fd, (char*) layer.filters, num*sizeof(float));
00097 }
00098 if(net.types[i] == CONNECTED){
00099 connected_layer layer = *(connected_layer *) net.layers[i];
00100 update_connected_layer(layer);
00101 write_all(fd, (char *)layer.biases, layer.outputs*sizeof(float));
00102 write_all(fd, (char *)layer.weights, layer.outputs*layer.inputs*sizeof(float));
00103 }
00104 }
00105
00106 close(fd);
00107 }
00108
00109 void server_update(network net)
00110 {
00111 int fd = socket_setup(1);
00112 int counter = 18000;
00113 listen(fd, 64);
00114 struct sockaddr_in client;
00115 socklen_t client_size = sizeof(client);
00116 time_t t=0;
00117 while(1){
00118 connection_info *info = calloc(1, sizeof(connection_info));
00119 info->net = net;
00120 info->counter = counter;
00121 pthread_t worker;
00122 int connection = accept(fd, (struct sockaddr *) &client, &client_size);
00123 if(!t) t=time(0);
00124 info->fd = connection;
00125 pthread_create(&worker, NULL, (void *) &handle_connection, info);
00126 ++counter;
00127 printf("%d\n", counter);
00128
00129 }
00130 close(fd);
00131 }
00132
00133 void client_update(network net, char *address)
00134 {
00135 int fd = socket_setup(0);
00136
00137 struct hostent *hp;
00138 struct sockaddr_in server;
00139
00140
00141 bzero((char*)&server, sizeof(server));
00142 server.sin_family = AF_INET;
00143 server.sin_port = htons(SERVER_PORT);
00144
00145
00146 hp = gethostbyname(address);
00147 if (!hp) {
00148 perror("no such host");
00149 fprintf(stderr, "could not obtain address of %s\n", "localhost");
00150 }
00151
00152
00153 memcpy((void *)&server.sin_addr, hp->h_addr_list[0], hp->h_length);
00154 if (connect(fd, (struct sockaddr *) &server, sizeof(server)) < 0) {
00155 error("error connecting");
00156 }
00157
00158
00159 int i;
00160
00161 for(i = 0; i < net.n; ++i){
00162 if(net.types[i] == CONVOLUTIONAL){
00163 convolutional_layer layer = *(convolutional_layer *) net.layers[i];
00164 write_all(fd, (char*) layer.bias_updates, layer.n*sizeof(float));
00165 int num = layer.n*layer.c*layer.size*layer.size;
00166 write_all(fd, (char*) layer.filter_updates, num*sizeof(float));
00167 memset(layer.bias_updates, 0, layer.n*sizeof(float));
00168 memset(layer.filter_updates, 0, num*sizeof(float));
00169 }
00170 if(net.types[i] == CONNECTED){
00171 connected_layer layer = *(connected_layer *) net.layers[i];
00172 write_all(fd, (char *)layer.bias_updates, layer.outputs*sizeof(float));
00173 write_all(fd, (char *)layer.weight_updates, layer.outputs*layer.inputs*sizeof(float));
00174 memset(layer.bias_updates, 0, layer.outputs*sizeof(float));
00175 memset(layer.weight_updates, 0, layer.inputs*layer.outputs*sizeof(float));
00176 }
00177 }
00178
00179
00180 for(i = 0; i < net.n; ++i){
00181 if(net.types[i] == CONVOLUTIONAL){
00182 convolutional_layer layer = *(convolutional_layer *) net.layers[i];
00183
00184 read_all(fd, (char*) layer.biases, layer.n*sizeof(float));
00185 int num = layer.n*layer.c*layer.size*layer.size;
00186 read_all(fd, (char*) layer.filters, num*sizeof(float));
00187
00188 #ifdef GPU
00189 push_convolutional_layer(layer);
00190 #endif
00191 }
00192 if(net.types[i] == CONNECTED){
00193 connected_layer layer = *(connected_layer *) net.layers[i];
00194
00195 read_all(fd, (char *)layer.biases, layer.outputs*sizeof(float));
00196 read_all(fd, (char *)layer.weights, layer.outputs*layer.inputs*sizeof(float));
00197
00198 #ifdef GPU
00199 push_connected_layer(layer);
00200 #endif
00201 }
00202 }
00203
00204 close(fd);
00205 }