blob: 772cb778299911fdf2968a2ff162206e5cc72652 [file] [log] [blame]
/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
package org.apache.reef.javabridge.generic;
import org.apache.reef.client.ClientConfiguration;
import org.apache.reef.runtime.local.client.LocalRuntimeConfiguration;
import org.apache.reef.runtime.yarn.client.YarnClientConfiguration;
import org.apache.reef.tang.Configuration;
import org.apache.reef.tang.Injector;
import org.apache.reef.tang.JavaConfigurationBuilder;
import org.apache.reef.tang.Tang;
import org.apache.reef.tang.annotations.Name;
import org.apache.reef.tang.annotations.NamedParameter;
import org.apache.reef.tang.exceptions.BindException;
import org.apache.reef.tang.exceptions.InjectionException;
import org.apache.reef.tang.formats.CommandLine;
import org.apache.reef.util.logging.LoggingScope;
import org.apache.reef.util.logging.LoggingScopeFactory;
import java.io.File;
import java.io.IOException;
import java.util.Arrays;
import java.util.Date;
import java.util.logging.Level;
import java.util.logging.Logger;
/**
* Clr Bridge example - main class.
*/
public final class Launch {
/**
* The upper limit on the number of Evaluators that the local resourcemanager will hand out concurrently.
*/
private static final int MAX_NUMBER_OF_EVALUATORS = 10;
/**
* Standard Java logger.
*/
private static final Logger LOG = Logger.getLogger(Launch.class.getName());
/**
* This class should not be instantiated.
*/
private Launch() {
throw new RuntimeException("Do not instantiate this class!");
}
/**
* Parse the command line arguments.
*
* @param args command line arguments, as passed to main()
* @return Configuration object.
* @throws org.apache.reef.tang.exceptions.BindException configuration error.
* @throws java.io.IOException error reading the configuration.
*/
private static Configuration parseCommandLine(final String[] args)
throws BindException, IOException {
final JavaConfigurationBuilder confBuilder = Tang.Factory.getTang().newConfigurationBuilder();
final CommandLine cl = new CommandLine(confBuilder);
cl.registerShortNameOfClass(Local.class);
cl.registerShortNameOfClass(NumRuns.class);
cl.registerShortNameOfClass(WaitTimeForDriver.class);
cl.registerShortNameOfClass(DriverMemoryInMb.class);
cl.registerShortNameOfClass(DriverIdentifier.class);
cl.registerShortNameOfClass(DriverJobSubmissionDirectory.class);
cl.registerShortNameOfClass(Submit.class);
cl.processCommandLine(args);
return confBuilder.build();
}
private static Configuration cloneCommandLineConfiguration(final Configuration commandLineConf)
throws InjectionException, BindException {
final Injector injector = Tang.Factory.getTang().newInjector(commandLineConf);
final JavaConfigurationBuilder cb = Tang.Factory.getTang().newConfigurationBuilder();
cb.bindNamedParameter(NumRuns.class, String.valueOf(injector.getNamedInstance(NumRuns.class)));
return cb.build();
}
/**
* Parse command line arguments and create TANG configuration ready to be submitted to REEF.
*
* @param args Command line arguments, as passed into main().
* @return (immutable) TANG Configuration object.
* @throws org.apache.reef.tang.exceptions.BindException if configuration commandLineInjector fails.
* @throws org.apache.reef.tang.exceptions.InjectionException if configuration commandLineInjector fails.
* @throws java.io.IOException error reading the configuration.
*/
private static Configuration getClientConfiguration(final String[] args)
throws BindException, InjectionException, IOException {
try (LoggingScope ls = LoggingScopeFactory.getNewLoggingScope(Level.INFO, "Launch::getClientConfiguration")) {
final Configuration commandLineConf = parseCommandLine(args);
final Configuration clientConfiguration = ClientConfiguration.CONF
.set(ClientConfiguration.ON_JOB_COMPLETED, JobClient.CompletedJobHandler.class)
.set(ClientConfiguration.ON_JOB_FAILED, JobClient.FailedJobHandler.class)
.set(ClientConfiguration.ON_RUNTIME_ERROR, JobClient.RuntimeErrorHandler.class)
.build();
final Injector commandLineInjector = Tang.Factory.getTang().newInjector(commandLineConf);
final boolean isLocal = commandLineInjector.getNamedInstance(Local.class);
final Configuration runtimeConfiguration;
if (isLocal) {
LOG.log(Level.INFO, "Running on the local runtime");
runtimeConfiguration = LocalRuntimeConfiguration.CONF
.set(LocalRuntimeConfiguration.MAX_NUMBER_OF_EVALUATORS, MAX_NUMBER_OF_EVALUATORS)
.build();
} else {
LOG.log(Level.INFO, "Running on YARN");
runtimeConfiguration = YarnClientConfiguration.CONF.build();
}
return Tang.Factory.getTang()
.newConfigurationBuilder(runtimeConfiguration, clientConfiguration,
cloneCommandLineConfiguration(commandLineConf))
.build();
}
}
/**
* Main method that starts the CLR Bridge from Java.
*
* @param args command line parameters.
*/
public static void main(final String[] args) {
LOG.log(Level.INFO, "Entering Launch at :::" + new Date());
try {
if (args == null || args.length == 0) {
throw new IllegalArgumentException("No arguments provided, at least a clrFolder should be supplied.");
}
final File dotNetFolder = new File(args[0]).getAbsoluteFile();
final String[] removedArgs = Arrays.copyOfRange(args, 1, args.length);
final Configuration config = getClientConfiguration(removedArgs);
final Injector commandLineInjector = Tang.Factory.getTang().newInjector(parseCommandLine(removedArgs));
final int waitTime = commandLineInjector.getNamedInstance(WaitTimeForDriver.class);
final int driverMemory = commandLineInjector.getNamedInstance(DriverMemoryInMb.class);
final boolean isLocal = commandLineInjector.getNamedInstance(Local.class);
final String driverIdentifier = commandLineInjector.getNamedInstance(DriverIdentifier.class);
final String jobSubmissionDirectory = commandLineInjector.getNamedInstance(DriverJobSubmissionDirectory.class);
final boolean submit = commandLineInjector.getNamedInstance(Submit.class);
final Injector injector = Tang.Factory.getTang().newInjector(config);
final JobClient client = injector.getInstance(JobClient.class);
client.setDriverInfo(driverIdentifier, driverMemory, jobSubmissionDirectory);
if (submit) {
client.submit(dotNetFolder, true, isLocal, null);
client.waitForCompletion(waitTime);
} else {
client.submit(dotNetFolder, false, isLocal, config);
client.waitForCompletion(0);
}
LOG.info("Done!");
} catch (final BindException | InjectionException | IOException ex) {
LOG.log(Level.SEVERE, "Job configuration error", ex);
}
}
/**
* Command line parameter: number of experiments to run.
*/
@NamedParameter(doc = "Number of times to run the command",
short_name = "num_runs", default_value = "1")
public static final class NumRuns implements Name<Integer> {
}
/**
* Command line parameter = true to run locally, or false to run on YARN.
*/
@NamedParameter(doc = "Whether or not to run on the local runtime",
short_name = "local", default_value = "true")
public static final class Local implements Name<Boolean> {
}
/**
* Command line parameter, number of seconds to wait till driver finishes ,
* = -1 : waits forever
* = 0: exit immediately without wait for driver.
*/
@NamedParameter(doc = "Whether or not to wait for driver to finish",
short_name = "wait_time", default_value = "-1")
public static final class WaitTimeForDriver implements Name<Integer> {
}
/**
* Command line parameter, driver memory, in MB.
*/
@NamedParameter(doc = "memory allocated to driver JVM",
short_name = "driver_memory", default_value = "512")
public static final class DriverMemoryInMb implements Name<Integer> {
}
/**
* Command line parameter, driver identifier.
*/
@NamedParameter(doc = "driver identifier for clr bridge",
short_name = "driver_id", default_value = "ReefClrBridge")
public static final class DriverIdentifier implements Name<String> {
}
/**
* Command line parameter = true to submit the job with driver config, or false to write config to current directory.
*/
@NamedParameter(doc = "Whether or not to submit the reef job after driver config is constructed",
short_name = "submit", default_value = "true")
public static final class Submit implements Name<Boolean> {
}
/**
* Command line parameter, job submission directory, if set, user should guarantee its uniqueness.
*/
@NamedParameter(doc = "driver job submission directory",
short_name = "submission_directory", default_value = "empty")
public static final class DriverJobSubmissionDirectory implements Name<String> {
}
}