001/** 002 * Licensed to the Apache Software Foundation (ASF) under one 003 * or more contributor license agreements. See the NOTICE file 004 * distributed with this work for additional information 005 * regarding copyright ownership. The ASF licenses this file 006 * to you under the Apache License, Version 2.0 (the 007 * "License"); you may not use this file except in compliance 008 * with the License. You may obtain a copy of the License at 009 * 010 * http://www.apache.org/licenses/LICENSE-2.0 011 * 012 * Unless required by applicable law or agreed to in writing, 013 * software distributed under the License is distributed on an 014 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 015 * KIND, either express or implied. See the License for the 016 * specific language governing permissions and limitations 017 * under the License. 018 */ 019package org.apache.reef.examples.retained_eval; 020 021import org.apache.reef.client.ClientConfiguration; 022import org.apache.reef.examples.library.Command; 023import org.apache.reef.runtime.local.client.LocalRuntimeConfiguration; 024import org.apache.reef.runtime.yarn.client.YarnClientConfiguration; 025import org.apache.reef.tang.Configuration; 026import org.apache.reef.tang.Injector; 027import org.apache.reef.tang.JavaConfigurationBuilder; 028import org.apache.reef.tang.Tang; 029import org.apache.reef.tang.annotations.Name; 030import org.apache.reef.tang.annotations.NamedParameter; 031import org.apache.reef.tang.exceptions.BindException; 032import org.apache.reef.tang.exceptions.InjectionException; 033import org.apache.reef.tang.formats.AvroConfigurationSerializer; 034import org.apache.reef.tang.formats.CommandLine; 035 036import java.io.IOException; 037import java.util.logging.Level; 038import java.util.logging.Logger; 039 040/** 041 * Retained Evaluators example - main class. 042 */ 043public final class Launch { 044 045 /** 046 * Number of REEF worker threads in local mode. 047 */ 048 private static final int NUM_LOCAL_THREADS = 4; 049 /** 050 * Standard Java logger 051 */ 052 private static final Logger LOG = Logger.getLogger(Launch.class.getName()); 053 054 /** 055 * This class should not be instantiated. 056 */ 057 private Launch() { 058 throw new RuntimeException("Do not instantiate this class!"); 059 } 060 061 /** 062 * Parse the command line arguments. 063 * 064 * @param args command line arguments, as passed to main() 065 * @return Configuration object. 066 * @throws BindException configuration error. 067 * @throws IOException error reading the configuration. 068 */ 069 private static Configuration parseCommandLine(final String[] args) 070 throws BindException, IOException { 071 final JavaConfigurationBuilder confBuilder = Tang.Factory.getTang().newConfigurationBuilder(); 072 final CommandLine cl = new CommandLine(confBuilder); 073 cl.registerShortNameOfClass(Local.class); 074 cl.registerShortNameOfClass(Command.class); 075 cl.registerShortNameOfClass(NumRuns.class); 076 cl.registerShortNameOfClass(NumEval.class); 077 cl.processCommandLine(args); 078 return confBuilder.build(); 079 } 080 081 private static Configuration cloneCommandLineConfiguration(final Configuration commandLineConf) 082 throws InjectionException, BindException { 083 final Injector injector = Tang.Factory.getTang().newInjector(commandLineConf); 084 final JavaConfigurationBuilder cb = Tang.Factory.getTang().newConfigurationBuilder(); 085 cb.bindNamedParameter(Command.class, injector.getNamedInstance(Command.class)); 086 cb.bindNamedParameter(NumRuns.class, String.valueOf(injector.getNamedInstance(NumRuns.class))); 087 cb.bindNamedParameter(NumEval.class, String.valueOf(injector.getNamedInstance(NumEval.class))); 088 return cb.build(); 089 } 090 091 /** 092 * Parse command line arguments and create TANG configuration ready to be submitted to REEF. 093 * 094 * @param args Command line arguments, as passed into main(). 095 * @return (immutable) TANG Configuration object. 096 * @throws BindException if configuration commandLineInjector fails. 097 * @throws InjectionException if configuration commandLineInjector fails. 098 * @throws IOException error reading the configuration. 099 */ 100 private static Configuration getClientConfiguration(final String[] args) 101 throws BindException, InjectionException, IOException { 102 103 final Configuration commandLineConf = parseCommandLine(args); 104 105 final Configuration clientConfiguration = ClientConfiguration.CONF 106 .set(ClientConfiguration.ON_JOB_RUNNING, JobClient.RunningJobHandler.class) 107 .set(ClientConfiguration.ON_JOB_MESSAGE, JobClient.JobMessageHandler.class) 108 .set(ClientConfiguration.ON_JOB_COMPLETED, JobClient.CompletedJobHandler.class) 109 .set(ClientConfiguration.ON_JOB_FAILED, JobClient.FailedJobHandler.class) 110 .set(ClientConfiguration.ON_RUNTIME_ERROR, JobClient.RuntimeErrorHandler.class) 111 .build(); 112 113 // TODO: Remove the injector, have stuff injected. 114 final Injector commandLineInjector = Tang.Factory.getTang().newInjector(commandLineConf); 115 final boolean isLocal = commandLineInjector.getNamedInstance(Local.class); 116 final Configuration runtimeConfiguration; 117 if (isLocal) { 118 LOG.log(Level.INFO, "Running on the local runtime"); 119 runtimeConfiguration = LocalRuntimeConfiguration.CONF 120 .set(LocalRuntimeConfiguration.NUMBER_OF_THREADS, NUM_LOCAL_THREADS) 121 .build(); 122 } else { 123 LOG.log(Level.INFO, "Running on YARN"); 124 runtimeConfiguration = YarnClientConfiguration.CONF.build(); 125 } 126 127 return Tang.Factory.getTang() 128 .newConfigurationBuilder(runtimeConfiguration, clientConfiguration, 129 cloneCommandLineConfiguration(commandLineConf)) 130 .build(); 131 } 132 133 /** 134 * Main method that starts the Retained Evaluators job. 135 * 136 * @return a string that contains last results from all evaluators. 137 */ 138 public static String run(final Configuration config) throws InjectionException { 139 final Injector injector = Tang.Factory.getTang().newInjector(config); 140 final JobClient client = injector.getInstance(JobClient.class); 141 client.submit(); 142 return client.waitForCompletion(); 143 } 144 145 /** 146 * Main method that starts the Retained Evaluators job. 147 * 148 * @param args command line parameters. 149 */ 150 public static void main(final String[] args) { 151 try { 152 final Configuration config = getClientConfiguration(args); 153 LOG.log(Level.FINEST, "Configuration:\n--\n{0}--", 154 new AvroConfigurationSerializer().toString(config)); 155 run(config); 156 LOG.info("Done!"); 157 } catch (final BindException | InjectionException | IOException ex) { 158 LOG.log(Level.SEVERE, "Job configuration error", ex); 159 } 160 } 161 162 /** 163 * Command line parameter: number of experiments to run. 164 */ 165 @NamedParameter(doc = "Number of times to run the command", 166 short_name = "num_runs", default_value = "1") 167 public static final class NumRuns implements Name<Integer> { 168 } 169 170 /** 171 * Command line parameter: number of evaluators to allocate. 172 */ 173 @NamedParameter(doc = "Number of evaluators to request", 174 short_name = "num_eval", default_value = "1") 175 public static final class NumEval implements Name<Integer> { 176 } 177 178 /** 179 * Command line parameter = true to run locally, or false to run on YARN. 180 */ 181 @NamedParameter(doc = "Whether or not to run on the local runtime", 182 short_name = "local", default_value = "true") 183 public static final class Local implements Name<Boolean> { 184 } 185}