void save_shifts (void) { shifts *p; short *sp1; short *sp2; short *send; p = (shifts *) mallocate((unsigned) (sizeof(shifts) + (nshifts - 1) * sizeof(short))); p->number = this_state->number; p->nshifts = nshifts; sp1 = shiftset; sp2 = p->shifts; send = shiftset + nshifts; while (sp1 < send) *sp2++ = *sp1++; if (last_shift) { last_shift->next = p; last_shift = p; } else { first_shift = p; last_shift = p; } }
/* init_sres initializes libSRES functionality, including population data, generations, ranges, etc. parameters: ip: the program's input parameters sp: parameters required by libSRES returns: nothing notes: Excuse the awful variable names. They are named according to libSRES conventions for the sake of consistency. Many of the parameters required by libSRES are not configurable via the command-line because they haven't needed to be changed but this does not mean they aren't significant. todo: */ void init_sres (input_params& ip, sres_params& sp) { // Initialize parameters required by libSRES int es = esDefESSlash; int constraint = 0; int dim = ip.num_dims; int miu = ip.pop_parents; int lambda = ip.pop_total; int gen = ip.generations; double gamma = esDefGamma; double alpha = esDefAlpha; double varphi = esDefVarphi; int retry = 0; sp.pf = essrDefPf; // Transform is a dummy function f(x)->x but is still required to fit libSRES's code structure sp.trsfm = (ESfcnTrsfm*)mallocate(sizeof(ESfcnTrsfm) * dim); for (int i = 0; i < dim; i++) { sp.trsfm[i] = transform; } // Call libSRES's initialize function int rank = get_rank(); ostream& v = term->verbose(); if (rank == 0) { cout << term->blue << "Running libSRES initialization simulations " << term->reset << ". . . "; cout.flush(); v << endl; } ESInitial(ip.seed, &(sp.param), sp.trsfm, fitness, es, constraint, dim, sp.ub, sp.lb, miu, lambda, gen, gamma, alpha, varphi, retry, &(sp.population), &(sp.stats)); if (rank == 0) { cout << term->blue << "Done"; v << " with libSRES initialization simulations"; cout << term->reset << endl; } }
/* Load code and prototypes from file */ static void load(char *_filename) { FILE *fp; char *cp; word n, left; char filename[100]; /* should suffice on all systems */ strcpy(filename, _filename); M = mallocate (memorysize + 1); /* allocate main memory array */ if (M == NULL) abend("Memory size too large (use /m option)\n"); addext(filename, ".ccd"); if ((fp = fopen(filename, BINARYREAD)) == NULL) { fprintf(stderr, "Cannot open .ccd file\n"); endrun(10); }; ic = 0; /* read static data and code */ left = memorysize + 1; /* from .ccd file */ do { if (left == 0) abend("Memory size too small (use /m option)\n"); n = min (IOBLOCK / sizeof(word), left); n = fread((char *) &M[ic], sizeof(word), (int) n, fp); ic += n; left -= n; } while (n != 0); /* now ic = number of words read */ fclose(fp); /* Get various addresses passed by GENERATOR */ ipradr = M[ic - 5]; /* primitive type desctriptions */ temporary = M[ic - 4]; /* global temporary variables */ strings = M[ic - 3]; /* string constants */ lastprot = M[ic - 2]; /* last prototype number */ freem = M[ic - 1]; /* first free word in memory */ /* Read prototypes from .pcd file */ addext(filename, ".pcd"); if ((fp = fopen(filename, BINARYREAD)) == NULL) { fprintf(stderr, "Cannot open .pcd file\n"); endrun(10); } for (n = MAINBLOCK; n <= lastprot; n++) { cp = ballocate (sizeof(protdescr)); if (cp == NULL) abend("Memory size too large (use /m option)\n"); prototype[n] = (protdescr *) cp; if (fread(cp, sizeof(protdescr), 1, fp) != 1) abend("Cannot read .pcd file\n"); } fclose(fp); /* Open trace file */ if (debug) { addext(filename, ".trd"); if ((tracefile = fopen(filename, "w")) == NULL) abend("Cannot open .trd file\n"); } } /* end load */
/* find which rules can be used for reduction transitions from the current state and make a reductions structure for the state to record their rule numbers. */ void save_reductions (void) { short *isp; short *rp1; short *rp2; int item; int count; reductions *p; short *rend; /* find and count the active items that represent ends of rules */ count = 0; for (isp = itemset; isp < itemsetend; isp++) { item = ritem[*isp]; if (item < 0) { redset[count++] = -item; } } /* make a reductions structure and copy the data into it. */ if (count) { p = (reductions *) mallocate((unsigned) (sizeof(reductions) + (count - 1) * sizeof(short))); p->number = this_state->number; p->nreds = count; rp1 = redset; rp2 = p->rules; rend = rp1 + count; while (rp1 < rend) *rp2++ = *rp1++; if (last_reduction) { last_reduction->next = p; last_reduction = p; } else { first_reduction = p; last_reduction = p; } } }
void initialize_states (void) { core *p; /* unsigned *rp1; JF unused */ /* unsigned *rp2; JF unused */ /* unsigned *rend; JF unused */ p = (core *) mallocate((unsigned) (sizeof(core) - sizeof(short))); first_state = last_state = this_state = p; nstates = 1; }
/* subroutine of augment_automaton. Create the next-to-final state, to which a shift has already been made in the initial state. */ void insert_start_shift (void) { core *statep; shifts *sp; statep = (core *) mallocate((unsigned) (sizeof(core) - sizeof(short))); statep->number = nstates; statep->accessing_symbol = start_symbol; last_state->next = statep; last_state = statep; /* Make a shift from this state to (what will be) the final state. */ sp = NEW(shifts); sp->number = nstates++; sp->nshifts = 1; sp->shifts[0] = nstates; last_shift->next = sp; last_shift = sp; }
/* read_file takes an input_data struct and stores the contents of the associated file in a string parameters: ifd: the input_data struct to contain the file name, buffer to store the contents, size of the file, and current index returns: nothing notes: The buffer in ifd will be sized large enough to fit the file todo: */ void read_file (input_data* ifd) { int rank = get_rank(); ostream& v = term->verbose(); term->rank(rank, v); v << term->blue << "Reading file " << term->reset << ifd->filename << " . . . "; // Open the file for reading FILE* file = fopen(ifd->filename, "r"); if (file == NULL) { cout << term->red << "Couldn't open " << ifd->filename << "!" << term->reset << endl; exit(EXIT_FILE_READ_ERROR); } // Seek to the end of the file, grab its size, and then rewind fseek(file, 0, SEEK_END); long size = ftell(file); ifd->size = size; rewind(file); // Allocate enough memory to contain the whole file ifd->buffer = (char*)mallocate(sizeof(char) * size + 1); // Copy the file's contents into the buffer long result = fread(ifd->buffer, 1, size, file); if (result != size) { cout << term->red << "Couldn't read from " << ifd->filename << term->reset << endl; exit(EXIT_FILE_READ_ERROR); } ifd->buffer[size] = '\0'; // Close the file if (fclose(file) != 0) { cout << term->red << "Couldn't close " << ifd->filename << term->reset << endl; exit(EXIT_FILE_READ_ERROR); } term->done(v); }
core * new_state (int symbol) { int n; core *p; short *isp1; short *isp2; short *iend; #ifdef TRACE fprintf(stderr, "Entering new_state, symbol = %d\n", symbol); #endif if (nstates >= MAXSHORT) toomany("states"); isp1 = kernel_base[symbol]; iend = kernel_end[symbol]; n = iend - isp1; p = (core *) mallocate((unsigned) (sizeof(core) + (n - 1) * sizeof(short))); p->accessing_symbol = symbol; p->number = nstates; p->nitems = n; isp2 = p->items; while (isp1 < iend) *isp2++ = *isp1++; last_state->next = p; last_state = p; nstates++; return (p); }
/* Make sure that the initial state has a shift that accepts the grammar's start symbol and goes to the next-to-final state, which has a shift going to the final state, which has a shift to the termination state. Create such states and shifts if they don't happen to exist already. */ void augment_automaton (void) { int i; int k; /* int found; JF unused */ core *statep; shifts *sp; shifts *sp2; shifts *sp1 = NULL; sp = first_shift; if (sp) { if (sp->number == 0) { k = sp->nshifts; statep = first_state->next; /* The states reached by shifts from first_state are numbered 1...K. Look for one reached by start_symbol. */ while (statep->accessing_symbol < start_symbol && statep->number < k) statep = statep->next; if (statep->accessing_symbol == start_symbol) { /* We already have a next-to-final state. Make sure it has a shift to what will be the final state. */ k = statep->number; while (sp && sp->number < k) { sp1 = sp; sp = sp->next; } if (sp && sp->number == k) { sp2 = (shifts *) mallocate((unsigned) (sizeof(shifts) + sp->nshifts * sizeof(short))); sp2->number = k; sp2->nshifts = sp->nshifts + 1; sp2->shifts[0] = nstates; for (i = sp->nshifts; i > 0; i--) sp2->shifts[i] = sp->shifts[i - 1]; /* Patch sp2 into the chain of shifts in place of sp, following sp1. */ sp2->next = sp->next; sp1->next = sp2; if (sp == last_shift) last_shift = sp2; FREE(sp); } else { sp2 = NEW(shifts); sp2->number = k; sp2->nshifts = 1; sp2->shifts[0] = nstates; /* Patch sp2 into the chain of shifts between sp1 and sp. */ sp2->next = sp; sp1->next = sp2; if (sp == (shifts *)NULL) last_shift = sp2; } } else { /* There is no next-to-final state as yet. */ /* Add one more shift in first_shift, going to the next-to-final state (yet to be made). */ sp = first_shift; sp2 = (shifts *) mallocate(sizeof(shifts) + sp->nshifts * sizeof(short)); sp2->nshifts = sp->nshifts + 1; /* Stick this shift into the vector at the proper place. */ statep = first_state->next; for (k = 0, i = 0; i < sp->nshifts; k++, i++) { if (statep->accessing_symbol > start_symbol && i == k) sp2->shifts[k++] = nstates; sp2->shifts[k] = sp->shifts[i]; statep = statep->next; } if (i == k) sp2->shifts[k++] = nstates; /* Patch sp2 into the chain of shifts in place of sp, at the beginning. */ sp2->next = sp->next; first_shift = sp2; if (last_shift == sp) last_shift = sp2; FREE(sp); /* Create the next-to-final state, with shift to what will be the final state. */ insert_start_shift(); } } else { /* The initial state didn't even have any shifts. Give it one shift, to the next-to-final state. */ sp = NEW(shifts); sp->nshifts = 1; sp->shifts[0] = nstates; /* Patch sp into the chain of shifts at the beginning. */ sp->next = first_shift; first_shift = sp; /* Create the next-to-final state, with shift to what will be the final state. */ insert_start_shift(); } } else { /* There are no shifts for any state. Make one shift, from the initial state to the next-to-final state. */ sp = NEW(shifts); sp->nshifts = 1; sp->shifts[0] = nstates; /* Initialize the chain of shifts with sp. */ first_shift = sp; last_shift = sp; /* Create the next-to-final state, with shift to what will be the final state. */ insert_start_shift(); } /* Make the final state--the one that follows a shift from the next-to-final state. The symbol for that shift is 0 (end-of-file). */ statep = (core *) mallocate((unsigned) (sizeof(core) - sizeof(short))); statep->number = nstates; last_state->next = statep; last_state = statep; /* Make the shift from the final state to the termination state. */ sp = NEW(shifts); sp->number = nstates++; sp->nshifts = 1; sp->shifts[0] = nstates; last_shift->next = sp; last_shift = sp; /* Note that the variable `final_state' refers to what we sometimes call the termination state. */ final_state = nstates; /* Make the termination state. */ statep = (core *) mallocate((unsigned) (sizeof(core) - sizeof(short))); statep->number = nstates++; last_state->next = statep; last_state = statep; }
/* simulate_set performs the required piping to setup and run a simulation with the given parameters parameters: parameters: the parameters to pass as a parameter set to the simulation returns: the score the simulation received notes: todo: */ double simulate_set (double parameters[]) { // Get the MPI rank of the process int rank = get_rank(); ostream& v = term->verbose(); // Create a pipe int pipes[2]; v << " "; term->rank(rank, v); v << term->blue << "Creating a pipe " << term->reset << ". . . "; if (pipe(pipes) == -1) { term->failed_pipe_create(); exit(EXIT_PIPE_CREATE_ERROR); } v << term->blue << "Done: " << term->reset << "using file descriptors " << pipes[0] << " and " << pipes[1] << endl; // Fork the process so the child can run the simulation v << " "; term->rank(rank, v); v << term->blue << "Forking the process " << term->reset << ". . . "; pid_t pid = fork(); if (pid == -1) { term->failed_fork(); exit(EXIT_FORK_ERROR); } int child_pid; if (pid == 0) { child_pid = getpid(); } else { child_pid = pid; v << term->blue << "Done: " << term->reset << "the child process's PID is " << child_pid << endl; } int rank_strlen = INT_STRLEN(rank); char* grad_fname = (char*)mallocate(sizeof(char) * (strlen("input-.gradients") + rank_strlen + 1)); sprintf(grad_fname, "input-%d.gradients", rank); if (pid == 0) { char** sim_args = copy_args(ip.sim_args, ip.num_sim_args); store_pipe(sim_args, ip.num_sim_args - 6, pipes[0]); store_pipe(sim_args, ip.num_sim_args - 4, pipes[1]); sim_args[ip.num_sim_args - 2] = grad_fname; ofstream grad_file; v << " "; term->rank(rank, v); open_file(&grad_file, grad_fname, false); if (ip.base_gradients != NULL) { grad_file << ip.base_gradients << "\n"; } int loc_start = parameters[0]; int loc_end = parameters[1]; int val = parameters[2]; gradient_index* gi = ip.gradient_indices; while (gi != NULL) { grad_file << gi->index << " (" << loc_start << " 100) (" << loc_end << " " << val << ")\n"; gi = gi->next; } grad_file.close(); v << " "; term->rank(rank, v); v << term->blue << "Checking that the simulation file exists and can be executed " << term->reset << ". . . "; if (access(ip.sim_file, X_OK) == -1) { term->failed_exec(); exit(EXIT_EXEC_ERROR); } term->done(v); if (execv(ip.sim_file, sim_args) == -1) { term->failed_exec(); exit(EXIT_EXEC_ERROR); } } else { v << " "; term->rank(rank, v); v << term->blue << "Writing to the pipe " << term->reset << "(file descriptor " << pipes[1] << ") . . . "; write_pipe(pipes[1], ip.sets, ip.num_sets); term->done(v); } // Wait for the child to finish simulating int status = 0; waitpid(pid, &status, WUNTRACED); if (WIFEXITED(status) == 0) { term->failed_child(); exit(EXIT_CHILD_ERROR); } // Close the writing end of the pipe if (close(pipes[1]) == -1) { term->failed_pipe_write(); exit(EXIT_PIPE_WRITE_ERROR); } // Pipe in the simulation's score int max_score; int scores[ip.num_sets]; memset(scores, 0, sizeof(int) * ip.num_sets); v << " "; term->rank(rank, v); v << term->blue << "Reading the pipe " << term->reset << "(file descriptor " << pipes[0] << ") . . . "; read_pipe(pipes[0], &max_score, scores, ip.num_sets); v << term->blue << "Done: " << term->reset << "(raw score of set 0: " << scores[0] << " / " << max_score << ")" << endl; // Close the reading end of the pipe v << " "; term->rank(rank, v); v << term->blue << "Closing the reading end of the pipe " << term->reset << "(file descriptor " << pipes[0] << ") . . . "; if (close(pipes[0]) == -1) { term->failed_pipe_read(); exit(EXIT_PIPE_WRITE_ERROR); } term->done(v); // Remove the gradient file v << " "; term->rank(rank, v); v << term->blue << "Removing " << term->reset << grad_fname << " . . . "; if (remove(grad_fname) != 0) { term->failed_file_remove(grad_fname); exit(EXIT_FILE_REMOVE_ERROR); } mfree(grad_fname); term->done(v); // Calculate the average score of all the runs int avg_score = 0; for (int i = 0; i < ip.num_sets; i++) { avg_score += scores[i]; } avg_score /= ip.num_sets; // libSRES requires scores from 0 to 1 with 0 being a perfect score so convert the simulation's score format into libSRES's return 1 - ((double)avg_score / max_score); }
/* JF this has been hacked to death. Nowaday it sets up the file names for the output files, and opens the tmp files and the parser */ void openfiles (void) { char *name_base; /*** char *cp; ***/ const char *filename; int base_length; int short_base_length; #ifdef VMS char *tmp_base = "sys$scratch:b_"; #else char *tmp_base = "/tmp/b."; #endif int tmp_len; #ifdef MSDOS tmp_base = getenv ("TMP"); if (tmp_base == 0) tmp_base = ""; strlwr (infile); #endif /* MSDOS */ tmp_len = strlen (tmp_base); if (spec_outfile) { /* -o was specified. The precise -o name will be used for ftable. For other output files, remove the ".c" or ".tab.c" suffix. */ name_base = (char *)spec_outfile; #ifdef MSDOS strlwr (name_base); #endif /* MSDOS */ /* BASE_LENGTH includes ".tab" but not ".c". */ base_length = strlen (name_base); if (!strcmp (name_base + base_length - 2, ".c")) base_length -= 2; /* SHORT_BASE_LENGTH includes neither ".tab" nor ".c". */ short_base_length = base_length; if (!strncmp (name_base + short_base_length - 4, ".tab", 4)) short_base_length -= 4; else if (!strncmp (name_base + short_base_length - 4, "_tab", 4)) short_base_length -= 4; } else if (spec_file_prefix) { /* -b was specified. Construct names from it. */ /* SHORT_BASE_LENGTH includes neither ".tab" nor ".c". */ short_base_length = strlen (spec_file_prefix); /* Count room for `.tab'. */ base_length = short_base_length + 4; name_base = (char *) mallocate (base_length + 1); /* Append `.tab'. */ strcpy (name_base, spec_file_prefix); #ifdef VMS strcat (name_base, "_tab"); #else strcat (name_base, ".tab"); #endif #ifdef MSDOS strlwr (name_base); #endif /* MSDOS */ } else { /* -o was not specified; compute output file name from input or use y.tab.c, etc., if -y was specified. */ name_base = fixed_outfiles ? "y.y" : infile; /* BASE_LENGTH gets length of NAME_BASE, sans ".y" suffix if any. */ base_length = strlen (name_base); if (!strcmp (name_base + base_length - 2, ".y")) base_length -= 2; short_base_length = base_length; #ifdef VMS name_base = stringappend(name_base, short_base_length, "_tab"); #else #ifdef MSDOS name_base = stringappend(name_base, short_base_length, "_tab"); #else name_base = stringappend(name_base, short_base_length, ".tab"); #endif /* not MSDOS */ #endif base_length = short_base_length + 4; } finput = tryopen(infile, "r"); filename = getenv ("BISON_SIMPLE"); #ifdef MSDOS /* File doesn't exist in current directory; try in INIT directory. */ cp = getenv("INIT"); if (filename == 0 && cp != 0) { filename = malloc(strlen(cp) + strlen(PFILE) + 2); strcpy(filename, cp); cp = filename + strlen(filename); *cp++ = '/'; strcpy(cp, PFILE); } #endif /* MSDOS */ fparser = tryopen (filename ? filename : PFILE, "r"); if (verboseflag) { #ifdef MSDOS outfile = stringappend(name_base, short_base_length, ".out"); #else /* We used to use just .out if spec_name_prefix (-p) was used, but that conflicts with Posix. */ outfile = stringappend(name_base, short_base_length, ".output"); #endif foutput = tryopen(outfile, "w"); } #ifdef MSDOS actfile = mktemp(stringappend(tmp_base, tmp_len, "acXXXXXX")); tmpattrsfile = mktemp(stringappend(tmp_base, tmp_len, "atXXXXXX")); tmptabfile = mktemp(stringappend(tmp_base, tmp_len, "taXXXXXX")); tmpdefsfile = mktemp(stringappend(tmp_base, tmp_len, "deXXXXXX")); #else actfile = mktemp(stringappend(tmp_base, tmp_len, "act.XXXXXX")); tmpattrsfile = mktemp(stringappend(tmp_base, tmp_len, "attrs.XXXXXX")); tmptabfile = mktemp(stringappend(tmp_base, tmp_len, "tab.XXXXXX")); tmpdefsfile = mktemp(stringappend(tmp_base, tmp_len, "defs.XXXXXX")); #endif /* not MSDOS */ faction = tryopen(actfile, "w+"); fattrs = tryopen(tmpattrsfile,"w+"); ftable = tryopen(tmptabfile, "w+"); if (definesflag) { defsfile = stringappend(name_base, base_length, ".h"); fdefines = tryopen(tmpdefsfile, "w+"); } #ifndef MSDOS unlink(actfile); unlink(tmpattrsfile); unlink(tmptabfile); unlink(tmpdefsfile); #endif /* These are opened by `done' or `open_extra_files', if at all */ if (spec_outfile) tabfile = (char *)spec_outfile; else tabfile = stringappend(name_base, base_length, ".c"); #ifdef VMS attrsfile = stringappend(name_base, short_base_length, "_stype.h"); guardfile = stringappend(name_base, short_base_length, "_guard.c"); #else #ifdef MSDOS attrsfile = stringappend(name_base, short_base_length, ".sth"); guardfile = stringappend(name_base, short_base_length, ".guc"); #else attrsfile = stringappend(name_base, short_base_length, ".stype.h"); guardfile = stringappend(name_base, short_base_length, ".guard.c"); #endif /* not MSDOS */ #endif /* not VMS */ }