📄 ckpoint.c
字号:
/* lil-gp Genetic Programming System, version 1.0, 11 July 1995 * Copyright (C) 1995 Michigan State University * * This program is free software; you can redistribute it and/or modify * it under the terms of version 2 of the GNU General Public License as * published by the Free Software Foundation. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. * * Douglas Zongker (zongker@isl.cps.msu.edu) * Dr. Bill Punch (punch@isl.cps.msu.edu) * * Computer Science Department * A-714 Wells Hall * Michigan State University * East Lansing, Michigan 48824 * USA * */#include <lilgp.h>#ifdef USEVFORKextern char **environ;#endif/* read_checkpoint() * * reads a checkpoint file, placing the generation number in gen and filling * the population (and other structures) with information from the file */void read_checkpoint ( char *filename, int *gen, multipop **mpop ){ FILE *f; char *buffer; ephem_const **eind; int random_state_bytes; int i, j; char *rand_state; /* miscellaneous buffer for reading. */ buffer = (char *)MALLOC ( MAXCHECKLINELENGTH ); /* open the file. */ f = fopen ( filename, "rb" ); if ( f == NULL ) { error ( E_FATAL_ERROR, "couldn't read checkpoint \"%s\".", filename ); } oprintf ( OUT_SYS, 30, "reading from checkpoint \"%s\".\n", filename ); /** confirm the magic word that starts every checkpoint file. **/ fgets ( buffer, MAXCHECKLINELENGTH, f ); if ( strcmp ( buffer, CK_MAGIC ) ) error ( E_FATAL_ERROR, "\"%s\" is not a lil-gp v1.0 checkpoint file.", filename ); /* skip the human-readable id line. */ fgets ( buffer, MAXCHECKLINELENGTH, f );#ifdef DEBUG printf ( "id line: %s", buffer );#endif /** read and print the timestamp. **/ fscanf ( f, "%*s " ); fgets ( buffer, MAXCHECKLINELENGTH, f ); /* chop the newline. */ buffer[strlen(buffer)-1] = 0; oprintf ( OUT_SYS, 30, " checkpoint timestamp: [%s].\n", buffer ); /* skip the "section: global" line. */ fgets ( buffer, MAXCHECKLINELENGTH, f );#ifdef DEBUG printf ( "should be global section: %s", buffer );#endif /* read the generation number. */ fscanf ( f, "%*s %d\n", gen ); /** read the random number state encoded as a string of hex chars. **/ /* first read the length. */ fscanf ( f, "%*s %d ", &random_state_bytes );#ifdef DEBUG fprintf ( stderr, "%d random state bytes.\n", random_state_bytes );#endif /* allocate the buffer. */ rand_state = (char *)MALLOC ( random_state_bytes+1 ); /* read the hex data into the buffer. */ read_hex_block ( rand_state, random_state_bytes, f ); /* set the state. */ random_set_state ( rand_state ); /* free the buffer. */ FREE ( rand_state ); /* slurp the newline character following the hex data. */ fgetc ( f ); /** skip the "section: parameter" line. **/ fgets ( buffer, MAXCHECKLINELENGTH, f );#ifdef DEBUG printf ( "should be parameter section: %s", buffer );#endif /* read the parameter database. */ read_parameter_database ( f ); /* make internal copies of function set(s). */ if ( app_build_function_sets() ) error ( E_FATAL_ERROR, "app_build_function_sets() failure." ); /** skip the "section: erc" line. **/ fgets ( buffer, MAXCHECKLINELENGTH, f );#ifdef DEBUG printf ( "should be erc section: %s", buffer );#endif /* read the list of ephemeral constants, and index them */ eind = read_ephem_list ( f ); /** skip the "section: erc" line. **/ fgets ( buffer, MAXCHECKLINELENGTH, f );#ifdef DEBUG printf ( "should be population section: %s", buffer );#endif /** read the population **/ /* allocate memory. */ *mpop = (multipop *)MALLOC ( sizeof ( multipop ) ); /* read number of subpops. */ fscanf ( f, "%*s %d\n", &((**mpop).size) ); /* allocate subpop list. */ (**mpop).pop = (population **)MALLOC ( (**mpop).size * sizeof ( population * ) ); for ( i = 0; i < (**mpop).size; ++i ) { /** skip each "subpop: #" line. **/ fgets ( buffer, MAXCHECKLINELENGTH, f );#ifdef DEBUG printf ( "should be subpop %d: %s", i, buffer );#endif /* read the population. */ (**mpop).pop[i] = read_population ( eind, f ); } /** skip the "section: application" line. **/ fgets ( buffer, MAXCHECKLINELENGTH, f );#ifdef DEBUG printf ( "should be application section: %s", buffer );#endif /* read application-specific stuff. */ app_read_checkpoint ( f ); /** skip the "section: statistics" line. **/ fgets ( buffer, MAXCHECKLINELENGTH, f );#ifdef DEBUG printf ( "should be statistics section: %s", buffer );#endif /* read the statistics. */ read_stats_checkpoint ( *mpop, eind, f ); /* close'n'free. */ FREE ( eind ); FREE ( buffer ); fclose ( f ); oprintf ( OUT_SYS, 30, "population read from checkpoint \"%s\".\n", filename );} /* write_checkpoint() * * checkpoints the population to the given file. */void write_checkpoint ( int gen, multipop *mpop, char *filename ){ FILE *f; unsigned char *rand_state; ephem_index *eind; int i, j; int random_state_bytes; time_t now; char *param; char *compresscommand[4] = { NULL, NULL, NULL, NULL }; /* open the file. */ f = fopen ( filename, "w" ); if ( f == NULL ) { error ( E_ERROR, "couldn't write checkpoint \"%s\"; skipping.", filename ); return; } /* write magic number and id string. */ fputs ( CK_MAGIC, f ); fputs ( CK_IDSTRING, f ); /* write timestamp. */ time ( &now ); fprintf ( f, "checkpoint-written: %s", ctime ( &now ) ); /* global section. */ fputs ( "section: global\n", f ); fprintf ( f, "generation: %d\n", gen ); /** write the state of the random number generator. **/ rand_state = random_get_state ( &random_state_bytes ); fprintf ( f, "random-state: %d ", random_state_bytes ); /* store buffer as hex data. */ write_hex_block ( rand_state, random_state_bytes, f ); fputc ( '\n', f ); FREE ( rand_state ); /** write the parameter database. **/ fprintf ( f, "section: parameter\n" ); write_parameter_database ( f ); /** write the list of ephemeral constants, and index them. **/ fprintf ( f, "section: erc\n" ); eind = write_ephem_list ( f ); /** write the population. **/ fprintf ( f, "section: population\n" ); fprintf ( f, "subpop-count: %d\n", mpop->size ); for ( i = 0; i < mpop->size; ++i ) { fprintf ( f, "subpop: %d\n", i ); write_population ( mpop->pop[i], eind, f ); } /** application-specific data. **/ fprintf ( f, "section: application\n" ); app_write_checkpoint ( f ); /** statistics structures. **/ fprintf ( f, "section: statistics\n" ); write_stats_checkpoint ( mpop, eind, f ); /** close'n'free. **/ FREE ( eind ); fclose ( f ); oprintf ( OUT_SYS, 20, " population checkpointed: \"%s\".\n", filename ); /** do we compress the checkpoint file? **/ param = get_parameter ( "checkpoint.compress" ); if ( param ) {#if defined(USEVFORK) || defined(USESYSTEM) /* allocate a string big enough to hold the command. */ compresscommand[2] = (char *)MALLOC ( 2*(strlen(param) + strlen(filename)) * sizeof ( char ) ); /* create the command string. */ sprintf ( compresscommand[2], param, filename );#ifdef DEBUG oprintf ( OUT_SYS, 20, " compression command is [%s]\n", compresscommand[2] );#endif#ifdef USEVFORK /* in unix (solaris at least), a system() call performs a fork(), * then an exec(). the fork system call copies the entire address * space of the parent process to the child process. for large * GP applications, this could be intolerably slow. * * vfork() does a fork without copying the address space. it can * be used when the child immediately exec()s following the * vfork(). * * we use exec() to do a "/bin/sh -c compresscommand" to parse * and execute the compression command. * * we neither wait for the child to complete nor check the exit * status to see if the compression was successful. */ /** create the rest of the argv[] array to pass to the child. */ compresscommand[0] = "/bin/sh"; compresscommand[1] = "-c"; if ( !vfork() ) { execve ( "/bin/sh", compresscommand, environ ); _exit(1); }#else /* this is provided for non-unix systems which don't provide the * vfork() call but do have the system() call. */ system ( compresscommand[2] );#endif FREE ( compresscommand[2] ); oprintf ( OUT_SYS, 20, " checkpoint compressed.\n" );#else /* neither vfork() nor system() is available; can't do compression. */ oprintf ( OUT_SYS, 20, " checkpoint compression unavailable.\n" );#endif } }/* read_population() * * allocates a population structure, reads a population from a checkpoint * file into it, and returns it. must be passed an index to look up ERCs * in. */population *read_population ( ephem_const **eind, FILE *f ){ int i; lnode *l; char *buffer; population *pop; /* allocate. */ pop = (population *)MALLOC ( sizeof ( population ) ); /* read the "size" and "next" fields. */ fscanf ( f, "%*s %d\n%*s %d\n", &(pop->size), &(pop->next) ); /* allocate the individual array. */ pop->ind = (individual *)MALLOC ( pop->size * sizeof ( individual ) ); /* this buffer is used by read_individual for reading and parsing function names in trees. we allocate it here, so that all calls to read_individual share the same buffer (we don't have to repeatedly allocate and free). */ buffer = (char *)MALLOC ( MAXCHECKLINELENGTH ); for ( i = 0; i < pop->size; ++i ) { read_individual ( pop->ind+i, eind, f, buffer ); } FREE ( buffer ); return pop;}/* read_individual() * * reads a single individual from a checkpoint file into the given individual * pointer. it does NOT allocate the pointer. */
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -