Files
mlpack/fastlib/trunk/contrib/houyang/pole_c/parser_input.h
T
2011-01-31 14:01:43 +00:00

430 lines
12 KiB
C++

#ifndef PARSER_INPUT_H
#define PARSER_INPUT_H
#include <boost/program_options.hpp>
#include <netdb.h>
#include <netinet/tcp.h>
#include "parallel.h"
namespace boost_po = boost::program_options;
void ParserInput(boost_po::variables_map &vm) {
// prepare to fetch data from port
if ( vm.count("port") ) {
int daemon = socket(PF_INET, SOCK_STREAM, 0);
if (daemon < 0) {
cerr << "Can't open a socket!" << endl;
exit(1);
}
int on = 1;
// set socket options
if (setsockopt(daemon, SOL_SOCKET, SO_REUSEADDR, (char*)&on, sizeof(on)) < 0) {
perror("setsockopt SO_REUSEADDR");
}
sockaddr_in address;
address.sin_family = AF_INET;
address.sin_addr.s_addr = htonl(INADDR_ANY);
short unsigned int port = vm["port"].as<size_t>();
port = port > 0 ? port : 39524; // default port
address.sin_port = htons(port);
if (bind(daemon,(sockaddr*)&address, sizeof(address)) < 0) {
cerr << "Failure to bind!" << endl;
exit(1);
}
cout << "Socket opened at port " << port << "." << endl;
int source_count = 1;
if (vm.count("num_port_sources")) {
source_count = vm["num_port_sources"].as<size_t>();
}
listen(daemon, source_count);
//sockaddr_in client_address;
//socklen_t size = sizeof(client_address);
// TODO: implement reading from multiple clients
}
// prepare to fetch data from file
if (vm.count("data_train")) {
global.train_data_fn = vm["data_train"].as<string>();
if (global.train_data_fn.length() != 0){
if (!global.quiet) {
cerr << "Input data from " << global.train_data_fn << "... ";
}
}
}
}
int space_or_null(int c) {
if (c==0)
return 1;
return isspace((unsigned char)c);
}
/* Scan through input file and count # of examples(lines), maximum # of
features per example, and the size of the longest line. */
void CountFile(string fn, size_t &num_examples, size_t &max_features_example, size_t &max_length_line)
{
FILE *fp;
int ic;
char c;
size_t current_length, current_fe;
if ((fp = fopen (fn.c_str(), "r")) == NULL) {
cerr << "Cannot open input example file: " << fn << ". Porgram stopped!"<< endl;
exit (1);
}
current_length = 0;
current_fe = 0;
max_length_line = 0;
num_examples = 1;
max_features_example = 0;
while ((ic=getc(fp)) != EOF) {
c = (char)ic;
current_length ++;
if (space_or_null((int)c)) {
current_fe ++;
}
if (c == '\n') {
num_examples ++;
if (current_length > max_length_line) {
max_length_line = current_length;
}
if (current_fe > max_features_example) {
max_features_example = current_fe;
}
current_length = 0;
current_fe = 0;
}
}
fclose(fp);
}
/* Read features from a line buffer */
int ReadFeatures(char *line, FEATURE *feat, T_LBL *label, size_t &num_feats, size_t &max_features_example, char **comment)
{
unsigned long wpos,pos;
unsigned long w_idx;
double w_val;
int numread;
char featurepair[1000],junk[1000];
pos = 0;
(*comment)=NULL;
while(line[pos]) { // strip comment
if((line[pos] == '#') && (!(*comment))) {
line[pos]=0;
(*comment) = &(line[pos+1]);
}
if(line[pos] == '\n') { // strip CR
line[pos]=0;
}
pos++;
}
if(!(*comment)) {
(*comment) = &(line[pos]);
}
wpos=0;
// check, that line starts with target value or zero, but not with feature pair
if(sscanf(line,"%s", featurepair) == EOF)
return(0);
pos=0;
while((featurepair[pos] != ':') && featurepair[pos])
pos++;
if(featurepair[pos] == ':') {
cerr << "Line must start with label or 0!!!" << endl;;
cerr << "Line: " << line << endl;
exit (1);
}
// read the target value
double lbl;
if(sscanf(line,"%lf", &lbl) == EOF)
return(0);
(*label) = (T_LBL)lbl;
pos=0;
while(space_or_null((int)line[pos]))
pos++;
while((!space_or_null((int)line[pos])) && line[pos])
pos++;
while(((numread=sscanf(line+pos,"%s",featurepair)) != EOF) &&
(numread > 0) && (wpos<max_features_example)) {
while(space_or_null((int)line[pos]))
pos++;
while((!space_or_null((int)line[pos])) && line[pos])
pos++;
if(sscanf(featurepair,"%ld:%lf%s", &w_idx, &w_val, junk)==2) {
// it is a regular feature
if(w_idx<=0) {
cerr << "Feature numbers must be larger or equal to 1!" << endl;
cerr << "Line: " << line << endl;
exit (1);
}
if((wpos>0) && ((feat[wpos-1]).widx >= w_idx)) {
cerr << "Features must be in increasing order!" << endl;
cerr << "Line: " << line << endl;
exit (1);
}
(feat[wpos]).widx = (T_IDX)w_idx; // feature index starts from 1
(feat[wpos]).wval = (T_VAL)w_val;
if (w_idx > global.max_feature_idx)
global.max_feature_idx = w_idx;
wpos++;
}
else {
cout << "Cannot parse feature/value pair!!!" << endl;
cerr << featurepair << " in LINE: " << line << endl;
exit (1);
}
}
num_feats = wpos;
return(1);
}
/* Batch read all data from a file */
void SerialRead(string &data_fn, EXAMPLE **examples, size_t &num_examples) {
FILE *fp;
char *line, *comment;
size_t max_num_examples, max_features_example, max_length_line;
size_t dnum=0, wpos, dpos=0, dneg=0, dunlab=0;
FEATURE *feat_cache;
T_LBL label_cache;
size_t i;
// scan size of input data file
CountFile(data_fn, max_num_examples, max_features_example, max_length_line);
max_num_examples --;
max_features_example --;
max_length_line += 2;
(*examples) = (EXAMPLE *)my_malloc( sizeof(EXAMPLE)*max_num_examples ); // feature vectors
line = (char *)my_malloc( sizeof(char)*max_length_line );
feat_cache = (FEATURE *)my_malloc( sizeof(FEATURE)*max_features_example );
dnum=0;
num_examples = 0;
if ((fp = fopen (data_fn.c_str(), "r")) == NULL) {
cerr << "Cannot open " << data_fn << ". Porgram stopped!"<< endl;
exit (1);
}
while((!feof(fp)) && fgets(line,(int)max_length_line,fp)) {
if(line[0] == '#') {
continue; // comment line
}
for (i=0; i<max_features_example; i++) {
feat_cache[i].widx = 0;
feat_cache[i].wval = 0;
}
if(!ReadFeatures(line, feat_cache, &label_cache, wpos, max_features_example, &comment)) {
cout << endl << "Cannot read line " << dnum << " !"<< endl << line << endl;
exit(1);
}
if(label_cache > 0)
dpos++;
if (label_cache < 0)
dneg++;
if (label_cache == 0)
dunlab++;
// setup an example
CreateExample((*examples)+dnum, feat_cache, label_cache, comment, max_features_example);
//print_ex((*examples)+dnum);
dnum++;
if(!global.quiet) {
if((dnum % 10000) == 0) {
cout << dnum << "..";
}
}
}
fclose(fp);
free(line);
free(feat_cache);
if(!global.quiet) {
cout << "done. " << dnum << " examples loaded: " << dpos << " positive and " << dneg <<" negative." << " Max dimension: " << global.max_feature_idx << endl;
}
num_examples = dnum;
}
void *ParReadThread(void *) {
// TODO
return NULL;
}
/* Read data parallelly while training */
void ParallelRead(size_t num_threads) {
pthread_create(&global.par_read_thread, NULL, ParReadThread, NULL);
}
void ReadData(boost_po::variables_map &vm) {
size_t i, j, left_ct;
global.max_feature_idx = 0;
if ( vm.count("par_read") ) {
ParallelRead(global.num_threads);
//ring_size = 1 << 11; // 2048
//parsed_ct = 0;
}
else {
SerialRead(global.train_data_fn, &train_exps, num_train_exps);
if (num_train_exps == 0) {
cout << "0 input samples!" << endl;
exit(1);
}
parsed_ct = num_train_exps;
/* To mimic the online learning senario, in each epoch,
we randomly permutate the training set, indexed by old_from_new */
old_from_new = (size_t *)my_malloc(sizeof(size_t) * parsed_ct);
for (i=0; i<parsed_ct; i++) {
old_from_new[i] = i;
}
for (i=0; i<parsed_ct; i++) {
j = rand() % parsed_ct;
swap(old_from_new[i], old_from_new[j]);
}
if (global.num_iter_res >= parsed_ct) {
global.num_epoches = global.num_epoches + (size_t)(global.num_iter_res / parsed_ct);
global.num_iter_res = global.num_iter_res % parsed_ct;
}
left_ct = global.num_threads*global.mb_size - (global.num_epoches * parsed_ct + global.num_iter_res) % (global.num_threads*global.mb_size);
global.num_iter_res = global.num_iter_res + left_ct;
cout << "n_epo= " <<global.num_epoches << ", n_iter_res= " << global.num_iter_res << endl;
//L + \lambda/2 \|w\|^2 <=> CL + 1/2 \|w\|^2
if (vm.count("C")) {
l1.C = vm["C"].as<double>();
if (l1.C <= 0.0) {
cout << "Parameter C should be positive!" << endl;
exit(1);
}
//l1.reg_factor = 1.0 / (l1.C * num_train_exps);
l1.reg_factor = 1.0 / l1.C;
}
if (vm.count("lambda")) {
l1.reg_factor = vm["lambda"].as<double>();
if (l1.reg_factor < 0.0) {
cout << "Parameter lambda should be non-negative!" << endl;
exit(1);
}
else if (l1.reg_factor == 0) {
cout << "Regularization factor == 0. No regularization imposed!" << endl;
}
else {
//l1.C = 1.0 / (l1.reg_factor * num_train_exps);
l1.C = 1.0 / l1.reg_factor;
}
}
//cout << "lambda= " << l1.reg_factor << ", C= " << l1.C << endl << endl;
}
//delay_indicies = (size_t*) calloc(l1.num_threads, sizeof(size_t));
//threads_to_use = (size_t*) calloc(ring_size, sizeof(size_t));
//delay_ring = (EXAMPLE**)calloc(ring_size, sizeof(EXAMPLE*));
//for (i = 0; i < ring_size; i++) {
// delay_ring[i] = NULL;
//}
}
void FinishData() {
for(size_t i=0; i<num_train_exps; i++) {
FreeExample(train_exps+i);
}
free(train_exps);
}
int GetImmedExample(EXAMPLE** x_p, size_t tid, learner &l) {
size_t i, j;
pthread_mutex_lock(&examples_lock);
if (epoch_ct < global.num_epoches) {
size_t ring_index = used_ct % parsed_ct;
if (ring_index == (parsed_ct-1)) { // one epoch finished
epoch_ct ++;
/* To mimic the online learning senario, in each epoch,
we randomly permutate the training set, indexed by old_from_new */
for (i=0; i<parsed_ct; i++) {
old_from_new[i] = i;
}
for (i=0; i<parsed_ct; i++) {
j = rand() % parsed_ct;
swap(old_from_new[i], old_from_new[j]);
}
}
train_exps[old_from_new[ring_index]].in_use = true;
used_ct ++;
l.num_used_exp[tid] = l.num_used_exp[tid] + 1;
(*x_p) = train_exps + old_from_new[ring_index];
pthread_mutex_unlock(&examples_lock);
return 1;
}
else if (iter_res_ct < global.num_iter_res) {
size_t ring_index = used_ct % parsed_ct;
train_exps[old_from_new[ring_index]].in_use = true;
used_ct ++;
l.num_used_exp[tid] = l.num_used_exp[tid] + 1;
(*x_p) = train_exps + old_from_new[ring_index];
iter_res_ct ++;
pthread_mutex_unlock(&examples_lock);
return 1;
}
else {
pthread_mutex_unlock(&examples_lock);
return 0;
}
}
/*
example* GetDelayedExample(size_t thread) {
if (delay_indicies[thread] == master_index) { // no delayed example available
return NULL;
}
else {
size_t index = delay_indicies[thread] % ring_size;
example* ret = delay_ring[index];
delay_indicies[thread]++;
pthread_mutex_lock(&ret->lock);
if (--threads_to_use[index] == 0) {
pthread_mutex_lock(&example_delay);
delay_ring[index] = NULL;
pthread_mutex_unlock(&example_delay);
}
pthread_mutex_unlock(&ret->lock);
return ret;
}
}
*/
/*
bool thread_done(size_t thread)
{
bool ret;
pthread_mutex_lock(&example_delay);
ret = (delay_indicies[thread] == master_index);
pthread_mutex_unlock(&example_delay);
return ret;
}
*/
#endif