<commit_before>/*
* Copyright (C) 2008-2011 J-P Nurmi jpnurmi@gmail.com
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program 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 General Public License for more details.
*/

#include "tabwidget.h"
#include "tabwidget_p.h"
#include "sharedtimer.h"
#include <QGestureEvent>
#include <QContextMenuEvent>
#include <QtDebug>

TabBar::TabBar(QWidget* parent) : QTabBar(parent)
{
    addTab(tr("+"));
    setSelectionBehaviorOnRemove(SelectLeftTab);
}

void TabBar::changeEvent(QEvent* event)
{
    if (event->type() == QEvent::StyleChange)
    {
        Qt::TextElideMode mode = elideMode();
        QTabBar::changeEvent(event);
        if (mode != elideMode())
            setElideMode(mode);
        return;
    }
    QTabBar::changeEvent(event);
}

void TabBar::contextMenuEvent(QContextMenuEvent* event)
{
    for (int i = 0; i < count() - 1; ++i)
    {
        if (tabRect(i).contains(event->pos()))
        {
            emit menuRequested(i, event->globalPos());
            break;
        }
    }
}

void TabBar::wheelEvent(QWheelEvent* event)
{
    if (event->delta() > 0)
        QMetaObject::invokeMethod(parent(), "moveToPrevTab");
    else
        QMetaObject::invokeMethod(parent(), "moveToNextTab");
    QWidget::wheelEvent(event);
}

TabWidget::TabWidget(QWidget* parent) : QTabWidget(parent)
{
    setTabBar(new TabBar(this));
    setElideMode(Qt::ElideMiddle);
    d.previous = -1;
    d.inactiveColor = palette().color(QPalette::Disabled, QPalette::Highlight);
    d.alertColor = palette().color(QPalette::Highlight);
    d.highlightColor = palette().color(QPalette::Highlight);
    d.swipeOrientation = Qt::Orientation(0);
    connect(this, SIGNAL(currentChanged(int)), this, SLOT(tabChanged(int)));
    connect(tabBar(), SIGNAL(menuRequested(int,QPoint)), this, SIGNAL(tabMenuRequested(int,QPoint)));
}

QColor TabWidget::inactiveColor() const
{
    return d.inactiveColor;
}

void TabWidget::setInactiveColor(const QColor& color)
{
    d.inactiveColor = color;
}

QColor TabWidget::alertColor() const
{
    return d.alertColor;
}

void TabWidget::setAlertColor(const QColor& color)
{
    d.alertColor = color;
}

QColor TabWidget::highlightColor() const
{
    return d.highlightColor;
}

void TabWidget::setHighlightColor(const QColor& color)
{
    d.highlightColor = color;
}

bool TabWidget::isTabInactive(int index)
{
    return d.inactiveIndexes.contains(index);
}

void TabWidget::setTabInactive(int index, bool inactive)
{
    if (!inactive)
    {
        int count = d.inactiveIndexes.removeAll(index);
        if (count > 0 && d.inactiveIndexes.isEmpty())
            emit inactiveStatusChanged(false);
    }
    else
    {
        if (d.inactiveIndexes.isEmpty())
            emit inactiveStatusChanged(true);
        if (!d.inactiveIndexes.contains(index))
            d.inactiveIndexes.append(index);
    }
    colorizeTab(index);
}

bool TabWidget::hasTabAlert(int index)
{
    return d.alertIndexes.contains(index);
}

void TabWidget::setTabAlert(int index, bool alert)
{
    if (!alert)
    {
        int count = d.alertIndexes.removeAll(index);
        if (count > 0 && d.alertIndexes.isEmpty())
        {
            emit alertStatusChanged(false);
            SharedTimer::instance()->unregisterReceiver(this, "alertTimeout");
        }
    }
    else
    {
        if (d.alertIndexes.isEmpty())
        {
            emit alertStatusChanged(true);
            SharedTimer::instance()->registerReceiver(this, "alertTimeout");
        }
        if (!d.alertIndexes.contains(index))
            d.alertIndexes.append(index);
    }
    colorizeTab(index);
}

bool TabWidget::hasTabHighlight(int index) const
{
    return d.highlightIndexes.contains(index);
}

void TabWidget::setTabHighlight(int index, bool highlight)
{
    if (!highlight)
    {
        int count = d.highlightIndexes.removeAll(index);
        if (count > 0 && d.highlightIndexes.isEmpty())
            emit highlightStatusChanged(false);
    }
    else
    {
        if (d.highlightIndexes.isEmpty())
            emit highlightStatusChanged(true);
        if (!d.highlightIndexes.contains(index))
            d.highlightIndexes.append(index);
    }
    colorizeTab(index);
}

void TabWidget::registerSwipeGestures(Qt::Orientation orientation)
{
    if (d.swipeOrientation != 0) {
        qWarning("TabWidget::registerSwipeGestures: already registered");
        return;
    }

    d.swipeOrientation = orientation;
    grabGesture(Qt::SwipeGesture);
}

void TabWidget::unregisterSwipeGestures()
{
    if (d.swipeOrientation == 0) {
        qWarning("TabWidget::unregisterSwipeGestures: not registered");
        return;
    }

    d.swipeOrientation = Qt::Orientation(0);
    ungrabGesture(Qt::SwipeGesture);
}

void TabWidget::moveToNextTab()
{
    int index = currentIndex();
    if (++index >= count() - 1)
        index = 0;
    setCurrentIndex(index);
}

void TabWidget::moveToPrevTab()
{
    int index = currentIndex();
    if (--index < 0)
        index = count() - 2;
    setCurrentIndex(index);
}

void TabWidget::setTabBarVisible(bool visible)
{
    tabBar()->setVisible(visible);
}

bool TabWidget::event(QEvent* event)
{
    if (event->type() == QEvent::Gesture)
    {
        QGestureEvent* gestureEvent = static_cast<QGestureEvent*>(event);
        QGesture* gesture = gestureEvent->gesture(Qt::SwipeGesture);
        QSwipeGesture* swipeGesture = static_cast<QSwipeGesture*>(gesture);
        if (swipeGesture)
        {
            bool accepted = false;
            switch (d.swipeOrientation)
            {
                case Qt::Horizontal:
                    accepted = handleSwipeGesture(swipeGesture, swipeGesture->horizontalDirection());
                    break;
                case Qt::Vertical:
                    accepted = handleSwipeGesture(swipeGesture, swipeGesture->verticalDirection());
                    break;
                default:
                    Q_ASSERT(false);
                    break;
            }
            gestureEvent->setAccepted(swipeGesture, accepted);
        }
    }
    return QTabWidget::event(event);
}

bool TabWidget::handleSwipeGesture(QSwipeGesture* gesture, QSwipeGesture::SwipeDirection direction)
{
    switch (direction)
    {
        case QSwipeGesture::Up:
        case QSwipeGesture::Left:
            if (gesture->state() == Qt::GestureFinished)
                moveToPrevTab();
            return true;
        case QSwipeGesture::Down:
        case QSwipeGesture::Right:
            if (gesture->state() == Qt::GestureFinished)
                moveToNextTab();
            return true;
        default:
            return false;
    }
}

static void shiftIndexesFrom(QList<int>& indexes, int from, int delta)
{
    QMutableListIterator<int> it(indexes);
    while (it.hasNext())
    {
        if (it.next() >= from)
            it.value() += delta;
    }
}

void TabWidget::tabInserted(int index)
{
    shiftIndexesFrom(d.inactiveIndexes, index, 1);
    shiftIndexesFrom(d.alertIndexes, index, 1);
    shiftIndexesFrom(d.highlightIndexes, index, 1);
}

void TabWidget::tabRemoved(int index)
{
    shiftIndexesFrom(d.inactiveIndexes, index, -1);
    shiftIndexesFrom(d.alertIndexes, index, -1);
    shiftIndexesFrom(d.highlightIndexes, index, -1);
}

void TabWidget::tabChanged(int index)
{
    if (index == count() - 1)
    {
        emit newTabRequested();
        if (d.previous != -1)
            setCurrentIndex(d.previous);
    }
    else
    {
        d.previous = index;
    }
}

void TabWidget::alertTimeout()
{
    if (d.currentAlertColor == d.alertColor)
        d.currentAlertColor = QColor();
    else
        d.currentAlertColor = d.alertColor;

    foreach (int index, d.alertIndexes)
        colorizeTab(index);
}

void TabWidget::colorizeTab(int index)
{
    if (isTabInactive(index))
        tabBar()->setTabTextColor(index, d.inactiveColor);
    else if (hasTabAlert(index))
        tabBar()->setTabTextColor(index, d.currentAlertColor);
    else if (hasTabHighlight(index))
        tabBar()->setTabTextColor(index, d.highlightColor);
    else
        tabBar()->setTabTextColor(index, QColor());
}
<commit_msg>TabBar::contextMenuEvent() cleanup<commit_after>/*
* Copyright (C) 2008-2011 J-P Nurmi jpnurmi@gmail.com
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program 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 General Public License for more details.
*/

#include "tabwidget.h"
#include "tabwidget_p.h"
#include "sharedtimer.h"
#include <QGestureEvent>
#include <QContextMenuEvent>
#include <QtDebug>

TabBar::TabBar(QWidget* parent) : QTabBar(parent)
{
    addTab(tr("+"));
    setSelectionBehaviorOnRemove(SelectLeftTab);
}

void TabBar::changeEvent(QEvent* event)
{
    if (event->type() == QEvent::StyleChange)
    {
        Qt::TextElideMode mode = elideMode();
        QTabBar::changeEvent(event);
        if (mode != elideMode())
            setElideMode(mode);
        return;
    }
    QTabBar::changeEvent(event);
}

void TabBar::contextMenuEvent(QContextMenuEvent* event)
{
    int index = tabAt(event->pos());
    if (index != -1)
        emit menuRequested(index, event->globalPos());
}

void TabBar::wheelEvent(QWheelEvent* event)
{
    if (event->delta() > 0)
        QMetaObject::invokeMethod(parent(), "moveToPrevTab");
    else
        QMetaObject::invokeMethod(parent(), "moveToNextTab");
    QWidget::wheelEvent(event);
}

TabWidget::TabWidget(QWidget* parent) : QTabWidget(parent)
{
    setTabBar(new TabBar(this));
    setElideMode(Qt::ElideMiddle);
    d.previous = -1;
    d.inactiveColor = palette().color(QPalette::Disabled, QPalette::Highlight);
    d.alertColor = palette().color(QPalette::Highlight);
    d.highlightColor = palette().color(QPalette::Highlight);
    d.swipeOrientation = Qt::Orientation(0);
    connect(this, SIGNAL(currentChanged(int)), this, SLOT(tabChanged(int)));
    connect(tabBar(), SIGNAL(menuRequested(int,QPoint)), this, SIGNAL(tabMenuRequested(int,QPoint)));
}

QColor TabWidget::inactiveColor() const
{
    return d.inactiveColor;
}

void TabWidget::setInactiveColor(const QColor& color)
{
    d.inactiveColor = color;
}

QColor TabWidget::alertColor() const
{
    return d.alertColor;
}

void TabWidget::setAlertColor(const QColor& color)
{
    d.alertColor = color;
}

QColor TabWidget::highlightColor() const
{
    return d.highlightColor;
}

void TabWidget::setHighlightColor(const QColor& color)
{
    d.highlightColor = color;
}

bool TabWidget::isTabInactive(int index)
{
    return d.inactiveIndexes.contains(index);
}

void TabWidget::setTabInactive(int index, bool inactive)
{
    if (!inactive)
    {
        int count = d.inactiveIndexes.removeAll(index);
        if (count > 0 && d.inactiveIndexes.isEmpty())
            emit inactiveStatusChanged(false);
    }
    else
    {
        if (d.inactiveIndexes.isEmpty())
            emit inactiveStatusChanged(true);
        if (!d.inactiveIndexes.contains(index))
            d.inactiveIndexes.append(index);
    }
    colorizeTab(index);
}

bool TabWidget::hasTabAlert(int index)
{
    return d.alertIndexes.contains(index);
}

void TabWidget::setTabAlert(int index, bool alert)
{
    if (!alert)
    {
        int count = d.alertIndexes.removeAll(index);
        if (count > 0 && d.alertIndexes.isEmpty())
        {
            emit alertStatusChanged(false);
            SharedTimer::instance()->unregisterReceiver(this, "alertTimeout");
        }
    }
    else
    {
        if (d.alertIndexes.isEmpty())
        {
            emit alertStatusChanged(true);
            SharedTimer::instance()->registerReceiver(this, "alertTimeout");
        }
        if (!d.alertIndexes.contains(index))
            d.alertIndexes.append(index);
    }
    colorizeTab(index);
}

bool TabWidget::hasTabHighlight(int index) const
{
    return d.highlightIndexes.contains(index);
}

void TabWidget::setTabHighlight(int index, bool highlight)
{
    if (!highlight)
    {
        int count = d.highlightIndexes.removeAll(index);
        if (count > 0 && d.highlightIndexes.isEmpty())
            emit highlightStatusChanged(false);
    }
    else
    {
        if (d.highlightIndexes.isEmpty())
            emit highlightStatusChanged(true);
        if (!d.highlightIndexes.contains(index))
            d.highlightIndexes.append(index);
    }
    colorizeTab(index);
}

void TabWidget::registerSwipeGestures(Qt::Orientation orientation)
{
    if (d.swipeOrientation != 0) {
        qWarning("TabWidget::registerSwipeGestures: already registered");
        return;
    }

    d.swipeOrientation = orientation;
    grabGesture(Qt::SwipeGesture);
}

void TabWidget::unregisterSwipeGestures()
{
    if (d.swipeOrientation == 0) {
        qWarning("TabWidget::unregisterSwipeGestures: not registered");
        return;
    }

    d.swipeOrientation = Qt::Orientation(0);
    ungrabGesture(Qt::SwipeGesture);
}

void TabWidget::moveToNextTab()
{
    int index = currentIndex();
    if (++index >= count() - 1)
        index = 0;
    setCurrentIndex(index);
}

void TabWidget::moveToPrevTab()
{
    int index = currentIndex();
    if (--index < 0)
        index = count() - 2;
    setCurrentIndex(index);
}

void TabWidget::setTabBarVisible(bool visible)
{
    tabBar()->setVisible(visible);
}

bool TabWidget::event(QEvent* event)
{
    if (event->type() == QEvent::Gesture)
    {
        QGestureEvent* gestureEvent = static_cast<QGestureEvent*>(event);
        QGesture* gesture = gestureEvent->gesture(Qt::SwipeGesture);
        QSwipeGesture* swipeGesture = static_cast<QSwipeGesture*>(gesture);
        if (swipeGesture)
        {
            bool accepted = false;
            switch (d.swipeOrientation)
            {
                case Qt::Horizontal:
                    accepted = handleSwipeGesture(swipeGesture, swipeGesture->horizontalDirection());
                    break;
                case Qt::Vertical:
                    accepted = handleSwipeGesture(swipeGesture, swipeGesture->verticalDirection());
                    break;
                default:
                    Q_ASSERT(false);
                    break;
            }
            gestureEvent->setAccepted(swipeGesture, accepted);
        }
    }
    return QTabWidget::event(event);
}

bool TabWidget::handleSwipeGesture(QSwipeGesture* gesture, QSwipeGesture::SwipeDirection direction)
{
    switch (direction)
    {
        case QSwipeGesture::Up:
        case QSwipeGesture::Left:
            if (gesture->state() == Qt::GestureFinished)
                moveToPrevTab();
            return true;
        case QSwipeGesture::Down:
        case QSwipeGesture::Right:
            if (gesture->state() == Qt::GestureFinished)
                moveToNextTab();
            return true;
        default:
            return false;
    }
}

static void shiftIndexesFrom(QList<int>& indexes, int from, int delta)
{
    QMutableListIterator<int> it(indexes);
    while (it.hasNext())
    {
        if (it.next() >= from)
            it.value() += delta;
    }
}

void TabWidget::tabInserted(int index)
{
    shiftIndexesFrom(d.inactiveIndexes, index, 1);
    shiftIndexesFrom(d.alertIndexes, index, 1);
    shiftIndexesFrom(d.highlightIndexes, index, 1);
}

void TabWidget::tabRemoved(int index)
{
    shiftIndexesFrom(d.inactiveIndexes, index, -1);
    shiftIndexesFrom(d.alertIndexes, index, -1);
    shiftIndexesFrom(d.highlightIndexes, index, -1);
}

void TabWidget::tabChanged(int index)
{
    if (index == count() - 1)
    {
        emit newTabRequested();
        if (d.previous != -1)
            setCurrentIndex(d.previous);
    }
    else
    {
        d.previous = index;
    }
}

void TabWidget::alertTimeout()
{
    if (d.currentAlertColor == d.alertColor)
        d.currentAlertColor = QColor();
    else
        d.currentAlertColor = d.alertColor;

    foreach (int index, d.alertIndexes)
        colorizeTab(index);
}

void TabWidget::colorizeTab(int index)
{
    if (isTabInactive(index))
        tabBar()->setTabTextColor(index, d.inactiveColor);
    else if (hasTabAlert(index))
        tabBar()->setTabTextColor(index, d.currentAlertColor);
    else if (hasTabHighlight(index))
        tabBar()->setTabTextColor(index, d.highlightColor);
    else
        tabBar()->setTabTextColor(index, QColor());
}
<|endoftext|>


<commit_before>#ifdef HAVE_CMAKE_CONFIG
  #include "cmake_config.h"
#elif defined (HAVE_CONFIG_H)
  #include "config.h"
#endif

#define HAVE_DUNE_DETAILED_DISCRETIZATIONS 1

#include <iostream>
#include <sstream>

#include <boost/filesystem.hpp>

#include <dune/common/exceptions.hh>
#include <dune/common/shared_ptr.hh>
#include <dune/common/timer.hh>

#include <dune/grid/io/file/vtk/vtkwriter.hh>

#include <dune/grid/part/leaf.hh>

#include <dune/fem/misc/mpimanager.hh>
#include <dune/fem/space/common/functionspace.hh>

#include <dune/stuff/common/parameter/tree.hh>
#include <dune/stuff/common/logging.hh>
#include <dune/stuff/grid/provider.hh>
#include <dune/stuff/grid/boundaryinfo.hh>
#include <dune/stuff/function/expression.hh>
#include <dune/stuff/discretefunction/projection/dirichlet.hh>
#include <dune/stuff/la/solver.hh>

#include <dune/detailed/discretizations/discretefunctionspace/continuous/lagrange.hh>
#include <dune/detailed/discretizations/discretefunctionspace/sub/linear.hh>
#include <dune/detailed/discretizations/la/container/factory/eigen.hh>
#include <dune/detailed/discretizations/discretefunction/default.hh>
#include <dune/detailed/discretizations/discretefunctionspace/sub/affine.hh>
#include <dune/detailed/discretizations/evaluation/local/binary/elliptic.hh>
#include <dune/detailed/discretizations/discreteoperator/local/codim0/integral.hh>
#include <dune/detailed/discretizations/evaluation/local/unary/scale.hh>
#include <dune/detailed/discretizations/discretefunctional/local/codim0/integral.hh>
#include <dune/detailed/discretizations/discretefunctional/local/codim1/integral.hh>
#include <dune/detailed/discretizations/assembler/local/codim0/matrix.hh>
#include <dune/detailed/discretizations/assembler/local/codim0/vector.hh>
#include <dune/detailed/discretizations/assembler/local/codim1/vector.hh>
#include <dune/detailed/discretizations/assembler/system.hh>

const std::string id = "elliptic.continuousgalerkin";

#ifndef POLORDER
  const int polOrder = 1;
#else
  const int polOrder = POLORDER;
#endif

/**
  \brief      Creates a parameter file if it does not exist.

              Nothing is done if the file already exists. If not, a parameter file will be created with all neccessary
              keys and values.
  \param[in]  filename
              (Relative) path to the file.
  **/
void ensureParamFile(const std::string& filename)
{
  // only write param file if there is none
  if (!boost::filesystem::exists(filename)) {
    std::ofstream file;
    file.open(filename);
    file << "[" << id << "]" << std::endl;
    file << "filename = " << id << std::endl;
    file << "grid = " << "gridprovider.cube" << std::endl;
    file << "boundaryinfo = " << "boundaryinfo.alldirichlet" << std::endl;
    file << "[gridprovider.cube]" << std::endl;
    file << "lowerLeft = [0.0; 0.0; 0.0]" << std::endl;
    file << "upperRight = [1.0; 1.0; 1.0]" << std::endl;
    file << "numElements = [12; 12; 12]" << std::endl;
    file << "[boundaryinfo.idbased]" << std::endl;
    file << "dirichlet = [1; 2; 3]" << std::endl;
    file << "neumann = [4]" << std::endl;
    file << "[diffusion]" << std::endl;
    file << "order = 0"  << std::endl;
    file << "variable = x" << std::endl;
    file << "expression = [1.0; 1.0; 1.0]" << std::endl;
    file << "[force]" << std::endl;
    file << "order = 0"  << std::endl;
    file << "variable = x" << std::endl;
    file << "expression = [1.0; 1.0; 1.0]" << std::endl;
    file << "[dirichlet]" << std::endl;
    file << "order = 0"  << std::endl;
    file << "variable = x" << std::endl;
    file << "expression = [0.1*x[0]; 0.0; 0.0]" << std::endl;
    file << "[neumann]" << std::endl;
    file << "order = 0"  << std::endl;
    file << "variable = x" << std::endl;
    file << "expression = [1.0; 0.0; 0.0]" << std::endl;
    file << "[solver]" << std::endl;
    file << "type = bicgstab.ilut"  << std::endl;
    file << "maxIter = 5000"  << std::endl;
    file << "precision = 1e-12"  << std::endl;
    file.close();
  } // only write param file if there is none
} // void ensureParamFile()

int main(int argc, char** argv)
{
  try {
    // mpi
    Dune::MPIManager::initialize(argc, argv);

    // parameter
    const std::string paramFilename = id + ".description";
    ensureParamFile(paramFilename);
    Dune::Stuff::Common::ExtendedParameterTree description(argc, argv, paramFilename);
    description.assertSub(id);

    // logger
    Dune::Stuff::Common::Logger().create(Dune::Stuff::Common::LOG_INFO |
                                         Dune::Stuff::Common::LOG_CONSOLE);
    Dune::Stuff::Common::LogStream& info = Dune::Stuff::Common::Logger().info();

    // timer
    Dune::Timer timer;

    info << "setting up grid:" << std::endl;
    typedef Dune::Stuff::GridProviderInterface<> GridProviderType;
    const GridProviderType* gridProvider
        = Dune::Stuff::GridProviders<>::create(description.get(id + ".grid", "stuff.grid.provider.cube"),
                                               description);
    typedef GridProviderType::GridType GridType;
    const Dune::shared_ptr< const GridType > grid = gridProvider->grid();
    typedef Dune::grid::Part::Leaf::Const< GridType > GridPartType;
    const GridPartType gridPart(*grid);
    typedef typename Dune::Stuff::GridboundaryInterface< typename GridPartType::GridViewType > BoundaryInfoType;
    const Dune::shared_ptr< const BoundaryInfoType > boundaryInfo(
          Dune::Stuff::Gridboundaries< typename GridPartType::GridViewType >::create(
              description.get(id + ".boundaryinfo", "stuff.grid.boundaryinfo.alldirichlet"),
                            description));

    info << "  took " << timer.elapsed() << " sec, has " << grid->size(0) << " entities" << std::endl;
    info << "visualizing grid... " << std::flush;
    timer.reset();
    gridProvider->visualize(description.get(id + ".filename", id) + ".grid");
    info << " done (took " << timer.elapsed() << " sek)" << std::endl;

    info << "initializing function space and data functions... " << std::flush;
    timer.reset();
    const int DUNE_UNUSED(dimDomain) = GridProviderType::dim;
    const int DUNE_UNUSED(dimRange) = 1;
    typedef double DomainFieldType;
    typedef double RangeFieldType;
    typedef Dune::FunctionSpace< DomainFieldType, RangeFieldType, dimDomain, dimRange > FunctionSpaceType;
    timer.reset();
    typedef Dune::Stuff::FunctionExpression< DomainFieldType, dimDomain, RangeFieldType, dimRange >
        ExpressionFunctionType;
    const Dune::shared_ptr< const ExpressionFunctionType >
        diffusion(ExpressionFunctionType::create(description.sub("diffusion")));
    const Dune::shared_ptr< const ExpressionFunctionType >
        force(ExpressionFunctionType::create(description.sub("force")));
    const Dune::shared_ptr< const ExpressionFunctionType >
        dirichlet(ExpressionFunctionType::create(description.sub("dirichlet")));
    const Dune::shared_ptr< const ExpressionFunctionType >
        neumann(ExpressionFunctionType::create(description.sub("neumann")));
    info << "done (took " << timer.elapsed() << " sec)" << std::endl;

    info << "initializing discrete function spaces... " << std::flush;
    typedef Dune::Detailed::Discretizations
        ::DiscreteFunctionSpace
        ::Continuous
        ::Lagrange< FunctionSpaceType, GridPartType, polOrder >
      LagrangeSpaceType;
    const LagrangeSpaceType lagrangeSpace(gridPart);
    typedef Dune::Detailed::Discretizations
        ::DiscreteFunctionSpace
        ::Sub
        ::Linear
        ::Dirichlet< LagrangeSpaceType >
      TestSpaceType;
    const TestSpaceType testSpace(lagrangeSpace, boundaryInfo);
    typedef TestSpaceType AnsatzSpaceType;
    const AnsatzSpaceType ansatzSpace(lagrangeSpace, boundaryInfo);
    typedef typename Dune::Detailed::Discretizations::LA::Container::Factory::Eigen< RangeFieldType > ContainerFactory;
    typedef typename ContainerFactory::DenseVectorType VectorType;
    typedef Dune::Detailed::Discretizations
        ::DiscreteFunction
        ::Default< LagrangeSpaceType, VectorType >
      DiscreteFunctionType;
    DiscreteFunctionType discreteDirichlet(lagrangeSpace, "dirichlet");
    Dune::Stuff::DiscreteFunction::Projection::Dirichlet::project(*boundaryInfo, *dirichlet, discreteDirichlet);
    info << "done (took " << timer.elapsed() << " sec)" << std::endl;

    info << "initializing operator and functionals... " << std::flush;
    timer.reset();
    // * left hand side
    //   * elliptic operator
    typedef Dune::Detailed::Discretizations
        ::Evaluation
        ::Local
        ::Binary
        ::Elliptic< FunctionSpaceType, ExpressionFunctionType >
      EllipticEvaluationType;
    const EllipticEvaluationType ellipticEvaluation(diffusion, description.sub("diffusion").get("order", 0));
    typedef Dune::Detailed::Discretizations
        ::DiscreteOperator
        ::Local
        ::Codim0
        ::Integral< EllipticEvaluationType >
      EllipticOperatorType;
    const EllipticOperatorType ellipticOperator(ellipticEvaluation);
    // * right hand side
    //   * L2 force functional
    typedef Dune::Detailed::Discretizations
        ::Evaluation
        ::Local
        ::Unary
        ::Scale< FunctionSpaceType, ExpressionFunctionType >
      ProductEvaluationType;
    const ProductEvaluationType forceEvaluation(force, description.sub("force").get("order", 0));
    typedef Dune::Detailed::Discretizations
        ::DiscreteFunctional
        ::Local
        ::Codim0
        ::Integral< ProductEvaluationType >
      L2VolumeFunctionalType;
    const L2VolumeFunctionalType forceFunctional(forceEvaluation);
    //   * L2 neumann functional
    const ProductEvaluationType neumannEvaluation(neumann, description.sub("neumann").get("order", 0));
    typedef typename Dune::Detailed::Discretizations
        ::DiscreteFunctional
        ::Local
        ::Codim1
        ::Integral
        ::Boundary< ProductEvaluationType >
      L2BoundaryFunctionalType;
    const L2BoundaryFunctionalType neumannFunctional(neumannEvaluation);
    info << "done (took " << timer.elapsed() << " sec)" << std::endl;

    info << "initializing matrix (of size " << testSpace.map().size() << "x" << ansatzSpace.map().size()
         << ") and vectors... " << std::flush;
    timer.reset();
    typedef ContainerFactory::RowMajorSparseMatrixType MatrixType;
    Dune::shared_ptr< MatrixType > systemMatrix = ContainerFactory::createRowMajorSparseMatrix(testSpace, ansatzSpace);
    Dune::shared_ptr< VectorType > forceVector = ContainerFactory::createDenseVector(testSpace);
    Dune::shared_ptr< VectorType > neumannVector = ContainerFactory::createDenseVector(testSpace);
    Dune::shared_ptr< VectorType > rhsVector = ContainerFactory::createDenseVector(testSpace);
    Dune::shared_ptr< VectorType > solutionVector = ContainerFactory::createDenseVector(testSpace);
    info << "done (took " << timer.elapsed() << " sec)" << std::endl;

    info << "assembing system... " << std::flush;
    timer.reset();
    // * local matrix assembler
    typedef Dune::Detailed::Discretizations::Assembler::Local::Codim0::Matrix< EllipticOperatorType >
        LocalMatrixAssemblerType;
    const Dune::shared_ptr< const LocalMatrixAssemblerType > localMatrixAssembler(
          new LocalMatrixAssemblerType(ellipticOperator));
    // * local vector assemblers
    //   * force vector
    typedef Dune::Detailed::Discretizations::Assembler::Local::Codim0::Vector< L2VolumeFunctionalType >
        LocalVolumeVectorAssemblerType;
    const Dune::shared_ptr< const LocalVolumeVectorAssemblerType > localforceVectorAssembler(
          new LocalVolumeVectorAssemblerType(forceFunctional));
    //   * neumann vector
    typedef Dune::Detailed::Discretizations::Assembler::Local::Codim1::Vector::Neumann< L2BoundaryFunctionalType,
                                                                                BoundaryInfoType >
        LocalNeumannVectorAssemblerType;
    const Dune::shared_ptr< const LocalNeumannVectorAssemblerType > localNeumannVectorAssembler(
          new LocalNeumannVectorAssemblerType(neumannFunctional, boundaryInfo));
    typedef Dune::Detailed::Discretizations::Assembler::System< TestSpaceType, AnsatzSpaceType > SystemAssemblerType;
    // * system assembler
    SystemAssemblerType systemAssembler(testSpace, ansatzSpace);
    systemAssembler.addLocalMatrixAssembler(localMatrixAssembler, systemMatrix);
    systemAssembler.addLocalVectorAssembler(localforceVectorAssembler, forceVector);
    systemAssembler.addLocalVectorAssembler(localNeumannVectorAssembler, neumannVector);
    systemAssembler.assemble();
    info << "done (took " << timer.elapsed() << " sec)" << std::endl;

    info << "applying constraints... " << std::flush;
    timer.reset();
    rhsVector->backend() = forceVector->backend()
        + neumannVector->backend()
        - systemMatrix->backend() * discreteDirichlet.vector()->backend();
    systemAssembler.applyConstraints(*systemMatrix, *rhsVector);
    info << "done (took " << timer.elapsed() << " sec)" << std::endl;

    info << "solving linear system (of size " << systemMatrix->rows() << "x" << systemMatrix->cols() << ")" << std::endl;
    const std::string solverType = description.get("solver.type", "bicgstab");
    const unsigned int solverMaxIter = description.get("solver.maxIter", 5000);
    const double solverPrecision = description.get("solver.precision", 1e-12);
    info << "  using '" << solverType << "'... " << std::flush;
    timer.reset();
    typedef typename Dune::Stuff::LA::Solver::Interface< MatrixType, VectorType > SolverType;
    Dune::shared_ptr< SolverType > solver(Dune::Stuff::LA::Solver::create< MatrixType, VectorType >(solverType));
    const unsigned int failure = solver->apply(*systemMatrix,
                                               *rhsVector,
                                               *solutionVector,
                                               solverMaxIter,
                                               solverPrecision);
    if (failure)
      DUNE_THROW(Dune::MathError,
                 "\nERROR: linear solver '" << solverType << "' reported a problem!");
    if (solutionVector->size() != ansatzSpace.map().size())
      DUNE_THROW(Dune::MathError,
                 "\nERROR: linear solver '" << solverType << "' produced a solution of wrong size (is "
                 << solutionVector->size() << ", should be " << ansatzSpace.map().size() << ")!");
    solutionVector->backend() += discreteDirichlet.vector()->backend();
    info << "done (took " << timer.elapsed() << " sec)" << std::endl;

    const std::string solutionFilename = description.get(id + ".filename", id) + ".solution";
    const std::string solutionName = id + ".solution";
    info << "writing solution to '" << solutionFilename;
    if (dimDomain == 1)
      info << ".vtp";
    else
      info << ".vtu";
    info << "'... " << std::flush;
    timer.reset();
    typedef Dune::Detailed::Discretizations
        ::DiscreteFunction
        ::DefaultConst< LagrangeSpaceType, VectorType >
      ConstDiscreteFunctionType;
    const Dune::shared_ptr< const ConstDiscreteFunctionType > solution(new ConstDiscreteFunctionType(lagrangeSpace,
                                                                                solutionVector,
                                                                                solutionName));
    typedef Dune::VTKWriter< LagrangeSpaceType::GridViewType > VTKWriterType;
    VTKWriterType vtkWriter(lagrangeSpace.gridView());
    vtkWriter.addVertexData(solution);
    vtkWriter.write(solutionFilename);
    info << "done (took " << timer.elapsed() << " sec)" << std::endl;

    // done
    return 0;
  } catch(Dune::Exception& e) {
    std::cerr << "Dune reported error: " << e.what() << std::endl;
  } catch(std::exception& e) {
    std::cerr << e.what() << std::endl;
  } catch( ... ) {
    std::cerr << "Unknown exception thrown!" << std::endl;
  } // try
} // main
<commit_msg>[examples.elliptic.continuousgalerkin] working again<commit_after>#ifdef HAVE_CMAKE_CONFIG
  #include "cmake_config.h"
#elif defined (HAVE_CONFIG_H)
  #include "config.h"
#endif

#define HAVE_DUNE_DETAILED_DISCRETIZATIONS 1

#include <iostream>
#include <sstream>
#include <vector>

#include <boost/filesystem.hpp>

#include <dune/common/exceptions.hh>
#include <dune/common/static_assert.hh>
#include <dune/common/timer.hh>
#include <dune/common/dynvector.hh>

#include <dune/grid/io/file/vtk/vtkwriter.hh>

#include <dune/grid/part/leaf.hh>

#include <dune/fem/misc/mpimanager.hh>
#include <dune/fem/space/common/functionspace.hh>

#include <dune/stuff/common/parameter/tree.hh>
#include <dune/stuff/common/logging.hh>
#include <dune/stuff/grid/provider.hh>
#include <dune/stuff/grid/boundaryinfo.hh>
#include <dune/stuff/function/expression.hh>
#include <dune/stuff/la/solver.hh>
#include <dune/stuff/discretefunction/projection/dirichlet.hh>

#include <dune/detailed/discretizations/space/continuouslagrange/fem.hh>
#include <dune/detailed/discretizations/la/containerfactory/eigen.hh>
#include <dune/detailed/discretizations/evaluation/elliptic.hh>
#include <dune/detailed/discretizations/evaluation/product.hh>
#include <dune/detailed/discretizations/localoperator/codim0.hh>
#include <dune/detailed/discretizations/localfunctional/codim0.hh>
#include <dune/detailed/discretizations/assembler/local/codim0.hh>
#include <dune/detailed/discretizations/space/constraints.hh>
#include <dune/detailed/discretizations/assembler/system.hh>
#include <dune/detailed/discretizations/discretefunction/default.hh>

const std::string id = "elliptic.continuousgalerkin";

#ifndef POLORDER
  const int polOrder = 1;
#else
  const int polOrder = POLORDER;
#endif
dune_static_assert((polOrder > 0), "ERROR: polOrder hast to be positive!");

using namespace Dune::Detailed::Discretizations;

/**
  \brief      Creates a parameter file if it does not exist.

              Nothing is done if the file already exists. If not, a parameter file will be created with all neccessary
              keys and values.
  \param[in]  filename
              (Relative) path to the file.
  **/
void ensureParamFile(const std::string& filename)
{
  // only write param file if there is none
  if (!boost::filesystem::exists(filename)) {
    std::ofstream file;
    file.open(filename);
    file << "[" << id << "]" << std::endl;
    file << "filename = " << id << std::endl;
    file << "grid = " << "gridprovider.cube" << std::endl;
    file << "boundaryinfo = " << "boundaryinfo.alldirichlet" << std::endl;
    file << "[gridprovider.cube]" << std::endl;
    file << "lowerLeft = [0.0; 0.0; 0.0]" << std::endl;
    file << "upperRight = [1.0; 1.0; 1.0]" << std::endl;
    file << "numElements = [12; 12; 12]" << std::endl;
    file << "[boundaryinfo.idbased]" << std::endl;
    file << "dirichlet = [1; 2; 3]" << std::endl;
    file << "neumann = [4]" << std::endl;
    file << "[diffusion]" << std::endl;
    file << "order = 0"  << std::endl;
    file << "variable = x" << std::endl;
    file << "expression = [1.0; 1.0; 1.0]" << std::endl;
    file << "[force]" << std::endl;
    file << "order = 0"  << std::endl;
    file << "variable = x" << std::endl;
    file << "expression = [1.0; 1.0; 1.0]" << std::endl;
    file << "[dirichlet]" << std::endl;
    file << "order = 0"  << std::endl;
    file << "variable = x" << std::endl;
    file << "expression = [0.1*x[0]; 0.0; 0.0]" << std::endl;
    file << "[neumann]" << std::endl;
    file << "order = 0"  << std::endl;
    file << "variable = x" << std::endl;
    file << "expression = [1.0; 0.0; 0.0]" << std::endl;
    file << "[solver]" << std::endl;
    file << "type = bicgstab.ilut"  << std::endl;
    file << "maxIter = 5000"  << std::endl;
    file << "precision = 1e-12"  << std::endl;
    file.close();
  } // only write param file if there is none
} // void ensureParamFile()

int main(int argc, char** argv)
{
  try {
    // mpi
    Dune::Fem::MPIManager::initialize(argc, argv);

    // parameter
    const std::string paramFilename = id + ".description";
    ensureParamFile(paramFilename);
    Dune::Stuff::Common::ExtendedParameterTree description(argc, argv, paramFilename);
    description.assertSub(id);

    // logger
    Dune::Stuff::Common::Logger().create(Dune::Stuff::Common::LOG_INFO |
                                         Dune::Stuff::Common::LOG_CONSOLE);
    Dune::Stuff::Common::LogStream& info = Dune::Stuff::Common::Logger().info();

    // timer
    Dune::Timer timer;

    info << "setting up grid:" << std::endl;
    typedef Dune::Stuff::GridProviderInterface<> GridProviderType;
    const GridProviderType* gridProvider
        = Dune::Stuff::GridProviders<>::create(description.get(id + ".grid", "gridprovider.cube"),
                                               description);
    typedef GridProviderType::GridType GridType;
    const std::shared_ptr< const GridType > grid = gridProvider->grid();
    typedef Dune::grid::Part::Leaf::Const< GridType > GridPartType;
    typedef typename GridPartType::GridViewType GridViewType;
    const GridPartType gridPart(*grid);
    typedef typename Dune::Stuff::GridboundaryInterface< typename GridPartType::GridViewType > BoundaryInfoType;
    const std::shared_ptr< const BoundaryInfoType > boundaryInfo(
          Dune::Stuff::Gridboundaries< typename GridPartType::GridViewType >::create(
            description.get(id + ".boundaryinfo", "boundaryinfo.alldirichlet"),
            description));
    info << "  took " << timer.elapsed() << " sec, has " << grid->size(0) << " entities" << std::endl;
     info << "visualizing grid... " << std::flush;
     timer.reset();
    gridProvider->visualize(description.get(id + ".boundaryinfo", "boundaryinfo.alldirichlet"),
                            description,
                            description.get(id + ".filename", id) + ".grid");
     info << " done (took " << timer.elapsed() << " sek)" << std::endl;

    const unsigned int DUNE_UNUSED(dimDomain) = GridProviderType::dim;
    const unsigned int DUNE_UNUSED(dimRange) = 1;
    typedef typename GridType::ctype DomainFieldType;
    typedef double RangeFieldType;

    typedef Dune::Stuff::FunctionExpression< DomainFieldType, dimDomain, RangeFieldType, dimRange >
        ExpressionFunctionType;
    const std::shared_ptr< const ExpressionFunctionType >
        diffusion(ExpressionFunctionType::create(description.sub("diffusion")));
    const std::shared_ptr< const ExpressionFunctionType >
        force(ExpressionFunctionType::create(description.sub("force")));
    const std::shared_ptr< const ExpressionFunctionType >
        dirichlet(ExpressionFunctionType::create(description.sub("dirichlet")));
    const std::shared_ptr< const ExpressionFunctionType >
        neumann(ExpressionFunctionType::create(description.sub("neumann")));

    // info << "initializing discrete function spaces... " << std::flush;
    // timer.reset();
    typedef Dune::Detailed::Discretizations
        ::ContinuousLagrangeSpace::FemWrapper< GridPartType, polOrder, RangeFieldType, dimRange > SpaceType;
    const SpaceType space(gridPart);

    // left hand side
    // * elliptic diffusion operator
    typedef Dune::Detailed::Discretizations::EvaluationElliptic<  DomainFieldType, dimDomain,
                                                                  RangeFieldType, dimRange >  EllipticEvaluationType;
    typedef Dune::Detailed::Discretizations::LocalOperatorCodim0Integral< EllipticEvaluationType,
                                                                  ExpressionFunctionType >    EllipticOperatorType;
    const EllipticOperatorType diffusionOperator(*diffusion);
    // * right hand side
    //   * L2 force functional
    typedef Dune::Detailed::Discretizations::EvaluationProduct< DomainFieldType, dimDomain,
                                                                RangeFieldType, dimRange >  ProductEvaluationType;
    typedef Dune::Detailed::Discretizations::LocalFunctionalCodim0Integral< ProductEvaluationType,
                                                                ExpressionFunctionType >    L2FunctionalType;
    const L2FunctionalType forceFunctional(*force);
    //   * L2 neumann functional
    const L2FunctionalType neumannFunctional(*neumann);

    info << "initializing matrix (of size " << space.mapper().size() << "x" << space.mapper().size()
         << ") and vectors... " << std::flush;
    // timer.reset();
    typedef ContainerFactoryEigen< RangeFieldType > ContainerFactory;
    typedef ContainerFactory::RowMajorSparseMatrixType MatrixType;
    typedef ContainerFactory::DenseVectorType VectorType;
    std::shared_ptr< MatrixType > systemMatrix(ContainerFactory::createRowMajorSparseMatrix(space, space));
    std::shared_ptr< VectorType > forceVector(ContainerFactory::createDenseVector(space));
    std::shared_ptr< VectorType > dirichletVector(ContainerFactory::createDenseVector(space));
    std::shared_ptr< VectorType > neumannVector(ContainerFactory::createDenseVector(space));
    std::shared_ptr< VectorType > rhsVector(ContainerFactory::createDenseVector(space));
    std::shared_ptr< VectorType > solutionVector(ContainerFactory::createDenseVector(space));
    info << "done (took " << timer.elapsed() << " sec)" << std::endl;

    info << "assembing system... " << std::flush;
    timer.reset();
    // * dirichlet boundary values
    typedef Dune::Detailed::Discretizations::DiscreteFunctionDefault< SpaceType, VectorType > DiscreteFunctionType;
    DiscreteFunctionType dirichletProjection(space, dirichletVector, "dirichlet");
    Dune::Stuff::DiscreteFunction::project(*boundaryInfo, *dirichlet, dirichletProjection);

    // * local matrix assembler
    typedef Dune::Detailed::Discretizations::LocalAssemblerCodim0Matrix< EllipticOperatorType >
        LocalEllipticOperatorMatrixAssemblerType;
    const LocalEllipticOperatorMatrixAssemblerType diffusionMatrixAssembler(diffusionOperator);
    // * local vector assemblers
    typedef Dune::Detailed::Discretizations::LocalAssemblerCodim0Vector< L2FunctionalType >
        LocalL2FunctionalVectorAssemblerType;
    //   * force vector
    const LocalL2FunctionalVectorAssemblerType forceVectorAssembler(forceFunctional);
    //   * neumann vector
    const LocalL2FunctionalVectorAssemblerType neumannVectorAssembler(neumannFunctional);
    // * system assembler
    typedef Dune::Detailed::Discretizations::SystemAssembler< SpaceType, SpaceType > SystemAssemblerType;
    SystemAssemblerType systemAssembler(space);
    systemAssembler.addLocalMatrixAssembler(diffusionMatrixAssembler, *systemMatrix);
    systemAssembler.addLocalVectorAssembler(forceVectorAssembler, *forceVector);
    systemAssembler.addLocalVectorAssembler(neumannVectorAssembler, *neumannVector);
    systemAssembler.assemble();
    info << "done (took " << timer.elapsed() << " sec)" << std::endl;

    info << "applying constraints... " << std::flush;
    timer.reset();
    Constraints::Dirichlet< GridViewType, RangeFieldType > dirichletConstraints(*boundaryInfo,
                                                                                space.mapper().maxNumDofs(),
                                                                                space.mapper().maxNumDofs());
    rhsVector->backend() = forceVector->backend()
        + neumannVector->backend()
        - systemMatrix->backend()*dirichletVector->backend();
    systemAssembler.applyConstraints(dirichletConstraints, *systemMatrix, *rhsVector);
    info << "done (took " << timer.elapsed() << " sec)" << std::endl;

    info << "solving linear system (of size " << systemMatrix->rows() << "x" << systemMatrix->cols() << ")" << std::endl;
    const std::string solverType = description.get("solver.type", "bicgstab");
    const unsigned int solverMaxIter = description.get("solver.maxIter", 5000);
    const double solverPrecision = description.get("solver.precision", 1e-12);
    info << "  using '" << solverType << "'... " << std::flush;
    timer.reset();
    typedef typename Dune::Stuff::LA::Solver::Interface< MatrixType, VectorType > SolverType;
    std::shared_ptr< SolverType > solver(Dune::Stuff::LA::Solver::create< MatrixType, VectorType >(solverType));
    const unsigned int failure = solver->apply(*systemMatrix,
                                               *rhsVector,
                                               *solutionVector,
                                               solverMaxIter,
                                               solverPrecision);
    if (failure)
      DUNE_THROW(Dune::MathError,
                 "\nERROR: linear solver '" << solverType << "' reported a problem!");
    if (solutionVector->size() != space.mapper().size())
      DUNE_THROW(Dune::MathError,
                 "\nERROR: linear solver '" << solverType << "' produced a solution of wrong size (is "
                 << solutionVector->size() << ", should be " << space.mapper().size() << ")!");
    solutionVector->backend() += dirichletVector->backend();
    info << "done (took " << timer.elapsed() << " sec)" << std::endl;

    const std::string solutionFilename = description.get(id + ".filename", id) + ".solution";
    const std::string solutionName = id + ".solution";
    info << "writing solution to '" << solutionFilename;
    if (dimDomain == 1)
      info << ".vtp";
    else
      info << ".vtu";
    info << "'... " << std::flush;
    timer.reset();
    typedef Dune::Detailed::Discretizations::DiscreteFunctionDefaultConst< SpaceType, VectorType > ConstDiscreteFunctionType;
    const std::shared_ptr< const ConstDiscreteFunctionType > solution(new ConstDiscreteFunctionType(space,
                                                                                solutionVector,
                                                                                solutionName));
    typedef Dune::VTKWriter< GridViewType > VTKWriterType;
    VTKWriterType vtkWriter(gridPart.gridView());
    vtkWriter.addVertexData(solution);
    vtkWriter.write(solutionFilename);
    info << "done (took " << timer.elapsed() << " sec)" << std::endl;

    // done
    return 0;
  } catch (Dune::Exception& e) {
    std::cerr << "Dune reported error: " << e.what() << std::endl;
  } catch (std::exception& e) {
    std::cerr << e.what() << std::endl;
  } catch (...) {
    std::cerr << "Unknown exception thrown!" << std::endl;
  } // try
} // main
<|endoftext|>


<commit_before>#include "gtest_utils.h"

#include "onnx/checker.h"
#include "onnx/onnxifi.h"
#include "onnx/onnxifi_loader.h"
#include "onnx/string_utils.h"

/**
 *	In order to not test the backend itself
 *	but only to test the funcionality of this test driver,
 *	include IO and integrity checkers,
 *	please set ONNXIFI_DUMMY_BACKEND to be true when compiling.
 *	By default it is false.
 */
#ifndef ONNXIFI_DUMMY_BACKEND
#define ONNXIFI_DUMMY_BACKEND false
#endif

#ifndef ONNXIFI_TESTDATA_EPS
#define ONNXIFI_TESTDATA_EPS 1e-5
#endif

const float onnxifi_testdata_eps = ONNXIFI_TESTDATA_EPS;

template <typename T>
class CompareOnnxifiData {
 public:
  bool IsEqual(void* P, void* Q) {
    T x = *((T*)P), y = *((T*)Q);
    return ((x - y) > -onnxifi_testdata_eps) &&
        ((x - y) < onnxifi_testdata_eps);
  }
};
class ONNXCppDriverTest
    : public testing::TestWithParam<ONNX_NAMESPACE::testing::ResolvedTestCase> {
 protected:
  std::vector<ONNX_NAMESPACE::testing::ResolvedTestData> protos_;
  ONNX_NAMESPACE::ModelProto model_;
  void SetUp() override {
    ONNX_NAMESPACE::testing::ResolvedTestCase t = GetParam();
    protos_ = t.proto_test_data_;
    model_ = t.model_;
  }
  uint64_t GetDescriptorSize(const onnxTensorDescriptorV1* t) {
    uint64_t d_size = 1;
    for (int i = 0; i < t->dimensions; i++) {
      d_size *= t->shape[i];
    }
    return d_size;
  }
  bool IsDescriptorEqual(
      const onnxTensorDescriptorV1& x,
      const onnxTensorDescriptorV1& y) {
    if (x.dataType != y.dataType || x.dimensions != y.dimensions) {
      return false;
    }
    const int dims = x.dimensions;
    for (int i = 0; i < dims; i++) {
      if (x.shape[i] != y.shape[i]) {
        return false;
      }
    }
    const uint64_t d_size = GetDescriptorSize(&x);
    void* p1 = (void*)x.buffer;
    void* p2 = (void*)y.buffer;
    bool is_equal = true;
    for (uint64_t i = 0; i < d_size; i++) {
      int offset = 1;
      switch (x.dataType) {
        case ONNXIFI_DATATYPE_UNDEFINED:
        case ONNXIFI_DATATYPE_INT8:
          CompareOnnxifiData<char> compare_int8;
          is_equal &= compare_int8.IsEqual(p1, p2);
          offset = sizeof(char);
          break;
        case ONNXIFI_DATATYPE_UINT8:
          CompareOnnxifiData<unsigned char> compare_uint8;
          is_equal &= compare_uint8.IsEqual(p1, p2);
          offset = sizeof(unsigned char);
          break;
        case ONNXIFI_DATATYPE_FLOAT16:
          // no support now
          break;
        case ONNXIFI_DATATYPE_INT16:
          CompareOnnxifiData<short> compare_int16;
          is_equal &= compare_int16.IsEqual(p1, p2);
          offset = sizeof(short);
          break;
        case ONNXIFI_DATATYPE_UINT16:
          CompareOnnxifiData<unsigned short> compare_uint16;
          is_equal &= compare_uint16.IsEqual(p1, p2);
          offset = sizeof(unsigned short);
          break;
        case ONNXIFI_DATATYPE_FLOAT32:
          CompareOnnxifiData<float> compare_float32;
          is_equal &= compare_float32.IsEqual(p1, p2);
          offset = sizeof(float);
          break;
        case ONNXIFI_DATATYPE_INT32:
          CompareOnnxifiData<int> compare_int32;
          is_equal &= compare_int32.IsEqual(p1, p2);
          offset = sizeof(int);
          break;
        case ONNXIFI_DATATYPE_UINT32:
          CompareOnnxifiData<unsigned int> compare_uint32;
          is_equal &= compare_uint32.IsEqual(p1, p2);
          offset = sizeof(unsigned int);
          break;
        case ONNXIFI_DATATYPE_FLOAT64:
          CompareOnnxifiData<long double> compare_float64;
          is_equal &= compare_float64.IsEqual(p1, p2);
          offset = sizeof(long double);
          break;
        case ONNXIFI_DATATYPE_INT64:
          CompareOnnxifiData<long long> compare_int64;
          is_equal &= compare_int64.IsEqual(p1, p2);
          offset = sizeof(long long);
          break;
        case ONNXIFI_DATATYPE_UINT64:
          CompareOnnxifiData<unsigned long long> compare_uint64;
          is_equal &= compare_uint64.IsEqual(p1, p2);
          offset = sizeof(unsigned long long);
          break;
        case ONNXIFI_DATATYPE_COMPLEX64:
        case ONNXIFI_DATATYPE_COMPLEX128:
          // no support now
          break;
      }
      p1 = (char*)p1 + offset;
      p2 = (char*)p2 + offset;
      if (!is_equal) {
        return false;
      }
    }
    return true;
  }
  void RunAndVerify(onnxifi_library& lib, onnxBackend& backend) {
    // Check Model
    ONNX_NAMESPACE::checker::check_model(model_);
    // Check Input&Output Tensors
    ONNX_NAMESPACE::checker::CheckerContext ctx;
    for (auto proto_test_data : protos_) {
      for (auto input : proto_test_data.inputs_) {
        ONNX_NAMESPACE::checker::check_tensor(input, ctx);
      }
      for (auto output : proto_test_data.outputs_) {
        ONNX_NAMESPACE::checker::check_tensor(output, ctx);
      }
    }
    if (!ONNXIFI_DUMMY_BACKEND) {
      onnxGraph graph;
      uint32_t weightCount = model_.graph().initializer_size();
      onnxTensorDescriptorV1 weightDescriptors,
          *weightDescriptors_pointer = NULL;
      if (weightCount != 0) {
        weightDescriptors =
            ONNX_NAMESPACE::testing::ProtoToOnnxTensorDescriptor(
                model_.graph().initializer(0));
        weightDescriptors_pointer = &weightDescriptors;
      }
      std::string serialized_model;
      model_.SerializeToString(&serialized_model);
      EXPECT_EQ(
          lib.onnxInitGraph(
              backend,
              NULL,
              serialized_model.size(),
              serialized_model.c_str(),
              weightCount,
              weightDescriptors_pointer,
              &graph),
          ONNXIFI_STATUS_SUCCESS);
      for (const auto& proto_test_data : protos_) {
        std::vector<onnxTensorDescriptorV1> input_descriptor, output_descriptor,
            result_descriptor;
        for (const auto& input : proto_test_data.inputs_) {
          input_descriptor.push_back(
              ONNX_NAMESPACE::testing::ProtoToOnnxTensorDescriptor(input));
        }
        int output_count = 0;
        for (auto& output : proto_test_data.outputs_) {
          output_count++;
          output_descriptor.push_back(
              ONNX_NAMESPACE::testing::ProtoToOnnxTensorDescriptor(output));
          onnxTensorDescriptorV1 result;
          result.tag = ONNXIFI_TAG_TENSOR_DESCRIPTOR_V1;
          std::string name_string =
              "output_" + ONNX_NAMESPACE::to_string(output_count);
          result.name = name_string.c_str();
          result.dataType = output.data_type();
          result.memoryType = ONNXIFI_MEMORY_TYPE_CPU;
          std::vector<uint64_t> shape_values(
              output.dims().begin(), output.dims().end());
          result.dimensions = shape_values.size();
          result.shape = shape_values.data();
          std::vector<uint8_t> raw_data(output.raw_data().size(), 0);
          result.buffer = (onnxPointer)raw_data.data();
          result_descriptor.emplace_back(std::move(result));
        }
        EXPECT_EQ(
            lib.onnxSetGraphIO(
                graph,
                input_descriptor.size(),
                input_descriptor.data(),
                result_descriptor.size(),
                result_descriptor.data()),
            ONNXIFI_STATUS_SUCCESS);

        onnxMemoryFenceV1 inputFence, outputFence;
        inputFence.tag = ONNXIFI_TAG_MEMORY_FENCE_V1;
        outputFence.tag = ONNXIFI_TAG_MEMORY_FENCE_V1;
        inputFence.type = ONNXIFI_SYNCHRONIZATION_EVENT;
        outputFence.type = ONNXIFI_SYNCHRONIZATION_EVENT;

        EXPECT_EQ(
            lib.onnxRunGraph(graph, &inputFence, &outputFence),
            ONNXIFI_STATUS_SUCCESS);
        EXPECT_EQ(lib.onnxWaitEvent(outputFence.event), ONNXIFI_STATUS_SUCCESS);
        for (int i = 0; i < output_descriptor.size(); i++) {
          auto output_size = GetDescriptorSize(&output_descriptor[i]);
          for (int j = 0; j < output_size; j++) {
            EXPECT_EQ(
                IsDescriptorEqual(output_descriptor[i], result_descriptor[i]),
                true);
            ;
          }
        }
      }
      EXPECT_EQ(lib.onnxReleaseGraph(graph), ONNXIFI_STATUS_SUCCESS);
    }
  }
};

/**
 *	When testing backend, we do not specify target backend here,
 *	but always use the by-default backend of onnxifi_loader.
 *	Check onnxifi_loader.c for more detail of how to indicate specific
 *  backend.
 */
TEST_P(ONNXCppDriverTest, ONNXCppDriverUnitTest){
  onnxifi_library lib;
  onnxBackendID backendID = NULL;
  onnxBackend backend;
  if (!ONNXIFI_DUMMY_BACKEND) {
    EXPECT_TRUE(onnxifi_load(1, NULL, &lib));
    size_t numBackends = 0;
    lib.onnxGetBackendIDs(&backendID, &numBackends);
    const uint64_t backendProperties[] = {ONNXIFI_BACKEND_PROPERTY_NONE};
    lib.onnxInitBackend(backendID, backendProperties, &backend);
  }
  RunAndVerify(lib, backend);
  if (!ONNXIFI_DUMMY_BACKEND) {
    lib.onnxReleaseBackend(backend);
    lib.onnxReleaseBackendID(backendID);
  }
}
INSTANTIATE_TEST_CASE_P(
    ONNXCppAllTest,
    ONNXCppDriverTest,
    testing::ValuesIn(GetTestCases()));
<commit_msg>[ONNXIFI]gtest:expect to assert (#1456)<commit_after>#include "gtest_utils.h"

#include "onnx/checker.h"
#include "onnx/onnxifi.h"
#include "onnx/onnxifi_loader.h"
#include "onnx/string_utils.h"

/**
 *	In order to not test the backend itself
 *	but only to test the funcionality of this test driver,
 *	include IO and integrity checkers,
 *	please set ONNXIFI_DUMMY_BACKEND to be true when compiling.
 *	By default it is false.
 */
#ifndef ONNXIFI_DUMMY_BACKEND
#define ONNXIFI_DUMMY_BACKEND false
#endif

#ifndef ONNXIFI_TESTDATA_EPS
#define ONNXIFI_TESTDATA_EPS 1e-5
#endif

const float onnxifi_testdata_eps = ONNXIFI_TESTDATA_EPS;

template <typename T>
class CompareOnnxifiData {
 public:
  bool IsEqual(void* P, void* Q) {
    T x = *((T*)P), y = *((T*)Q);
    return ((x - y) > -onnxifi_testdata_eps) &&
        ((x - y) < onnxifi_testdata_eps);
  }
};
class ONNXCppDriverTest
    : public testing::TestWithParam<ONNX_NAMESPACE::testing::ResolvedTestCase> {
 protected:
  std::vector<ONNX_NAMESPACE::testing::ResolvedTestData> protos_;
  ONNX_NAMESPACE::ModelProto model_;
  void SetUp() override {
    ONNX_NAMESPACE::testing::ResolvedTestCase t = GetParam();
    protos_ = t.proto_test_data_;
    model_ = t.model_;
  }
  uint64_t GetDescriptorSize(const onnxTensorDescriptorV1* t) {
    uint64_t d_size = 1;
    for (int i = 0; i < t->dimensions; i++) {
      d_size *= t->shape[i];
    }
    return d_size;
  }
  bool IsDescriptorEqual(
      const onnxTensorDescriptorV1& x,
      const onnxTensorDescriptorV1& y) {
    if (x.dataType != y.dataType || x.dimensions != y.dimensions) {
      return false;
    }
    const int dims = x.dimensions;
    for (int i = 0; i < dims; i++) {
      if (x.shape[i] != y.shape[i]) {
        return false;
      }
    }
    const uint64_t d_size = GetDescriptorSize(&x);
    void* p1 = (void*)x.buffer;
    void* p2 = (void*)y.buffer;
    bool is_equal = true;
    for (uint64_t i = 0; i < d_size; i++) {
      int offset = 1;
      switch (x.dataType) {
        case ONNXIFI_DATATYPE_UNDEFINED:
        case ONNXIFI_DATATYPE_INT8:
          CompareOnnxifiData<char> compare_int8;
          is_equal &= compare_int8.IsEqual(p1, p2);
          offset = sizeof(char);
          break;
        case ONNXIFI_DATATYPE_UINT8:
          CompareOnnxifiData<unsigned char> compare_uint8;
          is_equal &= compare_uint8.IsEqual(p1, p2);
          offset = sizeof(unsigned char);
          break;
        case ONNXIFI_DATATYPE_FLOAT16:
          // no support now
          break;
        case ONNXIFI_DATATYPE_INT16:
          CompareOnnxifiData<short> compare_int16;
          is_equal &= compare_int16.IsEqual(p1, p2);
          offset = sizeof(short);
          break;
        case ONNXIFI_DATATYPE_UINT16:
          CompareOnnxifiData<unsigned short> compare_uint16;
          is_equal &= compare_uint16.IsEqual(p1, p2);
          offset = sizeof(unsigned short);
          break;
        case ONNXIFI_DATATYPE_FLOAT32:
          CompareOnnxifiData<float> compare_float32;
          is_equal &= compare_float32.IsEqual(p1, p2);
          offset = sizeof(float);
          break;
        case ONNXIFI_DATATYPE_INT32:
          CompareOnnxifiData<int> compare_int32;
          is_equal &= compare_int32.IsEqual(p1, p2);
          offset = sizeof(int);
          break;
        case ONNXIFI_DATATYPE_UINT32:
          CompareOnnxifiData<unsigned int> compare_uint32;
          is_equal &= compare_uint32.IsEqual(p1, p2);
          offset = sizeof(unsigned int);
          break;
        case ONNXIFI_DATATYPE_FLOAT64:
          CompareOnnxifiData<long double> compare_float64;
          is_equal &= compare_float64.IsEqual(p1, p2);
          offset = sizeof(long double);
          break;
        case ONNXIFI_DATATYPE_INT64:
          CompareOnnxifiData<long long> compare_int64;
          is_equal &= compare_int64.IsEqual(p1, p2);
          offset = sizeof(long long);
          break;
        case ONNXIFI_DATATYPE_UINT64:
          CompareOnnxifiData<unsigned long long> compare_uint64;
          is_equal &= compare_uint64.IsEqual(p1, p2);
          offset = sizeof(unsigned long long);
          break;
        case ONNXIFI_DATATYPE_COMPLEX64:
        case ONNXIFI_DATATYPE_COMPLEX128:
          // no support now
          break;
      }
      p1 = (char*)p1 + offset;
      p2 = (char*)p2 + offset;
      if (!is_equal) {
        return false;
      }
    }
    return true;
  }
  void RunAndVerify(onnxifi_library& lib, onnxBackend& backend) {
    // Check Model
    ONNX_NAMESPACE::checker::check_model(model_);
    // Check Input&Output Tensors
    ONNX_NAMESPACE::checker::CheckerContext ctx;
    for (auto proto_test_data : protos_) {
      for (auto input : proto_test_data.inputs_) {
        ONNX_NAMESPACE::checker::check_tensor(input, ctx);
      }
      for (auto output : proto_test_data.outputs_) {
        ONNX_NAMESPACE::checker::check_tensor(output, ctx);
      }
    }
    if (!ONNXIFI_DUMMY_BACKEND) {
      onnxGraph graph;
      uint32_t weightCount = model_.graph().initializer_size();
      onnxTensorDescriptorV1 weightDescriptors,
          *weightDescriptors_pointer = NULL;
      if (weightCount != 0) {
        weightDescriptors =
            ONNX_NAMESPACE::testing::ProtoToOnnxTensorDescriptor(
                model_.graph().initializer(0));
        weightDescriptors_pointer = &weightDescriptors;
      }
      std::string serialized_model;
      model_.SerializeToString(&serialized_model);
      ASSERT_EQ(
          lib.onnxInitGraph(
              backend,
              NULL,
              serialized_model.size(),
              serialized_model.data(),
              weightCount,
              weightDescriptors_pointer,
              &graph),
          ONNXIFI_STATUS_SUCCESS);
      for (const auto& proto_test_data : protos_) {
        std::vector<onnxTensorDescriptorV1> input_descriptor, output_descriptor,
            result_descriptor;
        for (const auto& input : proto_test_data.inputs_) {
          input_descriptor.push_back(
              ONNX_NAMESPACE::testing::ProtoToOnnxTensorDescriptor(input));
        }
        int output_count = 0;
        for (auto& output : proto_test_data.outputs_) {
          output_count++;
          output_descriptor.push_back(
              ONNX_NAMESPACE::testing::ProtoToOnnxTensorDescriptor(output));
          onnxTensorDescriptorV1 result;
          result.tag = ONNXIFI_TAG_TENSOR_DESCRIPTOR_V1;
          std::string name_string =
              "output_" + ONNX_NAMESPACE::to_string(output_count);
          result.name = name_string.c_str();
          result.dataType = output.data_type();
          result.memoryType = ONNXIFI_MEMORY_TYPE_CPU;
          std::vector<uint64_t> shape_values(
              output.dims().begin(), output.dims().end());
          result.dimensions = shape_values.size();
          result.shape = shape_values.data();
          std::vector<uint8_t> raw_data(output.raw_data().size(), 0);
          result.buffer = (onnxPointer)raw_data.data();
          result_descriptor.emplace_back(std::move(result));
        }
        ASSERT_EQ(
            lib.onnxSetGraphIO(
                graph,
                input_descriptor.size(),
                input_descriptor.data(),
                result_descriptor.size(),
                result_descriptor.data()),
            ONNXIFI_STATUS_SUCCESS);

        onnxMemoryFenceV1 inputFence, outputFence;
        inputFence.tag = ONNXIFI_TAG_MEMORY_FENCE_V1;
        outputFence.tag = ONNXIFI_TAG_MEMORY_FENCE_V1;
        inputFence.type = ONNXIFI_SYNCHRONIZATION_EVENT;
        outputFence.type = ONNXIFI_SYNCHRONIZATION_EVENT;

        ASSERT_EQ(
            lib.onnxRunGraph(graph, &inputFence, &outputFence),
            ONNXIFI_STATUS_SUCCESS);
        ASSERT_EQ(lib.onnxWaitEvent(outputFence.event), ONNXIFI_STATUS_SUCCESS);
        for (int i = 0; i < output_descriptor.size(); i++) {
          auto output_size = GetDescriptorSize(&output_descriptor[i]);
          for (int j = 0; j < output_size; j++) {
            EXPECT_EQ(
                IsDescriptorEqual(output_descriptor[i], result_descriptor[i]),
                true);
            ;
          }
        }
      }
      ASSERT_EQ(lib.onnxReleaseGraph(graph), ONNXIFI_STATUS_SUCCESS);
    }
  }
};

/**
 *	When testing backend, we do not specify target backend here,
 *	but always use the by-default backend of onnxifi_loader.
 *	Check onnxifi_loader.c for more detail of how to indicate specific
 *  backend.
 */
TEST_P(ONNXCppDriverTest, ONNXCppDriverUnitTest){
  onnxifi_library lib;
  onnxBackendID backendID = NULL;
  onnxBackend backend;
  if (!ONNXIFI_DUMMY_BACKEND) {
    ASSERT_TRUE(onnxifi_load(1, NULL, &lib));
    size_t numBackends = 0;
    lib.onnxGetBackendIDs(&backendID, &numBackends);
    const uint64_t backendProperties[] = {ONNXIFI_BACKEND_PROPERTY_NONE};
    lib.onnxInitBackend(backendID, backendProperties, &backend);
  }
  RunAndVerify(lib, backend);
  if (!ONNXIFI_DUMMY_BACKEND) {
    lib.onnxReleaseBackend(backend);
    lib.onnxReleaseBackendID(backendID);
  }
}
INSTANTIATE_TEST_CASE_P(
    ONNXCppAllTest,
    ONNXCppDriverTest,
    testing::ValuesIn(GetTestCases()));
<|endoftext|>


<commit_before>/* Copyright (c) 2016 PaddlePaddle Authors. All Rights Reserved.

Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at

http://www.apache.org/licenses/LICENSE-2.0

Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License. */
#include "paddle/fluid/pybind/protobuf.h"

#include <deque>
#include <iostream>
#include <string>
#include <tuple>

#include "paddle/fluid/framework/block_desc.h"
#include "paddle/fluid/framework/op_desc.h"
#include "paddle/fluid/framework/program_desc.h"
#include "paddle/fluid/framework/var_desc.h"

// Cast boost::variant for PyBind.
// Copy from
// https://github.com/pybind/pybind11/issues/576#issuecomment-269563199
namespace pybind11 {
namespace detail {

// Can be replaced by a generic lambda in C++14
struct __attribute__((visibility("hidden"))) paddle_variant_caster_visitor
    : public boost::static_visitor<handle> {
  return_value_policy policy;
  handle parent;

  paddle_variant_caster_visitor(return_value_policy policy, handle parent)
      : policy(policy), parent(parent) {}

  template <class T>
  handle operator()(T const &src) const {
    return make_caster<T>::cast(src, policy, parent);
  }
};

template <class Variant>
struct paddle_variant_caster;

template <template <class...> class V, class... Ts>
struct paddle_variant_caster<V<Ts...>> {
  using Type = V<Ts...>;

  template <typename T>
  typename std::enable_if<
      !std::is_same<T, boost::detail::variant::void_>::value, bool>::type
  try_load(handle src, bool convert) {
    auto caster = make_caster<T>();
    if (!load_success_ && caster.load(src, convert)) {
      load_success_ = true;

      if (std::is_same<T, std::vector<float>>::value) {
        auto caster_ints = make_caster<std::vector<int64_t>>();
        if (caster_ints.load(src, convert)) {
          VLOG(40) << "This value are floats and int64_ts satisfy "
                      "simultaneously, will set it's type to "
                      "std::vector<int64_t>";
          value = cast_op<std::vector<int64_t>>(caster_ints);
          return true;
        }
      }

      value = cast_op<T>(caster);
      return true;
    }
    return false;
  }

  template <typename T>
  typename std::enable_if<std::is_same<T, boost::detail::variant::void_>::value,
                          bool>::type
  try_load(handle src, bool convert) {
    return false;
  }

  bool load(handle src, bool convert) {
    auto unused = {false, try_load<Ts>(src, convert)...};
    (void)(unused);
    return load_success_;
  }

  static handle cast(Type const &src, return_value_policy policy,
                     handle parent) {
    paddle_variant_caster_visitor visitor(policy, parent);
    return boost::apply_visitor(visitor, src);
  }

  PYBIND11_TYPE_CASTER(Type, _("Variant"));
  bool load_success_{false};
};

// Add specialization for concrete variant type
template <class... Args>
struct type_caster<boost::variant<Args...>>
    : paddle_variant_caster<boost::variant<Args...>> {};

}  // namespace detail
}  // namespace pybind11

namespace paddle {
namespace pybind {

namespace pd = paddle::framework;

template <typename T>
static pybind11::bytes SerializeMessage(
    T &self) {  // NOLINT due to pybind11 convention.
  // Check IsInitialized in Python
  std::string retv;
  PADDLE_ENFORCE(self.Proto()->SerializePartialToString(&retv),
                 "Cannot serialize message");
  return retv;
}

// Bind Methods
void BindProgramDesc(pybind11::module *m) {
  pybind11::class_<pd::ProgramDesc>(*m, "ProgramDesc", "")
      .def(pybind11::init<>())
      .def("__init__",
           [](pd::ProgramDesc &self, const pd::ProgramDesc &other) {
             new (&self) pd::ProgramDesc(other);
           })
      .def("__init__",
           [](pd::ProgramDesc &self, const pybind11::bytes &binary_str) {
             std::string str(binary_str);
             new (&self) pd::ProgramDesc(str);
           })
      .def("append_block", &pd::ProgramDesc::AppendBlock,
           pybind11::return_value_policy::reference)
      .def("block", &pd::ProgramDesc::MutableBlock,
           pybind11::return_value_policy::reference)
      .def("num_blocks", &pd::ProgramDesc::Size)
      .def("flush", &pd::ProgramDesc::Flush)
      .def("get_feed_target_names", &pd::ProgramDesc::GetFeedTargetNames)
      .def("get_fetch_target_names", &pd::ProgramDesc::GetFetchTargetNames)
      .def("serialize_to_string", SerializeMessage<pd::ProgramDesc>)
      .def("parse_from_string",
           [](pd::ProgramDesc &program_desc, const std::string &data) {
             pd::proto::ProgramDesc *desc = program_desc.Proto();
             PADDLE_ENFORCE(desc->ParseFromString(data),
                            "Fail to parse ProgramDesc from string. This could "
                            "be a bug of Paddle.");
           })
      .def("_version", [](pd::ProgramDesc &self) -> int64_t {
        return self.Proto()->version().version();
      });
}

void BindBlockDesc(pybind11::module *m) {
  pybind11::class_<pd::BlockDesc>(*m, "BlockDesc", "")
      .def_property_readonly("id", &pd::BlockDesc::ID)
      .def_property_readonly("parent", &pd::BlockDesc::Parent)
      .def("get_forward_block_idx", &pd::BlockDesc::ForwardBlockID)
      .def("_set_forward_block_idx", &pd::BlockDesc::SetForwardBlockID)
      .def("append_op", &pd::BlockDesc::AppendOp,
           pybind11::return_value_policy::reference)
      .def("_prepend_op", &pd::BlockDesc::PrependOp,
           pybind11::return_value_policy::reference)
      .def("_insert_op", &pd::BlockDesc::InsertOp,
           pybind11::return_value_policy::reference)
      .def("_remove_op", &pd::BlockDesc::RemoveOp)
      .def("var",
           [](pd::BlockDesc &self, pybind11::bytes byte_name) {
             std::string name = byte_name;
             return self.Var(name);
           },
           pybind11::return_value_policy::reference)
      .def("has_var",
           [](pd::BlockDesc &self, pybind11::bytes byte_name) {
             std::string name = byte_name;
             return self.HasVar(name);
           },
           pybind11::return_value_policy::reference)
      .def("_rename_var",
           [](pd::BlockDesc &self, const pybind11::bytes &byte_name,
              const pybind11::bytes &byte_name_new) {
             std::string name = byte_name;
             std::string new_name = byte_name_new;
             self.RenameVar(name, new_name);
           })
      .def("has_var_recursive",
           [](pd::BlockDesc &self, pybind11::bytes byte_name) {
             std::string name = byte_name;
             return self.HasVarRecursive(name);
           })
      .def("find_var",
           [](pd::BlockDesc &self, pybind11::bytes byte_name) {
             std::string name = byte_name;
             return self.FindVar(name);
           },
           pybind11::return_value_policy::reference)
      .def("find_var_recursive",
           [](pd::BlockDesc &self, pybind11::bytes byte_name) {
             std::string name = byte_name;
             return self.FindVarRecursive(name);
           },
           pybind11::return_value_policy::reference)
      .def("_remove_var",
           [](pd::BlockDesc &self, pybind11::bytes byte_name) {
             std::string name = byte_name;
             return self.RemoveVar(name);
           },
           pybind11::return_value_policy::reference)
      .def("all_vars", &pd::BlockDesc::AllVars,
           pybind11::return_value_policy::reference)
      .def("op_size", &pd::BlockDesc::OpSize)
      .def("op", &pd::BlockDesc::Op, pybind11::return_value_policy::reference)
      .def("serialize_to_string", SerializeMessage<pd::BlockDesc>);
}

void BindVarDsec(pybind11::module *m) {
  pybind11::class_<pd::VarDesc> var_desc(*m, "VarDesc", "");
  var_desc
      .def("name", &pd::VarDesc::Name, pybind11::return_value_policy::reference)
      .def("set_name", &pd::VarDesc::SetName)
      .def("set_shape", &pd::VarDesc::SetShape)
      .def("set_shapes", &pd::VarDesc::SetShapes)
      .def("set_dtype", &pd::VarDesc::SetDataType)
      .def("set_dtypes", &pd::VarDesc::SetDataTypes)
      .def("shape", &pd::VarDesc::GetShape,
           pybind11::return_value_policy::reference)
      .def("shapes", &pd::VarDesc::GetShapes,
           pybind11::return_value_policy::reference)
      .def("dtype", &pd::VarDesc::GetDataType,
           pybind11::return_value_policy::reference)
      .def("dtypes", &pd::VarDesc::GetDataTypes,
           pybind11::return_value_policy::reference)
      .def("lod_level", &pd::VarDesc::GetLoDLevel)
      .def("lod_levels", &pd::VarDesc::GetLoDLevels,
           pybind11::return_value_policy::reference)
      .def("set_lod_level", &pd::VarDesc::SetLoDLevel)
      .def("set_lod_levels", &pd::VarDesc::SetLoDLevels)
      .def("type", &pd::VarDesc::GetType)
      .def("set_type", &pd::VarDesc::SetType)
      .def("serialize_to_string", SerializeMessage<pd::VarDesc>)
      .def("persistable", &pd::VarDesc::Persistable)
      .def("set_persistable", &pd::VarDesc::SetPersistable);

  pybind11::enum_<pd::proto::VarType::Type>(var_desc, "VarType", "")
      .value("BOOL", pd::proto::VarType::BOOL)
      .value("UINT8", pd::proto::VarType::UINT8)
      .value("INT8", pd::proto::VarType::INT8)
      .value("INT16", pd::proto::VarType::INT16)
      .value("INT32", pd::proto::VarType::INT32)
      .value("INT64", pd::proto::VarType::INT64)
      .value("FP16", pd::proto::VarType::FP16)
      .value("FP32", pd::proto::VarType::FP32)
      .value("FP64", pd::proto::VarType::FP64)
      .value("LOD_TENSOR", pd::proto::VarType::LOD_TENSOR)
      .value("SELECTED_ROWS", pd::proto::VarType::SELECTED_ROWS)
      .value("FEED_MINIBATCH", pd::proto::VarType::FEED_MINIBATCH)
      .value("FETCH_LIST", pd::proto::VarType::FETCH_LIST)
      .value("STEP_SCOPES", pd::proto::VarType::STEP_SCOPES)
      .value("LOD_RANK_TABLE", pd::proto::VarType::LOD_RANK_TABLE)
      .value("LOD_TENSOR_ARRAY", pd::proto::VarType::LOD_TENSOR_ARRAY)
      .value("PLACE_LIST", pd::proto::VarType::PLACE_LIST)
      .value("READER", pd::proto::VarType::READER)
      .value("RAW", pd::proto::VarType::RAW);
}

void BindOpDesc(pybind11::module *m) {
  pybind11::enum_<pd::proto::AttrType>(*m, "AttrType", "")
      .value("INT", pd::proto::AttrType::INT)
      .value("INTS", pd::proto::AttrType::INTS)
      .value("LONG", pd::proto::AttrType::LONG)
      .value("LONGS", pd::proto::AttrType::LONGS)
      .value("FLOAT", pd::proto::AttrType::FLOAT)
      .value("FLOATS", pd::proto::AttrType::FLOATS)
      .value("STRING", pd::proto::AttrType::STRING)
      .value("STRINGS", pd::proto::AttrType::STRINGS)
      .value("BOOL", pd::proto::AttrType::BOOLEAN)
      .value("BOOLS", pd::proto::AttrType::BOOLEANS)
      .value("BLOCK", pd::proto::AttrType::BLOCK)
      .value("BLOCKS", pd::proto::AttrType::BLOCKS);

  pybind11::class_<pd::OpDesc> op_desc(*m, "OpDesc", "");
  op_desc
      .def("__init__", [](pd::OpDesc &self) { new (&self) pd::OpDesc(); },
           pybind11::return_value_policy::reference)
      .def("copy_from", &pd::OpDesc::CopyFrom)
      .def("type", &pd::OpDesc::Type)
      .def("set_type", &pd::OpDesc::SetType)
      .def("input", &pd::OpDesc::Input)
      .def("input_names", &pd::OpDesc::InputNames)
      .def("output", &pd::OpDesc::Output)
      .def("output_names", &pd::OpDesc::OutputNames)
      .def("set_input", &pd::OpDesc::SetInput)
      .def("set_output", &pd::OpDesc::SetOutput)
      .def("input_arg_names", &pd::OpDesc::InputArgumentNames)
      .def("output_arg_names", &pd::OpDesc::OutputArgumentNames)
      .def("_rename_input", &pd::OpDesc::RenameInput)
      .def("_rename_output", &pd::OpDesc::RenameOutput)
      .def("has_attr", &pd::OpDesc::HasAttr)
      .def("attr_type", &pd::OpDesc::GetAttrType)
      .def("attr_names", &pd::OpDesc::AttrNames)
      .def("_set_attr", &pd::OpDesc::SetAttr)
      .def("attr", &pd::OpDesc::GetAttr)
      .def("set_block_attr", &pd::OpDesc::SetBlockAttr)
      .def("set_blocks_attr", &pd::OpDesc::SetBlocksAttr)
      .def("set_serialized_attr",
           [](pd::OpDesc &self, const std::string &name,
              const pybind11::bytes &seriralized) {
             std::string ser(seriralized);
             self.SetAttr(name, ser);
           })
      .def("_block_attr_id", &pd::OpDesc::GetBlockAttrId)
      .def("_blocks_attr_ids", &pd::OpDesc::GetBlocksAttrIds)
      .def("check_attrs", &pd::OpDesc::CheckAttrs)
      .def("infer_shape", &pd::OpDesc::InferShape)
      .def("infer_var_type", &pd::OpDesc::InferVarType)
      .def("set_is_target", &pd::OpDesc::SetIsTarget)
      .def("serialize_to_string", SerializeMessage<pd::OpDesc>)
      .def("block", &pd::OpDesc::Block,
           pybind11::return_value_policy::reference);
}

}  // namespace pybind
}  // namespace paddle
<commit_msg>fix for build issue<commit_after>/* Copyright (c) 2016 PaddlePaddle Authors. All Rights Reserved.

Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at

http://www.apache.org/licenses/LICENSE-2.0

Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License. */
#include "paddle/fluid/pybind/protobuf.h"

#include <deque>
#include <iostream>
#include <string>
#include <tuple>

#include "paddle/fluid/framework/block_desc.h"
#include "paddle/fluid/framework/op_desc.h"
#include "paddle/fluid/framework/program_desc.h"
#include "paddle/fluid/framework/var_desc.h"

// Cast boost::variant for PyBind.
// Copy from
// https://github.com/pybind/pybind11/issues/576#issuecomment-269563199
namespace pybind11 {
namespace detail {

#if !defined(PYBIND11_HIDDEN)
#ifdef _WIN32
#define PYBIND11_HIDDEN __declspec(dllexport)
#else
#define PYBIND11_HIDDEN __attribute__((visibility("hidden")))
#endif
#endif

// Can be replaced by a generic lambda in C++14
struct PYBIND11_HIDDEN paddle_variant_caster_visitor
    : public boost::static_visitor<handle> {
  return_value_policy policy;
  handle parent;

  paddle_variant_caster_visitor(return_value_policy policy, handle parent)
      : policy(policy), parent(parent) {}

  template <class T>
  handle operator()(T const &src) const {
    return make_caster<T>::cast(src, policy, parent);
  }
};

template <class Variant>
struct paddle_variant_caster;

template <template <class...> class V, class... Ts>
struct paddle_variant_caster<V<Ts...>> {
  using Type = V<Ts...>;

  template <typename T>
  typename std::enable_if<
      !std::is_same<T, boost::detail::variant::void_>::value, bool>::type
  try_load(handle src, bool convert) {
    auto caster = make_caster<T>();
    if (!load_success_ && caster.load(src, convert)) {
      load_success_ = true;

      if (std::is_same<T, std::vector<float>>::value) {
        auto caster_ints = make_caster<std::vector<int64_t>>();
        if (caster_ints.load(src, convert)) {
          VLOG(40) << "This value are floats and int64_ts satisfy "
                      "simultaneously, will set it's type to "
                      "std::vector<int64_t>";
          value = cast_op<std::vector<int64_t>>(caster_ints);
          return true;
        }
      }

      value = cast_op<T>(caster);
      return true;
    }
    return false;
  }

  template <typename T>
  typename std::enable_if<std::is_same<T, boost::detail::variant::void_>::value,
                          bool>::type
  try_load(handle src, bool convert) {
    return false;
  }

  bool load(handle src, bool convert) {
    auto unused = {false, try_load<Ts>(src, convert)...};
    (void)(unused);
    return load_success_;
  }

  static handle cast(Type const &src, return_value_policy policy,
                     handle parent) {
    paddle_variant_caster_visitor visitor(policy, parent);
    return boost::apply_visitor(visitor, src);
  }

  PYBIND11_TYPE_CASTER(Type, _("Variant"));
  bool load_success_{false};
};

// Add specialization for concrete variant type
template <class... Args>
struct type_caster<boost::variant<Args...>>
    : paddle_variant_caster<boost::variant<Args...>> {};

}  // namespace detail
}  // namespace pybind11

namespace paddle {
namespace pybind {

namespace pd = paddle::framework;

template <typename T>
static pybind11::bytes SerializeMessage(
    T &self) {  // NOLINT due to pybind11 convention.
  // Check IsInitialized in Python
  std::string retv;
  PADDLE_ENFORCE(self.Proto()->SerializePartialToString(&retv),
                 "Cannot serialize message");
  return retv;
}

// Bind Methods
void BindProgramDesc(pybind11::module *m) {
  pybind11::class_<pd::ProgramDesc>(*m, "ProgramDesc", "")
      .def(pybind11::init<>())
      .def("__init__",
           [](pd::ProgramDesc &self, const pd::ProgramDesc &other) {
             new (&self) pd::ProgramDesc(other);
           })
      .def("__init__",
           [](pd::ProgramDesc &self, const pybind11::bytes &binary_str) {
             std::string str(binary_str);
             new (&self) pd::ProgramDesc(str);
           })
      .def("append_block", &pd::ProgramDesc::AppendBlock,
           pybind11::return_value_policy::reference)
      .def("block", &pd::ProgramDesc::MutableBlock,
           pybind11::return_value_policy::reference)
      .def("num_blocks", &pd::ProgramDesc::Size)
      .def("flush", &pd::ProgramDesc::Flush)
      .def("get_feed_target_names", &pd::ProgramDesc::GetFeedTargetNames)
      .def("get_fetch_target_names", &pd::ProgramDesc::GetFetchTargetNames)
      .def("serialize_to_string", SerializeMessage<pd::ProgramDesc>)
      .def("parse_from_string",
           [](pd::ProgramDesc &program_desc, const std::string &data) {
             pd::proto::ProgramDesc *desc = program_desc.Proto();
             PADDLE_ENFORCE(desc->ParseFromString(data),
                            "Fail to parse ProgramDesc from string. This could "
                            "be a bug of Paddle.");
           })
      .def("_version", [](pd::ProgramDesc &self) -> int64_t {
        return self.Proto()->version().version();
      });
}

void BindBlockDesc(pybind11::module *m) {
  pybind11::class_<pd::BlockDesc>(*m, "BlockDesc", "")
      .def_property_readonly("id", &pd::BlockDesc::ID)
      .def_property_readonly("parent", &pd::BlockDesc::Parent)
      .def("get_forward_block_idx", &pd::BlockDesc::ForwardBlockID)
      .def("_set_forward_block_idx", &pd::BlockDesc::SetForwardBlockID)
      .def("append_op", &pd::BlockDesc::AppendOp,
           pybind11::return_value_policy::reference)
      .def("_prepend_op", &pd::BlockDesc::PrependOp,
           pybind11::return_value_policy::reference)
      .def("_insert_op", &pd::BlockDesc::InsertOp,
           pybind11::return_value_policy::reference)
      .def("_remove_op", &pd::BlockDesc::RemoveOp)
      .def("var",
           [](pd::BlockDesc &self, pybind11::bytes byte_name) {
             std::string name = byte_name;
             return self.Var(name);
           },
           pybind11::return_value_policy::reference)
      .def("has_var",
           [](pd::BlockDesc &self, pybind11::bytes byte_name) {
             std::string name = byte_name;
             return self.HasVar(name);
           },
           pybind11::return_value_policy::reference)
      .def("_rename_var",
           [](pd::BlockDesc &self, const pybind11::bytes &byte_name,
              const pybind11::bytes &byte_name_new) {
             std::string name = byte_name;
             std::string new_name = byte_name_new;
             self.RenameVar(name, new_name);
           })
      .def("has_var_recursive",
           [](pd::BlockDesc &self, pybind11::bytes byte_name) {
             std::string name = byte_name;
             return self.HasVarRecursive(name);
           })
      .def("find_var",
           [](pd::BlockDesc &self, pybind11::bytes byte_name) {
             std::string name = byte_name;
             return self.FindVar(name);
           },
           pybind11::return_value_policy::reference)
      .def("find_var_recursive",
           [](pd::BlockDesc &self, pybind11::bytes byte_name) {
             std::string name = byte_name;
             return self.FindVarRecursive(name);
           },
           pybind11::return_value_policy::reference)
      .def("_remove_var",
           [](pd::BlockDesc &self, pybind11::bytes byte_name) {
             std::string name = byte_name;
             return self.RemoveVar(name);
           },
           pybind11::return_value_policy::reference)
      .def("all_vars", &pd::BlockDesc::AllVars,
           pybind11::return_value_policy::reference)
      .def("op_size", &pd::BlockDesc::OpSize)
      .def("op", &pd::BlockDesc::Op, pybind11::return_value_policy::reference)
      .def("serialize_to_string", SerializeMessage<pd::BlockDesc>);
}

void BindVarDsec(pybind11::module *m) {
  pybind11::class_<pd::VarDesc> var_desc(*m, "VarDesc", "");
  var_desc
      .def("name", &pd::VarDesc::Name, pybind11::return_value_policy::reference)
      .def("set_name", &pd::VarDesc::SetName)
      .def("set_shape", &pd::VarDesc::SetShape)
      .def("set_shapes", &pd::VarDesc::SetShapes)
      .def("set_dtype", &pd::VarDesc::SetDataType)
      .def("set_dtypes", &pd::VarDesc::SetDataTypes)
      .def("shape", &pd::VarDesc::GetShape,
           pybind11::return_value_policy::reference)
      .def("shapes", &pd::VarDesc::GetShapes,
           pybind11::return_value_policy::reference)
      .def("dtype", &pd::VarDesc::GetDataType,
           pybind11::return_value_policy::reference)
      .def("dtypes", &pd::VarDesc::GetDataTypes,
           pybind11::return_value_policy::reference)
      .def("lod_level", &pd::VarDesc::GetLoDLevel)
      .def("lod_levels", &pd::VarDesc::GetLoDLevels,
           pybind11::return_value_policy::reference)
      .def("set_lod_level", &pd::VarDesc::SetLoDLevel)
      .def("set_lod_levels", &pd::VarDesc::SetLoDLevels)
      .def("type", &pd::VarDesc::GetType)
      .def("set_type", &pd::VarDesc::SetType)
      .def("serialize_to_string", SerializeMessage<pd::VarDesc>)
      .def("persistable", &pd::VarDesc::Persistable)
      .def("set_persistable", &pd::VarDesc::SetPersistable);

  pybind11::enum_<pd::proto::VarType::Type>(var_desc, "VarType", "")
      .value("BOOL", pd::proto::VarType::BOOL)
      .value("UINT8", pd::proto::VarType::UINT8)
      .value("INT8", pd::proto::VarType::INT8)
      .value("INT16", pd::proto::VarType::INT16)
      .value("INT32", pd::proto::VarType::INT32)
      .value("INT64", pd::proto::VarType::INT64)
      .value("FP16", pd::proto::VarType::FP16)
      .value("FP32", pd::proto::VarType::FP32)
      .value("FP64", pd::proto::VarType::FP64)
      .value("LOD_TENSOR", pd::proto::VarType::LOD_TENSOR)
      .value("SELECTED_ROWS", pd::proto::VarType::SELECTED_ROWS)
      .value("FEED_MINIBATCH", pd::proto::VarType::FEED_MINIBATCH)
      .value("FETCH_LIST", pd::proto::VarType::FETCH_LIST)
      .value("STEP_SCOPES", pd::proto::VarType::STEP_SCOPES)
      .value("LOD_RANK_TABLE", pd::proto::VarType::LOD_RANK_TABLE)
      .value("LOD_TENSOR_ARRAY", pd::proto::VarType::LOD_TENSOR_ARRAY)
      .value("PLACE_LIST", pd::proto::VarType::PLACE_LIST)
      .value("READER", pd::proto::VarType::READER)
      .value("RAW", pd::proto::VarType::RAW);
}

void BindOpDesc(pybind11::module *m) {
  pybind11::enum_<pd::proto::AttrType>(*m, "AttrType", "")
      .value("INT", pd::proto::AttrType::INT)
      .value("INTS", pd::proto::AttrType::INTS)
      .value("LONG", pd::proto::AttrType::LONG)
      .value("LONGS", pd::proto::AttrType::LONGS)
      .value("FLOAT", pd::proto::AttrType::FLOAT)
      .value("FLOATS", pd::proto::AttrType::FLOATS)
      .value("STRING", pd::proto::AttrType::STRING)
      .value("STRINGS", pd::proto::AttrType::STRINGS)
      .value("BOOL", pd::proto::AttrType::BOOLEAN)
      .value("BOOLS", pd::proto::AttrType::BOOLEANS)
      .value("BLOCK", pd::proto::AttrType::BLOCK)
      .value("BLOCKS", pd::proto::AttrType::BLOCKS);

  pybind11::class_<pd::OpDesc> op_desc(*m, "OpDesc", "");
  op_desc
      .def("__init__", [](pd::OpDesc &self) { new (&self) pd::OpDesc(); },
           pybind11::return_value_policy::reference)
      .def("copy_from", &pd::OpDesc::CopyFrom)
      .def("type", &pd::OpDesc::Type)
      .def("set_type", &pd::OpDesc::SetType)
      .def("input", &pd::OpDesc::Input)
      .def("input_names", &pd::OpDesc::InputNames)
      .def("output", &pd::OpDesc::Output)
      .def("output_names", &pd::OpDesc::OutputNames)
      .def("set_input", &pd::OpDesc::SetInput)
      .def("set_output", &pd::OpDesc::SetOutput)
      .def("input_arg_names", &pd::OpDesc::InputArgumentNames)
      .def("output_arg_names", &pd::OpDesc::OutputArgumentNames)
      .def("_rename_input", &pd::OpDesc::RenameInput)
      .def("_rename_output", &pd::OpDesc::RenameOutput)
      .def("has_attr", &pd::OpDesc::HasAttr)
      .def("attr_type", &pd::OpDesc::GetAttrType)
      .def("attr_names", &pd::OpDesc::AttrNames)
      .def("_set_attr", &pd::OpDesc::SetAttr)
      .def("attr", &pd::OpDesc::GetAttr)
      .def("set_block_attr", &pd::OpDesc::SetBlockAttr)
      .def("set_blocks_attr", &pd::OpDesc::SetBlocksAttr)
      .def("set_serialized_attr",
           [](pd::OpDesc &self, const std::string &name,
              const pybind11::bytes &seriralized) {
             std::string ser(seriralized);
             self.SetAttr(name, ser);
           })
      .def("_block_attr_id", &pd::OpDesc::GetBlockAttrId)
      .def("_blocks_attr_ids", &pd::OpDesc::GetBlocksAttrIds)
      .def("check_attrs", &pd::OpDesc::CheckAttrs)
      .def("infer_shape", &pd::OpDesc::InferShape)
      .def("infer_var_type", &pd::OpDesc::InferVarType)
      .def("set_is_target", &pd::OpDesc::SetIsTarget)
      .def("serialize_to_string", SerializeMessage<pd::OpDesc>)
      .def("block", &pd::OpDesc::Block,
           pybind11::return_value_policy::reference);
}

}  // namespace pybind
}  // namespace paddle
<|endoftext|>


<commit_before>/* Copyright (c) 2016 PaddlePaddle Authors. All Rights Reserve.

   Licensed under the Apache License, Version 2.0 (the "License");
   you may not use this file except in compliance with the License.
   You may obtain a copy of the License at

   http://www.apache.org/licenses/LICENSE-2.0

   Unless required by applicable law or agreed to in writing, software
   distributed under the License is distributed on an "AS IS" BASIS,
   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
   See the License for the specific language governing permissions and
   limitations under the License. */

#include "paddle/string/to_string.h"
#include <gtest/gtest.h>

constexpr char OUT_STR[] = "User Defined Output";
class UserDefinedClass {
public:
};

std::ostream& operator<<(std::ostream& s, const UserDefinedClass& ins) {
  s << OUT_STR;
  return s;
}

// android macro comes from
// https://stackoverflow.com/questions/15328751/android-macro-suddenly-not-defined
#if !defined(ANDROID) && !defined(__ANDROID__)
// In android, std::to_string is not defined.
// https://stackoverflow.com/questions/22774009/android-ndk-stdto-string-support
TEST(to_string, normal) {
  using namespace paddle::string;
  ASSERT_EQ(std::to_string(10), to_string(10));
  ASSERT_EQ("abc", to_string("abc"));

  auto std_to_string = std::to_string(1.2);
  auto my_to_string = to_string(1.2);

  // std::to_string might fill zero after float value, like 1.2000
  for (size_t i = 0; i < my_to_string.size(); ++i) {
    ASSERT_EQ(my_to_string[i], std_to_string[i]);
  }
}
#endif

TEST(to_string, user_defined) {
  using namespace paddle::string;
  UserDefinedClass instance;
  ASSERT_EQ(OUT_STR, to_string(instance));
}<commit_msg>Refine unit-test for to_string<commit_after>/* Copyright (c) 2016 PaddlePaddle Authors. All Rights Reserve.

   Licensed under the Apache License, Version 2.0 (the "License");
   you may not use this file except in compliance with the License.
   You may obtain a copy of the License at

   http://www.apache.org/licenses/LICENSE-2.0

   Unless required by applicable law or agreed to in writing, software
   distributed under the License is distributed on an "AS IS" BASIS,
   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
   See the License for the specific language governing permissions and
   limitations under the License. */

#include "paddle/string/to_string.h"
#include <gtest/gtest.h>

constexpr char OUT_STR[] = "User Defined Output";
class UserDefinedClass {
public:
};

std::ostream& operator<<(std::ostream& s, const UserDefinedClass& ins) {
  s << OUT_STR;
  return s;
}

TEST(to_string, normal) {
  using namespace paddle::string;
  ASSERT_EQ("10", to_string(10));
  ASSERT_EQ("abc", to_string("abc"));
  ASSERT_EQ("1.2", to_string(1.2));
}

TEST(to_string, user_defined) {
  using namespace paddle::string;
  UserDefinedClass instance;
  ASSERT_EQ(OUT_STR, to_string(instance));
}<|endoftext|>


<commit_before>#include "Vision.h"

Vision::Vision ( bool webcam ) {
  HSV_lower = Scalar(70, 138, 156);
  HSV_upper = Scalar(100, 255, 255);

}

Mat Vision::getHSVimage (Mat image) {
  //IplImage* hsv_image = cvCreateImage(cvGetSize(image), 8, 3);
  Mat hsv_image;
  cvtColor(image, hsv_image, CV_BGR2HSV);
  //cvCvtColor(image, hsv_image, CV_BGR2HSV);
  return hsv_image;

}

Mat Vision::doImgProc (Mat image) {
  Mat binimg;
  vector<vector<Point> > contours;
  blur(image, image, Size(3,3));

  cvtColor(image, binimg, CV_BGR2HSV);
  inRange(binimg, HSV_lower, HSV_upper, binimg);
  findContours(binimg, contours, CV_RETR_LIST, CV_CHAIN_APPROX_SIMPLE);
  for( int i = 0; i< contours.size(); i++ ) {
    drawContours( image, contours, i, Scalar( 0, 0, 255 ), 3);
  }

  return image;

}

Vector<Rect> Vision::getRects(Mat image) {
  Mat binimg;
  vector<vector<Point> > contours;
  blur(image, image, Size(3,3));

  cvtColor(image, binimg, CV_BGR2HSV);
  inRange(binimg, HSV_lower, HSV_upper, binimg);
  findContours(binimg, contours, CV_RETR_LIST, CV_CHAIN_APPROX_SIMPLE);
  Vector<Rect> rects;

  for( int i = 0; i< contours.size(); i++ ) {
    rects.push_back(boundingRect(contours[i]));
  }

  return rects;

}

<commit_msg>removed function<commit_after>#include "Vision.h"

Vision::Vision ( bool webcam ) {
  HSV_lower = Scalar(70, 138, 156);
  HSV_upper = Scalar(100, 255, 255);

}

Mat Vision::doImgProc (Mat image) {
  Mat binimg;
  vector<vector<Point> > contours;
  blur(image, image, Size(3,3));

  cvtColor(image, binimg, CV_BGR2HSV);
  inRange(binimg, HSV_lower, HSV_upper, binimg);
  findContours(binimg, contours, CV_RETR_LIST, CV_CHAIN_APPROX_SIMPLE);
  for( int i = 0; i< contours.size(); i++ ) {
    drawContours( image, contours, i, Scalar( 0, 0, 255 ), 3);
  }

  return image;

}

Vector<Rect> Vision::getRects(Mat image) {
  Mat binimg;
  vector<vector<Point> > contours;
  blur(image, image, Size(3,3));

  cvtColor(image, binimg, CV_BGR2HSV);
  inRange(binimg, HSV_lower, HSV_upper, binimg);
  findContours(binimg, contours, CV_RETR_LIST, CV_CHAIN_APPROX_SIMPLE);
  Vector<Rect> rects;

  for( int i = 0; i< contours.size(); i++ ) {
    rects.push_back(boundingRect(contours[i]));
  }

  return rects;

}

<|endoftext|>