<commit_before>/*************************************************************************
 *
 *  OpenOffice.org - a multi-platform office productivity suite
 *
 *  $RCSfile: XMLImageMapExport.hxx,v $
 *
 *  $Revision: 1.5 $
 *
 *  last change: $Author: hr $ $Date: 2007-06-26 13:35:01 $
 *
 *  The Contents of this file are made available subject to
 *  the terms of GNU Lesser General Public License Version 2.1.
 *
 *
 *    GNU Lesser General Public License Version 2.1
 *    =============================================
 *    Copyright 2005 by Sun Microsystems, Inc.
 *    901 San Antonio Road, Palo Alto, CA 94303, USA
 *
 *    This library is free software; you can redistribute it and/or
 *    modify it under the terms of the GNU Lesser General Public
 *    License version 2.1, as published by the Free Software Foundation.
 *
 *    This library is distributed in the hope that it will be useful,
 *    but WITHOUT ANY WARRANTY; without even the implied warranty of
 *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 *    Lesser General Public License for more details.
 *
 *    You should have received a copy of the GNU Lesser General Public
 *    License along with this library; if not, write to the Free Software
 *    Foundation, Inc., 59 Temple Place, Suite 330, Boston,
 *    MA  02111-1307  USA
 *
 ************************************************************************/

#ifndef _XMLOFF_XMLIMAGEMAPEXPORT_HXX_
#define _XMLOFF_XMLIMAGEMAPEXPORT_HXX_

#ifndef _RTL_USTRING_HXX_
#include <rtl/ustring.hxx>
#endif

namespace com { namespace sun { namespace star {
    namespace uno { template<class X> class Reference; }
    namespace beans { class XPropertySet; }
    namespace container { class XIndexContainer; }
} } }
class SvXMLExport;

/**
 * Export an ImageMap as defined by service com.sun.star.image.ImageMap to XML.
 */
class XMLImageMapExport
{
    const ::rtl::OUString msBoundary;
    const ::rtl::OUString msCenter;
    const ::rtl::OUString msDescription;
    const ::rtl::OUString msImageMap;
    const ::rtl::OUString msIsActive;
    const ::rtl::OUString msName;
    const ::rtl::OUString msPolygon;
    const ::rtl::OUString msRadius;
    const ::rtl::OUString msTarget;
    const ::rtl::OUString msURL;
    const ::rtl::OUString msTitle;

    SvXMLExport& mrExport;

    sal_Bool mbWhiteSpace;  /// use whitespace between image map elements?

public:
    XMLImageMapExport(SvXMLExport& rExport);

    ~XMLImageMapExport();

    /**
     * Get the ImageMap object from the "ImageMap" property and subsequently
     * export the map (if present).
     */
    void Export(
        /// the property set containing the ImageMap property
        const ::com::sun::star::uno::Reference<
            ::com::sun::star::beans::XPropertySet> & rPropertySet);
    /**
     * Export an ImageMap (XIndexContainer).
     */
    void Export(
        /// the container containing the image map elements
        const ::com::sun::star::uno::Reference<
            ::com::sun::star::container::XIndexContainer> & rContainer);

protected:

    /**
     * Export a single, named map entry.
     * (as given by com.sun.star.image.ImageMapObject)
     * Calls methods for specific image map entries.
     */
    void ExportMapEntry(
        const ::com::sun::star::uno::Reference<
            ::com::sun::star::beans::XPropertySet> & rPropertySet);

    /**
     * Export the specifics of a rectangular image map entry.
     * To be called by ExportMapEntry.
     */
    void ExportRectangle(
        const ::com::sun::star::uno::Reference<
            ::com::sun::star::beans::XPropertySet> & rPropertySet);

    /**
     * Export the specifics of a circular image map entry.
     * To be called by ExportMapEntry.
     */
    void ExportCircle(
        const ::com::sun::star::uno::Reference<
            ::com::sun::star::beans::XPropertySet> & rPropertySet);

    /**
     * Export the specifics of a polygonal image map entry;
     * To be called by ExportMapEntry.
     */
    void ExportPolygon(
        const ::com::sun::star::uno::Reference<
            ::com::sun::star::beans::XPropertySet> & rPropertySet);
};

#endif
<commit_msg>INTEGRATION: CWS changefileheader (1.5.162); FILE MERGED 2008/04/01 16:09:08 thb 1.5.162.2: #i85898# Stripping all external header guards 2008/03/31 16:27:53 rt 1.5.162.1: #i87441# Change license header to LPGL v3.<commit_after>/*************************************************************************
 *
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
 *
 * Copyright 2008 by Sun Microsystems, Inc.
 *
 * OpenOffice.org - a multi-platform office productivity suite
 *
 * $RCSfile: XMLImageMapExport.hxx,v $
 * $Revision: 1.6 $
 *
 * This file is part of OpenOffice.org.
 *
 * OpenOffice.org is free software: you can redistribute it and/or modify
 * it under the terms of the GNU Lesser General Public License version 3
 * only, as published by the Free Software Foundation.
 *
 * OpenOffice.org is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU Lesser General Public License version 3 for more details
 * (a copy is included in the LICENSE file that accompanied this code).
 *
 * You should have received a copy of the GNU Lesser General Public License
 * version 3 along with OpenOffice.org.  If not, see
 * <http://www.openoffice.org/license.html>
 * for a copy of the LGPLv3 License.
 *
 ************************************************************************/

#ifndef _XMLOFF_XMLIMAGEMAPEXPORT_HXX_
#define _XMLOFF_XMLIMAGEMAPEXPORT_HXX_

#include <rtl/ustring.hxx>

namespace com { namespace sun { namespace star {
    namespace uno { template<class X> class Reference; }
    namespace beans { class XPropertySet; }
    namespace container { class XIndexContainer; }
} } }
class SvXMLExport;

/**
 * Export an ImageMap as defined by service com.sun.star.image.ImageMap to XML.
 */
class XMLImageMapExport
{
    const ::rtl::OUString msBoundary;
    const ::rtl::OUString msCenter;
    const ::rtl::OUString msDescription;
    const ::rtl::OUString msImageMap;
    const ::rtl::OUString msIsActive;
    const ::rtl::OUString msName;
    const ::rtl::OUString msPolygon;
    const ::rtl::OUString msRadius;
    const ::rtl::OUString msTarget;
    const ::rtl::OUString msURL;
    const ::rtl::OUString msTitle;

    SvXMLExport& mrExport;

    sal_Bool mbWhiteSpace;  /// use whitespace between image map elements?

public:
    XMLImageMapExport(SvXMLExport& rExport);

    ~XMLImageMapExport();

    /**
     * Get the ImageMap object from the "ImageMap" property and subsequently
     * export the map (if present).
     */
    void Export(
        /// the property set containing the ImageMap property
        const ::com::sun::star::uno::Reference<
            ::com::sun::star::beans::XPropertySet> & rPropertySet);
    /**
     * Export an ImageMap (XIndexContainer).
     */
    void Export(
        /// the container containing the image map elements
        const ::com::sun::star::uno::Reference<
            ::com::sun::star::container::XIndexContainer> & rContainer);

protected:

    /**
     * Export a single, named map entry.
     * (as given by com.sun.star.image.ImageMapObject)
     * Calls methods for specific image map entries.
     */
    void ExportMapEntry(
        const ::com::sun::star::uno::Reference<
            ::com::sun::star::beans::XPropertySet> & rPropertySet);

    /**
     * Export the specifics of a rectangular image map entry.
     * To be called by ExportMapEntry.
     */
    void ExportRectangle(
        const ::com::sun::star::uno::Reference<
            ::com::sun::star::beans::XPropertySet> & rPropertySet);

    /**
     * Export the specifics of a circular image map entry.
     * To be called by ExportMapEntry.
     */
    void ExportCircle(
        const ::com::sun::star::uno::Reference<
            ::com::sun::star::beans::XPropertySet> & rPropertySet);

    /**
     * Export the specifics of a polygonal image map entry;
     * To be called by ExportMapEntry.
     */
    void ExportPolygon(
        const ::com::sun::star::uno::Reference<
            ::com::sun::star::beans::XPropertySet> & rPropertySet);
};

#endif
<|endoftext|>


<commit_before>/**
 * Copyright (c) 2016-2017 Los Alamos National Security, LLC
 *                         All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions are met:
 *
 * 1. Redistributions of source code must retain the above copyright notice,
 * this list of conditions and the following disclaimer.
 *
 * 2. Redistributions in binary form must reproduce the above copyright notice,
 * this list of conditions and the following disclaimer in the documentation
 * and/or other materials provided with the distribution.
 *
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
 * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
 * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
 * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
 * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 *
 * LA-CC 10-123
 */

//@HEADER
// ***************************************************
//
// HPCG: High Performance Conjugate Gradient Benchmark
//
// Contact:
// Michael A. Heroux ( maherou@sandia.gov)
// Jack Dongarra     (dongarra@eecs.utk.edu)
// Piotr Luszczek    (luszczek@eecs.utk.edu)
//
// ***************************************************
//@HEADER

#pragma once

#include "Geometry.hpp"
#include "LegionArrays.hpp"
#include "VectorOps.hpp"
#include "LegionMatrices.hpp"
#include "RegionToRegionCopy.hpp"

#include <cstdlib>

#if 0
#define LGNCG_DO_TASKY_EXCHANGE
#endif

#ifdef LGNCG_DO_TASKY_EXCHANGE
/**
 *
 */
struct ExchangeHaloArgs {
    int nTxNeighbors;
    int nRxNeighbors;
};

/*
 * PhaseBarriers debug: -level barrier=2 -logfile barriers.log
 */

/*!
    Communicates data that is at the border of the part of the domain assigned to
    this processor.

    @param[in]    A The known system matrix
    @param[inout] x On entry: the local vector entries followed by entries to be
    communicated; on exit: the vector with non-local entries updated by other
    processors
 */
inline void
ExchangeHalo(
    SparseMatrix &A,
    Array<floatType> &x,
    Context ctx,
    Runtime *lrt
) {
    // Extract Matrix pieces
    const SparseMatrixScalars *const Asclrs = A.sclrs->data();
    const int nTxNeighbors = Asclrs->numberOfSendNeighbors;
    const int nRxNeighbors = Asclrs->numberOfRecvNeighbors;
    const int *const neighbors = A.neighbors->data();
    // Nothing to do.
    if (nTxNeighbors == 0) return;
    // Make sure that x's ghosts are already setup.
    if (!x.hasGhosts()) {
        assert(false && "x does not have ghost regions setup.");
    }
    ExchangeHaloArgs args {
        .nTxNeighbors = nTxNeighbors,
        .nRxNeighbors = nRxNeighbors
    };
    TaskLauncher tl(
        EXCHANGE_HALO_TID,
        TaskArgument(&args, sizeof(args))
    );
    LogicalRegion xPrivateLR;
    {
        auto xis = x.logicalRegion.get_index_space();
        auto xip = lrt->get_index_partition(ctx, xis, 0 /* color */);
        auto xlp = lrt->get_logical_partition(ctx, x.logicalRegion, xip);
        xPrivateLR = lrt->get_logical_subregion_by_color(
            ctx,
            xlp,
            DomainPoint::from_point<1>(0) // First is private.
        );
    }
    // x (private partition).
    RegionRequirement xrr(
        xPrivateLR, RO_E, xPrivateLR
    );
    tl.add_region_requirement(xrr).add_field(x.fid);
    // Matrix pieces.
    A.neighbors->intent(RO_E, tl, ctx, lrt);
    A.elementsToSend->intent(RO_E, tl, ctx, lrt);
    A.sendLength->intent(RO_E, tl, ctx, lrt);
    A.synchronizers->intent(RW_E, tl, ctx, lrt);
    // Pull Buffers.
    for (int n = 0; n < nTxNeighbors; ++n) {
        A.pullBuffers[n]->intent(RW_E, tl, ctx, lrt);
    }
    // Pull regions in neighbor order.
    for (int n = 0; n < nRxNeighbors; ++n) {
        const int nid = neighbors[n];
        auto srcIt = A.nidToPullRegion.find(nid);
        assert(srcIt != A.nidToPullRegion.end());
        auto srclr = srcIt->second.get_logical_region();
        //
        RegionRequirement srcrr(
            srclr, RO_E, srclr
        );
        static const int fid = 0;
        tl.add_region_requirement(srcrr).add_field(fid);
    }
    for (int n = 0; n < nTxNeighbors; ++n) {
        LogicalArray<floatType> *dstArray = x.ghosts[n];
        assert(dstArray->hasParentLogicalRegion());
        RegionRequirement dstrr(
            dstArray->logicalRegion,
            WO_E,
            dstArray->getParentLogicalRegion()
        );
        tl.add_region_requirement(dstrr).add_field(dstArray->fid);
    }
    //
    lrt->execute_task(ctx, tl);
}

/**
 *
 */
void
ExchangeHaloTask(
    const Task *task,
    const std::vector<PhysicalRegion> &regions,
    Context ctx,
    Runtime *lrt
) {
    const auto *const args = (ExchangeHaloArgs *)task->args;
    const int nTxNeighbors = args->nTxNeighbors;
    const int nRxNeighbors = args->nRxNeighbors;
    int rid = 0;
    // x
    Array<floatType> x(regions[rid++], ctx, lrt);
    const floatType *const xv = x.data();
    assert(xv);
    // Matrix pieces.
    Array<int> Aneighbors(regions[rid++], ctx, lrt);
    const int *const neighbors = Aneighbors.data();
    assert(neighbors);
    //
    Array<local_int_t> AelementsToSend(regions[rid++], ctx, lrt);
    const local_int_t *const elementsToSend = AelementsToSend.data();
    assert(elementsToSend);
    //
    Array<local_int_t> AsendLength(regions[rid++], ctx, lrt);
    const local_int_t *const sendLengthsd = AsendLength.data();
    assert(sendLengthsd);
    //
    Array<Synchronizers> Asyncs(regions[rid++], ctx, lrt);
    Synchronizers *syncs = Asyncs.data();
    assert(syncs);
    PhaseBarriers &myPBs = syncs->mine;
    //
    std::vector<Array<floatType> *> ApullBuffers;
    for (int n = 0; n < nTxNeighbors; ++n) {
        auto *item = new Array<floatType>(regions[rid++], ctx, lrt);
        assert(item->data());
        ApullBuffers.push_back(item);
    }
    std::vector<LogicalRegion> srclrs;
    for (int n = 0; n < nRxNeighbors; ++n) {
        srclrs.push_back(regions[rid++].get_logical_region());
    }
    std::vector<LogicalRegion> dstlrs;
    for (int n = 0; n < nRxNeighbors; ++n) {
        dstlrs.push_back(regions[rid++].get_logical_region());
    }
    //
    myPBs.done.wait();
    myPBs.done = lrt->advance_phase_barrier(ctx, myPBs.done);
    // Fill up pull buffers (the buffers that neighboring task will pull from).
    for (int n = 0, txidx = 0; n < nTxNeighbors; ++n) {
        floatType *const pbd = ApullBuffers[n]->data();
        //
        for (int i = 0; i < sendLengthsd[n]; ++i) {
            pbd[i] = xv[elementsToSend[txidx++]];
        }
    }
    myPBs.ready.arrive(1);
    myPBs.ready = lrt->advance_phase_barrier(ctx, myPBs.ready);
    //
    for (int n = 0; n < nTxNeighbors; ++n) {
        static const int fid = 0;
        // Source region requirement.
        RegionRequirement srcrr(
            srclrs[n], RO_E, srclrs[n]
        );
        srcrr.add_field(fid);
        // Destination region requirement.
        //
        RegionRequirement dstrr(
            dstlrs[n], WO_E, dstlrs[n]
        );
        dstrr.add_field(fid);
        //
        TaskLauncher tl(
            REGION_TO_REGION_COPY_TID,
            TaskArgument(NULL, 0)
        );
        tl.add_region_requirement(srcrr);
        tl.add_region_requirement(dstrr);
        //
        syncs->neighbors[n].ready = lrt->advance_phase_barrier(
            ctx, syncs->neighbors[n].ready
        );
        tl.add_wait_barrier(syncs->neighbors[n].ready);
        //
        tl.add_arrival_barrier(syncs->neighbors[n].done);
        syncs->neighbors[n].done = lrt->advance_phase_barrier(
            ctx, syncs->neighbors[n].done
        );
        //
        lrt->execute_task(ctx, tl);
    }
    // Cleanup
    for (int n = 0; n < nTxNeighbors; ++n) {
        delete ApullBuffers[n];
    }
}
#endif

/**
 *
 */
inline void
registerExchangeHaloTasks(void)
{
#ifdef LGNCG_DO_TASKY_EXCHANGE
    HighLevelRuntime::register_legion_task<ExchangeHaloTask>(
        EXCHANGE_HALO_TID /* task id */,
        Processor::LOC_PROC /* proc kind  */,
        true /* single */,
        false /* index */,
        AUTO_GENERATE_ID,
        TaskConfigOptions(false /* leaf task */),
        "ExchangeHaloTask"
    );
#endif
}

#ifndef LGNCG_DO_TASKY_EXCHANGE
inline void
ExchangeHalo(
    SparseMatrix &A,
    Array<floatType> &x,
    Context ctx,
    Runtime *lrt
) {
    using namespace std;
    // Extract Matrix pieces
    const SparseMatrixScalars *const Asclrs = A.sclrs->data();
    const int nNeighbors = Asclrs->numberOfSendNeighbors;
    // Nothing to do.
    if (nNeighbors == 0) return;
    // Else we have neighbors and data to move around.
    const int *const neighbors = A.neighbors->data();
    // Non-region memory populated during SetupHalo().
    const local_int_t *const elementsToSend = A.elementsToSend->data();
    assert(elementsToSend);
    // Setup ghost regions if not already there.
    if (!x.hasGhosts()) {
        assert(false && "x does not have ghost regions setup.");
    }
    //
    const floatType *const xv = x.data();
    assert(xv);
    //
    Synchronizers *syncs = A.synchronizers->data();
    PhaseBarriers &myPBs = syncs->mine;
    //
    myPBs.done.wait();
    myPBs.done = lrt->advance_phase_barrier(ctx, myPBs.done);
    // Fill up pull buffers (the buffers that neighboring task will pull from).
    const local_int_t *const sendLengthsd = A.sendLength->data();
    assert(sendLengthsd);
    //
    for (int n = 0, txidx = 0; n < nNeighbors; ++n) {
        floatType *const pbd = A.pullBuffers[n]->data();
        assert(pbd);
        //
        for (int i = 0; i < sendLengthsd[n]; ++i) {
            pbd[i] = xv[elementsToSend[txidx++]];
        }
    }
    myPBs.ready.arrive(1);
    myPBs.ready = lrt->advance_phase_barrier(ctx, myPBs.ready);
    //
    for (int n = 0; n < nNeighbors; ++n) {
        //
        const int nid = neighbors[n];
        // Source
        auto srcIt = A.nidToPullRegion.find(nid);
        assert(srcIt != A.nidToPullRegion.end());
        auto srclr = srcIt->second.get_logical_region();
        //
        RegionRequirement srcrr(
            srclr, RO_E, srclr
        );
        // Only ever one field for all of our structures.
        static const int srcFid = 0;
        srcrr.add_field(srcFid);
        // Destination.
        LogicalArray<floatType> *dstArray = x.ghosts[n];
        assert(dstArray->hasParentLogicalRegion());
        //
        RegionRequirement dstrr(
            dstArray->logicalRegion,
            WO_E,
            dstArray->getParentLogicalRegion()
        );
        dstrr.add_field(dstArray->fid);
        //
        TaskLauncher tl(
            REGION_TO_REGION_COPY_TID,
            TaskArgument(NULL, 0)
        );
        tl.add_region_requirement(srcrr);
        tl.add_region_requirement(dstrr);
        //
        syncs->neighbors[n].ready = lrt->advance_phase_barrier(
            ctx, syncs->neighbors[n].ready
        );
        tl.add_wait_barrier(syncs->neighbors[n].ready);
        //
        tl.add_arrival_barrier(syncs->neighbors[n].done);
        syncs->neighbors[n].done = lrt->advance_phase_barrier(
            ctx, syncs->neighbors[n].done
        );
        //
        lrt->execute_task(ctx, tl);
    }
}
#endif
<commit_msg>use subtask for halo exchange with LGNCG_TASKING<commit_after>/**
 * Copyright (c) 2016-2017 Los Alamos National Security, LLC
 *                         All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions are met:
 *
 * 1. Redistributions of source code must retain the above copyright notice,
 * this list of conditions and the following disclaimer.
 *
 * 2. Redistributions in binary form must reproduce the above copyright notice,
 * this list of conditions and the following disclaimer in the documentation
 * and/or other materials provided with the distribution.
 *
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
 * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
 * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
 * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
 * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 *
 * LA-CC 10-123
 */

//@HEADER
// ***************************************************
//
// HPCG: High Performance Conjugate Gradient Benchmark
//
// Contact:
// Michael A. Heroux ( maherou@sandia.gov)
// Jack Dongarra     (dongarra@eecs.utk.edu)
// Piotr Luszczek    (luszczek@eecs.utk.edu)
//
// ***************************************************
//@HEADER

#pragma once

#include "Geometry.hpp"
#include "LegionArrays.hpp"
#include "VectorOps.hpp"
#include "LegionMatrices.hpp"
#include "RegionToRegionCopy.hpp"

#include <cstdlib>

#ifdef LGNCG_TASKING
#define LGNCG_DO_TASKY_EXCHANGE
#endif

#ifdef LGNCG_DO_TASKY_EXCHANGE
/**
 *
 */
struct ExchangeHaloArgs {
    int nTxNeighbors;
    int nRxNeighbors;
};

/*
 * PhaseBarriers debug: -level barrier=2 -logfile barriers.log
 */

/*!
    Communicates data that is at the border of the part of the domain assigned to
    this processor.

    @param[in]    A The known system matrix
    @param[inout] x On entry: the local vector entries followed by entries to be
    communicated; on exit: the vector with non-local entries updated by other
    processors
 */
inline void
ExchangeHalo(
    SparseMatrix &A,
    Array<floatType> &x,
    Context ctx,
    Runtime *lrt
) {
    // Extract Matrix pieces
    const SparseMatrixScalars *const Asclrs = A.sclrs->data();
    const int nTxNeighbors = Asclrs->numberOfSendNeighbors;
    const int nRxNeighbors = Asclrs->numberOfRecvNeighbors;
    const int *const neighbors = A.neighbors->data();
    // Nothing to do.
    if (nTxNeighbors == 0) return;
    // Make sure that x's ghosts are already setup.
    if (!x.hasGhosts()) {
        assert(false && "x does not have ghost regions setup.");
    }
    ExchangeHaloArgs args {
        .nTxNeighbors = nTxNeighbors,
        .nRxNeighbors = nRxNeighbors
    };
    TaskLauncher tl(
        EXCHANGE_HALO_TID,
        TaskArgument(&args, sizeof(args))
    );
    LogicalRegion xPrivateLR;
    {
        auto xis = x.logicalRegion.get_index_space();
        auto xip = lrt->get_index_partition(ctx, xis, 0 /* color */);
        auto xlp = lrt->get_logical_partition(ctx, x.logicalRegion, xip);
        xPrivateLR = lrt->get_logical_subregion_by_color(
            ctx,
            xlp,
            DomainPoint::from_point<1>(0) // First is private.
        );
    }
    // x (private partition).
    RegionRequirement xrr(
        xPrivateLR, RO_E, x.logicalRegion
    );
    tl.add_region_requirement(xrr).add_field(x.fid);
    // Matrix pieces.
    A.neighbors->intent(RO_E, tl, ctx, lrt);
    A.elementsToSend->intent(RO_E, tl, ctx, lrt);
    A.sendLength->intent(RO_E, tl, ctx, lrt);
    A.synchronizers->intent(RW_E, tl, ctx, lrt);
    // Pull Buffers.
    for (int n = 0; n < nTxNeighbors; ++n) {
        A.pullBuffers[n]->intent(RW_E, tl, ctx, lrt);
    }
    // Pull regions in neighbor order.
    for (int n = 0; n < nRxNeighbors; ++n) {
        const int nid = neighbors[n];
        auto srcIt = A.nidToPullRegion.find(nid);
        assert(srcIt != A.nidToPullRegion.end());
        auto srclr = srcIt->second.get_logical_region();
        //
        RegionRequirement srcrr(
            srclr, RO_E, srclr
        );
        static const int fid = 0;
        tl.add_region_requirement(srcrr).add_field(fid);
    }
    for (int n = 0; n < nTxNeighbors; ++n) {
        LogicalArray<floatType> *dstArray = x.ghosts[n];
        assert(dstArray->hasParentLogicalRegion());
        RegionRequirement dstrr(
            dstArray->logicalRegion,
            WO_E,
            dstArray->getParentLogicalRegion()
        );
        tl.add_region_requirement(dstrr).add_field(dstArray->fid);
    }
    //
    lrt->execute_task(ctx, tl);
}

/**
 *
 */
void
ExchangeHaloTask(
    const Task *task,
    const std::vector<PhysicalRegion> &regions,
    Context ctx,
    Runtime *lrt
) {
    const auto *const args = (ExchangeHaloArgs *)task->args;
    const int nTxNeighbors = args->nTxNeighbors;
    const int nRxNeighbors = args->nRxNeighbors;
    int rid = 0;
    // x
    Array<floatType> x(regions[rid++], ctx, lrt);
    const floatType *const xv = x.data();
    assert(xv);
    // Matrix pieces.
    Array<int> Aneighbors(regions[rid++], ctx, lrt);
    const int *const neighbors = Aneighbors.data();
    assert(neighbors);
    //
    Array<local_int_t> AelementsToSend(regions[rid++], ctx, lrt);
    const local_int_t *const elementsToSend = AelementsToSend.data();
    assert(elementsToSend);
    //
    Array<local_int_t> AsendLength(regions[rid++], ctx, lrt);
    const local_int_t *const sendLengthsd = AsendLength.data();
    assert(sendLengthsd);
    //
    Array<Synchronizers> Asyncs(regions[rid++], ctx, lrt);
    Synchronizers *syncs = Asyncs.data();
    assert(syncs);
    PhaseBarriers &myPBs = syncs->mine;
    //
    std::vector<Array<floatType> *> ApullBuffers;
    for (int n = 0; n < nTxNeighbors; ++n) {
        auto *item = new Array<floatType>(regions[rid++], ctx, lrt);
        assert(item->data());
        ApullBuffers.push_back(item);
    }
    std::vector<LogicalRegion> srclrs;
    for (int n = 0; n < nRxNeighbors; ++n) {
        srclrs.push_back(regions[rid++].get_logical_region());
    }
    std::vector<LogicalRegion> dstlrs;
    for (int n = 0; n < nRxNeighbors; ++n) {
        dstlrs.push_back(regions[rid++].get_logical_region());
    }
    //
    myPBs.done.wait();
    myPBs.done = lrt->advance_phase_barrier(ctx, myPBs.done);
    // Fill up pull buffers (the buffers that neighboring task will pull from).
    for (int n = 0, txidx = 0; n < nTxNeighbors; ++n) {
        floatType *const pbd = ApullBuffers[n]->data();
        //
        for (int i = 0; i < sendLengthsd[n]; ++i) {
            pbd[i] = xv[elementsToSend[txidx++]];
        }
    }
    myPBs.ready.arrive(1);
    myPBs.ready = lrt->advance_phase_barrier(ctx, myPBs.ready);
    lrt->unmap_all_regions(ctx);
    //
    for (int n = 0; n < nTxNeighbors; ++n) {
        static const int fid = 0;
        // Source region requirement.
        RegionRequirement srcrr(
            srclrs[n], RO_E, srclrs[n]
        );
        srcrr.add_field(fid);
        // Destination region requirement.
        //
        RegionRequirement dstrr(
            dstlrs[n], WO_E, dstlrs[n]
        );
        dstrr.add_field(fid);
        //
        TaskLauncher tl(
            REGION_TO_REGION_COPY_TID,
            TaskArgument(NULL, 0)
        );
        tl.add_region_requirement(srcrr);
        tl.add_region_requirement(dstrr);
        //
        syncs->neighbors[n].ready = lrt->advance_phase_barrier(
            ctx, syncs->neighbors[n].ready
        );
        tl.add_wait_barrier(syncs->neighbors[n].ready);
        //
        tl.add_arrival_barrier(syncs->neighbors[n].done);
        syncs->neighbors[n].done = lrt->advance_phase_barrier(
            ctx, syncs->neighbors[n].done
        );
        //
        lrt->execute_task(ctx, tl);
    }
    // Cleanup
    for (int n = 0; n < nTxNeighbors; ++n) {
        delete ApullBuffers[n];
    }
}
#endif

/**
 *
 */
inline void
registerExchangeHaloTasks(void)
{
#ifdef LGNCG_DO_TASKY_EXCHANGE
    HighLevelRuntime::register_legion_task<ExchangeHaloTask>(
        EXCHANGE_HALO_TID /* task id */,
        Processor::LOC_PROC /* proc kind  */,
        true /* single */,
        false /* index */,
        AUTO_GENERATE_ID,
        TaskConfigOptions(false /* leaf task */),
        "ExchangeHaloTask"
    );
#endif
}

#ifndef LGNCG_DO_TASKY_EXCHANGE
inline void
ExchangeHalo(
    SparseMatrix &A,
    Array<floatType> &x,
    Context ctx,
    Runtime *lrt
) {
    using namespace std;
    // Extract Matrix pieces
    const SparseMatrixScalars *const Asclrs = A.sclrs->data();
    const int nNeighbors = Asclrs->numberOfSendNeighbors;
    // Nothing to do.
    if (nNeighbors == 0) return;
    // Else we have neighbors and data to move around.
    const int *const neighbors = A.neighbors->data();
    // Non-region memory populated during SetupHalo().
    const local_int_t *const elementsToSend = A.elementsToSend->data();
    assert(elementsToSend);
    // Setup ghost regions if not already there.
    if (!x.hasGhosts()) {
        assert(false && "x does not have ghost regions setup.");
    }
    //
    const floatType *const xv = x.data();
    assert(xv);
    //
    Synchronizers *syncs = A.synchronizers->data();
    PhaseBarriers &myPBs = syncs->mine;
    //
    myPBs.done.wait();
    myPBs.done = lrt->advance_phase_barrier(ctx, myPBs.done);
    // Fill up pull buffers (the buffers that neighboring task will pull from).
    const local_int_t *const sendLengthsd = A.sendLength->data();
    assert(sendLengthsd);
    //
    for (int n = 0, txidx = 0; n < nNeighbors; ++n) {
        floatType *const pbd = A.pullBuffers[n]->data();
        assert(pbd);
        //
        for (int i = 0; i < sendLengthsd[n]; ++i) {
            pbd[i] = xv[elementsToSend[txidx++]];
        }
    }
    myPBs.ready.arrive(1);
    myPBs.ready = lrt->advance_phase_barrier(ctx, myPBs.ready);
    //
    for (int n = 0; n < nNeighbors; ++n) {
        //
        const int nid = neighbors[n];
        // Source
        auto srcIt = A.nidToPullRegion.find(nid);
        assert(srcIt != A.nidToPullRegion.end());
        auto srclr = srcIt->second.get_logical_region();
        //
        RegionRequirement srcrr(
            srclr, RO_E, srclr
        );
        // Only ever one field for all of our structures.
        static const int srcFid = 0;
        srcrr.add_field(srcFid);
        // Destination.
        LogicalArray<floatType> *dstArray = x.ghosts[n];
        assert(dstArray->hasParentLogicalRegion());
        //
        RegionRequirement dstrr(
            dstArray->logicalRegion,
            WO_E,
            dstArray->getParentLogicalRegion()
        );
        dstrr.add_field(dstArray->fid);
        //
        TaskLauncher tl(
            REGION_TO_REGION_COPY_TID,
            TaskArgument(NULL, 0)
        );
        tl.add_region_requirement(srcrr);
        tl.add_region_requirement(dstrr);
        //
        syncs->neighbors[n].ready = lrt->advance_phase_barrier(
            ctx, syncs->neighbors[n].ready
        );
        tl.add_wait_barrier(syncs->neighbors[n].ready);
        //
        tl.add_arrival_barrier(syncs->neighbors[n].done);
        syncs->neighbors[n].done = lrt->advance_phase_barrier(
            ctx, syncs->neighbors[n].done
        );
        //
        lrt->execute_task(ctx, tl);
    }
}
#endif
<|endoftext|>


<commit_before>// Copyright 2011, Tokyo Institute of Technology.
// All rights reserved.
//
// This file is distributed under the license described in
// LICENSE.txt.
//
// Author: Naoya Maruyama (naoya@matsulab.is.titech.ac.jp)

#include <boost/program_options.hpp>

#include "translator/config.h"
#include "translator/reference_translator.h"
//#if defined(CUDA_ENABLED)
#include "translator/cuda_translator.h"
//#endif
//#if defined(MPI_ENABLED)
#include "translator/mpi_translator.h"
//#endif
//#if defined(MPI_ENABLED) && defined(CUDA_ENABLED)
#include "translator/mpi_cuda_translator.h"
//#endif
#include "translator/translator_common.h"
#include "translator/translation_context.h"
#include "translator/translator.h"
#include "translator/configuration.h"

using std::string;
namespace bpo = boost::program_options;
namespace pt = physis::translator;
//namespace pu = physis::util;

namespace physis {
namespace translator {

struct CommandLineOptions {
  bool ref_trans;
  bool cuda_trans;
  bool mpi_trans;
  bool mpi_cuda_trans;
  std::pair<bool, string> config_file_path;
  CommandLineOptions(): ref_trans(false), cuda_trans(false),
                        mpi_trans(false), mpi_cuda_trans(false),
                        config_file_path(std::make_pair(false, "")) {}
};

void parseOptions(int argc, char *argv[], CommandLineOptions &opts,
                  vector<string> &rem) {
  // Declare the supported options.
  bpo::options_description desc("Allowed options");
  desc.add_options()("help", "produce help message");
  desc.add_options()("ref", "reference translation");

  desc.add_options()("config", bpo::value<string>(),
                     "read configuration file");

  //#ifdef CUDA_ENABLED
  desc.add_options()("cuda", "CUDA translation");
  //#endif
  //#ifdef MPI_ENABLED
  desc.add_options()("mpi", "MPI translation");
  //#endif
  //#if defined(MPI_ENABLED) && defined(CUDA_ENABLED)
  desc.add_options()("mpi-cuda", "MPI-CUDA translation");
  //#endif
  desc.add_options()("list-targets", "List available targets");

  bpo::variables_map vm;
  bpo::parsed_options parsed = bpo::command_line_parser(argc, argv).
      options(desc).allow_unregistered().
      style(bpo::command_line_style::default_style &
            ~bpo::command_line_style::allow_guessing).run();
  vector<string> unrec_opts = bpo::collect_unrecognized
      (parsed.options, bpo::include_positional);
  FOREACH (it, unrec_opts.begin(), unrec_opts.end()) {
    rem.push_back(*it);
  }
  bpo::store(parsed, vm);
  bpo::notify(vm);

  if (vm.count("help")) {
    std::cout << desc << "\n";
    exit(0);
  }

  if (vm.count("config")) {
    opts.config_file_path = make_pair(true, vm["config"].as<string>());
    LOG_DEBUG() << "Configuration file specified: "
                << opts.config_file_path.second << ".\n";
  }

  if (vm.count("ref")) {
    LOG_DEBUG() << "Reference translation.\n";
    opts.ref_trans = true;
    return;
  }

  //#ifdef CUDA_ENABLED
  if (vm.count("cuda")) {
    LOG_DEBUG() << "CUDA translation.\n";
    opts.cuda_trans = true;
    return;
  }
  //#endif
  //#ifdef MPI_ENABLED
  if (vm.count("mpi")) {
    LOG_DEBUG() << "MPI translation.\n";
    opts.mpi_trans = true;
    return;
  }
  //#endif

      //#if defined(MPI_ENABLED) && defined(CUDA_ENABLED)
  if (vm.count("mpi-cuda")) {
    LOG_DEBUG() << "MPI-CUDA translation.\n";
    opts.mpi_cuda_trans = true;
    return;
  }
  //#endif

  if (vm.count("list-targets")) {
    StringJoin sj(" ");
    sj << "ref";
    sj << "mpi";
    sj << "cuda";
    sj << "mpi-cuda";
    std::cout << sj << "\n";
    exit(0);
  }

  LOG_INFO() << "No translation target given.\n";
  std::cout << desc << "\n";
  exit(0);

  return;
}

string generate_output_filename(string srcname, string suffix) {
  return srcname.substr(0, srcname.rfind(".")) + "." + suffix;
}

// Set target-wise output file name
void set_output_filename(SgFile *file, string suffix) {
  string name = generate_output_filename(file->get_sourceFileNameWithoutPath(),
                                         suffix);
  file->set_unparse_output_filename(name);
  return;
}

} // namespace translator
} // namespace physis

int main(int argc, char *argv[]) {
  pt::Translator *trans = NULL;
  string filename_suffix;
  string extra_arg;
  pt::CommandLineOptions opts;
  std::vector<std::string> argvec;
  argvec.push_back(argv[0]);
  pt::parseOptions(argc, argv, opts, argvec);

  argvec.push_back("-DPHYSIS_USER");

  pt::Configuration config;
  if (opts.config_file_path.first) {
    config.LoadFile(opts.config_file_path.second);
  }

  if (opts.ref_trans) {
    trans = new pt::ReferenceTranslator(config);
    filename_suffix = "ref.c";
    argvec.push_back("-DPHYSIS_REF");
  }

  //#ifdef CUDA_ENABLED
  if (opts.cuda_trans) {
    trans = new pt::CUDATranslator(config);
    filename_suffix = "cuda.cu";
    argvec.push_back("-DPHYSIS_CUDA");
    //    argvec.push_back("-I" + string(CUDA_INCLUDE_DIR));
    //    argvec.push_back("-I" + string(CUDA_CUT_INCLUDE_DIR));
  }
  //#endif

  //#ifdef MPI_ENABLED
  if (opts.mpi_trans) {
    trans = new pt::MPITranslator(config);
    filename_suffix = "mpi.c";
    argvec.push_back("-DPHYSIS_MPI");
    //argvec.push_back("-I" + string(MPI_INCLUDE_DIR));
  }
  //#endif

      //#if defined(MPI_ENABLED) && defined(CUDA_ENABLED)
  if (opts.mpi_cuda_trans) {
    trans = new pt::MPICUDATranslator(config);
    filename_suffix = "mpi-cuda.cu";
    argvec.push_back("-DPHYSIS_MPI_CUDA");
    //argvec.push_back("-I" + string(MPI_INCLUDE_DIR));
    //argvec.push_back("-I" + string(CUDA_INCLUDE_DIR));
    //argvec.push_back("-I" + string(CUDA_CUT_INCLUDE_DIR));
  }
  //#endif

  if (trans == NULL) {
    LOG_INFO() << "No translation done.\n";
    exit(0);
  }

#if defined(PS_VERBOSE_DEBUG)
  physis::StringJoin sj;
  FOREACH (it, argvec.begin(), argvec.end()) {
    sj << *it;
  }
  LOG_DEBUG() << "Rose command line: " << sj << "\n";
#endif

  // Build the AST used by ROSE
  SgProject* proj = frontend(argvec);
  proj->skipfinalCompileStep(true);

  LOG_INFO() << "AST generation done\n";

  if (proj->numberOfFiles() == 0) {
    LOG_INFO() << "No input source\n";
    exit(0);
  }

  // Run internal consistency tests on AST
  // AstTests::runAllTests(proj);

  pt::TranslationContext tx(proj);

  trans->SetUp(proj, &tx);
  LOG_DEBUG() << "Translating the AST\n";
  trans->Translate();
  // TODO: optimization is disabled
  //trans->Optimize();
  LOG_DEBUG() << "Translation done\n";
  trans->Finish();

  pt::set_output_filename(proj->get_fileList()[0], filename_suffix);

  int b = backend(proj);
  LOG_INFO() << "Code generation complete.\n";
  return b;
}
<commit_msg>[REFACTORING] Remove obsolete comment lines<commit_after>// Copyright 2011, Tokyo Institute of Technology.
// All rights reserved.
//
// This file is distributed under the license described in
// LICENSE.txt.
//
// Author: Naoya Maruyama (naoya@matsulab.is.titech.ac.jp)

#include <boost/program_options.hpp>

#include "translator/config.h"
#include "translator/reference_translator.h"
#include "translator/cuda_translator.h"
#include "translator/mpi_translator.h"
#include "translator/mpi_cuda_translator.h"
#include "translator/translator_common.h"
#include "translator/translation_context.h"
#include "translator/translator.h"
#include "translator/configuration.h"

using std::string;
namespace bpo = boost::program_options;
namespace pt = physis::translator;

namespace physis {
namespace translator {

struct CommandLineOptions {
  bool ref_trans;
  bool cuda_trans;
  bool mpi_trans;
  bool mpi_cuda_trans;
  std::pair<bool, string> config_file_path;
  CommandLineOptions(): ref_trans(false), cuda_trans(false),
                        mpi_trans(false), mpi_cuda_trans(false),
                        config_file_path(std::make_pair(false, "")) {}
};

void parseOptions(int argc, char *argv[], CommandLineOptions &opts,
                  vector<string> &rem) {
  // Declare the supported options.
  bpo::options_description desc("Allowed options");
  desc.add_options()("help", "produce help message");
  desc.add_options()("ref", "reference translation");
  desc.add_options()("config", bpo::value<string>(),
                     "read configuration file");
  desc.add_options()("cuda", "CUDA translation");
  desc.add_options()("mpi", "MPI translation");
  desc.add_options()("mpi-cuda", "MPI-CUDA translation");
  desc.add_options()("list-targets", "List available targets");

  bpo::variables_map vm;
  bpo::parsed_options parsed = bpo::command_line_parser(argc, argv).
      options(desc).allow_unregistered().
      style(bpo::command_line_style::default_style &
            ~bpo::command_line_style::allow_guessing).run();
  vector<string> unrec_opts = bpo::collect_unrecognized
      (parsed.options, bpo::include_positional);
  FOREACH (it, unrec_opts.begin(), unrec_opts.end()) {
    rem.push_back(*it);
  }
  bpo::store(parsed, vm);
  bpo::notify(vm);

  if (vm.count("help")) {
    std::cout << desc << "\n";
    exit(0);
  }

  if (vm.count("config")) {
    opts.config_file_path = make_pair(true, vm["config"].as<string>());
    LOG_DEBUG() << "Configuration file specified: "
                << opts.config_file_path.second << ".\n";
  }

  if (vm.count("ref")) {
    LOG_DEBUG() << "Reference translation.\n";
    opts.ref_trans = true;
    return;
  }

  if (vm.count("cuda")) {
    LOG_DEBUG() << "CUDA translation.\n";
    opts.cuda_trans = true;
    return;
  }

  if (vm.count("mpi")) {
    LOG_DEBUG() << "MPI translation.\n";
    opts.mpi_trans = true;
    return;
  }

  if (vm.count("mpi-cuda")) {
    LOG_DEBUG() << "MPI-CUDA translation.\n";
    opts.mpi_cuda_trans = true;
    return;
  }

  if (vm.count("list-targets")) {
    StringJoin sj(" ");
    sj << "ref";
    sj << "mpi";
    sj << "cuda";
    sj << "mpi-cuda";
    std::cout << sj << "\n";
    exit(0);
  }

  LOG_INFO() << "No translation target given.\n";
  std::cout << desc << "\n";
  exit(0);

  return;
}

string generate_output_filename(string srcname, string suffix) {
  return srcname.substr(0, srcname.rfind(".")) + "." + suffix;
}

// Set target-wise output file name
void set_output_filename(SgFile *file, string suffix) {
  string name = generate_output_filename(file->get_sourceFileNameWithoutPath(),
                                         suffix);
  file->set_unparse_output_filename(name);
  return;
}

} // namespace translator
} // namespace physis

int main(int argc, char *argv[]) {
  pt::Translator *trans = NULL;
  string filename_suffix;
  string extra_arg;
  pt::CommandLineOptions opts;
  std::vector<std::string> argvec;
  argvec.push_back(argv[0]);
  pt::parseOptions(argc, argv, opts, argvec);

  argvec.push_back("-DPHYSIS_USER");

  pt::Configuration config;
  if (opts.config_file_path.first) {
    config.LoadFile(opts.config_file_path.second);
  }

  if (opts.ref_trans) {
    trans = new pt::ReferenceTranslator(config);
    filename_suffix = "ref.c";
    argvec.push_back("-DPHYSIS_REF");
  }

  if (opts.cuda_trans) {
    trans = new pt::CUDATranslator(config);
    filename_suffix = "cuda.cu";
    argvec.push_back("-DPHYSIS_CUDA");
  }

  if (opts.mpi_trans) {
    trans = new pt::MPITranslator(config);
    filename_suffix = "mpi.c";
    argvec.push_back("-DPHYSIS_MPI");
  }

  if (opts.mpi_cuda_trans) {
    trans = new pt::MPICUDATranslator(config);
    filename_suffix = "mpi-cuda.cu";
    argvec.push_back("-DPHYSIS_MPI_CUDA");
  }

  if (trans == NULL) {
    LOG_INFO() << "No translation done.\n";
    exit(0);
  }

#if defined(PS_VERBOSE_DEBUG)
  physis::StringJoin sj;
  FOREACH (it, argvec.begin(), argvec.end()) {
    sj << *it;
  }
  LOG_DEBUG() << "Rose command line: " << sj << "\n";
#endif

  // Build the AST used by ROSE
  SgProject* proj = frontend(argvec);
  proj->skipfinalCompileStep(true);

  LOG_INFO() << "AST generation done\n";

  if (proj->numberOfFiles() == 0) {
    LOG_INFO() << "No input source\n";
    exit(0);
  }

  // Run internal consistency tests on AST
  // AstTests::runAllTests(proj);

  pt::TranslationContext tx(proj);

  trans->SetUp(proj, &tx);
  LOG_DEBUG() << "Translating the AST\n";
  trans->Translate();
  // TODO: optimization is disabled
  //trans->Optimize();
  LOG_DEBUG() << "Translation done\n";
  trans->Finish();

  pt::set_output_filename(proj->get_fileList()[0], filename_suffix);

  int b = backend(proj);
  LOG_INFO() << "Code generation complete.\n";
  return b;
}
<|endoftext|>


<commit_before>/*******************************************************************************
 * Copyright (c) 2012, Dougal J. Sutherland (dsutherl@cs.cmu.edu).             *
 * All rights reserved.                                                        *
 *                                                                             *
 * Redistribution and use in source and binary forms, with or without          *
 * modification, are permitted provided that the following conditions are met: *
 *                                                                             *
 *     * Redistributions of source code must retain the above copyright        *
 *       notice, this list of conditions and the following disclaimer.         *
 *                                                                             *
 *     * Redistributions in binary form must reproduce the above copyright     *
 *       notice, this list of conditions and the following disclaimer in the   *
 *       documentation and/or other materials provided with the distribution.  *
 *                                                                             *
 *     * Neither the name of Carnegie Mellon University nor the                *
 *       names of the contributors may be used to endorse or promote products  *
 *       derived from this software without specific prior written permission. *
 *                                                                             *
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" *
 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE   *
 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE  *
 * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE   *
 * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR         *
 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF        *
 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS    *
 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN     *
 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)     *
 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE  *
 * POSSIBILITY OF SUCH DAMAGE.                                                 *
 ******************************************************************************/
#include "sdm/basics.hpp"

#include <algorithm>
#include <cmath>
#include <stdexcept>
#include <boost/format.hpp>

#include "sdm/kernel_projection.hpp"

using boost::format;

namespace sdm {

////////////////////////////////////////////////////////////////////////////////
// General matrix math helpers

// symmetrize a matrix: m = (m + m') / 2
void symmetrize(double* matrix, size_t n) {
    // loop over half of matrix
    for (size_t i = 1; i < n; i++) {
        for (size_t j = 0; j < i; j++) {
            matrix[i + j*n] = matrix[j + i*n] =
                (matrix[i + j*n] + matrix[j + i*n]) / 2.;
        }
    }
}

////////////////////////////////////////////////////////////////////////////////
// Eigenvalues / eigenvectors helpers

// LAPACK: computes the eigenvalues/vectors of a square symmetric dense matrix
extern "C" void dsyev_(char *jobz, char *uplo, int *n, double *a,
        int *lda, double *w, double *work, int *lwork, int *info);

/* Takes an n x n symmetric matrix and computes its eigendecomposition.
 *
 * Eigenvalues go in the n-element arre vals (in ascending order).
 *
 * Orthonormal eigenvectors go in the columns of the n^2-element array vecs,
 * in column-major order.
 *
 * jobz determines whether eigenvalues are actually calculated, but use the
 * overload below if you don't want them.
 *
 * Throws std::domain_error if dsyev fails.
 */
void eig(double* matrix, int n, double* vals, double* vecs, char jobz='V') {
    char uplo = 'U'; // indicate that upper-triangular part of matrix is present
    int info; // indicates whether the call was successful
    int lwork = 3*n - 1; // size of the work array
    double *work = new double[lwork]; // the work array

    // copy matrix into vecs, since dsyev_ is in-place
    std::copy(matrix, matrix + n*n, vecs);

    dsyev_(&jobz, &uplo, &n, vecs, &n, vals, work, &lwork, &info);

    delete[] work;

    if (info < 0) {
        throw std::domain_error(
            (format("problem with dsyev argument %d") % (-info)).str());
    } else if (info > 0) {
        throw std::domain_error("dsyev: failed to converge");
    }
}

/* Takes an n x n symmetric matrix and stores its eigenvalues in the n-element
 * array vals, in ascending order.
 */
void eig(double* matrix, size_t n, double* vals) {
    double* vecs = new double[n*n]; // allocate memory for dsyev to destroy
    eig(matrix, n, vals, vecs, 'N');
    delete[] vecs;
}

////////////////////////////////////////////////////////////////////////////////
// Spectral reconstruction

// BLAS: scales a vector by a constant
extern "C" void dscal_(int *n, double *alpha, double *x, int *incx);

// BLAS: computes generalized matrix product  C := alpha * A * B + beta * C
extern "C" void dgemm_(char *transa, char *transb,
       int *m, int *n, int *k,
       double *alpha, double *a, int *lda, void *b, int *ldb,
       double *beta, void *c, int *ldc);

/* Given an array of eigenvalues and corresponding orthonormal eigenvectors
 * (in column-major format), calculates the reconstructed matrix, optionally
 * throwing away any negative eigenvalues (which projects to the nearest
 * positive semidefinite matrix).
 */
void spectral_reconstruction(int n, double *eigvals, double *eigvecs,
        double *matrix, bool nonnegative_only = false)
{
    // We're calculating  V * max(diag(D), 0) * V'

    int step = 1;

    // First do the left-hand side: V * max(dig(D), 0)
    // Need to scale each column of V by the corresponding eigenvector
    double *leftside = new double[n * n];
    std::copy(eigvecs, eigvecs + n*n, leftside);

    for (size_t j = 0; j < n; j++) {
        double v = eigvals[j];
        if (nonnegative_only && v < 0)
            v = 0.;

        dscal_(&n, &v, eigvecs + j*n, &step);
    }

    // Now do (V * max(diag(D), 0)) * V'
    char no = 'N';
    char trans = 'T';
    double one = 1.;
    double zero = 0.;
    int size = (int) n;
    dgemm_(&no, &trans, &size, &size, &size,
            &one, leftside, &size, eigvecs, &size,
            &zero, matrix, &size);

    delete[] leftside;
}

////////////////////////////////////////////////////////////////////////////////

/* Takes an n x n matrix stored as a flat array, symmetrizes it, and projects
 * in-place to the nearest positive semidefinite matrix.
 */
void project_to_symmetric_psd(double* matrix, size_t n) {
    double* eigvals = new double[n];
    double* eigvecs = new double[n*n];

    symmetrize(matrix, n);

    try {
        eig(matrix, n, eigvals, eigvecs);

        // are any of our eigenvalues actually negative?
        // (note that we get the values back in ascending order)
        if (eigvals[0] < 0) {
            spectral_reconstruction(n, eigvals, eigvecs, matrix, true);
            symmetrize(matrix, n);
        }

    } catch (...) { delete[] eigvals; delete[] eigvecs; throw; }
    delete[] eigvals; delete[] eigvecs;
}

/* Takes an n x n matrix, stored as a flat array, symmetrizes it, and projects
 * it in-place to the nearest positive semidefinite matrix with unit diagonal.
 */
void project_to_covariance(double* matrix, size_t n, size_t steps, double tol) {
    // The alternating projection method (algorithm 3.3) of
    //   Nicholas J. Higham, 2002.
    //   Computing the Nearest Correlation Matrix: a Problem from Finance.
    //   IMA Journal of Numerical Analysis, pages 329-343.

    double* eigvals = new double[n];
    double* eigvecs = new double[n*n];

    // Dykstra's correction
    double *S = new double[n*n];
    std::fill(S, S+n*n, 0);

    // R is the corrected form of matrix
    double *R = new double[n*n];

    // X is projected to be symmetric PSD
    double *X = new double[n*n];
    std::copy(matrix, matrix + n*n, X);

    // used to check for x's convergence
    double *prev_X = new double[n*n];

    try {
        symmetrize(matrix, n);

        for (size_t iter = 0; iter < steps; iter++) {
            // remember the previous x
            std::copy(X, X + n*n, prev_X);

            // R is the matrix minus the correction
            for (size_t i = 0; i < n*n; i++)
                R[i] = matrix[i] - S[i];

            // X is projection of R to symmetric PSD matrix
            eig(R, n, eigvals, eigvecs);
            spectral_reconstruction(n, eigvals, eigvecs, X, true);
            symmetrize(X, n);

            // new correction is the difference between X and R
            for (size_t i = 0; i < n*n; i++)
                S[i] = X[i] - R[i];

            // new matrix is X with unit diagonal
            std::copy(X, X + n*n, matrix);
            for (size_t i = 0; i < n; i++)
                matrix[i + i*n] = 1.;

            // have we converged?
            if (iter > 0) {
                double biggest_x = 0;
                double biggest_change = 0;
                for (size_t i = 0; i < n*n; i++) {
                    double mag = std::abs(X[i]);
                    if (mag > biggest_x)
                        biggest_x = mag;

                    double change = std::abs(X[i] - prev_X[i]);
                    if (change > biggest_change)
                        biggest_change = change;
                }

                if (biggest_change <= 1e-7 * biggest_x) {
                    break;
                }
            }
        }

        // make sure we don't have any too-negative eigenvalues
        eig(matrix, n, eigvals);
        if (eigvals[0] < tol) {
            throw std::domain_error(
                    (format("Failed to project to kernel matrix: min eig %g")
                     % eigvals[0]).str());
        }

    } catch (...) { // fake a finally block
        delete[] eigvals; delete[] eigvecs;
        delete[] S; delete[] R;
        delete[] X; delete[] prev_X;
        throw;
    }
    delete[] eigvals; delete[] eigvecs;
    delete[] S; delete[] R;
    delete[] X; delete[] prev_X;
}

} // end namespace
<commit_msg>add TODO<commit_after>/*******************************************************************************
 * Copyright (c) 2012, Dougal J. Sutherland (dsutherl@cs.cmu.edu).             *
 * All rights reserved.                                                        *
 *                                                                             *
 * Redistribution and use in source and binary forms, with or without          *
 * modification, are permitted provided that the following conditions are met: *
 *                                                                             *
 *     * Redistributions of source code must retain the above copyright        *
 *       notice, this list of conditions and the following disclaimer.         *
 *                                                                             *
 *     * Redistributions in binary form must reproduce the above copyright     *
 *       notice, this list of conditions and the following disclaimer in the   *
 *       documentation and/or other materials provided with the distribution.  *
 *                                                                             *
 *     * Neither the name of Carnegie Mellon University nor the                *
 *       names of the contributors may be used to endorse or promote products  *
 *       derived from this software without specific prior written permission. *
 *                                                                             *
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" *
 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE   *
 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE  *
 * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE   *
 * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR         *
 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF        *
 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS    *
 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN     *
 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)     *
 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE  *
 * POSSIBILITY OF SUCH DAMAGE.                                                 *
 ******************************************************************************/
#include "sdm/basics.hpp"

#include <algorithm>
#include <cmath>
#include <stdexcept>
#include <boost/format.hpp>

#include "sdm/kernel_projection.hpp"

using boost::format;

namespace sdm {

////////////////////////////////////////////////////////////////////////////////
// General matrix math helpers

// symmetrize a matrix: m = (m + m') / 2
void symmetrize(double* matrix, size_t n) {
    // loop over half of matrix
    for (size_t i = 1; i < n; i++) {
        for (size_t j = 0; j < i; j++) {
            matrix[i + j*n] = matrix[j + i*n] =
                (matrix[i + j*n] + matrix[j + i*n]) / 2.;
        }
    }
}

////////////////////////////////////////////////////////////////////////////////
// Eigenvalues / eigenvectors helpers

// LAPACK: computes the eigenvalues/vectors of a square symmetric dense matrix
extern "C" void dsyev_(char *jobz, char *uplo, int *n, double *a,
        int *lda, double *w, double *work, int *lwork, int *info);
// FIXME: figure out how to support ILP64 lapacks, so that matlab interface
//  works on linux without LD_PRELOAD

/* Takes an n x n symmetric matrix and computes its eigendecomposition.
 *
 * Eigenvalues go in the n-element arre vals (in ascending order).
 *
 * Orthonormal eigenvectors go in the columns of the n^2-element array vecs,
 * in column-major order.
 *
 * jobz determines whether eigenvalues are actually calculated, but use the
 * overload below if you don't want them.
 *
 * Throws std::domain_error if dsyev fails.
 */
void eig(double* matrix, int n, double* vals, double* vecs, char jobz='V') {
    char uplo = 'U'; // indicate that upper-triangular part of matrix is present
    int info; // indicates whether the call was successful
    int lwork = 3*n - 1; // size of the work array
    double *work = new double[lwork]; // the work array

    // copy matrix into vecs, since dsyev_ is in-place
    std::copy(matrix, matrix + n*n, vecs);

    dsyev_(&jobz, &uplo, &n, vecs, &n, vals, work, &lwork, &info);

    delete[] work;

    if (info < 0) {
        throw std::domain_error(
            (format("problem with dsyev argument %d") % (-info)).str());
    } else if (info > 0) {
        throw std::domain_error("dsyev: failed to converge");
    }
}

/* Takes an n x n symmetric matrix and stores its eigenvalues in the n-element
 * array vals, in ascending order.
 */
void eig(double* matrix, size_t n, double* vals) {
    double* vecs = new double[n*n]; // allocate memory for dsyev to destroy
    eig(matrix, n, vals, vecs, 'N');
    delete[] vecs;
}

////////////////////////////////////////////////////////////////////////////////
// Spectral reconstruction

// BLAS: scales a vector by a constant
extern "C" void dscal_(int *n, double *alpha, double *x, int *incx);

// BLAS: computes generalized matrix product  C := alpha * A * B + beta * C
extern "C" void dgemm_(char *transa, char *transb,
       int *m, int *n, int *k,
       double *alpha, double *a, int *lda, void *b, int *ldb,
       double *beta, void *c, int *ldc);

/* Given an array of eigenvalues and corresponding orthonormal eigenvectors
 * (in column-major format), calculates the reconstructed matrix, optionally
 * throwing away any negative eigenvalues (which projects to the nearest
 * positive semidefinite matrix).
 */
void spectral_reconstruction(int n, double *eigvals, double *eigvecs,
        double *matrix, bool nonnegative_only = false)
{
    // We're calculating  V * max(diag(D), 0) * V'

    int step = 1;

    // First do the left-hand side: V * max(dig(D), 0)
    // Need to scale each column of V by the corresponding eigenvector
    double *leftside = new double[n * n];
    std::copy(eigvecs, eigvecs + n*n, leftside);

    for (size_t j = 0; j < n; j++) {
        double v = eigvals[j];
        if (nonnegative_only && v < 0)
            v = 0.;

        dscal_(&n, &v, eigvecs + j*n, &step);
    }

    // Now do (V * max(diag(D), 0)) * V'
    char no = 'N';
    char trans = 'T';
    double one = 1.;
    double zero = 0.;
    int size = (int) n;
    dgemm_(&no, &trans, &size, &size, &size,
            &one, leftside, &size, eigvecs, &size,
            &zero, matrix, &size);

    delete[] leftside;
}

////////////////////////////////////////////////////////////////////////////////

/* Takes an n x n matrix stored as a flat array, symmetrizes it, and projects
 * in-place to the nearest positive semidefinite matrix.
 */
void project_to_symmetric_psd(double* matrix, size_t n) {
    double* eigvals = new double[n];
    double* eigvecs = new double[n*n];

    symmetrize(matrix, n);

    try {
        eig(matrix, n, eigvals, eigvecs);

        // are any of our eigenvalues actually negative?
        // (note that we get the values back in ascending order)
        if (eigvals[0] < 0) {
            spectral_reconstruction(n, eigvals, eigvecs, matrix, true);
            symmetrize(matrix, n);
        }

    } catch (...) { delete[] eigvals; delete[] eigvecs; throw; }
    delete[] eigvals; delete[] eigvecs;
}

/* Takes an n x n matrix, stored as a flat array, symmetrizes it, and projects
 * it in-place to the nearest positive semidefinite matrix with unit diagonal.
 */
void project_to_covariance(double* matrix, size_t n, size_t steps, double tol) {
    // The alternating projection method (algorithm 3.3) of
    //   Nicholas J. Higham, 2002.
    //   Computing the Nearest Correlation Matrix: a Problem from Finance.
    //   IMA Journal of Numerical Analysis, pages 329-343.

    double* eigvals = new double[n];
    double* eigvecs = new double[n*n];

    // Dykstra's correction
    double *S = new double[n*n];
    std::fill(S, S+n*n, 0);

    // R is the corrected form of matrix
    double *R = new double[n*n];

    // X is projected to be symmetric PSD
    double *X = new double[n*n];
    std::copy(matrix, matrix + n*n, X);

    // used to check for x's convergence
    double *prev_X = new double[n*n];

    try {
        symmetrize(matrix, n);

        for (size_t iter = 0; iter < steps; iter++) {
            // remember the previous x
            std::copy(X, X + n*n, prev_X);

            // R is the matrix minus the correction
            for (size_t i = 0; i < n*n; i++)
                R[i] = matrix[i] - S[i];

            // X is projection of R to symmetric PSD matrix
            eig(R, n, eigvals, eigvecs);
            spectral_reconstruction(n, eigvals, eigvecs, X, true);
            symmetrize(X, n);

            // new correction is the difference between X and R
            for (size_t i = 0; i < n*n; i++)
                S[i] = X[i] - R[i];

            // new matrix is X with unit diagonal
            std::copy(X, X + n*n, matrix);
            for (size_t i = 0; i < n; i++)
                matrix[i + i*n] = 1.;

            // have we converged?
            if (iter > 0) {
                double biggest_x = 0;
                double biggest_change = 0;
                for (size_t i = 0; i < n*n; i++) {
                    double mag = std::abs(X[i]);
                    if (mag > biggest_x)
                        biggest_x = mag;

                    double change = std::abs(X[i] - prev_X[i]);
                    if (change > biggest_change)
                        biggest_change = change;
                }

                if (biggest_change <= 1e-7 * biggest_x) {
                    break;
                }
            }
        }

        // make sure we don't have any too-negative eigenvalues
        eig(matrix, n, eigvals);
        if (eigvals[0] < tol) {
            throw std::domain_error(
                    (format("Failed to project to kernel matrix: min eig %g")
                     % eigvals[0]).str());
        }

    } catch (...) { // fake a finally block
        delete[] eigvals; delete[] eigvecs;
        delete[] S; delete[] R;
        delete[] X; delete[] prev_X;
        throw;
    }
    delete[] eigvals; delete[] eigvecs;
    delete[] S; delete[] R;
    delete[] X; delete[] prev_X;
}

} // end namespace
<|endoftext|>


<commit_before>#include "selfdrive/ui/qt/window.h"

#include <QFontDatabase>

#include "selfdrive/hardware/hw.h"

