/// <summary>Loads a ParameterDatabase from checkpoint if "-params" is in the command-line arguments. </summary> public static IParameterDatabase LoadParameterDatabase(string paramsFileName) { if (string.IsNullOrEmpty(paramsFileName)) { Output.InitialError("The parameter file name is null or empty.", false); Environment.Exit(1); // This was originally part of the InitialError call in ECJ. But we make Evolve responsible. } if (!File.Exists(paramsFileName)) { Output.InitialError($"The specified parameter file does not exist: {paramsFileName}", false); Environment.Exit(1); // This was originally part of the InitialError call in ECJ. But we make Evolve responsible. } IParameterDatabase parameters = null; try { if (!string.IsNullOrEmpty(paramsFileName)) { parameters = new ParameterDatabase(new FileInfo(paramsFileName)); } } catch (Exception e) { Output.InitialError($"Error reading the parameter file \"{paramsFileName}\": {e.Message}", false); Environment.Exit(1); // This was originally part of the InitialError call in ECJ. But we make Evolve responsible. } if (parameters == null) { Output.InitialError("No parameter file was specified.", false); Environment.Exit(1); // This was originally part of the InitialError call in ECJ. But we make Evolve responsible. } return(parameters); }
/** Override this method to revise the provided parameter database to reflect the "parameters" specified in the * given meta-individual. 'Run' is the current run number for this individual's evaluation. */ public void ModifyParameters(IEvolutionState state, IParameterDatabase database, int run, Individual metaIndividual) { if (!(metaIndividual is DoubleVectorIndividual)) { state.Output.Fatal("Meta-individual is not a DoubleVectorIndividual."); } var individual = (DoubleVectorIndividual)metaIndividual; var species = (FloatVectorSpecies)individual.Species; double[] genome = individual.genome; IParameter pb = ParamBase.Push(P_PARAM); for (int i = 0; i < genome.Length; i++) { IParameter p = pb.Push("" + i); String param = state.Parameters.GetString(p, null); if (param == null) { state.Output.Fatal("Meta parameter number " + i + " missing.", p); } // load it database.SetParameter(new Parameter(param), "" + Map(state, genome, species, i)); } }
/// <summary>Loads the number of threads. </summary> public static int DetermineThreads(Output output, IParameterDatabase parameters, IParameter threadParameter) { var thread = 1; var tmp_s = parameters.GetString(threadParameter, null); if (tmp_s == null) // uh oh { output.Fatal("Threads number must exist.", threadParameter, null); } else if (V_THREADS_AUTO.ToUpper().Equals(tmp_s.ToUpper())) { } else { try { thread = parameters.GetInt(threadParameter, null); } catch (FormatException) { output.Fatal("Invalid, non-integer threads value (" + thread + ")", threadParameter, null); } } return(thread); }
/// <summary> /// Initializes an evolutionary run given the parameters and a random seed adjustment (added to each random seed). /// The adjustment offers a convenient way to change the seeds of the random number generators each time you /// do a new evolutionary run. You are of course welcome to replace the random number generators after initialize(...) /// but before startFresh(...) /// </summary> public static EvolutionState Initialize(IParameterDatabase parameters, int randomSeedOffset) { var output = BuildOutput(); // now continue intialization return(Initialize(parameters, randomSeedOffset, output)); }
/// <summary> /// Initializes an evolutionary run given the parameters and a random seed adjustment (added to each random seed), /// with the Output pre-constructed. /// The adjustment offers a convenient way to change the seeds of the random number generators each time you /// do a new evolutionary run. You are of course welcome to replace the random number generators after initialize(...) /// but before startFresh(...). /// </summary> /// <param name="parameters"></param> /// <param name="randomSeedOffset"></param> /// <param name="output"></param> /// <returns></returns> public static EvolutionState Initialize(IParameterDatabase parameters, int randomSeedOffset, Output output) { var breedthreads = 1; var evalthreads = 1; //bool store; //int x; // output was already created for us. output.SystemMessage(ECVersion.Message()); // 2. set up thread values breedthreads = DetermineThreads(output, parameters, new Parameter(P_BREEDTHREADS)); evalthreads = DetermineThreads(output, parameters, new Parameter(P_EVALTHREADS)); var auto = (V_THREADS_AUTO.ToUpper().Equals(parameters.GetString(new Parameter(P_BREEDTHREADS), null).ToUpper()) || V_THREADS_AUTO.ToUpper().Equals( parameters.GetString(new Parameter(P_EVALTHREADS), null).ToUpper())); // at least one thread is automatic. Seeds may need to be dynamic. // 3. create the Mersenne Twister random number generators, // one per thread var random = new MersenneTwisterFast[1]; var seedMessage = "Seed: "; // Get time in milliseconds var time = (int)DateTimeHelper.CurrentTimeMilliseconds; var seed = 0; seed = DetermineSeed(output, parameters, new Parameter(P_SEED).Push("" + 0), time + 0, random.Length * randomSeedOffset, auto); random[0] = PrimeGenerator(new MersenneTwisterFast(seed)); // we prime the generator to be more sure of randomness. seedMessage = seedMessage + seed + " "; // 4. Start up the evolution // what evolution state to use? var state = (EvolutionState)parameters.GetInstanceForParameter(new Parameter(P_STATE), null, typeof(IEvolutionState)); state.Parameters = parameters; state.Random = random; state.Output = output; state.EvalThreads = evalthreads; state.BreedThreads = breedthreads; state.RandomSeedOffset = randomSeedOffset; output.SystemMessage($"Threads: breed/{breedthreads} eval/{evalthreads}"); output.SystemMessage(seedMessage); return(state); }
// NOTE: We should use the framework's thread pool! //public static ThreadPool Pool = new ThreadPool(); #endregion // Static #region Operations public static void EvaluateSimpleProblem(IEvolutionState state, bool returnIndividuals, BinaryReader dataIn, BinaryWriter dataOut, string[] args) { IParameterDatabase parameters = null; // first load the individuals var numInds = 1; try { numInds = dataIn.ReadInt32(); } catch (IOException e) { state.Output.Fatal("Unable to read the number of individuals from the master:\n" + e); } // load the subpops var subpops = new int[numInds]; // subpops desired by each ind var indsPerSubpop = new int[state.Population.Subpops.Count]; // num inds for each subpop for (var i = 0; i < numInds; i++) { try { subpops[i] = dataIn.ReadInt32(); if (subpops[i] < 0 || subpops[i] >= state.Population.Subpops.Count) { state.Output.Fatal("Bad subpop number for individual #" + i + ": " + subpops[i]); } indsPerSubpop[subpops[i]]++; } catch (IOException e) { state.Output.Fatal("Unable to read the subpop number from the master:\n" + e); } } // Read the individual(s) from the stream and evaluate // Either evaluate all the individuals once and return them immediately // (we'll do so in a steady-state-ish fashion, firing off threads as soon as we read in individuals, // and returning them as soon as they come in, albeit in the proper order) if (!RunEvolve) { EvaluateSimpleProblemCore(state, returnIndividuals, dataIn, dataOut, numInds, subpops); } // OR we will do some evolution. Here we'll read in ALL the individuals, do some evolution, then // write them ALL out, very slightly less efficient else // (runEvolve) { EvolveSimpleProblemCore(state, returnIndividuals, dataIn, dataOut, numInds, subpops, indsPerSubpop); } }
/// <summary> /// Initializes an evolutionary run given the parameters and a random seed adjustment (added to each random seed). /// The adjustment offers a convenient way to change the seeds of the random number generators each time you /// do a new evolutionary run. You are of course welcome to replace the random number generators after initialize(...) /// but before startFresh(...) /// </summary> public static EvolutionState Initialize(IParameterDatabase parameters, int randomSeedOffset) { var output = new Output(true); // stdout is always log #0. stderr is always log #1. // stderr accepts announcements, and both are fully verbose // by default. output.AddLog(Log.D_STDOUT, false); output.AddLog(Log.D_STDERR, true); // now continue intialization return(Initialize(parameters, randomSeedOffset, output)); }
/// <summary> /// Loads a random generator seed. First, the seed is loaded from the seedParameter. If the parameter /// is V_SEED_TIME, the seed is set to the currentTime value. Then the seed is incremented by the offset. /// This method is broken out of initialize(...) primarily to share code with ec.eval.MasterProblem. /// </summary> public static int DetermineSeed(Output output, IParameterDatabase parameters, IParameter seedParameter, long currentTime, int offset, bool auto) { var seed = 1; // have to initialize to make the compiler happy try { seed = parameters.GetInt(seedParameter, null); } catch (FormatException) { output.Fatal("Invalid, non-integer seed value (" + seed + ")", seedParameter, null); } return(seed + offset); }
/// <summary> /// Loads the number of threads. /// </summary> public static int DetermineThreads(Output output, IParameterDatabase parameters, IParameter threadParameter) { var thread = 1; var tmp_s = parameters.GetString(threadParameter, null); if (tmp_s == null) // uh oh { output.Fatal("Threads number must exist.", threadParameter, null); } else if (V_THREADS_AUTO.ToUpper().Equals(tmp_s.ToUpper())) { var runtime = Process.GetCurrentProcess(); try { return(Environment.ProcessorCount); } catch (Exception) { output.Fatal("Whoa! Problem getting processor count.", threadParameter, null); } } else { try { thread = parameters.GetInt(threadParameter, null); if (thread <= 0) { output.Fatal("Threads value must be > 0", threadParameter, null); } } catch (FormatException) { output.Fatal("Invalid, non-integer threads value (" + thread + ")", threadParameter, null); } } return(thread); }
/// <summary> /// Loads a random generator seed. First, the seed is loaded from the seedParameter. If the parameter /// is V_SEED_TIME, the seed is set to the currentTime value. Then the seed is incremented by the offset. /// This method is broken out of initialize(...) primarily to share code with ec.eval.MasterProblem. /// </summary> public static int DetermineSeed(Output output, IParameterDatabase parameters, IParameter seedParameter, long currentTime, int offset, bool auto) { var seed = 1; // have to initialize to make the compiler happy var tmp_s = parameters.GetString(seedParameter, null); if (tmp_s == null && !auto) // uh oh { output.Fatal("Seed must exist.", seedParameter, null); } //else if (V_SEED_TIME.Equals(tmp_s, StringComparison.InvariantCultureIgnoreCase) || (tmp_s == null && auto)) else if (tmp_s == null && auto || V_SEED_TIME.Equals(tmp_s, StringComparison.InvariantCultureIgnoreCase)) // BRS : Just flipped { if (tmp_s == null && auto) // BRS : What? { output.WarnOnce("Using automatic determination number of threads, but not all seeds are defined." + "\nThe rest will be defined using the wall clock time."); } seed = (int)currentTime; // using low-order bits so it's probably okay if (seed == 0) { output.Fatal("Whoa! This Java version is returning 0 for currentTimeMillis(), which ain't right." + " This means you can't use '" + V_SEED_TIME + "' as a seed ", seedParameter, null); } } else { try { seed = parameters.GetInt(seedParameter, null); } catch (FormatException) { output.Fatal("Invalid, non-integer seed value (" + seed + ")", seedParameter, null); } } return(seed + offset); }
/// <summary> /// Initializes an evolutionary run given the parameters and a random seed adjustment (added to each random seed), /// with the Output pre-constructed. /// The adjustment offers a convenient way to change the seeds of the random number generators each time you /// do a new evolutionary run. You are of course welcome to replace the random number generators after initialize(...) /// but before startFresh(...). /// </summary> public static EvolutionState Initialize(IParameterDatabase parameters, int randomSeedOffset, Output output) { var breedthreads = 1; var evalthreads = 1; // Should we muzzle stdout and stderr? if (parameters.ParameterExists(new Parameter(P_MUZZLE), null)) { output.Warning("" + new Parameter(P_MUZZLE) + " has been deprecated. We suggest you use " + new Parameter(P_SILENT) + " or similar newer options."); } if (parameters.GetBoolean(new Parameter(P_SILENT), null, false) || parameters.GetBoolean(new Parameter(P_MUZZLE), null, false)) { output.GetLog(0).Silent = true; output.GetLog(1).Silent = true; } //bool store; int x; // output was already created for us. output.SystemMessage(ECVersion.Message()); // 2. set up thread values breedthreads = DetermineThreads(output, parameters, new Parameter(P_BREEDTHREADS)); evalthreads = DetermineThreads(output, parameters, new Parameter(P_EVALTHREADS)); var auto = (V_THREADS_AUTO.ToUpper().Equals( parameters.GetString(new Parameter(P_BREEDTHREADS), null).ToUpper()) || V_THREADS_AUTO.ToUpper().Equals( parameters.GetString(new Parameter(P_EVALTHREADS), null).ToUpper())); // at least one thread is automatic. Seeds may need to be dynamic. // 3. create the Mersenne Twister random number generators, // one per thread var random = new IMersenneTwister[breedthreads > evalthreads ? breedthreads : evalthreads]; var seeds = new int[random.Length]; var seedMessage = "Seed: "; // Get time in milliseconds var time = (int)DateTimeHelper.CurrentTimeMilliseconds; for (x = 0; x < random.Length; x++) { seeds[x] = DetermineSeed(output, parameters, new Parameter(P_SEED).Push("" + x), time + x, random.Length * randomSeedOffset, auto); for (var y = 0; y < x; y++) { if (seeds[x] == seeds[y]) { output.Fatal(P_SEED + "." + x + " (" + seeds[x] + ") and " + P_SEED + "." + y + " (" + seeds[y] + ") ought not be the same seed.", null, null); } } random[x] = PrimeGenerator(new MersenneTwisterFast(seeds[x])); // we prime the generator to be more sure of randomness. seedMessage = seedMessage + seeds[x] + " "; } // 4. Start up the evolution // what evolution state to use? var state = (EvolutionState)parameters.GetInstanceForParameter(new Parameter(P_STATE), null, typeof(IEvolutionState)); state.Parameters = parameters; state.Random = random; state.Output = output; state.EvalThreads = evalthreads; state.BreedThreads = breedthreads; state.RandomSeedOffset = randomSeedOffset; output.SystemMessage($"Threads: breed/{breedthreads} eval/{evalthreads}"); output.SystemMessage(seedMessage); return(state); }
/// <summary> /// Loads a ParameterDatabase from checkpoint if "-params" is in the command-line arguments. /// </summary> public static IParameterDatabase LoadParameterDatabase(string[] args) { // search for a -file IParameterDatabase parameters = null; for (var x = 0; x < args.Length - 1; x++) { if (args[x].Equals(A_FILE)) { try { parameters = new ParameterDatabase(new FileInfo(args[x + 1]), args); Trace.WriteLine("Using database file location " + parameters.Label); break; } catch (Exception e) { Trace.WriteLine(e.Message); Output.InitialError( "An exception was generated upon reading the parameter file \"" + args[x + 1] + "\".\nHere it is:\n" + e, false); Environment.Exit(1); // This was originally part of the InitialError call in ECJ. But we make Evolve responsible. } } } // search for a resource class (we may or may not use this) Type cls = null; for (var x = 0; x < args.Length - 1; x++) { if (args[x].Equals(A_AT)) { try { if (parameters != null) // uh oh { Output.InitialError("Both -file and -at arguments provided. This is not permitted.\nFor help, try: java ec.Evolve -help"); } else { cls = Type.GetType(args[x + 1]); } break; } catch (Exception e) { Trace.WriteLine(e.Message); Output.InitialError( "An exception was generated upon extracting the class to load the parameter file relative to: " + args[x + 1] + "\nFor help, try: java ec.Evolve -help\n\n" + e); } } } // search for a resource (we may or may not use this) for (var x = 0; x < args.Length - 1; x++) { if (args[x].Equals(A_FROM)) { try { if (parameters != null) // uh oh { Output.InitialError("Both -file and -from arguments provided. This is not permitted.\nFor help, try: java ec.Evolve -help"); } else { if (cls == null) // no -at { cls = typeof(Evolve); } parameters = new ParameterDatabase(args[x + 1], cls, args); Trace.WriteLine("Using database resource location " + parameters.Label); } break; } catch (Exception e) { Trace.WriteLine(e.Message); Output.InitialError( "The parameter file is missing at the resource location: " + args[x + 1] + " relative to the class: " + cls + "\n\nFor help, try: java ec.Evolve -help"); } } } if (parameters == null) { Output.InitialError("No parameter or checkpoint file was specified.\nFor help, try: java ec.Evolve -help", false); Environment.Exit(1); // This was originally part of the InitialError call in ECJ. But we make Evolve responsible. } return(parameters); }
public static void Main(string[] args) { IEvolutionState state = null; IParameterDatabase parameters = null; Output output = null; //bool store; int x; // 0. find the parameter database for (x = 0; x < args.Length - 1; x++) { if (args[x].Equals(A_FILE)) { try { parameters = new ParameterDatabase(new FileInfo(new FileInfo(args[x + 1]).FullName), args); // add the fact that I am a slave: eval.i-am-slave = true // this is used only by the Evaluator to determine whether to use the MasterProblem parameters.SetParameter(new Parameter(EvolutionState.P_EVALUATOR).Push(Evaluator.P_IAMSLAVE), "true"); break; } catch (FileNotFoundException e) { Output.InitialError( "A File Not Found Exception was generated upon" + " reading the parameter file \"" + args[x + 1] + "\".\nHere it is:\n" + e, false); Environment.Exit(1); // This was originally part of the InitialError call in ECJ. But we make Slave responsible. } catch (IOException e) { Output.InitialError("An IO Exception was generated upon reading the" + " parameter file \"" + args[x + 1] + "\".\nHere it is:\n" + e, false); Environment.Exit(1); // This was originally part of the InitialError call in ECJ. But we make Slave responsible. } } } if (parameters == null) { Output.InitialError("No parameter file was specified.", false); Environment.Exit(1); // This was originally part of the InitialError call in ECJ. But we make Slave responsible. } // 5. Determine whether or not to return entire Individuals or just Fitnesses // (plus whether or not the Individual has been evaluated). var returnIndividuals = parameters.GetBoolean(new Parameter(P_RETURNINDIVIDUALS), null, false); // 5.5 should we silence the whole thing? bool silent = parameters.GetBoolean(new Parameter(P_SILENT), null, false); if (parameters.ParameterExists(new Parameter(P_MUZZLE), null)) { Output.InitialWarning("" + new Parameter(P_MUZZLE) + " has been deprecated. We suggest you use " + new Parameter(P_SILENT) + " or similar newer options."); } silent = silent || parameters.GetBoolean(new Parameter(P_MUZZLE), null, false); // 6. Open a server socket and listen for requests var slaveName = parameters.GetString(new Parameter(P_EVALSLAVENAME), null); var masterHost = parameters.GetString(new Parameter(P_EVALMASTERHOST), null); if (masterHost == null) { Output.InitialError("Master Host missing", new Parameter(P_EVALMASTERHOST)); } var masterPort = parameters.GetInt(new Parameter(P_EVALMASTERPORT), null, 0); if (masterPort == -1) { Output.InitialError("Master Port missing", new Parameter(P_EVALMASTERPORT)); } var useCompression = parameters.GetBoolean(new Parameter(P_EVALCOMPRESSION), null, false); RunTime = parameters.GetInt(new Parameter(P_RUNTIME), null, 0); RunEvolve = parameters.GetBoolean(new Parameter(P_RUNEVOLVE), null, false); OneShot = parameters.GetBoolean(new Parameter(P_ONESHOT), null, true); if (RunEvolve && !returnIndividuals) { Output.InitialError( "You have the slave running in 'evolve' mode, but it's only returning fitnesses to the master, not whole individuals. This is almost certainly wrong.", new Parameter(P_RUNEVOLVE), new Parameter(P_RETURNINDIVIDUALS)); Environment.Exit(1); // This was originally part of the InitialError call in ECJ. But we make Slave responsible. } if (!silent) { Output.InitialMessage("ECCS Slave"); if (RunEvolve) { Output.InitialMessage("Running in Evolve mode, evolve time is " + RunTime + " milliseconds"); } if (returnIndividuals) { Output.InitialMessage("Whole individuals will be returned"); } else { Output.InitialMessage("Only fitnesses will be returned"); } } // Continue to serve new masters until killed. TcpClient socket = null; // BRS: TcpClient is a wrapper around the Socket class while (true) { try { long connectAttemptCount = 0; if (!silent) { Output.InitialMessage("Connecting to master at " + masterHost + ":" + masterPort); } while (true) { try { socket = new TcpClient(masterHost, masterPort); break; } catch (Exception) // it's not up yet... { connectAttemptCount++; try { Thread.Sleep(new TimeSpan((Int64)10000 * SLEEP_TIME)); } catch (ThreadInterruptedException) { } } } if (!silent) { Output.InitialMessage("Connected to master after " + (connectAttemptCount * SLEEP_TIME) + " ms"); } BinaryReader dataIn = null; BinaryWriter dataOut = null; try { Stream tmpIn = socket.GetStream(); Stream tmpOut = socket.GetStream(); if (useCompression) { //Output.InitialError("JDK 1.5 has broken compression. For now, you must set eval.compression=false"); //Environment.Exit(1); // This was originally part of the InitialError call in ECJ. But we make Slave responsible. /* * tmpIn = new CompressingInputStream(tmpIn); * tmpOut = new CompressingOutputStream(tmpOut); */ tmpIn = Output.MakeCompressingInputStream(tmpIn); tmpOut = Output.MakeCompressingOutputStream(tmpOut); if (tmpIn == null || tmpOut == null) { var err = "You do not appear to have JZLib installed on your system, and so must set eval.compression=false. " + "To get JZLib, download from the ECJ website or from http://www.jcraft.com/jzlib/"; if (!silent) { Output.InitialMessage(err); } throw new OutputExitException(err); } } dataIn = new BinaryReader(tmpIn); dataOut = new BinaryWriter(tmpOut); } catch (IOException e) { var err = "Unable to open input stream from socket:\n" + e; if (!silent) { Output.InitialMessage(err); } throw new OutputExitException(err); } // specify the slaveName if (slaveName == null) { // BRS : TODO : Check equivalence of the address returned from .NET socket.Client.LocalEndPoint slaveName = socket.Client.LocalEndPoint + "/" + (DateTime.Now.Ticks - 621355968000000000) / 10000; if (!silent) { Output.InitialMessage("No slave name specified. Using: " + slaveName); } } dataOut.Write(slaveName); // Default encoding of BinaryWriter is UTF-8 dataOut.Flush(); // 1. create the output // store = parameters.GetBoolean(new Parameter(P_STORE), null, false); if (output != null) { output.Close(); } output = new Output(storeAnnouncementsInMemory: false) // do not store messages, just print them { ThrowsErrors = true // don't do System.exit(1) }; // stdout is always log #0. stderr is always log #1. // stderr accepts announcements, and both are fully verbose by default. output.AddLog(Log.D_STDOUT, false); output.AddLog(Log.D_STDERR, true); if (silent) { output.GetLog(0).Silent = true; output.GetLog(1).Silent = true; } if (!silent) { output.SystemMessage(ECVersion.Message()); } // 2. set up thread values int breedthreads = Evolve.DetermineThreads(output, parameters, new Parameter(Evolve.P_BREEDTHREADS)); int evalthreads = Evolve.DetermineThreads(output, parameters, new Parameter(Evolve.P_EVALTHREADS)); // Note that either breedthreads or evalthreads (or both) may be 'auto'. We don't warn about this because // the user isn't providing the thread seeds. // 3. create the Mersenne Twister random number generators, one per thread var random = new IMersenneTwister[breedthreads > evalthreads ? breedthreads : evalthreads]; var seed = dataIn.ReadInt32(); for (var i = 0; i < random.Length; i++) { random[i] = Evolve.PrimeGenerator(new MersenneTwisterFast(seed++)); } // we prime the generator to be more sure of randomness. // 4. Set up the evolution state // what evolution state to use? state = (IEvolutionState) parameters.GetInstanceForParameter(new Parameter(Evolve.P_STATE), null, typeof(IEvolutionState)); state.Parameters = new ParameterDatabase(); state.Parameters.AddParent(parameters); state.Random = random; state.Output = output; state.EvalThreads = evalthreads; state.BreedThreads = breedthreads; state.Setup(state, null); state.Population = state.Initializer.SetupPopulation(state, 0); // 5. Optionally do further loading var storage = state.Evaluator.MasterProblem; storage.ReceiveAdditionalData(state, dataIn); storage.TransferAdditionalData(state); try { while (true) { var newState = state; if (RunEvolve) { // Construct and use a new EvolutionState. This will be inefficient the first time around // as we've set up TWO EvolutionStates in a row with no good reason. IParameterDatabase coverDatabase = new ParameterDatabase(); // protect the underlying one coverDatabase.AddParent(state.Parameters); newState = Evolve.Initialize(coverDatabase, 0); newState.StartFresh(); newState.Output.Message("Replacing random number generators, ignore above seed message"); newState.Random = state.Random; // continue with RNG storage.TransferAdditionalData(newState); // load the arbitrary data again } // 0 means to shut down //Console.Error.WriteLine("reading next problem"); int problemType = dataIn.ReadByte(); //Console.Error.WriteLine("Read problem: " + problemType); switch (problemType) { case (int)SlaveEvaluationType.Shutdown: socket.Close(); if (OneShot) { return; // we're outa here } else { throw new OutputExitException("SHUTDOWN"); } case (int)SlaveEvaluationType.Simple: EvaluateSimpleProblem(newState, returnIndividuals, dataIn, dataOut, args); break; case (int)SlaveEvaluationType.Grouped: EvaluateGroupedProblem(newState, returnIndividuals, dataIn, dataOut); break; default: state.Output.Fatal("Unknown problem form specified: " + problemType); break; } //System.err.PrintLn("Done Evaluating Individual"); } } catch (IOException e) { // Since an IOException can happen here if the peer closes the socket // on it's end, we don't necessarily have to exit. Maybe we don't // even need to print a warning, but we'll do so just to indicate // something happened. state.Output.Fatal( "Unable to read type of evaluation from master. Maybe the master closed its socket and exited?:\n" + e); } catch (Exception e) { if (state != null) { state.Output.Fatal(e.Message); } else if (!silent) { Console.Error.WriteLine("FATAL ERROR (EvolutionState not created yet): " + e.Message); } } } catch (OutputExitException e) { // here we restart if necessary try { socket.Close(); } catch (Exception e2) { } if (OneShot) { Environment.Exit(0); } } catch (OutOfMemoryException e) { // Let's try fixing things state = null; GC.Collect(); GC.WaitForPendingFinalizers(); GC.Collect(); GC.WaitForPendingFinalizers(); try { socket.Close(); } catch (Exception e2) { } socket = null; // TODO: Overkill? Track memory before and after. GC.Collect(); GC.WaitForPendingFinalizers(); GC.Collect(); GC.WaitForPendingFinalizers(); Console.Error.WriteLine(e); if (OneShot) { Environment.Exit(0); } } if (!silent) { Output.InitialMessage("\n\nResetting Slave"); } } }