001/*
002 * To change this license header, choose License Headers in Project Properties.
003 * To change this template file, choose Tools | Templates
004 * and open the template in the editor.
005 */
006package org.dllearner.cli.unife;
007
008import java.io.File;
009import java.io.FileOutputStream;
010import java.io.IOException;
011import java.io.PrintStream;
012import java.util.ArrayList;
013import java.util.List;
014import java.util.Map;
015import mpi.MPI;
016import mpi.MPIException;
017import org.apache.commons.lang.exception.ExceptionUtils;
018import org.apache.log4j.Level;
019import org.apache.log4j.Logger;
020import org.dllearner.cli.CLI;
021import org.dllearner.configuration.IConfiguration;
022import org.dllearner.configuration.spring.ApplicationContextBuilder;
023import org.dllearner.configuration.spring.DefaultApplicationContextBuilder;
024import org.dllearner.confparser.ConfParserConfiguration;
025import org.dllearner.confparser.ParseException;
026import org.dllearner.core.ComponentInitException;
027import org.dllearner.core.ReasoningMethodUnsupportedException;
028import org.dllearner.core.probabilistic.unife.AbstractPSLA;
029import org.springframework.context.ApplicationContext;
030import org.springframework.core.io.FileSystemResource;
031import org.springframework.core.io.Resource;
032import unife.bundle.logging.BundleLoggerFactory;
033import unife.edge.mpi.MPIUtilities;
034import org.dllearner.core.probabilistic.unife.ProbabilisticStructureLearningAlgorithm;
035import org.semanticweb.owlapi.model.OWLOntologyCreationException;
036import org.semanticweb.owlapi.model.OWLOntologyStorageException;
037
038/**
039 *
040 * @author Giuseppe Cota <giuseppe.cota@unife.it>, Riccardo Zese
041 * <riccardo.zese@unife.it>
042 */
043public class CLIDistributedLEAP extends CLI {
044
045    private IConfiguration configuration;
046    private ProbabilisticStructureLearningAlgorithm algorithm;
047    private AbstractPSLA psla;
048    // TO DO: creare e gestire i gruppi MPI ed il ranking
049
050    @Override
051    public void init() throws IOException {
052        super.init();
053        psla = getContext().getBean(AbstractPSLA.class);
054    }
055
056    @Override
057    public void run(){
058        System.out.println("CLI Distributed LEAP");
059        Logger logger = Logger.getLogger(CLIDistributedLEAP.class.getName(), new BundleLoggerFactory());
060        logger.info("CLI Distributed LEAP");
061        try {
062            org.apache.log4j.Logger.getLogger("org.dllearner").setLevel(Level.toLevel(getLogLevel().toUpperCase()));
063        } catch (Exception e) {
064            logger.warn("Error setting log level to " + getLogLevel());
065        }
066
067//        init();
068        boolean master = MPIUtilities.isMaster(MPI.COMM_WORLD);
069//        try {
070//            master = MPIUtilities.isMaster(MPI.COMM_WORLD);
071//        } catch (MPIException mpiEx) {
072//            String msg = "Unable to estabilish if the current process is master: " 
073//                    + mpiEx.getMessage();
074//            logger.error(msg);
075//            throw new RuntimeException(msg);
076//        }
077
078
079        if (isPerformCrossValidation()) {
080//            PosNegLP lp = context.getBean(PosNegLP.class);
081//            if (la instanceof QTL2) {
082//                new SPARQLCrossValidation((QTL2) la, lp, rs, nrOfFolds, false);
083//            } else {
084            try {
085                new LEAPCrossValidation(psla, getNrOfFolds(), false, true);
086            } catch (OWLOntologyCreationException | OWLOntologyStorageException e) {
087                logger.error(e.getMessage(), e);
088                e.printStackTrace();
089            }
090//            }
091            throw new UnsupportedOperationException("Not supported yet.");
092        } else {
093            for (Map.Entry<String, ProbabilisticStructureLearningAlgorithm> entry : getContext().getBeansOfType(ProbabilisticStructureLearningAlgorithm.class).entrySet()) {
094                algorithm = entry.getValue();
095                logger.info("Running algorithm instance \"" + entry.getKey() + "\" (" + algorithm.getClass().getSimpleName() + ")");
096                algorithm.start();
097            }
098        }
099
100    }
101
102    public static void main(String[] args) throws ParseException, IOException,
103            ReasoningMethodUnsupportedException {
104
105        System.out.println("DL-Learner command line interface");
106
107        // currently, CLI has exactly one parameter - the conf file
108        if (args.length == 0) {
109            System.out.println("You need to give a conf file as argument.");
110            System.exit(0);
111        }
112
113        // read file and print and print a message if it does not exist
114        File file = new File(args[args.length - 1]);
115        if (!file.exists()) {
116            System.out.println("File \"" + file + "\" does not exist.");
117            System.exit(0);
118        }
119
120        // MPI Initialization
121        try {
122            args = MPI.Init(args);
123        } catch (MPIException mpiEx) {
124            String msg = "Impossible to initialize MPI: " + mpiEx.getMessage();
125            System.err.print(msg);
126        }
127        // Setting output file for logging
128        String slaveIdLog = System.getProperty("slaveId");
129        if (slaveIdLog != null) {
130            throw new RuntimeException("slaveId property already defined somewhere else.");
131        }
132
133        // set the index for the log file: log/leap${slaveId}.log
134        MPIUtilities.createLogFile("slaveId");
135
136        Logger logger = Logger.getLogger(CLIDistributedLEAP.class.getName(), new BundleLoggerFactory());
137
138        Resource confFile = new FileSystemResource(file);
139
140        List<Resource> springConfigResources = new ArrayList<Resource>();
141        logger.debug("Spring!");
142        try {
143            //DL-Learner Configuration Object
144            IConfiguration configuration = new ConfParserConfiguration(confFile);
145
146            ApplicationContextBuilder builder = new DefaultApplicationContextBuilder();
147            ApplicationContext context = builder.buildApplicationContext(configuration, springConfigResources);
148
149            // TODO: later we could check which command line interface is specified in the conf file
150            // for now we just use the default one
151            CLI cli;
152            if (context.containsBean("cli")) {
153                cli = (CLI) context.getBean("cli");
154            } else {
155                cli = new CLI();
156            }
157            logger.debug("setting context");
158            cli.setContext(context);
159            logger.debug("context set");
160            logger.debug("setting conf file");
161            cli.setConfFile(file);
162            logger.debug("conf file set");
163            logger.debug("Start Running");
164            cli.run();
165        } catch (Exception e) {
166            e.printStackTrace();
167            String stacktraceFileName = "log/error.log";
168
169//            e.printStackTrace();
170            //Find the primary cause of the exception.
171            Throwable primaryCause = findPrimaryCause(e);
172
173            // Get the Root Error Message
174            logger.error("An Error Has Occurred During Processing.");
175//            logger.error(primaryCause.getMessage());
176            logger.debug("Stack Trace: ", e);
177            logger.error("Terminating DL-Learner...and writing stacktrace to: " + stacktraceFileName);
178            FileOutputStream fos = new FileOutputStream(stacktraceFileName);
179            PrintStream ps = new PrintStream(fos);
180            e.printStackTrace(ps);
181        } finally {
182            try {
183                MPI.Finalize();
184            } catch (MPIException mpiEx) {
185                String msg = "Cannot finalize MPI";
186                System.err.print(msg);
187                logger.error(msg);
188            }
189        }
190    }
191
192    /**
193     * Find the primary cause of the specified exception.
194     *
195     * @param e The exception to analyze
196     * @return The primary cause of the exception.
197     */
198    protected static Throwable findPrimaryCause(Exception e) {
199        // The throwables from the stack of the exception
200        Throwable[] throwables = ExceptionUtils.getThrowables(e);
201
202        //Look For a Component Init Exception and use that as the primary cause of failure, if we find it
203        int componentInitExceptionIndex = ExceptionUtils.indexOfThrowable(e, ComponentInitException.class);
204
205        Throwable primaryCause;
206        if (componentInitExceptionIndex > -1) {
207            primaryCause = throwables[componentInitExceptionIndex];
208        } else {
209            //No Component Init Exception on the Stack Trace, so we'll use the root as the primary cause.
210            primaryCause = ExceptionUtils.getRootCause(e);
211        }
212        return primaryCause;
213    }
214
215}