Package org.carrot2.workbench.core.ui

Source Code of org.carrot2.workbench.core.ui.BenchmarkJob

/*
* Carrot2 project.
*
* Copyright (C) 2002-2014, Dawid Weiss, Stanisław Osiński.
* All rights reserved.
*
* Refer to the full license file "carrot2.LICENSE"
* in the root folder of the repository checkout or at:
* http://www.carrot2.org/carrot2.LICENSE
*/

package org.carrot2.workbench.core.ui;

import static org.apache.commons.lang.SystemUtils.*;

import java.io.*;
import java.util.*;
import java.util.concurrent.Callable;
import java.util.concurrent.CountDownLatch;

import org.apache.commons.lang.mutable.MutableInt;
import org.carrot2.core.*;
import org.carrot2.core.attribute.AttributeNames;
import org.carrot2.util.CloseableUtils;
import org.carrot2.workbench.core.WorkbenchCorePlugin;
import org.carrot2.workbench.core.helpers.Utils;
import org.eclipse.core.runtime.*;
import org.eclipse.core.runtime.jobs.Job;

import com.google.common.collect.Maps;

/**
* Actual background benchmarking job.
*/
final class BenchmarkJob extends Job
{
    /**
     * Search input for this job.
     */
    private final SearchInput input;

    /**
     * A clone of benchmark settings for this job.
     */
    final BenchmarkSettings settings;

    /**
     * Public volatile statistics when the job is in progress.
     */
    public volatile BenchmarkStatistics statistics;

    /**
     * Shared log writer. You must synchronize on this object to write.
     */
    public PrintWriter logWriter;

    /**
     * Log file (if {@link #logWriter} is writing to a file).
     */
    public File logFile;

    public BenchmarkJob(SearchInput input, BenchmarkSettings settings)
    {
        super("Benchmarking...");

        this.settings = settings;
        this.input = input;
        this.statistics = new BenchmarkStatistics(settings.warmupRounds, settings.benchmarksRounds);
    }

    /* */
    @Override
    protected IStatus run(IProgressMonitor monitor)
    {
        prepareLogs();
        pushLogHeaders();


        // Create a pool of executing threads.
        final int totalRounds = settings.getTotalRounds();
        final CountDownLatch latch = new CountDownLatch(1);
        final MutableInt rounds = new MutableInt(totalRounds);
        final Callable<Long> benchmarkRunner = createBenchmarkRunner();
        final Thread [] pool = createBenchmarkThreads(latch, rounds, monitor, benchmarkRunner);

        // Start all benchmark threads at once and wait for all of them to finish.
        monitor.beginTask("Running...", totalRounds);
        latch.countDown();
        for (Thread t : pool)
        {
            try
            {
                t.join();
            }
            catch (InterruptedException e)
            {
                // If interrupted, fall through, but terminate all threads whenever possible.
                monitor.setCanceled(true);
            }
        }

        synchronized (logWriter)
        {
            if (monitor.isCanceled())
            {
                logWriter.println("# (cancelled)");
            }
            else
            {
                logWriter.println("# Statistics:");
                logWriter.println("# " + statistics.toString());
            }
        }

        monitor.done();
        CloseableUtils.close(logWriter);

        return Status.OK_STATUS;
    }

    /**
     * Return the benchmark runner.
     */
    private Callable<Long> createBenchmarkRunner()
    {
        final WorkbenchCorePlugin core = WorkbenchCorePlugin.getDefault();
        final Controller controller = core.getController();

        final ProcessingComponentDescriptor source = core.getComponent(input.getSourceId());
        final ProcessingComponentDescriptor algorithm = core.getComponent(input.getAlgorithmId());
       
        final Map<String, Object> attributes =
            Maps.newHashMap(input.getAttributeValueSet().getAttributeValues());
       
        return new Callable<Long>() {
            public Long call() throws Exception
            {
                final long start = System.currentTimeMillis();
                controller.process(attributes, source.getId(), algorithm.getId());
                return System.currentTimeMillis() - start;
            }
        };
    }

    /**
     * Create a set of benchmark threads.
     */
    private Thread [] createBenchmarkThreads(
        final CountDownLatch latch,
        final MutableInt rounds,
        final IProgressMonitor monitor,
        final Callable<Long> benchmarkRunner)
    {
        final Thread [] pool = new Thread [settings.threads];
        for (int i = 0; i < settings.threads; i++)
        {
            final int threadID = i + 1;
            pool[i] = new Thread() {
                public void run()
                {
                    while (!Thread.currentThread().isInterrupted())
                    {
                        final int totalRounds = settings.warmupRounds + settings.benchmarksRounds;
                        final int round;
                        synchronized (logWriter)
                        {
                            round = rounds.intValue();
                            if (round == 0 || monitor.isCanceled())
                            {
                                // Exit if tests finished.
                                return;
                            }
                            rounds.decrement();
                        }
   
                        long time;
                        try
                        {
                            time = benchmarkRunner.call();
                        }
                        catch (Exception e)
                        {
                            Utils.logError(e, false);
                            time = 0;
                        }
   
                        synchronized (logWriter)
                        {
                            logWriter.format(Locale.ENGLISH,
                                "%2d  %4d  %8.03f\n",
                                threadID, totalRounds - round, time / 1000d);

                            statistics = statistics.update((int) time);
                            monitor.worked(1);
                        }
                    }
                }
            };
            pool[i].setName("benchmark-" + i);
            pool[i].setPriority(settings.priority.threadPriority);
            pool[i].start();
        }

        return pool;
    }

    /**
     * Push log headers.
     */
    private void pushLogHeaders()
    {
        if (logWriter == null) return;

        logWriter.println("# Benchmarking log.");
        logWriter.println("# ");
        logWriter.println("# Source: " + input.getSourceId());
        logWriter.println("# Algorithm: " + input.getAlgorithmId());
        logWriter.println("# Query: " + input.getAttribute(AttributeNames.QUERY));
        logWriter.println("# Results: " + input.getAttribute(AttributeNames.RESULTS));
        logWriter.println("# ");
        logWriter.println("# JVM: " + JAVA_VM_NAME
            + ", " + JAVA_VM_VERSION
            + ", " + JAVA_VM_INFO
            + ", " + JAVA_VM_VENDOR);
        logWriter.println("# OS arch: " + OS_ARCH
            + ", name: " + OS_NAME
            + ", version: " + OS_VERSION);
        logWriter.println("# ");
        logWriter.println("# Benchmark rounds: " + settings.benchmarksRounds);
        logWriter.println("# Warmup rounds: " + settings.warmupRounds);
        logWriter.println("# Threads: " + settings.threads + " (available CPUs or cores: "
            + Runtime.getRuntime().availableProcessors() + "), "
            + "running at " + settings.priority + " priority.");
        logWriter.println("# ");
        logWriter.println("# thread_id  round_number  time[s]");
    }

    /**
     * Prepare log output.
     */
    private void prepareLogs()
    {
        final String logName =
            String.format(Locale.ENGLISH,
                "benchmark_%1$tF_%1$tH-%1$tM-%1$tS.txt", new Date());

        try
        {
            if (this.settings.logDirectory != null)
            {
                this.logFile = new File(settings.logDirectory, logName);
            }
            else
            {
                this.logFile = new File(System.getProperty("java.io.tmpdir", "."), logName);
            }
            this.logWriter = new PrintWriter(logFile, "UTF-8");
        }
        catch (IOException e)
        {
            Utils.logError(e, false);

            this.logFile = null;
            this.logWriter = null;
        }
    }
}
TOP

Related Classes of org.carrot2.workbench.core.ui.BenchmarkJob

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.