void train(Matrix sampleInputs, Matrix targetOutputs){ for(int i = 0; i < sampleInputs.size(); i++){ inputs = sampleInputs[i]; outputs = computeOutputs(sampleInputs[i]); updateWeights(targetOutputs[i], 0.5, 0.3); } }
void update(Array in, int reward){ if(reward > 0 && random(5) % 2 == 0){ trainingInputs.push_back(inputs); trainingOutputs.push_back(outputs); updateWeights(outputs, 0.5, 0.3); } if(trainingInputs.size() > 300){ trainingInputs.erase(trainingInputs.begin()); trainingOutputs.erase(trainingOutputs.begin()); } inputs = in; outputs = computeOutputs(inputs); }
int evaluator_online(char *dir, const int *eval_inputs, int num_eval_inputs, int num_chained_gcs, ChainingType chainingType, uint64_t *tot_time, uint64_t *tot_time_no_load) { /* Performs the online stage of the evaluator. * The first part of the function loads data from disk * that was saved during the online phase. * Next, perform OT correction to acquire input labels * corresponding to the evaluators' inputs. * Next, receive instructions on how to evaluate and chain * the garbled circuits. * Next, receive garbler labels and the output instructions. * The output instructions are unary gates mapping output labels to 0 or 1. * Next, we call evaluator_evaluate to evaluate the garbled circuits using * the information acquired. * Finally, use the output instructions to process the output of the * evaluation subprocedure to acquire actual bits of the output. * * @param dir the director which OT and gc data are saved during the offline phase * @param eval_inputs an array of the evaluator's inputs; either 0 or 1 * @param num_eval_inputs the length of the eval_inputs array * @param num_chained_gcs the number of garbled circuits saved to disk. * @param chainingType indicates whether to do standard or SIMD-style chaining. * WARNING: SIMD-style chaining is deprecated. * @param tot_time an unpopulated int* (of length 1). evaluator_online populates * value with the total amount of time it took to evaluate. * @param tot_time_no_load an unpopulated int* (of length 1). evaluator_online populates * value with the total amount of time it took to evaluate, not including * the time to load data from disk. */ ChainedGarbledCircuit* chained_gcs; FunctionSpec function; block *garb_labels = NULL, *eval_labels = NULL, *outputmap = NULL, *offsets = NULL; int *corrections = NULL, *circuitMapping, sockfd; uint64_t start, end, _start, _end, loading_time; int num_garb_inputs = 0; /* later received from garbler */ size_t tmp; block *labels[num_chained_gcs + 1]; /* start timing after socket connection */ _start = current_time_(); { /* Load things from disk */ chained_gcs = calloc(num_chained_gcs, sizeof(ChainedGarbledCircuit)); loadChainedGarbledCircuits(chained_gcs, num_chained_gcs, dir, chainingType); loadOTPreprocessing(&eval_labels, &corrections, dir); for (int i = 1; i < num_chained_gcs + 1; i++) { labels[i] = garble_allocate_blocks(chained_gcs[i-1].gc.n); } } _end = current_time_(); loading_time = _end - _start; fprintf(stderr, "Load components: %llu\n", (_end - _start)); if ((sockfd = net_init_client(HOST, PORT)) == FAILURE) { perror("net_init_client"); exit(EXIT_FAILURE); } start = current_time_(); /* Receive eval labels: OT correction */ _start = current_time_(); if (num_eval_inputs > 0) { block *recvLabels; uint64_t _start, _end; for (int i = 0; i < num_eval_inputs; ++i) { assert(corrections[i] == 0 || corrections[i] == 1); assert(eval_inputs[i] == 0 || eval_inputs[i] == 1); corrections[i] ^= eval_inputs[i]; } recvLabels = garble_allocate_blocks(2 * num_eval_inputs); /* valgrind is saying corrections is unitialized, but it seems to be */ _start = current_time_(); { net_send(sockfd, corrections, sizeof(int) * num_eval_inputs, 0); } _end = current_time_(); fprintf(stderr, "OT correction (send): %llu\n", _end - _start); _start = current_time_(); { tmp = g_bytes_received; net_recv(sockfd, recvLabels, sizeof(block) * 2 * num_eval_inputs, 0); } _end = current_time_(); fprintf(stderr, "OT correction (receive): %llu\n", _end - _start); fprintf(stderr, "\tBytes: %lu\n", g_bytes_received - tmp); for (int i = 0; i < num_eval_inputs; ++i) { eval_labels[i] = garble_xor(eval_labels[i], recvLabels[2 * i + eval_inputs[i]]); } free(recvLabels); } free(corrections); _end = current_time_(); fprintf(stderr, "OT correction: %llu\n", _end - _start); /* Receive circuit mapping which maps instructions-gc-id to disk-gc-id */ _start = current_time_(); { int size; tmp = g_bytes_received; net_recv(sockfd, &size, sizeof(int), 0); circuitMapping = malloc(sizeof(int) * size); net_recv(sockfd, circuitMapping, sizeof(int) * size, 0); } _end = current_time_(); fprintf(stderr, "Receive circuit map: %llu\n", _end - _start); fprintf(stderr, "\tBytes: %lu\n", g_bytes_received - tmp); /* receive garbler labels */ _start = current_time_(); { tmp = g_bytes_received; net_recv(sockfd, &num_garb_inputs, sizeof(int), 0); if (num_garb_inputs > 0) { garb_labels = garble_allocate_blocks(sizeof(block) * num_garb_inputs); net_recv(sockfd, garb_labels, sizeof(block) * num_garb_inputs, 0); } } _end = current_time_(); fprintf(stderr, "Receive garbler labels: %llu\n", _end - _start); fprintf(stderr, "\tBytes: %lu\n", g_bytes_received - tmp); /* Receive output instructions */ OutputInstructions output_instructions; _start = current_time_(); { tmp = g_bytes_received; net_recv(sockfd, &output_instructions.size, sizeof(output_instructions.size), 0); output_instructions.output_instruction = malloc(output_instructions.size * sizeof(OutputInstruction)); net_recv(sockfd, output_instructions.output_instruction, output_instructions.size * sizeof(OutputInstruction), 0); } _end = current_time_(); fprintf(stderr, "Receive output instructions: %llu\n", _end - _start); fprintf(stderr, "\tBytes: %lu\n", g_bytes_received - tmp); _start = current_time_(); { tmp = g_bytes_received; recvInstructions(sockfd, &function.instructions, &offsets); } _end = current_time_(); fprintf(stderr, "Receive instructions: %llu\n", _end - _start); fprintf(stderr, "\tBytes: %lu\n", g_bytes_received - tmp); /* Done with socket, so close */ close(sockfd); /* Follow instructions and evaluate */ _start = current_time_(); block **computedOutputMap = malloc(sizeof(block *) * (num_chained_gcs + 1)); { computedOutputMap[0] = garble_allocate_blocks(num_garb_inputs + num_eval_inputs); labels[0] = garble_allocate_blocks(num_garb_inputs + num_eval_inputs); memcpy(&computedOutputMap[0][0], garb_labels, sizeof(block) * num_garb_inputs); memcpy(&computedOutputMap[0][num_garb_inputs], eval_labels, sizeof(block) * num_eval_inputs); memcpy(&labels[0][0], garb_labels, sizeof(block) * num_garb_inputs); memcpy(&labels[0][num_garb_inputs], eval_labels, sizeof(block) * num_eval_inputs); for (int i = 1; i < num_chained_gcs + 1; i++) { computedOutputMap[i] = garble_allocate_blocks(chained_gcs[i-1].gc.m); } evaluator_evaluate(chained_gcs, num_chained_gcs, &function.instructions, labels, circuitMapping, computedOutputMap, offsets, chainingType); } _end = current_time_(); fprintf(stderr, "Evaluate: %llu\n", _end - _start); _start = current_time_(); int *output = calloc(output_instructions.size, sizeof(int)); { int res = computeOutputs(&output_instructions, output, computedOutputMap); if (res == FAILURE) { fprintf(stderr, "computeOutputs failed\n"); /* return FAILURE; */ } } free(output_instructions.output_instruction); _end = current_time_(); fprintf(stderr, "Map outputs: %llu\n", _end - _start); /* cleanup */ free(circuitMapping); for (int i = 0; i < num_chained_gcs; ++i) { freeChainedGarbledCircuit(&chained_gcs[i], false, chainingType); free(labels[i]); free(computedOutputMap[i]); computedOutputMap[i] = NULL; } //free(labels[num_chained_gcs]); free(computedOutputMap[num_chained_gcs]); free(chained_gcs); free(computedOutputMap); free(outputmap); free(output); free(garb_labels); free(eval_labels); if (function.instructions.instr) { free(function.instructions.instr); function.instructions.instr = NULL; } free(offsets); end = current_time_(); if (tot_time) *tot_time = end - start + loading_time; if (tot_time_no_load) *tot_time_no_load = end - start; return SUCCESS; }