MainWindow::MainWindow(QWidget *parent) : QWidget(parent) {
  main_layout = new QStackedLayout(this);
  main_layout->setMargin(0);

  homeWindow = new HomeWindow(this);
  main_layout->addWidget(homeWindow);
  QObject::connect(homeWindow, &HomeWindow::openSettings, this, &MainWindow::openSettings);
  QObject::connect(homeWindow, &HomeWindow::closeSettings, this, &MainWindow::closeSettings);
  QObject::connect(&qs, &QUIState::uiUpdate, homeWindow, &HomeWindow::update);
  QObject::connect(&qs, &QUIState::offroadTransition, homeWindow, &HomeWindow::offroadTransition);
  QObject::connect(&qs, &QUIState::offroadTransition, homeWindow, &HomeWindow::offroadTransitionSignal);
  QObject::connect(&device, &Device::displayPowerChanged, homeWindow, &HomeWindow::displayPowerChanged);

  settingsWindow = new SettingsWindow(this);
  main_layout->addWidget(settingsWindow);
  QObject::connect(settingsWindow, &SettingsWindow::closeSettings, this, &MainWindow::closeSettings);
  QObject::connect(&qs, &QUIState::offroadTransition, settingsWindow, &SettingsWindow::offroadTransition);
  QObject::connect(settingsWindow, &SettingsWindow::reviewTrainingGuide, [=]() {
    onboardingWindow->showTrainingGuide();
    main_layout->setCurrentWidget(onboardingWindow);
  });
  QObject::connect(settingsWindow, &SettingsWindow::showDriverView, [=] {
    homeWindow->showDriverView(true);
  });

  onboardingWindow = new OnboardingWindow(this);
  main_layout->addWidget(onboardingWindow);
  QObject::connect(onboardingWindow, &OnboardingWindow::onboardingDone, [=]() {
    main_layout->setCurrentWidget(homeWindow);
  });
  if (!onboardingWindow->completed()) {
    main_layout->setCurrentWidget(onboardingWindow);
  }

  device.setAwake(true, true);
  QObject::connect(&qs, &QUIState::uiUpdate, &device, &Device::update);
  QObject::connect(&qs, &QUIState::offroadTransition, [=](bool offroad) {
    if (!offroad) {
      closeSettings();
    }
  });
  QObject::connect(&device, &Device::displayPowerChanged, [=]() {
     if(main_layout->currentWidget() != onboardingWindow) {
       closeSettings();
     }
  });

  // load fonts
  QFontDatabase::addApplicationFont("../assets/fonts/opensans_regular.ttf");
  QFontDatabase::addApplicationFont("../assets/fonts/opensans_bold.ttf");
  QFontDatabase::addApplicationFont("../assets/fonts/Inter-Black.ttf");
  QFontDatabase::addApplicationFont("../assets/fonts/Inter-Bold.ttf");
  QFontDatabase::addApplicationFont("../assets/fonts/Inter-ExtraBold.ttf");
  QFontDatabase::addApplicationFont("../assets/fonts/Inter-ExtraLight.ttf");
  QFontDatabase::addApplicationFont("../assets/fonts/Inter-Medium.ttf");
  QFontDatabase::addApplicationFont("../assets/fonts/Inter-Regular.ttf");
  QFontDatabase::addApplicationFont("../assets/fonts/Inter-SemiBold.ttf");
  QFontDatabase::addApplicationFont("../assets/fonts/Inter-Thin.ttf");

  // no outline to prevent the focus rectangle
  setStyleSheet(R"(
    * {
      font-family: Inter;
      outline: none;
    }
  )");
  setAttribute(Qt::WA_NoSystemBackground);
}

void MainWindow::openSettings() {
  main_layout->setCurrentWidget(settingsWindow);
}

void MainWindow::closeSettings() {
  main_layout->setCurrentWidget(homeWindow);

  if (QUIState::ui_state.scene.started) {
    emit homeWindow->showSidebar(false);
  }
}

bool MainWindow::eventFilter(QObject *obj, QEvent *event) {
  // wake screen on tap
  if (event->type() == QEvent::MouseButtonPress || event->type() == QEvent::TouchBegin) {
    device.setAwake(true, true);
  }

#ifdef QCOM
  // filter out touches while in android activity
  const static QSet<QEvent::Type> filter_events({QEvent::MouseButtonPress, QEvent::MouseMove, QEvent::TouchBegin, QEvent::TouchUpdate, QEvent::TouchEnd});
  if (HardwareEon::launched_activity && filter_events.contains(event->type())) {
    HardwareEon::check_activity();
    if (HardwareEon::launched_activity) {
      return true;
    }
  }
#endif
  return false;
}
<commit_msg>UI: add opensans semibold<commit_after>#include "selfdrive/ui/qt/window.h"

#include <QFontDatabase>

#include "selfdrive/hardware/hw.h"

MainWindow::MainWindow(QWidget *parent) : QWidget(parent) {
  main_layout = new QStackedLayout(this);
  main_layout->setMargin(0);

  homeWindow = new HomeWindow(this);
  main_layout->addWidget(homeWindow);
  QObject::connect(homeWindow, &HomeWindow::openSettings, this, &MainWindow::openSettings);
  QObject::connect(homeWindow, &HomeWindow::closeSettings, this, &MainWindow::closeSettings);
  QObject::connect(&qs, &QUIState::uiUpdate, homeWindow, &HomeWindow::update);
  QObject::connect(&qs, &QUIState::offroadTransition, homeWindow, &HomeWindow::offroadTransition);
  QObject::connect(&qs, &QUIState::offroadTransition, homeWindow, &HomeWindow::offroadTransitionSignal);
  QObject::connect(&device, &Device::displayPowerChanged, homeWindow, &HomeWindow::displayPowerChanged);

  settingsWindow = new SettingsWindow(this);
  main_layout->addWidget(settingsWindow);
  QObject::connect(settingsWindow, &SettingsWindow::closeSettings, this, &MainWindow::closeSettings);
  QObject::connect(&qs, &QUIState::offroadTransition, settingsWindow, &SettingsWindow::offroadTransition);
  QObject::connect(settingsWindow, &SettingsWindow::reviewTrainingGuide, [=]() {
    onboardingWindow->showTrainingGuide();
    main_layout->setCurrentWidget(onboardingWindow);
  });
  QObject::connect(settingsWindow, &SettingsWindow::showDriverView, [=] {
    homeWindow->showDriverView(true);
  });

  onboardingWindow = new OnboardingWindow(this);
  main_layout->addWidget(onboardingWindow);
  QObject::connect(onboardingWindow, &OnboardingWindow::onboardingDone, [=]() {
    main_layout->setCurrentWidget(homeWindow);
  });
  if (!onboardingWindow->completed()) {
    main_layout->setCurrentWidget(onboardingWindow);
  }

  device.setAwake(true, true);
  QObject::connect(&qs, &QUIState::uiUpdate, &device, &Device::update);
  QObject::connect(&qs, &QUIState::offroadTransition, [=](bool offroad) {
    if (!offroad) {
      closeSettings();
    }
  });
  QObject::connect(&device, &Device::displayPowerChanged, [=]() {
     if(main_layout->currentWidget() != onboardingWindow) {
       closeSettings();
     }
  });

  // load fonts
  QFontDatabase::addApplicationFont("../assets/fonts/opensans_regular.ttf");
  QFontDatabase::addApplicationFont("../assets/fonts/opensans_bold.ttf");
  QFontDatabase::addApplicationFont("../assets/fonts/opensans_semibold.ttf");
  QFontDatabase::addApplicationFont("../assets/fonts/Inter-Black.ttf");
  QFontDatabase::addApplicationFont("../assets/fonts/Inter-Bold.ttf");
  QFontDatabase::addApplicationFont("../assets/fonts/Inter-ExtraBold.ttf");
  QFontDatabase::addApplicationFont("../assets/fonts/Inter-ExtraLight.ttf");
  QFontDatabase::addApplicationFont("../assets/fonts/Inter-Medium.ttf");
  QFontDatabase::addApplicationFont("../assets/fonts/Inter-Regular.ttf");
  QFontDatabase::addApplicationFont("../assets/fonts/Inter-SemiBold.ttf");
  QFontDatabase::addApplicationFont("../assets/fonts/Inter-Thin.ttf");

  // no outline to prevent the focus rectangle
  setStyleSheet(R"(
    * {
      font-family: Inter;
      outline: none;
    }
  )");
  setAttribute(Qt::WA_NoSystemBackground);
}

void MainWindow::openSettings() {
  main_layout->setCurrentWidget(settingsWindow);
}

void MainWindow::closeSettings() {
  main_layout->setCurrentWidget(homeWindow);

  if (QUIState::ui_state.scene.started) {
    emit homeWindow->showSidebar(false);
  }
}

bool MainWindow::eventFilter(QObject *obj, QEvent *event) {
  // wake screen on tap
  if (event->type() == QEvent::MouseButtonPress || event->type() == QEvent::TouchBegin) {
    device.setAwake(true, true);
  }

#ifdef QCOM
  // filter out touches while in android activity
  const static QSet<QEvent::Type> filter_events({QEvent::MouseButtonPress, QEvent::MouseMove, QEvent::TouchBegin, QEvent::TouchUpdate, QEvent::TouchEnd});
  if (HardwareEon::launched_activity && filter_events.contains(event->type())) {
    HardwareEon::check_activity();
    if (HardwareEon::launched_activity) {
      return true;
    }
  }
#endif
  return false;
}
<|endoftext|>


<commit_before>#include "data-course.hpp"
using namespace std;

void Course::init(string identifier) {
	// cout << identifier << endl;
	copy(getCourse(identifier));
}
void Course::copy(const Course& c) {
	id = c.id;
	number = c.number;
	title = c.title;
	description = c.description;
	section = c.section;
	majors = c.majors;
	department = c.department;
	concentrations = c.concentrations;
	conversations = c.conversations;
	professor = c.professor;

	half_semester = c.half_semester;
	pass_fail = c.pass_fail;
	credits = c.credits;
	location = c.location;

	lab = c.lab;
	geneds = c.geneds;

	for (int i = 0; i < 7; ++i){
		days[i] = c.days[i];
		time[i] = c.time[i];
	}
}

Course::Course() {

}

Course::Course(string str) {
	init(str);
}

Course::Course(const Course& c) {
	copy(c);
}

Course& Course::operator = (const Course &c) {
	if (this == &c) return *this;
	copy(c);
	return *this;
}

Course::Course(istream &is) {
	// cout << "Now indise Course()" << endl;
	if (!is) return;
	// cout << "Now inside Course(after return)" << endl;

	string tmpLine;
	getline(is, tmpLine); // read in so we can do things with it.

	vector<string> record = split(tmpLine, ',');
	for (vector<string>::iterator i=record.begin(); i != record.end(); ++i) {
		*i = removeAllQuotes(*i);
		*i = removeTrailingSlashes(*i);
	}

	// printEntireRecord(record);

	// Ignore the first column;
	// record.at(0);

	// so, the *first* column (that we care about) has the course id,
	id = record.at(1);
	parseID(id);

	// Second column has the section,
	section = record.at(2);

	// Third holds the lab boolean,
	if (record.at(3).empty()) lab = false;
	else                      lab = true;

	// while Fourth contains the title of the course;
	title = record.at(4);

	// Fifth hands over the length (half semester or not)
	// it's actually an int that tells us how many times the course is offered per semester.
	half_semester = stringToInt(record.at(5));
	if (half_semester != 0 && half_semester != 1 && half_semester != 2)
		half_semester = 0;

	// Sixth tells us the number of credits,
	credits = stringToFloat(record.at(6));

	// Seventh shows us if it can be taken pass/no-pass,
	if (record.at(7) == "Y")
		pass_fail = true;
	else
		pass_fail = false;

	// while Eighth gives us the GEs of the course,
	// GEreqs = record.at(8);

	// and Nine spits out the days and times;
	// Times = record.at(9);

	// Ten holds the location,
	location = record.at(10);
	location = deDoubleString(location);

	// and Eleven knows who teaches.
	if (record.size() == 13) {
		string profLastName = record.at(11);
		string profFirstName = record.at(12);
		profFirstName.erase(0, 1); // remove the extra space from the start of the name
		professor = profFirstName + " " + profLastName;
	}
	else {
		professor = record.at(11);
	}

	updateID();
	title = cleanTitle(title);
	record.clear();
}

