001: /*
002: * This file is part of JGAP.
003: *
004: * JGAP offers a dual license model containing the LGPL as well as the MPL.
005: *
006: * For licensing information please see the file license.txt included with JGAP
007: * or have a look at the top of class org.jgap.Chromosome which representatively
008: * includes the JGAP license policy applicable for any file delivered with JGAP.
009: */
010: package org.jgap.distr.grid.gp;
011:
012: import org.apache.log4j.*;
013: import org.homedns.dade.jcgrid.client.*;
014: import org.jgap.*;
015: import org.jgap.gp.*;
016: import org.jgap.gp.impl.*;
017: import org.homedns.dade.jcgrid.message.*;
018: import org.homedns.dade.jcgrid.cmd.*;
019: import org.apache.commons.cli.*;
020:
021: /**
022: * A client defines work for the grid and sends it to the JGAPServer.
023: * Use this class as base class for your grid client implementations.
024: *
025: * @author Klaus Meffert
026: * @since 3.2
027: */
028: public class JGAPClientGP extends Thread {
029: /** String containing the CVS revision. Read out via reflection!*/
030: private final static String CVS_REVISION = "$Revision: 1.6 $";
031:
032: private transient Logger log = Logger.getLogger(getClass());
033:
034: protected GridNodeClientConfig m_gridconfig;
035:
036: protected JGAPRequestGP m_workReq;
037:
038: private GridClient m_gc;
039:
040: private IGridConfigurationGP m_gridConfig;
041:
042: public JGAPClientGP(GridNodeClientConfig a_gridconfig,
043: String a_clientClassName) throws Exception {
044: m_gridconfig = a_gridconfig;
045: Class client = Class.forName(a_clientClassName);
046: m_gridConfig = (IGridConfigurationGP) client.getConstructor(
047: new Class[] {}).newInstance(new Object[] {});
048: m_gridConfig.initialize(m_gridconfig);
049: if (m_gridConfig.getClientFeedback() == null) {
050: m_gridConfig.setClientFeedback(new NullClientFeedbackGP());
051: }
052: // Setup work request.
053: // -------------------
054: JGAPRequestGP req = new JGAPRequestGP(m_gridconfig
055: .getSessionName(), 0, m_gridConfig);
056: req.setWorkerReturnStrategy(m_gridConfig
057: .getWorkerReturnStrategy());
058: req.setGenotypeInitializer(m_gridConfig
059: .getGenotypeInitializer());
060: req.setEvolveStrategy(m_gridConfig.getWorkerEvolveStrategy());
061: // Evolution takes place on client only!
062: // -------------------------------------
063: req.setEvolveStrategy(null);
064: setWorkRequest(req);
065: // Start the threaded process.
066: // ---------------------------
067: start();
068: join();
069: }
070:
071: public void setWorkRequest(JGAPRequestGP a_request) {
072: m_workReq = a_request;
073: }
074:
075: protected GridClient startClient() throws Exception {
076: GridClient gc = new GridClient();
077: gc.setNodeConfig(m_gridconfig);
078: gc.start();
079: return gc;
080: }
081:
082: /**
083: * Threaded: Splits work, sends it to workers and receives computed solutions.
084: *
085: * @author Klaus Meffert
086: * @since 3.01
087: */
088: public void run() {
089: try {
090: // Start client.
091: // -------------
092: m_gc = startClient();
093: try {
094: // Initialize evolution.
095: // ---------------------
096: IClientEvolveStrategyGP clientEvolver = m_gridConfig
097: .getClientEvolveStrategy();
098: if (clientEvolver != null) {
099: clientEvolver.initialize(m_gc, getConfiguration(),
100: m_gridConfig.getClientFeedback());
101: }
102: // Do the evolution.
103: // -----------------
104: evolve(m_gc);
105: } finally {
106: try {
107: m_gc.stop();
108: } catch (Exception ex) {
109: }
110: }
111: } catch (Exception ex) {
112: ex.printStackTrace();
113: m_gridConfig.getClientFeedback().error(
114: "Error while doing the work", ex);
115: }
116: }
117:
118: protected void sendWorkRequests(JGAPRequestGP[] a_workList)
119: throws Exception {
120: // Send work requests.
121: // -------------------
122: for (int i = 0; i < a_workList.length; i++) {
123: JGAPRequestGP req = a_workList[i];
124: GPPopulation pop = req.getPopulation();
125: if (pop == null || pop.isFirstEmpty()) {
126: log
127: .error("Initial population to send to worker is empty!");
128: }
129: m_gridConfig.getClientFeedback()
130: .sendingFragmentRequest(req);
131: m_gc.send(new GridMessageWorkRequest(req));
132: if (this .isInterrupted()) {
133: break;
134: }
135: }
136: }
137:
138: protected void receiveWorkResults(JGAPRequestGP[] workList)
139: throws Exception {
140: IClientFeedbackGP feedback = m_gridConfig.getClientFeedback();
141: // Receive work results.
142: // ---------------------
143: int idx = -1;
144: for (int i = 0; i < workList.length; i++) {
145: feedback.setProgressValue(i + workList.length);
146: m_gc.getGridMessageChannel();
147: GridMessageWorkResult gmwr = (GridMessageWorkResult) m_gc
148: .recv(i);
149: JGAPResultGP workResult = (JGAPResultGP) gmwr
150: .getWorkResult();
151: m_gridConfig.getClientEvolveStrategy().resultReceived(
152: workResult);
153: idx = workResult.getRID();
154: // Fire listener.
155: // --------------
156: feedback.receivedFragmentResult(workList[idx], workResult,
157: idx);
158: if (this .isInterrupted()) {
159: break;
160: }
161: }
162: }
163:
164: /**
165: * If necessary: override to implement your evolution cycle individually.
166: *
167: * @param gc GridClient
168: * @throws Exception
169: */
170: protected void evolve(GridClient gc) throws Exception {
171: // Do the complete evolution cycle until end.
172: // ------------------------------------------
173: IClientFeedbackGP feedback = m_gridConfig.getClientFeedback();
174: feedback.beginWork();
175: IClientEvolveStrategyGP evolver = m_gridConfig
176: .getClientEvolveStrategy();
177: IRequestSplitStrategyGP splitter = m_gridConfig
178: .getRequestSplitStrategy();
179: int evolutionIndex = 0;
180: do {
181: log.warn("Beginning evolution cycle " + evolutionIndex);
182: // m_clientEvolveStrategy.beforeGenerateWorkResults();
183: JGAPRequestGP[] workRequests = evolver
184: .generateWorkRequests(m_workReq, splitter, null);
185: feedback.setProgressMaximum(0);
186: feedback.setProgressMaximum(workRequests.length - 1);
187: sendWorkRequests(workRequests);
188: if (this .isInterrupted()) {
189: break;
190: }
191: evolver.afterWorkRequestsSent();
192: receiveWorkResults(workRequests);
193: evolver.evolve();
194: // Fire listener that one evolution cycle is complete.
195: // ---------------------------------------------------
196: feedback.completeFrame(evolutionIndex);
197: evolutionIndex++;
198: // Check if evolution is finished.
199: // -------------------------------
200: if (evolver.isEvolutionFinished(evolutionIndex)) {
201: evolver.onFinished();
202: break;
203: }
204: } while (true);
205: m_gridConfig.getClientFeedback().endWork();
206: }
207:
208: public void start() {
209: try {
210: m_gridConfig.validate();
211: } catch (Exception ex) {
212: throw new RuntimeException(ex);
213: }
214: super .start();
215: }
216:
217: public GPConfiguration getConfiguration() {
218: return m_gridConfig.getConfiguration();
219: }
220:
221: /**
222: * Starts a client (first parameter: name of specific setup class).
223: *
224: * @param args String[]
225: *
226: * @author Klaus Meffert
227: * @since 3.01
228: */
229: public static void main(String[] args) {
230: if (args.length < 1) {
231: System.out
232: .println("Please provide a name of the grid configuration class to use");
233: System.out
234: .println("An example class would be "
235: + "examples.grid.fitnessDistributed.GridConfiguration");
236: System.exit(1);
237: }
238: try {
239: // Setup logging.
240: // --------------
241: MainCmd.setUpLog4J("client", true);
242: // Command line options.
243: // ---------------------
244: GridNodeClientConfig config = new GridNodeClientConfig();
245: Options options = new Options();
246: CommandLine cmd = MainCmd.parseCommonOptions(options,
247: config, args);
248: // Setup and start client.
249: // -----------------------
250: new JGAPClientGP(config, args[0]);
251: } catch (Exception ex) {
252: ex.printStackTrace();
253: System.exit(1);
254: }
255: }
256: }
|