use of org.apache.sysml.runtime.controlprogram.parfor.stat.Timing in project incubator-systemml by apache.
the class FrameIndexingAppendTest method execDMLScriptviaJMLC.
private static ArrayList<String[][]> execDMLScriptviaJMLC(String testname, String[][] F1, String[][] M, boolean modelReuse) throws IOException {
Timing time = new Timing(true);
ArrayList<String[][]> ret = new ArrayList<String[][]>();
// establish connection to SystemML
Connection conn = new Connection();
try {
// prepare input arguments
HashMap<String, String> args = new HashMap<String, String>();
args.put("$TRANSFORM_SPEC1", "{ \"ids\": true ,\"recode\": [ 1, 2] }");
args.put("$TRANSFORM_SPEC2", "{ \"ids\": true ,\"recode\": [ 1] }");
// read and precompile script
String script = conn.readScript(SCRIPT_DIR + TEST_DIR + testname + ".dml");
PreparedScript pstmt = conn.prepareScript(script, args, new String[] { "F1", "M" }, new String[] { "F2" }, false);
if (modelReuse)
pstmt.setFrame("M", M, true);
// execute script multiple times
for (int i = 0; i < nRuns; i++) {
// bind input parameters
if (!modelReuse)
pstmt.setFrame("M", M);
pstmt.setFrame("F1", F1);
// execute script
ResultVariables rs = pstmt.executeScript();
// get output parameter
String[][] Y = rs.getFrame("F2");
// keep result for comparison
ret.add(Y);
}
} catch (Exception ex) {
ex.printStackTrace();
throw new IOException(ex);
} finally {
IOUtilFunctions.closeSilently(conn);
}
System.out.println("JMLC scoring w/ " + nRuns + " runs in " + time.stop() + "ms.");
return ret;
}
use of org.apache.sysml.runtime.controlprogram.parfor.stat.Timing in project incubator-systemml by apache.
the class FrameTransformTest method execDMLScriptviaJMLC.
private static ArrayList<double[][]> execDMLScriptviaJMLC(String testname, String[][] X, String[][] M, boolean modelReuse) throws IOException {
Timing time = new Timing(true);
ArrayList<double[][]> ret = new ArrayList<double[][]>();
// establish connection to SystemML
Connection conn = new Connection();
try {
// prepare input arguments
HashMap<String, String> args = new HashMap<String, String>();
args.put("$TRANSFORM_SPEC", "{ \"ids\": true ,\"recode\": [ 1, 2, 3] }");
// read and precompile script
String script = conn.readScript(SCRIPT_DIR + TEST_DIR + testname + ".dml");
PreparedScript pstmt = conn.prepareScript(script, args, new String[] { "X", "M" }, new String[] { "Y" }, false);
if (modelReuse)
pstmt.setFrame("M", M, true);
// execute script multiple times
for (int i = 0; i < nRuns; i++) {
// bind input parameters
if (!modelReuse)
pstmt.setFrame("M", M);
pstmt.setFrame("X", X);
// execute script
ResultVariables rs = pstmt.executeScript();
// get output parameter
double[][] Y = rs.getMatrix("Y");
// keep result for comparison
ret.add(Y);
}
} catch (Exception ex) {
ex.printStackTrace();
throw new IOException(ex);
} finally {
IOUtilFunctions.closeSilently(conn);
}
System.out.println("JMLC scoring w/ " + nRuns + " runs in " + time.stop() + "ms.");
return ret;
}
use of org.apache.sysml.runtime.controlprogram.parfor.stat.Timing in project systemml by apache.
the class ParForStatementBlock method validate.
@Override
public VariableSet validate(DMLProgram dmlProg, VariableSet ids, HashMap<String, ConstIdentifier> constVars, boolean conditional) {
LOG.trace("PARFOR(" + _ID + "): validating ParForStatementBlock.");
// create parent variable set via cloning
_vsParent = new VariableSet(ids);
if (// note: A is matrix, and A[i,1] is scalar
LOG.isTraceEnabled())
for (DataIdentifier di : _vsParent.getVariables().values()) LOG.trace("PARFOR: non-local " + di._name + ": " + di.getDataType().toString() + " with rowDim = " + di.getDim1());
// normal validate via ForStatement (sequential)
// NOTES:
// * validate/dependency checking of nested parfor-loops happens at this point
// * validate includes also constant propagation for from, to, incr expressions
// * this includes also function inlining
VariableSet vs = super.validate(dmlProg, ids, constVars, conditional);
// check of correctness of specified parfor parameter names and
// set default parameter values for all not specified parameters
ParForStatement pfs = (ParForStatement) _statements.get(0);
IterablePredicate predicate = pfs.getIterablePredicate();
HashMap<String, String> params = predicate.getParForParams();
if (// if parameter specified
params != null) {
// check for valid parameter types
for (String key : params.keySet()) if (// always unconditional
!_paramNames.contains(key))
raiseValidateError("PARFOR: The specified parameter '" + key + "' is no valid parfor parameter.", false);
// set defaults for all non-specified values
// (except if CONSTRAINT optimizer, in order to distinguish specified parameters)
boolean constrained = (params.containsKey(OPT_MODE) && params.get(OPT_MODE).equals(POptMode.CONSTRAINED.toString()));
for (String key : _paramNames) if (!params.containsKey(key)) {
if (constrained) {
params.put(key, _paramDefaults2.get(key));
} else // special treatment for degree of parallelism
if (key.equals(PAR) && params.containsKey(EXEC_MODE) && params.get(EXEC_MODE).equals(PExecMode.REMOTE_MR.toString())) {
int maxPMap = InfrastructureAnalyzer.getRemoteParallelMapTasks();
// correction max number of reducers on yarn clusters
if (InfrastructureAnalyzer.isYarnEnabled())
maxPMap = (int) Math.max(maxPMap, YarnClusterAnalyzer.getNumCores());
params.put(key, String.valueOf(maxPMap));
} else if (key.equals(PAR) && params.containsKey(EXEC_MODE) && params.get(EXEC_MODE).equals(PExecMode.REMOTE_MR_DP.toString())) {
int maxPRed = InfrastructureAnalyzer.getRemoteParallelReduceTasks();
// correction max number of reducers on yarn clusters
if (InfrastructureAnalyzer.isYarnEnabled())
maxPRed = (int) Math.max(maxPRed, YarnClusterAnalyzer.getNumCores() / 2);
params.put(key, String.valueOf(maxPRed));
} else
// default case
params.put(key, _paramDefaults.get(key));
}
} else {
// set all defaults
params = new HashMap<>();
params.putAll(_paramDefaults);
predicate.setParForParams(params);
}
// start time measurement for normalization and dependency analysis
Timing time = new Timing(true);
// LOOP DEPENDENCY ANALYSIS (test for dependency existence)
// no false negative guaranteed, but possibly false positives
/* Basic intuition: WRITES to NON-local variables are only permitted iff
* - no data dep (no read other than own iteration w i < r j)
* - no anti dep (no read other than own iteration w i > r j)
* - no output dep (no write other than own iteration)
*
* ALGORITHM:
* 1) Determine candidates C (writes to non-local variables)
* 2) Prune all c from C where no dependencies --> C'
* 3) Raise an exception/warning if C' not the empty set
*
* RESTRICTIONS:
* - array subscripts of non-local variables must be linear functions of the form
* a0+ a1*i + ... + a2*j, where i and j are for or parfor indexes.
* - for and parfor increments must be integer values
* - only static (integer lower, upper bounds) range indexing
* - only input variables considered as potential candidates for checking
*
* (TODO: in order to remove the last restriction, dependencies must be checked again after
* live variable analysis against LIVEOUT)
*
* NOTE: validity is only checked during compilation, i.e., for dynamic from, to, incr MIN MAX values assumed.
*/
LOG.trace("PARFOR: running loop dependency analysis ...");
// ### Step 1 ###: determine candidate set C
HashSet<Candidate> C = new HashSet<>();
HashSet<Candidate> C2 = new HashSet<>();
// object for call by ref
Integer sCount = 0;
rDetermineCandidates(pfs.getBody(), C, sCount);
if (LOG.isTraceEnabled())
for (Candidate c : C) LOG.trace("PARFOR: dependency candidate: var '" + c._var + "' (accum=" + c._isAccum + ")");
boolean check = (Integer.parseInt(params.get(CHECK)) == 1);
if (check) {
// ### Step 2 ###: prune c without dependencies
_bounds = new Bounds();
for (FunctionStatementBlock fsb : dmlProg.getFunctionStatementBlocks()) // writes to _bounds
rDetermineBounds(fsb, false);
// writes to _bounds
rDetermineBounds(dmlProg.getStatementBlocks(), false);
for (Candidate c : C) {
// might be different in DataIdentifier
DataType cdt = _vsParent.getVariables().get(c._var).getDataType();
// assume no dependency
sCount = 0;
// output, data, anti
boolean[] dep = new boolean[] { false, false, false };
rCheckCandidates(c, cdt, pfs.getBody(), sCount, dep);
if (LOG.isTraceEnabled()) {
if (dep[0])
LOG.trace("PARFOR: output dependency detected for var '" + c._var + "'.");
if (dep[1])
LOG.trace("PARFOR: data dependency detected for var '" + c._var + "'.");
if (dep[2])
LOG.trace("PARFOR: anti dependency detected for var '" + c._var + "'.");
}
if (dep[0] || dep[1] || dep[2]) {
C2.add(c);
if (ABORT_ON_FIRST_DEPENDENCY)
break;
}
}
// ### Step 3 ###: raise an exception / warning
if (C2.size() > 0) {
LOG.trace("PARFOR: loop dependencies detected.");
StringBuilder depVars = new StringBuilder();
for (Candidate c : C2) {
if (depVars.length() > 0)
depVars.append(", ");
depVars.append(c._var);
}
// always unconditional (to ensure we always raise dependency issues)
raiseValidateError("PARFOR loop dependency analysis: " + "inter-iteration (loop-carried) dependencies detected for variable(s): " + depVars.toString() + ". \n " + "Please, ensure independence of iterations.", false);
} else {
LOG.trace("PARFOR: no loop dependencies detected.");
}
} else {
LOG.debug("INFO: PARFOR(" + _ID + "): loop dependency analysis skipped.");
}
// a) add own candidates
for (Candidate var : C) if (check || var._dat.getDataType() != DataType.SCALAR)
addToResultVariablesNoDup(var._var, var._isAccum);
// b) get and add child result vars (if required)
ArrayList<ResultVar> tmp = new ArrayList<>();
rConsolidateResultVars(pfs.getBody(), tmp);
for (ResultVar var : tmp) if (_vsParent.containsVariable(var._name))
addToResultVariablesNoDup(var);
if (LDEBUG)
for (ResultVar rvar : _resultVars) LOG.debug("INFO: PARFOR final result variable: " + rvar._name);
// cleanup function cache in order to prevent side effects between parfor statements
if (USE_FN_CACHE)
_fncache.clear();
LOG.debug("INFO: PARFOR(" + _ID + "): validate successful (no dependencies) in " + time.stop() + "ms.");
return vs;
}
use of org.apache.sysml.runtime.controlprogram.parfor.stat.Timing in project systemml by apache.
the class DMLYarnClient method launchDMLYarnAppmaster.
/**
* Method to launch the dml yarn app master and execute the given dml script
* with the given configuration and jar file.
*
* NOTE: on launching the yarn app master, we do not explicitly probe if we
* are running on a yarn or MR1 cluster. In case of MR1, already the class
* YarnConfiguration will not be found and raise a classnotfound. In case of any
* exception we fall back to run CP directly in the client process.
*
* @return true if dml program successfully executed as yarn app master
* @throws IOException if IOException occurs
* @throws DMLScriptException if DMLScriptException occurs
*/
protected boolean launchDMLYarnAppmaster() throws IOException, DMLScriptException {
boolean ret = false;
String hdfsWD = null;
try {
Timing time = new Timing(true);
// load yarn configuration
YarnConfiguration yconf = new YarnConfiguration();
// create yarn client
YarnClient yarnClient = YarnClient.createYarnClient();
yarnClient.init(yconf);
yarnClient.start();
// create application and get the ApplicationID
YarnClientApplication app = yarnClient.createApplication();
ApplicationSubmissionContext appContext = app.getApplicationSubmissionContext();
ApplicationId appId = appContext.getApplicationId();
LOG.debug("Created application (applicationID: " + appId + ")");
// prepare hdfs working directory via ApplicationID
// copy script, config, jar file to hdfs
hdfsWD = DMLAppMasterUtils.constructHDFSWorkingDir(_dmlConfig, appId);
copyResourcesToHdfsWorkingDir(yconf, hdfsWD);
// construct command line argument
String command = constructAMCommand(_args, _dmlConfig);
LOG.debug("Constructed application master command: \n" + command);
// set up the container launch context for the application master
ContainerLaunchContext amContainer = Records.newRecord(ContainerLaunchContext.class);
amContainer.setCommands(Collections.singletonList(command));
amContainer.setLocalResources(constructLocalResourceMap(yconf));
amContainer.setEnvironment(constructEnvionmentMap(yconf));
// Set up resource type requirements for ApplicationMaster
int memHeap = _dmlConfig.getIntValue(DMLConfig.YARN_APPMASTERMEM);
int memAlloc = (int) computeMemoryAllocation(memHeap);
Resource capability = Records.newRecord(Resource.class);
capability.setMemory(memAlloc);
capability.setVirtualCores(NUM_CORES);
LOG.debug("Requested application resources: memory=" + memAlloc + ", vcores=" + NUM_CORES);
// Finally, set-up ApplicationSubmissionContext for the application
String qname = _dmlConfig.getTextValue(DMLConfig.YARN_APPQUEUE);
// application name
appContext.setApplicationName(APPMASTER_NAME);
appContext.setAMContainerSpec(amContainer);
appContext.setResource(capability);
// queue
appContext.setQueue(qname);
LOG.debug("Configured application meta data: name=" + APPMASTER_NAME + ", queue=" + qname);
// submit application (non-blocking)
yarnClient.submitApplication(appContext);
// Check application status periodically (and output web ui address)
ApplicationReport appReport = yarnClient.getApplicationReport(appId);
LOG.info("Application tracking-URL: " + appReport.getTrackingUrl());
YarnApplicationState appState = appReport.getYarnApplicationState();
YarnApplicationState oldState = appState;
LOG.info("Application state: " + appState);
while (appState != YarnApplicationState.FINISHED && appState != YarnApplicationState.KILLED && appState != YarnApplicationState.FAILED) {
// wait for 200ms
Thread.sleep(APP_STATE_INTERVAL);
appReport = yarnClient.getApplicationReport(appId);
appState = appReport.getYarnApplicationState();
if (appState != oldState) {
oldState = appState;
LOG.info("Application state: " + appState);
}
}
// check final status (failed or succeeded)
FinalApplicationStatus finalState = appReport.getFinalApplicationStatus();
LOG.info("Application final status: " + finalState);
// show application and total runtime
double appRuntime = (double) (appReport.getFinishTime() - appReport.getStartTime()) / 1000;
LOG.info("Application runtime: " + appRuntime + " sec.");
LOG.info("Total runtime: " + String.format("%.3f", time.stop() / 1000) + " sec.");
// raised script-level error in case of failed final status
if (finalState != FinalApplicationStatus.SUCCEEDED) {
// propagate script-level stop call message
String stop_msg = readMessageToHDFSWorkingDir(_dmlConfig, yconf, appId);
if (stop_msg != null)
throw new DMLScriptException(stop_msg);
// generic failure message
throw new DMLRuntimeException("DML yarn app master finished with final status: " + finalState + ".");
}
ret = true;
} catch (DMLScriptException ex) {
// rethrow DMLScriptException to propagate stop call
throw ex;
} catch (Exception ex) {
LOG.error("Failed to run DML yarn app master.", ex);
ret = false;
} finally {
// cleanup working directory
if (hdfsWD != null)
MapReduceTool.deleteFileIfExistOnHDFS(hdfsWD);
}
return ret;
}
use of org.apache.sysml.runtime.controlprogram.parfor.stat.Timing in project systemml by apache.
the class ResourceOptimizer method optimizeResourceConfig.
public static synchronized ResourceConfig optimizeResourceConfig(ArrayList<ProgramBlock> prog, YarnClusterConfig cc, GridEnumType cptype, GridEnumType mrtype) {
ResourceConfig ROpt = null;
try {
// init statistics and counters
Timing time = new Timing(true);
initStatistics();
// get constraints (yarn-specific: force higher min to limit degree of parallelism)
long max = (long) (YarnOptimizerUtils.toB(cc.getMaxAllocationMB()) / DMLYarnClient.MEM_FACTOR);
long minCP = (long) Math.max(YarnOptimizerUtils.toB(cc.getMinAllocationMB()) / DMLYarnClient.MEM_FACTOR, MIN_CP_BUDGET);
long minMR = YarnOptimizerUtils.computeMinContraint(minCP, max, cc.getAvgNumCores());
// enumerate grid points for given types (refers to jvm max heap)
ArrayList<Long> SRc = enumerateGridPoints(prog, minCP, max, cptype);
ArrayList<Long> SRm = enumerateGridPoints(prog, minMR, max, mrtype);
// init resource config and global costs
ROpt = new ResourceConfig(prog, minMR);
double costOpt = Double.MAX_VALUE;
for (// enumerate CP memory rc
Long rc : // enumerate CP memory rc
SRc) {
// baseline compile and pruning
// unrolled Bp
ArrayList<ProgramBlock> B = compileProgram(prog, null, rc, minMR);
ArrayList<ProgramBlock> Bp = pruneProgramBlocks(B);
LOG.debug("Enum (rc=" + rc + "): |B|=" + B.size() + ", |Bp|=" + Bp.size());
// init local memo table [resource, cost]
double[][] memo = initLocalMemoTable(Bp, minMR);
for (// for all relevant blocks
int i = 0; // for all relevant blocks
i < Bp.size(); // for all relevant blocks
i++) {
ProgramBlock pb = Bp.get(i);
for (// for each MR memory
Long rm : // for each MR memory
SRm) {
// recompile program block
recompileProgramBlock(pb, rc, rm);
// local costing and memo table maintenance (cost entire program to account for
// in-memory status of variables and loops)
double lcost = getProgramCosts(pb);
if (lcost < memo[i][1]) {
// accept new local opt
memo[i][0] = rm;
memo[i][1] = lcost;
// LOG.debug("Enum (rc="+rc+"): found new local opt w/ cost="+lcost);
}
// LOG.debug("Enum (rc="+rc+", rm="+rm+"): lcost="+lcost+", mincost="+memo[i][1]);
}
}
// global costing
double[][] gmemo = initGlobalMemoTable(B, Bp, memo, minMR);
recompileProgramBlocks(B, rc, gmemo);
double gcost = getProgramCosts(B.get(0).getProgram());
if (gcost < costOpt) {
// accept new global opt
ROpt.setCPResource(rc.longValue());
ROpt.setMRResources(B, gmemo);
costOpt = gcost;
LOG.debug("Enum (rc=" + rc + "): found new opt w/ cost=" + gcost);
}
}
// print optimization summary
LOG.info("Optimization summary:");
LOG.info("-- optimal plan (rc, rm): " + YarnOptimizerUtils.toMB(ROpt.getCPResource()) + "MB, " + YarnOptimizerUtils.toMB(ROpt.getMaxMRResource()) + "MB");
LOG.info("-- costs of optimal plan: " + costOpt);
LOG.info("-- # of block compiles: " + _cntCompilePB);
LOG.info("-- # of block costings: " + _cntCostPB);
LOG.info("-- optimization time: " + String.format("%.3f", (double) time.stop() / 1000) + " sec.");
LOG.info("-- optimal plan details: " + ROpt.serialize());
} catch (Exception ex) {
throw new DMLRuntimeException(ex);
}
return ROpt;
}
Aggregations