string Course::cleanTitle(string title) {
	vector<string> badEndings, badBeginnings;

	badEndings.push_back(" Closed");
	badEndings.push_back(" During course submission process");
	badEndings.push_back(" Especially for ");
	badEndings.push_back(" Film screenings");
	badEndings.push_back(" First-Year Students may register only");
	badEndings.push_back(" New course");
	badEndings.push_back(" Not open to first-year students.");
	badEndings.push_back(" Open only to ");
	badEndings.push_back(" Open to ");
	badEndings.push_back(" Permission of ");
	badEndings.push_back(" Prereq");
	badEndings.push_back(" Registration");
	badEndings.push_back(" Taught in English.");
	badEndings.push_back(" This course");
	badEndings.push_back(" This lab has been canceled.");
	badEndings.push_back(" Students in ");

	badBeginnings.push_back("Top: ");
	badBeginnings.push_back("Sem: ");
	badBeginnings.push_back("Res: ");

	for (vector<string>::iterator i=badEndings.begin(); i != badEndings.end(); ++i)
		title = removeTrailingText(title, *i);
	for (vector<string>::iterator i=badBeginnings.begin(); i != badBeginnings.end(); ++i)
		title = removeStartingText(title, *i);

	return title;
}

string Course::getProfessor() {
	return professor;
}

void Course::parseID(string str) {
	// Get the number of the course, aka the last three slots.
	stringstream(str.substr(str.size() - 3)) >> number;

	// Check if it's one of those dastardly "split courses".
	string dept = str.substr(0,str.size()-3);

	if (str.find('/') != string::npos) {
		department.push_back(Department(dept.substr(0,2)));
		department.push_back(Department(dept.substr(3,2)));
	}
	else {
		department.push_back(Department(dept));
	}
}

void Course::updateID() {
	string dept;
	for (std::vector<Department>::iterator i = department.begin(); i != department.end(); ++i) {
		dept += i->getName();
		if (i!=department.end()-1)
			dept += "/";
	}
	id = dept + " " + tostring(number);
}

string Course::getID() {
	return id;
}

ostream& Course::getData(ostream &os) {
	os << id << section;
	if (lab) os << " L";
	os << " - ";
	os << title << " | ";
	if (professor.length() > 0 && professor != " ")
		os << professor;
	return os;
}

void Course::showAll() {
	cout << id << section << endl;
	cout << "Title: " << title << endl;
	cout << "Professor: " << professor << endl;
	cout << "Lab? " << lab << endl;
	cout << "Half-semester? " << half_semester << endl;
	cout << "Credits: " << credits << endl;
	cout << "Pass/Fail? " << pass_fail << endl;
	cout << "Location: " << location << endl;
	cout << endl;
}

ostream &operator<<(ostream &os, Course &item) {
	return item.getData(os);
}

void Course::display() {
	cout << *this << endl;
}

void Course::displayMany() {
	cout << id;
	if (lab) cout << " L";
	cout << "\t- ";
	cout << title << " | ";
	if (professor.length() > 0 && professor != " ")
		cout << professor;
	cout << endl;
}

Course getCourse(string identifier) {
	// Make sure everything is uppercase
	std::transform(identifier.begin(), identifier.end(), identifier.begin(), ::toupper);

	// Remove a possible space at the front
	if (identifier[0] == ' ')
		identifier.erase(0, 1);

	// add a space into the course id, if there isn't one already
	int shouldBeSpaceIndex = identifier.length()-4;
	if (identifier[shouldBeSpaceIndex] != ' ')
		identifier.insert(shouldBeSpaceIndex+1, 1, ' ');

	// Remove the seciton speficier, if given
	if (identifier[identifier.length()-1] < 65)
		identifier = identifier.substr(0, identifier.length()-1);

	for (vector<Course>::iterator i = all_courses.begin(); i != all_courses.end(); ++i)
		if (i->getID() == identifier)
			return *i;

	// If no match, return a blanck course.
	Course c;
	return c;
}
<commit_msg>Gah, typos.<commit_after>#include "data-course.hpp"
using namespace std;

void Course::init(string identifier) {
	// cout << identifier << endl;
	copy(getCourse(identifier));
}
void Course::copy(const Course& c) {
	id = c.id;
	number = c.number;
	title = c.title;
	description = c.description;
	section = c.section;
	majors = c.majors;
	department = c.department;
	concentrations = c.concentrations;
	conversations = c.conversations;
	professor = c.professor;

	half_semester = c.half_semester;
	pass_fail = c.pass_fail;
	credits = c.credits;
	location = c.location;

	lab = c.lab;
	geneds = c.geneds;

	for (int i = 0; i < 7; ++i){
		days[i] = c.days[i];
		time[i] = c.time[i];
	}
}

Course::Course() {

}

Course::Course(string str) {
	init(str);
}

Course::Course(const Course& c) {
	copy(c);
}

Course& Course::operator = (const Course &c) {
	if (this == &c) return *this;
	copy(c);
	return *this;
}

Course::Course(istream &is) {
	// cout << "Now indise Course()" << endl;
	if (!is) return;
	// cout << "Now inside Course(after return)" << endl;

	string tmpLine;
	getline(is, tmpLine); // read in so we can do things with it.

	vector<string> record = split(tmpLine, ',');
	for (vector<string>::iterator i=record.begin(); i != record.end(); ++i) {
		*i = removeAllQuotes(*i);
		*i = removeTrailingSlashes(*i);
	}

	// printEntireRecord(record);

	// Ignore the first column;
	// record.at(0);

	// so, the *first* column (that we care about) has the course id,
	id = record.at(1);
	parseID(id);

	// Second column has the section,
	section = record.at(2);

	// Third holds the lab boolean,
	if (record.at(3).empty()) lab = false;
	else                      lab = true;

	// while Fourth contains the title of the course;
	title = record.at(4);

	// Fifth hands over the length (half semester or not)
	// it's actually an int that tells us how many times the course is offered per semester.
	half_semester = stringToInt(record.at(5));
	if (half_semester != 0 && half_semester != 1 && half_semester != 2)
		half_semester = 0;

	// Sixth tells us the number of credits,
	credits = stringToFloat(record.at(6));

	// Seventh shows us if it can be taken pass/no-pass,
	if (record.at(7) == "Y")
		pass_fail = true;
	else
		pass_fail = false;

	// while Eighth gives us the GEs of the course,
	// GEreqs = record.at(8);

	// and Nine spits out the days and times;
	// Times = record.at(9);

	// Ten holds the location,
	location = record.at(10);
	location = deDoubleString(location);

	// and Eleven knows who teaches.
	if (record.size() == 13) {
		string profLastName = record.at(11);
		string profFirstName = record.at(12);
		profFirstName.erase(0, 1); // remove the extra space from the start of the name
		professor = profFirstName + " " + profLastName;
	}
	else {
		professor = record.at(11);
	}

	updateID();
	title = cleanTitle(title);
	record.clear();
}

string Course::cleanTitle(string title) {
	vector<string> badEndings, badBeginnings;

	badEndings.push_back(" Closed");
	badEndings.push_back(" During course submission process");
	badEndings.push_back(" Especially for ");
	badEndings.push_back(" Film screenings");
	badEndings.push_back(" First-Year Students may register only");
	badEndings.push_back(" New course");
	badEndings.push_back(" Not open to first-year students.");
	badEndings.push_back(" Open only to ");
	badEndings.push_back(" Open to ");
	badEndings.push_back(" Permission of ");
	badEndings.push_back(" Prereq");
	badEndings.push_back(" Registration");
	badEndings.push_back(" Taught in English.");
	badEndings.push_back(" This course");
	badEndings.push_back(" This lab has been canceled.");
	badEndings.push_back(" Students in ");

	badBeginnings.push_back("Top: ");
	badBeginnings.push_back("Sem: ");
	badBeginnings.push_back("Res: ");

	for (vector<string>::iterator i=badEndings.begin(); i != badEndings.end(); ++i)
		title = removeTrailingText(title, *i);
	for (vector<string>::iterator i=badBeginnings.begin(); i != badBeginnings.end(); ++i)
		title = removeStartingText(title, *i);

	return title;
}

string Course::getProfessor() {
	return professor;
}

void Course::parseID(string str) {
	// Get the number of the course, aka the last three slots.
	stringstream(str.substr(str.size() - 3)) >> number;

	// Check if it's one of those dastardly "split courses".
	string dept = str.substr(0,str.size()-3);

	if (str.find('/') != string::npos) {
		department.push_back(Department(dept.substr(0,2)));
		department.push_back(Department(dept.substr(3,2)));
	}
	else {
		department.push_back(Department(dept));
	}
}

void Course::updateID() {
	string dept;
	for (std::vector<Department>::iterator i = department.begin(); i != department.end(); ++i) {
		dept += i->getName();
		if (i!=department.end()-1)
			dept += "/";
	}
	id = dept + " " + tostring(number);
}

string Course::getID() {
	return id;
}

ostream& Course::getData(ostream &os) {
	os << id << section;
	if (lab) os << " L";
	os << " - ";
	os << title << " | ";
	if (professor.length() > 0 && professor != " ")
		os << professor;
	return os;
}

void Course::showAll() {
	cout << id << section << endl;
	cout << "Title: " << title << endl;
	cout << "Professor: " << professor << endl;
	cout << "Lab? " << lab << endl;
	cout << "Half-semester? " << half_semester << endl;
	cout << "Credits: " << credits << endl;
	cout << "Pass/Fail? " << pass_fail << endl;
	cout << "Location: " << location << endl;
	cout << endl;
}

ostream &operator<<(ostream &os, Course &item) {
	return item.getData(os);
}

void Course::display() {
	cout << *this << endl;
}

void Course::displayMany() {
	cout << id;
	if (lab) cout << " L";
	cout << "\t- ";
	cout << title << " | ";
	if (professor.length() > 0 && professor != " ")
		cout << professor;
	cout << endl;
}

Course getCourse(string identifier) {
	// Make sure everything is uppercase
	std::transform(identifier.begin(), identifier.end(), identifier.begin(), ::toupper);

	// Remove a possible space at the front
	if (identifier[0] == ' ')
		identifier.erase(0, 1);

	// add a space into the course id, if there isn't one already
	int shouldBeSpaceIndex = identifier.length()-4;
	if (identifier[shouldBeSpaceIndex] != ' ')
		identifier.insert(shouldBeSpaceIndex+1, 1, ' ');

	// Remove the section specifier, if given
	if (identifier[identifier.length()-1] < 65)
		identifier = identifier.substr(0, identifier.length()-1);

	for (vector<Course>::iterator i = all_courses.begin(); i != all_courses.end(); ++i)
		if (i->getID() == identifier)
			return *i;

	// If no match, return a blanck course.
	Course c;
	return c;
}
<|endoftext|>