Java tutorial
/** * (C) Copyright IBM Corp. 2010, 2015 * * Licensed 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 com.ibm.bi.dml.runtime.controlprogram.parfor.opt; import java.io.BufferedReader; import java.io.File; import java.io.FileInputStream; import java.io.FileOutputStream; import java.io.FileReader; import java.io.FileWriter; import java.io.IOException; import java.util.ArrayList; import java.util.Date; import java.util.HashMap; import java.util.LinkedList; import java.util.Random; import java.util.StringTokenizer; import java.util.Map.Entry; import javax.xml.stream.XMLInputFactory; import javax.xml.stream.XMLOutputFactory; import javax.xml.stream.XMLStreamConstants; import javax.xml.stream.XMLStreamException; import javax.xml.stream.XMLStreamReader; import javax.xml.stream.XMLStreamWriter; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; import au.com.bytecode.opencsv.CSVReader; import au.com.bytecode.opencsv.CSVWriter; import com.ibm.bi.dml.api.DMLException; import com.ibm.bi.dml.api.DMLScript; import com.ibm.bi.dml.lops.Lop; import com.ibm.bi.dml.lops.MMTSJ.MMTSJType; import com.ibm.bi.dml.parser.DMLProgram; import com.ibm.bi.dml.parser.DMLTranslator; import com.ibm.bi.dml.parser.DataIdentifier; import com.ibm.bi.dml.parser.ExternalFunctionStatement; import com.ibm.bi.dml.parser.ParseException; import com.ibm.bi.dml.parser.Expression.DataType; import com.ibm.bi.dml.parser.Expression.ValueType; import com.ibm.bi.dml.runtime.DMLRuntimeException; import com.ibm.bi.dml.runtime.DMLUnsupportedOperationException; import com.ibm.bi.dml.runtime.controlprogram.ExternalFunctionProgramBlockCP; import com.ibm.bi.dml.runtime.controlprogram.LocalVariableMap; import com.ibm.bi.dml.runtime.controlprogram.Program; import com.ibm.bi.dml.runtime.controlprogram.ProgramBlock; import com.ibm.bi.dml.runtime.controlprogram.caching.CacheException; import com.ibm.bi.dml.runtime.controlprogram.caching.LazyWriteBuffer; import com.ibm.bi.dml.runtime.controlprogram.caching.MatrixObject; import com.ibm.bi.dml.runtime.controlprogram.context.ExecutionContext; import com.ibm.bi.dml.runtime.controlprogram.context.ExecutionContextFactory; import com.ibm.bi.dml.runtime.controlprogram.parfor.stat.Timing; import com.ibm.bi.dml.runtime.controlprogram.parfor.util.IDHandler; import com.ibm.bi.dml.runtime.controlprogram.parfor.util.IDSequence; import com.ibm.bi.dml.runtime.instructions.CPInstructionParser; import com.ibm.bi.dml.runtime.instructions.Instruction; import com.ibm.bi.dml.runtime.instructions.MRJobInstruction; import com.ibm.bi.dml.runtime.instructions.cp.Data; import com.ibm.bi.dml.runtime.instructions.cp.DataGenCPInstruction; import com.ibm.bi.dml.runtime.instructions.cp.FunctionCallCPInstruction; import com.ibm.bi.dml.runtime.io.IOUtilFunctions; import com.ibm.bi.dml.runtime.matrix.MatrixCharacteristics; import com.ibm.bi.dml.runtime.matrix.MatrixFormatMetaData; import com.ibm.bi.dml.runtime.matrix.data.InputInfo; import com.ibm.bi.dml.runtime.matrix.data.MatrixBlock; import com.ibm.bi.dml.runtime.matrix.data.OutputInfo; import com.ibm.bi.dml.runtime.util.LocalFileUtils; import com.ibm.bi.dml.runtime.util.MapReduceTool; /** * DML Instructions Performance Test Tool: * * Creates an offline performance profile (required once per installation) of DML instructions. * The profile is a combination of all individual statistical models trained per combination of * instruction and test configuration. In order to train those models, we execute and measure * real executions of DML instructions on random input data. Finally, during runtime, the profile * is used by the costs estimator in order to create statistic estimates for cost-based optimization. * * */ public class PerfTestTool { //public parameters (used for estimation) public static final long MIN_DATASIZE = 1000; public static final long MAX_DATASIZE = 1000000; public static final long DEFAULT_DATASIZE = 500000;//(MAX_DATASIZE-MIN_DATASIZE)/2; public static final long DATASIZE_MR_SCALE = 20; public static final double MIN_DIMSIZE = 1; public static final double MAX_DIMSIZE = 1000; public static final double MIN_SPARSITY = 0.1; public static final double MAX_SPARSITY = 1.0; public static final double DEFAULT_SPARSITY = 0.5;//(MAX_SPARSITY-MIN_SPARSITY)/2; public static final double MIN_SORT_IO_MEM = 10; public static final double MAX_SORT_IO_MEM = 500; public static final double DEFAULT_SORT_IO_MEM = 256; //BI: default 256MB, hadoop: default 100MB //internal parameters private static final boolean READ_STATS_ON_STARTUP = false; private static final int TEST_REPETITIONS = 10; private static final int NUM_SAMPLES_PER_TEST = 11; private static final int MODEL_MAX_ORDER = 2; private static final boolean MODEL_INTERCEPT = true; private static final String PERF_TOOL_DIR = "./conf/PerfTestTool/"; // private static final String PERF_RESULTS_FNAME = PERF_TOOL_DIR + "%id%.dat"; private static final String PERF_PROFILE_FNAME = PERF_TOOL_DIR + "performance_profile.xml"; private static final String DML_SCRIPT_FNAME = "./src/com/ibm/bi/dml/runtime/controlprogram/parfor/opt/PerfTestToolRegression.dml"; private static final String DML_TMP_FNAME = PERF_TOOL_DIR + "temp.dml"; //XML profile tags and attributes private static final String XML_PROFILE = "profile"; private static final String XML_DATE = "date"; private static final String XML_INSTRUCTION = "instruction"; private static final String XML_ID = "id"; private static final String XML_NAME = "name"; private static final String XML_COSTFUNCTION = "cost_function"; private static final String XML_MEASURE = "measure"; private static final String XML_VARIABLE = "lvariable"; private static final String XML_INTERNAL_VARIABLES = "pvariables"; private static final String XML_DATAFORMAT = "dataformat"; private static final String XML_ELEMENT_DELIMITER = "\u002c"; //","; //ID sequences for instructions and test definitions private static IDSequence _seqInst = null; private static IDSequence _seqTestDef = null; //registered instructions and test definitions private static HashMap<Integer, PerfTestDef> _regTestDef = null; private static HashMap<Integer, Instruction> _regInst = null; private static HashMap<Integer, String> _regInst_IDNames = null; private static HashMap<String, Integer> _regInst_NamesID = null; private static HashMap<Integer, Integer[]> _regInst_IDTestDef = null; private static HashMap<Integer, Boolean> _regInst_IDVectors = null; private static HashMap<Integer, IOSchema> _regInst_IDIOSchema = null; protected static final Log LOG = LogFactory.getLog(PerfTestTool.class.getName()); private static Integer[] _defaultConf = null; // private static Integer[] _MRConf = null; //raw measurement data (instID, physical defID, results) private static HashMap<Integer, HashMap<Integer, LinkedList<Double>>> _results = null; //profile data private static boolean _flagReadData = false; private static HashMap<Integer, HashMap<Integer, CostFunction>> _profile = null; public enum TestMeasure //logical test measure { EXEC_TIME, MEMORY_USAGE } public enum TestVariable //logical test variable { DATA_SIZE, SPARSITY, PARALLELISM, //some mr specific conf properites SORT_IO_MEM } public enum InternalTestVariable //physical test variable { DATA_SIZE, DIM1_SIZE, DIM2_SIZE, DIM3_SIZE, SPARSITY, NUM_THREADS, NUM_MAPPERS, NUM_REDUCERS, SORT_IO_MEM } public enum IOSchema { NONE_NONE, NONE_UNARY, UNARY_NONE, UNARY_UNARY, BINARY_NONE, BINARY_UNARY } public enum DataFormat //logical data format { DENSE, SPARSE } public enum TestConstants //logical test constants { DFS_READ_THROUGHPUT, DFS_WRITE_THROUGHPUT, LFS_READ_THROUGHPUT, LFS_WRITE_THROUGHPUT } static { //init repository _seqInst = new IDSequence(); _seqTestDef = new IDSequence(); _regTestDef = new HashMap<Integer, PerfTestDef>(); _regInst = new HashMap<Integer, Instruction>(); _regInst_IDNames = new HashMap<Integer, String>(); _regInst_NamesID = new HashMap<String, Integer>(); _regInst_IDTestDef = new HashMap<Integer, Integer[]>(); _regInst_IDVectors = new HashMap<Integer, Boolean>(); _regInst_IDIOSchema = new HashMap<Integer, IOSchema>(); _results = new HashMap<Integer, HashMap<Integer, LinkedList<Double>>>(); _profile = new HashMap<Integer, HashMap<Integer, CostFunction>>(); _flagReadData = false; //load existing profile if required try { if (READ_STATS_ON_STARTUP) readProfile(PERF_PROFILE_FNAME); } catch (Exception ex) { throw new RuntimeException(ex); } } /** * * @throws DMLRuntimeException */ public static void lazyInit() throws DMLRuntimeException { //read profile for first access if (!_flagReadData) { try { //register all testdefs and instructions registerTestConfigurations(); registerInstructions(); //read profile readProfile(PERF_PROFILE_FNAME); } catch (Exception ex) { throw new DMLRuntimeException(ex); } } if (_profile == null) throw new DMLRuntimeException("Performance test results have not been loaded completely."); } /** * * @param opStr * @return * @throws DMLRuntimeException */ public static boolean isRegisteredInstruction(String opStr) throws DMLRuntimeException { //init if required lazyInit(); //determine if inst registered return _regInst_NamesID.containsKey(opStr); } /** * * @param instName * @return * @throws DMLRuntimeException */ public static CostFunction getCostFunction(String instName, TestMeasure measure, TestVariable variable, DataFormat dataformat) throws DMLRuntimeException { //init if required lazyInit(); CostFunction tmp = null; int instID = getInstructionID(instName); if (instID != -1) //existing profile { int tdefID = getMappedTestDefID(instID, measure, variable, dataformat); tmp = _profile.get(instID).get(tdefID); } return tmp; } /** * * @param measure * @param variable * @param dataformat * @return */ public CostFunction getInvariantCostFunction(TestMeasure measure, TestVariable[] variable, DataFormat dataformat) { //TODO: implement for additional rewrites throw new RuntimeException("Not implemented yet."); } /** * * @return */ @SuppressWarnings("all") public static boolean runTest() { boolean ret = false; try { Timing time = new Timing(); time.start(); //init caching LazyWriteBuffer.init(); //register all testdefs and instructions registerTestConfigurations(); registerInstructions(); //execute tests for all confs and all instructions executeTest(); //compute regression models int rows = NUM_SAMPLES_PER_TEST; int cols = MODEL_MAX_ORDER + (MODEL_INTERCEPT ? 1 : 0); HashMap<Integer, Long> tmp = writeResults(PERF_TOOL_DIR); computeRegressionModels(DML_SCRIPT_FNAME, DML_TMP_FNAME, PERF_TOOL_DIR, tmp.size(), rows, cols); readRegressionModels(PERF_TOOL_DIR, tmp); //execConstantRuntimeTest(); //execConstantMemoryTest(); //write final profile to XML file writeProfile(PERF_TOOL_DIR, PERF_PROFILE_FNAME); System.out .format("SystemML PERFORMANCE TEST TOOL: finished profiling (in %.2f min), profile written to " + PERF_PROFILE_FNAME + "%n", time.stop() / 60000); ret = true; } catch (Exception ex) { LOG.error("Failed to run performance test.", ex); } return ret; } /** * */ private static void registerTestConfigurations() { //reset ID Sequence for consistent IDs _seqTestDef.reset(); //register default testdefs //TODO TestMeasure[] M = new TestMeasure[] { TestMeasure.EXEC_TIME/*, TestMeasure.MEMORY_USAGE*/ }; DataFormat[] D = new DataFormat[] { DataFormat.DENSE/*,DataFormat.SPARSE*/ }; Integer[] defaultConf = new Integer[M.length * D.length * 2]; int i = 0; for (TestMeasure m : M) //for all measures for (DataFormat d : D) //for all data formats { defaultConf[i++] = registerTestDef(new PerfTestDef(m, TestVariable.DATA_SIZE, d, InternalTestVariable.DATA_SIZE, MIN_DATASIZE, MAX_DATASIZE, NUM_SAMPLES_PER_TEST)); defaultConf[i++] = registerTestDef(new PerfTestDef(m, TestVariable.SPARSITY, d, InternalTestVariable.SPARSITY, MIN_SPARSITY, MAX_SPARSITY, NUM_SAMPLES_PER_TEST)); } //register advanced (multi-dim) test defs //FIXME enable /*for( TestMeasure m : M ) //for all measures for( DataFormat d : D ) //for all data formats { registerTestDef( new PerfTestDef( m, TestVariable.DATA_SIZE, d, new InternalTestVariable[]{InternalTestVariable.DIM1_SIZE,InternalTestVariable.DIM2_SIZE,InternalTestVariable.DIM3_SIZE}, MIN_DIMSIZE, MAX_DIMSIZE, NUM_SAMPLES_PER_TEST ) ); }?* //register MR specific instructions FIXME: just for test /*Integer[] mrConf = new Integer[D.length]; i = 0; for( DataFormat d : D ) { mrConf[i++] = registerTestDef( new PerfTestDef(TestMeasure.EXEC_TIME, TestVariable.SORT_IO_MEM, d, InternalTestVariable.SORT_IO_MEM, MIN_SORT_IO_MEM, MAX_SORT_IO_MEM, NUM_SAMPLES_PER_TEST ) ); }*/ //set default testdefs _defaultConf = defaultConf; //_MRConf = mrConf; } /** * * @throws DMLUnsupportedOperationException * @throws DMLRuntimeException */ private static void registerInstructions() throws DMLUnsupportedOperationException, DMLRuntimeException { //reset ID sequences for consistent IDs _seqInst.reset(); /////// // CP instructions //matrix multiply mmtsj registerInstruction("CP" + Lop.OPERAND_DELIMITOR + "tsmm", CPInstructionParser.parseSingleInstruction("CP" + Lop.OPERAND_DELIMITOR + "tsmm" + Lop.OPERAND_DELIMITOR + "A" + Lop.DATATYPE_PREFIX + "MATRIX" + Lop.VALUETYPE_PREFIX + "DOUBLE" + Lop.OPERAND_DELIMITOR + "C" + Lop.DATATYPE_PREFIX + "MATRIX" + Lop.VALUETYPE_PREFIX + "DOUBLE" + Lop.OPERAND_DELIMITOR + MMTSJType.LEFT), getDefaultTestDefs(), false, IOSchema.UNARY_UNARY); /* //matrix multiply registerInstruction( "CP"+Lops.OPERAND_DELIMITOR+"ba+*", CPInstructionParser.parseSingleInstruction("CP"+Lops.OPERAND_DELIMITOR+"ba+*"+Lops.OPERAND_DELIMITOR+"A"+Lops.DATATYPE_PREFIX+"MATRIX"+Lops.VALUETYPE_PREFIX+"DOUBLE"+Lops.OPERAND_DELIMITOR+"B"+Lops.DATATYPE_PREFIX+"MATRIX"+Lops.VALUETYPE_PREFIX+"DOUBLE"+Lops.OPERAND_DELIMITOR+"C"+Lops.DATATYPE_PREFIX+"MATRIX"+Lops.VALUETYPE_PREFIX+"DOUBLE"), getDefaultTestDefs(), false, IOSchema.BINARY_UNARY ); ////registerInstruction( "CP"+Lops.OPERAND_DELIMITOR+"ba+*", CPInstructionParser.parseSingleInstruction("CP"+Lops.OPERAND_DELIMITOR+"ba+*"+Lops.OPERAND_DELIMITOR+"A"+Lops.DATATYPE_PREFIX+"MATRIX"+Lops.VALUETYPE_PREFIX+"DOUBLE"+Lops.OPERAND_DELIMITOR+"B"+Lops.DATATYPE_PREFIX+"MATRIX"+Lops.VALUETYPE_PREFIX+"DOUBLE"+Lops.OPERAND_DELIMITOR+"C"+Lops.DATATYPE_PREFIX+"MATRIX"+Lops.VALUETYPE_PREFIX+"DOUBLE"), //// changeToMuliDimTestDefs(TestVariable.DATA_SIZE, getDefaultTestDefs()) ); //rand registerInstruction( "CP"+Lops.OPERAND_DELIMITOR+"Rand", CPInstructionParser.parseSingleInstruction("CP"+Lops.OPERAND_DELIMITOR+"Rand"+Lops.OPERAND_DELIMITOR+"rows=1"+Lops.OPERAND_DELIMITOR+"cols=1"+Lops.OPERAND_DELIMITOR+"rowsInBlock=1000"+Lops.OPERAND_DELIMITOR+"colsInBlock=1000"+Lops.OPERAND_DELIMITOR+"min=1.0"+Lops.OPERAND_DELIMITOR+"max=100.0"+Lops.OPERAND_DELIMITOR+"sparsity=1.0"+Lops.OPERAND_DELIMITOR+"seed=7"+Lops.OPERAND_DELIMITOR+"pdf=uniform"+Lops.OPERAND_DELIMITOR+"dir=."+Lops.OPERAND_DELIMITOR+"C"+Lops.DATATYPE_PREFIX+"MATRIX"+Lops.VALUETYPE_PREFIX+"DOUBLE"), getDefaultTestDefs(), false, IOSchema.NONE_UNARY ); //matrix transpose registerInstruction( "CP"+Lops.OPERAND_DELIMITOR+"r'", CPInstructionParser.parseSingleInstruction("CP"+Lops.OPERAND_DELIMITOR+"r'"+Lops.OPERAND_DELIMITOR+"A"+Lops.DATATYPE_PREFIX+"MATRIX"+Lops.VALUETYPE_PREFIX+"DOUBLE"+Lops.OPERAND_DELIMITOR+"C"+Lops.DATATYPE_PREFIX+"MATRIX"+Lops.VALUETYPE_PREFIX+"DOUBLE"), getDefaultTestDefs(), false, IOSchema.UNARY_UNARY ); //sum registerInstruction( "CP"+Lops.OPERAND_DELIMITOR+"uak+", CPInstructionParser.parseSingleInstruction("CP"+Lops.OPERAND_DELIMITOR+"uak+"+Lops.OPERAND_DELIMITOR+"A"+Lops.DATATYPE_PREFIX+"MATRIX"+Lops.VALUETYPE_PREFIX+"DOUBLE"+Lops.OPERAND_DELIMITOR+"B"+Lops.DATATYPE_PREFIX+"MATRIX"+Lops.VALUETYPE_PREFIX+"DOUBLE"), //needs B instead of C getDefaultTestDefs(), false, IOSchema.UNARY_UNARY ); //external function registerInstruction( "CP"+Lops.OPERAND_DELIMITOR+"extfunct", CPInstructionParser.parseSingleInstruction("CP"+Lops.OPERAND_DELIMITOR+"extfunct"+Lops.OPERAND_DELIMITOR+DMLProgram.DEFAULT_NAMESPACE+""+Lops.OPERAND_DELIMITOR+"execPerfTestExtFunct"+Lops.OPERAND_DELIMITOR+"1"+Lops.OPERAND_DELIMITOR+"1"+Lops.OPERAND_DELIMITOR+"A"+Lops.OPERAND_DELIMITOR+"C"), getDefaultTestDefs(), false, IOSchema.UNARY_UNARY ); //central moment registerInstruction( "CP"+Lops.OPERAND_DELIMITOR+"cm", CPInstructionParser.parseSingleInstruction("CP"+Lops.OPERAND_DELIMITOR+"cm"+Lops.OPERAND_DELIMITOR+"A"+Lops.DATATYPE_PREFIX+"MATRIX"+Lops.VALUETYPE_PREFIX+"DOUBLE"+Lops.OPERAND_DELIMITOR+"2"+Lops.DATATYPE_PREFIX+"SCALAR"+Lops.VALUETYPE_PREFIX+"INT"+Lops.OPERAND_DELIMITOR+"c"+Lops.DATATYPE_PREFIX+"SCALAR"+Lops.VALUETYPE_PREFIX+"DOUBLE"), getDefaultTestDefs(), true, IOSchema.UNARY_NONE ); //co-variance registerInstruction( "CP"+Lops.OPERAND_DELIMITOR+"cov", CPInstructionParser.parseSingleInstruction("CP"+Lops.OPERAND_DELIMITOR+"cov"+Lops.OPERAND_DELIMITOR+"A"+Lops.DATATYPE_PREFIX+"MATRIX"+Lops.VALUETYPE_PREFIX+"DOUBLE"+Lops.OPERAND_DELIMITOR+"B"+Lops.DATATYPE_PREFIX+"MATRIX"+Lops.VALUETYPE_PREFIX+"DOUBLE"+Lops.OPERAND_DELIMITOR+"c"+Lops.DATATYPE_PREFIX+"SCALAR"+Lops.VALUETYPE_PREFIX+"DOUBLE"), getDefaultTestDefs(), true, IOSchema.BINARY_NONE ); */ /* /////// // MR instructions registerInstruction( "jobtypeMMRJ", createMRJobInstruction(JobType.MMRJ, MRInstructionParser.parseSingleInstruction("MR"+Lops.OPERAND_DELIMITOR+ "rmm"+Lops.OPERAND_DELIMITOR+ "0"+Lops.DATATYPE_PREFIX+"MATRIX"+Lops.VALUETYPE_PREFIX+"DOUBLE"+Lops.OPERAND_DELIMITOR+ "1"+Lops.DATATYPE_PREFIX+"MATRIX"+Lops.VALUETYPE_PREFIX+"DOUBLE"+Lops.OPERAND_DELIMITOR+ "2"+Lops.DATATYPE_PREFIX+"MATRIX"+Lops.VALUETYPE_PREFIX+"DOUBLE ")), _MRConf, false, IOSchema.BINARY_UNARY ); */ /*ADD ADDITIONAL INSTRUCTIONS HERE*/ //extend list to all (expensive) instructions; maybe also: createvar, assignvar, cpvar, rm, mv, setfilename, rmfilevar } /* private static Instruction createMRJobInstruction(JobType type, MRInstruction inst) { MRJobInstruction mrinst = new MRJobInstruction(type); if( type == JobType.MMRJ ) { ArrayList<String> inLab = new ArrayList<String>(); ArrayList<String> outLab = new ArrayList<String>(); inLab.add("A"); inLab.add("B"); outLab.add("C"); mrinst.setMMRJInstructions(new String[]{"A","B"}, "", inst.toString(), "", "", new String[]{"C"}, new byte[]{2}, 10, 1 ); } return mrinst; } */ /** * * @param def * @return */ private static int registerTestDef(PerfTestDef def) { int ID = (int) _seqTestDef.getNextID(); _regTestDef.put(ID, def); return ID; } /** * * @param iname * @param inst * @param testDefIDs * @param vectors * @param schema */ private static void registerInstruction(String iname, Instruction inst, Integer[] testDefIDs, boolean vectors, IOSchema schema) { int ID = (int) _seqInst.getNextID(); registerInstruction(ID, iname, inst, testDefIDs, vectors, schema); } /** * * @param ID * @param iname * @param inst * @param testDefIDs * @param vector * @param schema */ private static void registerInstruction(int ID, String iname, Instruction inst, Integer[] testDefIDs, boolean vector, IOSchema schema) { _regInst.put(ID, inst); _regInst_IDNames.put(ID, iname); _regInst_NamesID.put(iname, ID); _regInst_IDTestDef.put(ID, testDefIDs); _regInst_IDVectors.put(ID, vector); _regInst_IDIOSchema.put(ID, schema); } /** * * @param instID * @param measure * @param variable * @param dataformat * @return */ private static int getMappedTestDefID(int instID, TestMeasure measure, TestVariable variable, DataFormat dataformat) { int ret = -1; for (Integer defID : _regInst_IDTestDef.get(instID)) { PerfTestDef def = _regTestDef.get(defID); if (def.getMeasure() == measure && def.getVariable() == variable && def.getDataformat() == dataformat) { ret = defID; break; } } return ret; } /** * * @param measure * @param lvariable * @param dataformat * @param pvariable * @return */ @SuppressWarnings("unused") private static int getTestDefID(TestMeasure measure, TestVariable lvariable, DataFormat dataformat, InternalTestVariable pvariable) { return getTestDefID(measure, lvariable, dataformat, new InternalTestVariable[] { pvariable }); } /** * * @param measure * @param lvariable * @param dataformat * @param pvariables * @return */ private static int getTestDefID(TestMeasure measure, TestVariable lvariable, DataFormat dataformat, InternalTestVariable[] pvariables) { int ret = -1; for (Entry<Integer, PerfTestDef> e : _regTestDef.entrySet()) { PerfTestDef def = e.getValue(); TestMeasure tmp1 = def.getMeasure(); TestVariable tmp2 = def.getVariable(); DataFormat tmp3 = def.getDataformat(); InternalTestVariable[] tmp4 = def.getInternalVariables(); if (tmp1 == measure && tmp2 == lvariable && tmp3 == dataformat) { boolean flag = true; for (int i = 0; i < tmp4.length; i++) flag &= (tmp4[i] == pvariables[i]); if (flag) { ret = e.getKey(); break; } } } return ret; } /** * * @param instName * @return */ private static int getInstructionID(String instName) { Integer ret = _regInst_NamesID.get(instName); return (ret != null) ? ret : -1; } /** * * @return */ @SuppressWarnings("unused") private static Integer[] getAllTestDefs() { return _regTestDef.keySet().toArray(new Integer[0]); } /** * * @return */ private static Integer[] getDefaultTestDefs() { return _defaultConf; } /** * * @param v * @param IDs * @return */ @SuppressWarnings("unused") private static Integer[] changeToMuliDimTestDefs(TestVariable v, Integer[] IDs) { Integer[] tmp = new Integer[IDs.length]; for (int i = 0; i < tmp.length; i++) { PerfTestDef def = _regTestDef.get(IDs[i]); if (def.getVariable() == v) //filter logical variables { //find multidim version InternalTestVariable[] in = null; switch (v) { case DATA_SIZE: in = new InternalTestVariable[] { InternalTestVariable.DIM1_SIZE, InternalTestVariable.DIM2_SIZE, InternalTestVariable.DIM3_SIZE }; break; default: //do nothing } int newid = getTestDefID(def.getMeasure(), def.getVariable(), def.getDataformat(), in); //exchange testdef ID tmp[i] = newid; } else { tmp[i] = IDs[i]; } } return tmp; } /** * * @throws DMLRuntimeException * @throws DMLUnsupportedOperationException * @throws IOException */ private static void executeTest() throws DMLRuntimeException, DMLUnsupportedOperationException, IOException { System.out.println("SystemML PERFORMANCE TEST TOOL:"); //foreach registered instruction for (Entry<Integer, Instruction> inst : _regInst.entrySet()) { int instID = inst.getKey(); System.out.println("Running INSTRUCTION " + _regInst_IDNames.get(instID)); Integer[] testDefIDs = _regInst_IDTestDef.get(instID); boolean vectors = _regInst_IDVectors.get(instID); IOSchema schema = _regInst_IDIOSchema.get(instID); //create tmp program block and set instruction Program prog = new Program(); ProgramBlock pb = new ProgramBlock(prog); ArrayList<Instruction> ainst = new ArrayList<Instruction>(); ainst.add(inst.getValue()); pb.setInstructions(ainst); ExecutionContext ec = ExecutionContextFactory.createContext(); //foreach registered test configuration for (Integer defID : testDefIDs) { PerfTestDef def = _regTestDef.get(defID); TestMeasure m = def.getMeasure(); TestVariable lv = def.getVariable(); DataFormat df = def.getDataformat(); InternalTestVariable[] pv = def.getInternalVariables(); double min = def.getMin(); double max = def.getMax(); double samples = def.getNumSamples(); System.out.println("Running TESTDEF(measure=" + m + ", variable=" + String.valueOf(lv) + " " + pv.length + ", format=" + String.valueOf(df) + ")"); //vary input variable LinkedList<Double> dmeasure = new LinkedList<Double>(); LinkedList<Double> dvariable = generateSequence(min, max, samples); int plen = pv.length; if (plen == 1) //1D function { for (Double var : dvariable) { dmeasure.add(executeTestCase1D(m, pv[0], df, var, pb, vectors, schema, ec)); } } else //multi-dim function { //init index stack int[] index = new int[plen]; for (int i = 0; i < plen; i++) index[i] = 0; //execute test int dlen = dvariable.size(); double[] buff = new double[plen]; while (index[0] < dlen) { //set buffer values for (int i = 0; i < plen; i++) buff[i] = dvariable.get(index[i]); //core execution dmeasure.add(executeTestCaseMD(m, pv, df, buff, pb, schema, ec)); //not applicable for vector flag //increment indexes for (int i = plen - 1; i >= 0; i--) { if (i == plen - 1) index[i]++; else if (index[i + 1] >= dlen) { index[i]++; index[i + 1] = 0; } } } } //append values to results if (!_results.containsKey(instID)) _results.put(instID, new HashMap<Integer, LinkedList<Double>>()); _results.get(instID).put(defID, dmeasure); } } } /** * * @param m * @param v * @param df * @param varValue * @param pb * @param vectors * @param schema * * @return * @throws DMLRuntimeException * @throws DMLUnsupportedOperationException * @throws IOException */ private static double executeTestCase1D(TestMeasure m, InternalTestVariable v, DataFormat df, double varValue, ProgramBlock pb, boolean vectors, IOSchema schema, ExecutionContext ec) throws DMLRuntimeException, DMLUnsupportedOperationException, IOException { double datasize = -1; double dim1 = -1, dim2 = -1; double sparsity = -1; //double sortio = -1; System.out.println("VAR VALUE " + varValue); //set test variables switch (v) { case DATA_SIZE: datasize = varValue; sparsity = DEFAULT_SPARSITY; break; case SPARSITY: datasize = DEFAULT_DATASIZE; sparsity = varValue; break; case SORT_IO_MEM: //FIXME datasize = DEFAULT_DATASIZE * DATASIZE_MR_SCALE; sparsity = DEFAULT_SPARSITY; //sortio = varValue; break; default: //do nothing } //set specific dimensions if (vectors) { dim1 = datasize; dim2 = 1; } else { dim1 = Math.sqrt(datasize); dim2 = dim1; } //instruction-specific configurations Instruction inst = pb.getInstruction(0); //always exactly one instruction if (inst instanceof DataGenCPInstruction) { DataGenCPInstruction rand = (DataGenCPInstruction) inst; rand.setRows((long) dim1); rand.setCols((long) dim2); rand.setSparsity(sparsity); } else if (inst instanceof FunctionCallCPInstruction) //ExternalFunctionInvocationInstruction { Program prog = pb.getProgram(); ArrayList<DataIdentifier> in = new ArrayList<DataIdentifier>(); DataIdentifier dat1 = new DataIdentifier("A"); dat1.setDataType(DataType.MATRIX); dat1.setValueType(ValueType.DOUBLE); in.add(dat1); ArrayList<DataIdentifier> out = new ArrayList<DataIdentifier>(); DataIdentifier dat2 = new DataIdentifier("C"); dat2.setDataType(DataType.MATRIX); dat2.setValueType(ValueType.DOUBLE); out.add(dat2); HashMap<String, String> params = new HashMap<String, String>(); params.put(ExternalFunctionStatement.CLASS_NAME, PerfTestExtFunctCP.class.getName()); ExternalFunctionProgramBlockCP fpb = new ExternalFunctionProgramBlockCP(prog, in, out, params, PERF_TOOL_DIR); prog.addFunctionProgramBlock(DMLProgram.DEFAULT_NAMESPACE, "execPerfTestExtFunct", fpb); } else if (inst instanceof MRJobInstruction) { //FIXME hardcoded for test //MMRJMR.SORT_IO_MEM = sortio; } //generate input and output matrices LocalVariableMap vars = ec.getVariables(); vars.removeAll(); double mem1 = PerfTestMemoryObserver.getUsedMemory(); if (schema != IOSchema.NONE_NONE && schema != IOSchema.NONE_UNARY) vars.put("A", generateInputDataset(PERF_TOOL_DIR + "/A", dim1, dim2, sparsity, df)); if (schema == IOSchema.BINARY_NONE || schema == IOSchema.BINARY_UNARY || schema == IOSchema.UNARY_UNARY) vars.put("B", generateInputDataset(PERF_TOOL_DIR + "/B", dim1, dim2, sparsity, df)); if (schema == IOSchema.NONE_UNARY || schema == IOSchema.UNARY_UNARY || schema == IOSchema.BINARY_UNARY) vars.put("C", generateEmptyResult(PERF_TOOL_DIR + "/C", dim1, dim2, df)); double mem2 = PerfTestMemoryObserver.getUsedMemory(); //foreach repetition double value = 0; for (int i = 0; i < TEST_REPETITIONS; i++) { System.out.println("run " + i); value += executeGenericProgramBlock(m, pb, ec); } value /= TEST_REPETITIONS; //result correction and print result switch (m) { case EXEC_TIME: System.out.println("--- RESULT: " + value + " ms"); break; case MEMORY_USAGE: //System.out.println("--- RESULT: "+value+" byte"); if ((mem2 - mem1) > 0) value = value + mem2 - mem1; //correction: input sizes added System.out.println("--- RESULT: " + value + " byte"); break; default: System.out.println("--- RESULT: " + value); break; } return value; } /** * * @param m * @param v * @param df * @param varValue * @param pb * @param schema * @return * @throws DMLRuntimeException * @throws DMLUnsupportedOperationException * @throws IOException */ private static double executeTestCaseMD(TestMeasure m, InternalTestVariable[] v, DataFormat df, double[] varValue, ProgramBlock pb, IOSchema schema, ExecutionContext ec) throws DMLRuntimeException, DMLUnsupportedOperationException, IOException { //double datasize = DEFAULT_DATASIZE; double sparsity = DEFAULT_SPARSITY; double dim1 = -1; double dim2 = -1; double dim3 = -1; for (int i = 0; i < v.length; i++) { System.out.println("VAR VALUE " + varValue[i]); switch (v[i]) { case DIM1_SIZE: dim1 = varValue[i]; break; case DIM2_SIZE: dim2 = varValue[i]; break; case DIM3_SIZE: dim3 = varValue[i]; break; default: //do nothing } } //generate input and output matrices LocalVariableMap vars = ec.getVariables(); vars.removeAll(); double mem1 = PerfTestMemoryObserver.getUsedMemory(); if (schema != IOSchema.NONE_NONE && schema != IOSchema.NONE_UNARY) vars.put("A", generateInputDataset(PERF_TOOL_DIR + "/A", dim1, dim2, sparsity, df)); if (schema == IOSchema.BINARY_NONE || schema == IOSchema.BINARY_UNARY || schema == IOSchema.UNARY_UNARY) vars.put("B", generateInputDataset(PERF_TOOL_DIR + "/B", dim2, dim3, sparsity, df)); if (schema == IOSchema.NONE_UNARY || schema == IOSchema.UNARY_UNARY || schema == IOSchema.BINARY_UNARY) vars.put("C", generateEmptyResult(PERF_TOOL_DIR + "/C", dim1, dim3, df)); double mem2 = PerfTestMemoryObserver.getUsedMemory(); //foreach repetition double value = 0; for (int i = 0; i < TEST_REPETITIONS; i++) { System.out.println("run " + i); value += executeGenericProgramBlock(m, pb, ec); } value /= TEST_REPETITIONS; //result correction and print result switch (m) { case EXEC_TIME: System.out.println("--- RESULT: " + value + " ms"); break; case MEMORY_USAGE: //System.out.println("--- RESULT: "+value+" byte"); if ((mem2 - mem1) > 0) value = value + mem2 - mem1; //correction: input sizes added System.out.println("--- RESULT: " + value + " byte"); break; default: System.out.println("--- RESULT: " + value); break; } return value; } /** * * @param measure * @param pb * @return * @throws DMLRuntimeException * @throws DMLUnsupportedOperationException */ public static double executeGenericProgramBlock(TestMeasure measure, ProgramBlock pb, ExecutionContext ec) throws DMLRuntimeException, DMLUnsupportedOperationException { double value = 0; try { switch (measure) { case EXEC_TIME: Timing time = new Timing(); time.start(); pb.execute(ec); value = time.stop(); break; case MEMORY_USAGE: PerfTestMemoryObserver mo = new PerfTestMemoryObserver(); mo.measureStartMem(); Thread t = new Thread(mo); t.start(); pb.execute(ec); mo.setStopped(); value = mo.getMaxMemConsumption(); t.join(); break; } } catch (Exception ex) { throw new DMLRuntimeException(ex); } //clear matrixes from cache for (String str : ec.getVariables().keySet()) { Data dat = ec.getVariable(str); if (dat instanceof MatrixObject) ((MatrixObject) dat).clearData(); } return value; } /** * * @param min * @param max * @param num * @return */ public static LinkedList<Double> generateSequence(double min, double max, double num) { LinkedList<Double> data = new LinkedList<Double>(); double increment = (max - min) / (num - 1); for (int i = 0; i < num; i++) data.add(Double.valueOf(min + i * increment)); return data; } /** * * @param fname * @param datasize * @param sparsity * @param df * @return * @throws IOException * @throws CacheException */ public static MatrixObject generateInputDataset(String fname, double datasize, double sparsity, DataFormat df) throws IOException, CacheException { int dim = (int) Math.sqrt(datasize); //create random test data double[][] d = generateTestMatrix(dim, dim, 1, 100, sparsity, 7); //create matrix block MatrixBlock mb = null; switch (df) { case DENSE: mb = new MatrixBlock(dim, dim, false); break; case SPARSE: mb = new MatrixBlock(dim, dim, true, (int) (sparsity * dim * dim)); break; } //insert data for (int i = 0; i < dim; i++) for (int j = 0; j < dim; j++) if (d[i][j] != 0) mb.setValue(i, j, d[i][j]); MapReduceTool.deleteFileIfExistOnHDFS(fname); MatrixCharacteristics mc = new MatrixCharacteristics(dim, dim, DMLTranslator.DMLBlockSize, DMLTranslator.DMLBlockSize); MatrixFormatMetaData md = new MatrixFormatMetaData(mc, OutputInfo.BinaryBlockOutputInfo, InputInfo.BinaryBlockInputInfo); MatrixObject mo = new MatrixObject(ValueType.DOUBLE, fname, md); mo.acquireModify(mb); mo.release(); mo.exportData(); //write to HDFS return mo; } /** * * @param fname * @param dim1 * @param dim2 * @param sparsity * @param df * @return * @throws IOException * @throws CacheException */ public static MatrixObject generateInputDataset(String fname, double dim1, double dim2, double sparsity, DataFormat df) throws IOException, CacheException { int d1 = (int) dim1; int d2 = (int) dim2; System.out.println(d1 + " " + d2); //create random test data double[][] d = generateTestMatrix(d1, d2, 1, 100, sparsity, 7); //create matrix block MatrixBlock mb = null; switch (df) { case DENSE: mb = new MatrixBlock(d1, d2, false); break; case SPARSE: mb = new MatrixBlock(d1, d2, true, (int) (sparsity * dim1 * dim2)); break; } //insert data for (int i = 0; i < d1; i++) for (int j = 0; j < d2; j++) if (d[i][j] != 0) mb.setValue(i, j, d[i][j]); MapReduceTool.deleteFileIfExistOnHDFS(fname); MatrixCharacteristics mc = new MatrixCharacteristics(d1, d2, DMLTranslator.DMLBlockSize, DMLTranslator.DMLBlockSize); MatrixFormatMetaData md = new MatrixFormatMetaData(mc, OutputInfo.BinaryBlockOutputInfo, InputInfo.BinaryBlockInputInfo); MatrixObject mo = new MatrixObject(ValueType.DOUBLE, fname, md); mo.acquireModify(mb); mo.release(); mo.exportData(); //write to HDFS return mo; } /** * * @param fname * @param datasize * @param df * @return * @throws IOException * @throws CacheException */ public static MatrixObject generateEmptyResult(String fname, double datasize, DataFormat df) throws IOException, CacheException { int dim = (int) Math.sqrt(datasize); /* MatrixBlock mb = null; switch( df ) { case DENSE: mb = new MatrixBlock(dim,dim,false); break; case SPARSE: mb = new MatrixBlock(dim,dim,true); break; }*/ MatrixCharacteristics mc = new MatrixCharacteristics(dim, dim, DMLTranslator.DMLBlockSize, DMLTranslator.DMLBlockSize); MatrixFormatMetaData md = new MatrixFormatMetaData(mc, OutputInfo.BinaryBlockOutputInfo, InputInfo.BinaryBlockInputInfo); MatrixObject mo = new MatrixObject(ValueType.DOUBLE, fname, md); return mo; } /** * * @param fname * @param dim1 * @param dim2 * @param df * @return * @throws IOException * @throws CacheException */ public static MatrixObject generateEmptyResult(String fname, double dim1, double dim2, DataFormat df) throws IOException, CacheException { int d1 = (int) dim1; int d2 = (int) dim2; /* MatrixBlock mb = null; switch( df ) { case DENSE: mb = new MatrixBlock(dim,dim,false); break; case SPARSE: mb = new MatrixBlock(dim,dim,true); break; }*/ MatrixCharacteristics mc = new MatrixCharacteristics(d1, d2, DMLTranslator.DMLBlockSize, DMLTranslator.DMLBlockSize); MatrixFormatMetaData md = new MatrixFormatMetaData(mc, OutputInfo.BinaryBlockOutputInfo, InputInfo.BinaryBlockInputInfo); MatrixObject mo = new MatrixObject(ValueType.DOUBLE, fname, md); return mo; } /** * NOTE: This is a copy of TestUtils.generateTestMatrix, it was replicated in order to prevent * dependency of SystemML.jar to our test package. */ public static double[][] generateTestMatrix(int rows, int cols, double min, double max, double sparsity, long seed) { double[][] matrix = new double[rows][cols]; Random random; if (seed == -1) random = new Random(System.nanoTime()); else random = new Random(seed); for (int i = 0; i < rows; i++) { for (int j = 0; j < cols; j++) { if (random.nextDouble() > sparsity) continue; matrix[i][j] = (random.nextDouble() * (max - min) + min); } } return matrix; } /** * * @param fname * @throws DMLUnsupportedOperationException * @throws DMLRuntimeException * @throws XMLStreamException * @throws IOException */ public static void externalReadProfile(String fname) throws DMLUnsupportedOperationException, DMLRuntimeException, XMLStreamException, IOException { //validate external name (security issue) if (!LocalFileUtils.validateExternalFilename(fname, false)) throw new DMLRuntimeException("Invalid (non-trustworthy) external profile filename."); //register internals and read external profile registerTestConfigurations(); registerInstructions(); readProfile(fname); } /** * * @param dirname * @return * @throws IOException * @throws DMLUnsupportedOperationException */ @SuppressWarnings("all") private static HashMap<Integer, Long> writeResults(String dirname) throws IOException, DMLUnsupportedOperationException { HashMap<Integer, Long> map = new HashMap<Integer, Long>(); int count = 1; int offset = (MODEL_INTERCEPT ? 1 : 0); int cols = MODEL_MAX_ORDER + offset; for (Entry<Integer, HashMap<Integer, LinkedList<Double>>> inst : _results.entrySet()) { int instID = inst.getKey(); HashMap<Integer, LinkedList<Double>> instCF = inst.getValue(); for (Entry<Integer, LinkedList<Double>> cfun : instCF.entrySet()) { int tDefID = cfun.getKey(); long ID = IDHandler.concatIntIDsToLong(instID, tDefID); LinkedList<Double> dmeasure = cfun.getValue(); PerfTestDef def = _regTestDef.get(tDefID); LinkedList<Double> dvariable = generateSequence(def.getMin(), def.getMax(), NUM_SAMPLES_PER_TEST); int dlen = dvariable.size(); int plen = def.getInternalVariables().length; //write variable data set CSVWriter writer1 = new CSVWriter(new FileWriter(dirname + count + "_in1.csv"), ',', CSVWriter.NO_QUOTE_CHARACTER); if (plen == 1) //one dimensional function { //write 1, x, x^2, x^3, ... String[] sbuff = new String[cols]; for (Double val : dvariable) { for (int j = 0; j < cols; j++) sbuff[j] = String.valueOf(Math.pow(val, j + 1 - offset)); writer1.writeNext(sbuff); } } else // multi-dimensional function { //write 1, x,y,z,x^2,y^2,z^2, xy, xz, yz, xyz String[] sbuff = new String[(int) Math.pow(2, plen) - 1 + plen + offset - 1]; //String[] sbuff = new String[plen+offset]; if (offset == 1) sbuff[0] = "1"; //init index stack int[] index = new int[plen]; for (int i = 0; i < plen; i++) index[i] = 0; //execute test double[] buff = new double[plen]; while (index[0] < dlen) { //set buffer values for (int i = 0; i < plen; i++) buff[i] = dvariable.get(index[i]); //core writing for (int i = 1; i <= plen; i++) { if (i == 1) { for (int j = 0; j < plen; j++) sbuff[offset + j] = String.valueOf(buff[j]); for (int j = 0; j < plen; j++) sbuff[offset + plen + j] = String.valueOf(Math.pow(buff[j], 2)); } else if (i == 2) { int ix = 0; for (int j = 0; j < plen - 1; j++) for (int k = j + 1; k < plen; k++, ix++) sbuff[offset + 2 * plen + ix] = String.valueOf(buff[j] * buff[k]); } else if (i == plen) { //double tmp=1; //for( int j=0; j<plen; j++ ) // tmp *= buff[j]; //sbuff[offset+2*plen+plen*(plen-1)/2] = String.valueOf(tmp); } else throw new DMLUnsupportedOperationException( "More than 3 dims currently not supported."); } //for( int i=0; i<plen; i++ ) // sbuff[offset+i] = String.valueOf( buff[i] ); writer1.writeNext(sbuff); //increment indexes for (int i = plen - 1; i >= 0; i--) { if (i == plen - 1) index[i]++; else if (index[i + 1] >= dlen) { index[i]++; index[i + 1] = 0; } } } } writer1.close(); //write measure data set CSVWriter writer2 = new CSVWriter(new FileWriter(dirname + count + "_in2.csv"), ',', CSVWriter.NO_QUOTE_CHARACTER); String[] buff2 = new String[1]; for (Double val : dmeasure) { buff2[0] = String.valueOf(val); writer2.writeNext(buff2); } writer2.close(); map.put(count, ID); count++; } } return map; } /** * * @param dmlname * @param dmltmpname * @param dir * @param models * @param rows * @param cols * @throws IOException * @throws ParseException * @throws DMLException */ private static void computeRegressionModels(String dmlname, String dmltmpname, String dir, int models, int rows, int cols) throws IOException, ParseException, DMLException { //clean scratch space //AutomatedTestBase.cleanupScratchSpace(); //read DML template StringBuilder buffer = new StringBuilder(); BufferedReader br = new BufferedReader(new FileReader(new File(dmlname))); try { String line = null; while ((line = br.readLine()) != null) { buffer.append(line); buffer.append("\n"); } } finally { if (br != null) br.close(); } //replace parameters String template = buffer.toString(); template = template.replaceAll("%numModels%", String.valueOf(models)); template = template.replaceAll("%numRows%", String.valueOf(rows)); template = template.replaceAll("%numCols%", String.valueOf(cols)); template = template.replaceAll("%indir%", String.valueOf(dir)); // write temp DML file File fout = new File(dmltmpname); FileOutputStream fos = new FileOutputStream(fout); try { fos.write(template.getBytes()); } finally { if (fos != null) fos.close(); } // execute DML script DMLScript.main(new String[] { "-f", dmltmpname }); } /** * * @param dname * @param IDMapping * @throws IOException */ private static void readRegressionModels(String dname, HashMap<Integer, Long> IDMapping) throws IOException { for (Entry<Integer, Long> e : IDMapping.entrySet()) { int count = e.getKey(); long ID = e.getValue(); int instID = IDHandler.extractIntIDFromLong(ID, 1); int tDefID = IDHandler.extractIntIDFromLong(ID, 2); //read file and parse LinkedList<Double> params = new LinkedList<Double>(); CSVReader reader1 = new CSVReader(new FileReader(dname + count + "_out.csv"), ','); String[] nextline = null; while ((nextline = reader1.readNext()) != null) { params.add(Double.parseDouble(nextline[0])); } reader1.close(); double[] dparams = new double[params.size()]; int i = 0; for (Double d : params) { dparams[i] = d; i++; } //create new cost function boolean multidim = _regTestDef.get(tDefID).getInternalVariables().length > 1; CostFunction cf = new CostFunction(dparams, multidim); //append to profile if (!_profile.containsKey(instID)) _profile.put(instID, new HashMap<Integer, CostFunction>()); _profile.get(instID).put(tDefID, cf); } } /** * * @param vars * @return */ private static String serializeTestVariables(InternalTestVariable[] vars) { StringBuilder sb = new StringBuilder(); for (int i = 0; i < vars.length; i++) { if (i > 0) sb.append(XML_ELEMENT_DELIMITER); sb.append(String.valueOf(vars[i])); } return sb.toString(); } /** * * @param vars * @return */ private static InternalTestVariable[] parseTestVariables(String vars) { StringTokenizer st = new StringTokenizer(vars, XML_ELEMENT_DELIMITER); InternalTestVariable[] v = new InternalTestVariable[st.countTokens()]; for (int i = 0; i < v.length; i++) v[i] = InternalTestVariable.valueOf(st.nextToken()); return v; } /** * * @param vals * @return */ private static String serializeParams(double[] vals) { StringBuilder sb = new StringBuilder(); for (int i = 0; i < vals.length; i++) { if (i > 0) sb.append(XML_ELEMENT_DELIMITER); sb.append(String.valueOf(vals[i])); } return sb.toString(); } /** * * @param valStr * @return */ private static double[] parseParams(String valStr) { StringTokenizer st = new StringTokenizer(valStr, XML_ELEMENT_DELIMITER); double[] params = new double[st.countTokens()]; for (int i = 0; i < params.length; i++) params[i] = Double.parseDouble(st.nextToken()); return params; } /** * * @param fname * @throws XMLStreamException * @throws IOException */ private static void readProfile(String fname) throws XMLStreamException, IOException { //init profile map _profile = new HashMap<Integer, HashMap<Integer, CostFunction>>(); //read existing profile FileInputStream fis = new FileInputStream(fname); try { //xml parsing XMLInputFactory xif = XMLInputFactory.newInstance(); XMLStreamReader xsr = xif.createXMLStreamReader(fis); int e = xsr.nextTag(); // profile start while (true) //read all instructions { e = xsr.nextTag(); // instruction start if (e == XMLStreamConstants.END_ELEMENT) break; //reached profile end tag //parse instruction int ID = Integer.parseInt(xsr.getAttributeValue(null, XML_ID)); //String name = xsr.getAttributeValue(null, XML_NAME).trim().replaceAll(" ", Lops.OPERAND_DELIMITOR); HashMap<Integer, CostFunction> tmp = new HashMap<Integer, CostFunction>(); _profile.put(ID, tmp); while (true) { e = xsr.nextTag(); // cost function start if (e == XMLStreamConstants.END_ELEMENT) break; //reached instruction end tag //parse cost function TestMeasure m = TestMeasure.valueOf(xsr.getAttributeValue(null, XML_MEASURE)); TestVariable lv = TestVariable.valueOf(xsr.getAttributeValue(null, XML_VARIABLE)); InternalTestVariable[] pv = parseTestVariables( xsr.getAttributeValue(null, XML_INTERNAL_VARIABLES)); DataFormat df = DataFormat.valueOf(xsr.getAttributeValue(null, XML_DATAFORMAT)); int tDefID = getTestDefID(m, lv, df, pv); xsr.next(); //read characters double[] params = parseParams(xsr.getText()); boolean multidim = _regTestDef.get(tDefID).getInternalVariables().length > 1; CostFunction cf = new CostFunction(params, multidim); tmp.put(tDefID, cf); xsr.nextTag(); // cost function end //System.out.println("added cost function"); } } xsr.close(); } finally { IOUtilFunctions.closeSilently(fis); } //mark profile as successfully read _flagReadData = true; } /** * StAX for efficient streaming XML writing. * * @throws IOException * @throws XMLStreamException */ private static void writeProfile(String dname, String fname) throws IOException, XMLStreamException { //create initial directory and file File dir = new File(dname); if (!dir.exists()) dir.mkdir(); File f = new File(fname); f.createNewFile(); FileOutputStream fos = new FileOutputStream(f); try { //create document XMLOutputFactory xof = XMLOutputFactory.newInstance(); XMLStreamWriter xsw = xof.createXMLStreamWriter(fos); //TODO use an alternative way for intentation //xsw = new IndentingXMLStreamWriter( xsw ); //remove this line if no indenting required //write document content xsw.writeStartDocument(); xsw.writeStartElement(XML_PROFILE); xsw.writeAttribute(XML_DATE, String.valueOf(new Date())); //foreach instruction (boundle of cost functions) for (Entry<Integer, HashMap<Integer, CostFunction>> inst : _profile.entrySet()) { int instID = inst.getKey(); String instName = _regInst_IDNames.get(instID); xsw.writeStartElement(XML_INSTRUCTION); xsw.writeAttribute(XML_ID, String.valueOf(instID)); xsw.writeAttribute(XML_NAME, instName.replaceAll(Lop.OPERAND_DELIMITOR, " ")); //foreach testdef cost function for (Entry<Integer, CostFunction> cfun : inst.getValue().entrySet()) { int tdefID = cfun.getKey(); PerfTestDef def = _regTestDef.get(tdefID); CostFunction cf = cfun.getValue(); xsw.writeStartElement(XML_COSTFUNCTION); xsw.writeAttribute(XML_ID, String.valueOf(tdefID)); xsw.writeAttribute(XML_MEASURE, def.getMeasure().toString()); xsw.writeAttribute(XML_VARIABLE, def.getVariable().toString()); xsw.writeAttribute(XML_INTERNAL_VARIABLES, serializeTestVariables(def.getInternalVariables())); xsw.writeAttribute(XML_DATAFORMAT, def.getDataformat().toString()); xsw.writeCharacters(serializeParams(cf.getParams())); xsw.writeEndElement();// XML_COSTFUNCTION } xsw.writeEndElement(); //XML_INSTRUCTION } xsw.writeEndElement();//XML_PROFILE xsw.writeEndDocument(); xsw.close(); } finally { IOUtilFunctions.closeSilently(fos); } } /** * Main for invoking the actual performance test in order to produce profile.xml * * @param args */ public static void main(String[] args) { //execute the local / remote performance test PerfTestTool.runTest(); } }