<commit_before>/*=========================================================================

  Program:   Insight Segmentation & Registration Toolkit
  Module:    itkTimeProbesTest.cxx
  Language:  C++
  Date:      $Date$
  Version:   $Revision$

  Copyright (c) Insight Software Consortium. All rights reserved.
  See ITKCopyright.txt or http://www.itk.org/HTML/Copyright.htm for details.

     This software is distributed WITHOUT ANY WARRANTY; without even
     the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
     PURPOSE.  See the above copyright notices for more information.

=========================================================================*/
#if defined(_MSC_VER)
#pragma warning ( disable : 4786 )
#endif

#include "itkTimeProbesCollectorBase.h"
#include "itkImage.h"
#include "itkOrientedImage.h"
#include "itkPoint.h"
#include "itkImageRegion.h"
#include "itkIndex.h"
#include "itkSize.h"

#include <iostream>

template <class T>
void TestTransformIndexToPhysicalPoint(T * image)
{
  T::IndexType index3D;
  T::PointType point3D;

    for (int k = 0; k < 10; k++)
    {
    index3D[2] = k;
    for (int j = 0; j < 1000; j++)
      {
      index3D[1] = j;
      for (int i = 0; i < 1000; i++)
        {
        index3D[0] = i;
        image->TransformIndexToPhysicalPoint(index3D, point3D);
        }
      }
    if (k == 5) std::cout << point3D << std::endl;
    }
}
template <class T>
void TestTransformPhysicalPointToIndex(T * image)
{
  T::IndexType index3D;
  T::PointType point3D;

    for (double k = 0; k < 10; k++)
    {
    point3D[2] = k;
    for (double j = 0; j < 1000; j++)
      {
      point3D[1] = j;
      for (double i = 0; i < 1000; i++)
        {
        point3D[0] = i;
        image->TransformPhysicalPointToIndex(point3D, index3D);
        }
      }
    if (k == 5) std::cout << point3D << std::endl;
    }
}
//-------------------------
//
//   This file test the interface to the TimeProbe classes
//
//-------------------------
int itkTimeProbesTest(int, char* [] )
{

  std::cout << "clock() precision = " << CLOCKS_PER_SEC;
  std::cout << "  ticks per second " << std::endl;
  std::cout << std::endl;

  itk::TimeProbesCollectorBase   collector;

  const unsigned int N =  1000L;
  const unsigned int M = 10000L;

  collector.Start("Loop1"); // label that identify the range of the probe

  // Do slow stuff here...
  {
  for(unsigned int i=0; i<N; i++)
    {
    char * dummy = new char [ M ];
    for(unsigned int j=0; j<M; j++)
      {
      dummy[j] = j;
      }
    delete [] dummy;
    }
  }
  collector.Stop("Loop1");

  collector.Start("Loop2"); // label that identify the range of the probe

  // Do other slow stuff here...
  {
  for(unsigned int i=0; i<M; i++)
    {
    char * dummy = new char [ N ];
    for(unsigned int j=0; j<N; j++)
      {
      dummy[j] = j;
      }
    delete [] dummy;
    }
  }
  collector.Stop("Loop2");

  typedef itk::Image<float,3> Image3DType;
  typedef itk::OrientedImage<float,3> OrientedImage3DType;

  Image3DType::Pointer image3D = Image3DType::New();
  OrientedImage3DType::Pointer orientedImage3D = OrientedImage3DType::New();

  Image3DType::PointType point3D;

  typedef itk::ImageRegion< 3 >  Region3DType;
  typedef Region3DType::IndexType Index3DType;
  typedef Region3DType::SizeType  Size3DType;
  Region3DType region3D;
  Size3DType size3D = {{ 1000, 1000, 1000 }};

  region3D.SetSize(  size3D );
  collector.Start("i->TransformIndexToPhysicalPoint");
  TestTransformIndexToPhysicalPoint<Image3DType> (image3D);
  collector.Stop("i->TransformIndexToPhysicalPoint");

  collector.Start("i->TransformPhysicalPointToIndex");
  TestTransformPhysicalPointToIndex<Image3DType> (image3D);
  collector.Stop("i->TransformPhysicalPointToIndex");

  collector.Start("o->TransformIndexToPhysicalPoint");
  TestTransformIndexToPhysicalPoint<OrientedImage3DType> (orientedImage3D);
  collector.Stop("o->TransformIndexToPhysicalPoint");

  collector.Start("o->TransformPhysicalPointToIndex");
  TestTransformPhysicalPointToIndex<OrientedImage3DType> (orientedImage3D);
  collector.Stop("o->TransformPhysicalPointToIndex");

  // Print the results of the time probes
  collector.Report();

  return EXIT_SUCCESS;

}

<commit_msg>COMP: missing ttypenames.<commit_after>/*=========================================================================

  Program:   Insight Segmentation & Registration Toolkit
  Module:    itkTimeProbesTest.cxx
  Language:  C++
  Date:      $Date$
  Version:   $Revision$

  Copyright (c) Insight Software Consortium. All rights reserved.
  See ITKCopyright.txt or http://www.itk.org/HTML/Copyright.htm for details.

     This software is distributed WITHOUT ANY WARRANTY; without even
     the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
     PURPOSE.  See the above copyright notices for more information.

=========================================================================*/
#if defined(_MSC_VER)
#pragma warning ( disable : 4786 )
#endif

#include "itkTimeProbesCollectorBase.h"
#include "itkImage.h"
#include "itkOrientedImage.h"
#include "itkPoint.h"
#include "itkImageRegion.h"
#include "itkIndex.h"
#include "itkSize.h"

#include <iostream>

template <class T>
void TestTransformIndexToPhysicalPoint(T * image)
{
  typename T::IndexType index3D;
  typename T::PointType point3D;

    for (int k = 0; k < 10; k++)
    {
    index3D[2] = k;
    for (int j = 0; j < 1000; j++)
      {
      index3D[1] = j;
      for (int i = 0; i < 1000; i++)
        {
        index3D[0] = i;
        image->TransformIndexToPhysicalPoint(index3D, point3D);
        }
      }
    if (k == 5) std::cout << point3D << std::endl;
    }
}
template <class T>
void TestTransformPhysicalPointToIndex(T * image)
{
  typename T::IndexType index3D;
  typename T::PointType point3D;

    for (double k = 0; k < 10; k++)
    {
    point3D[2] = k;
    for (double j = 0; j < 1000; j++)
      {
      point3D[1] = j;
      for (double i = 0; i < 1000; i++)
        {
        point3D[0] = i;
        image->TransformPhysicalPointToIndex(point3D, index3D);
        }
      }
    if (k == 5) std::cout << point3D << std::endl;
    }
}
//-------------------------
//
//   This file test the interface to the TimeProbe classes
//
//-------------------------
int itkTimeProbesTest(int, char* [] )
{

  std::cout << "clock() precision = " << CLOCKS_PER_SEC;
  std::cout << "  ticks per second " << std::endl;
  std::cout << std::endl;

  itk::TimeProbesCollectorBase   collector;

  const unsigned int N =  1000L;
  const unsigned int M = 10000L;

  collector.Start("Loop1"); // label that identify the range of the probe

  // Do slow stuff here...
  {
  for(unsigned int i=0; i<N; i++)
    {
    char * dummy = new char [ M ];
    for(unsigned int j=0; j<M; j++)
      {
      dummy[j] = j;
      }
    delete [] dummy;
    }
  }
  collector.Stop("Loop1");

  collector.Start("Loop2"); // label that identify the range of the probe

  // Do other slow stuff here...
  {
  for(unsigned int i=0; i<M; i++)
    {
    char * dummy = new char [ N ];
    for(unsigned int j=0; j<N; j++)
      {
      dummy[j] = j;
      }
    delete [] dummy;
    }
  }
  collector.Stop("Loop2");

  typedef itk::Image<float,3> Image3DType;
  typedef itk::OrientedImage<float,3> OrientedImage3DType;

  Image3DType::Pointer image3D = Image3DType::New();
  OrientedImage3DType::Pointer orientedImage3D = OrientedImage3DType::New();

  Image3DType::PointType point3D;

  typedef itk::ImageRegion< 3 >  Region3DType;
  typedef Region3DType::IndexType Index3DType;
  typedef Region3DType::SizeType  Size3DType;
  Region3DType region3D;
  Size3DType size3D = {{ 1000, 1000, 1000 }};

  region3D.SetSize(  size3D );
  collector.Start("i->TransformIndexToPhysicalPoint");
  TestTransformIndexToPhysicalPoint<Image3DType> (image3D);
  collector.Stop("i->TransformIndexToPhysicalPoint");

  collector.Start("i->TransformPhysicalPointToIndex");
  TestTransformPhysicalPointToIndex<Image3DType> (image3D);
  collector.Stop("i->TransformPhysicalPointToIndex");

  collector.Start("o->TransformIndexToPhysicalPoint");
  TestTransformIndexToPhysicalPoint<OrientedImage3DType> (orientedImage3D);
  collector.Stop("o->TransformIndexToPhysicalPoint");

  collector.Start("o->TransformPhysicalPointToIndex");
  TestTransformPhysicalPointToIndex<OrientedImage3DType> (orientedImage3D);
  collector.Stop("o->TransformPhysicalPointToIndex");

  // Print the results of the time probes
  collector.Report();

  return EXIT_SUCCESS;

}

<|endoftext|>


<commit_before>/* medViewerConfigurationFiltering.cpp ---
 *
 * @author Clément Philipot <clement.philipot@inria.fr>
 *
 */

#include "medViewerConfigurationFiltering.h"
#include <medViewContainerFiltering.h>

#include <medDatabaseNonPersistentController.h>
#include <medMetaDataKeys.h>
#include <medStorage.h>

#include <medViewerToolBoxViewProperties.h>
#include <medToolBoxFiltering.h>

#include <medViewContainer.h>
#include <medViewContainerMulti.h>
#include <medTabbedViewContainers.h>
#include <medToolBoxFilteringCustom.h>

#include <dtkCore/dtkAbstractData.h>
#include <dtkCore/dtkAbstractView.h>
#include <dtkCore/dtkAbstractViewFactory.h>

#include <medCore/medDataManager.h>

class medViewerConfigurationFilteringPrivate
{
public:
    medViewerToolBoxViewProperties      *viewPropertiesToolBox;
    medToolBoxFiltering *filteringToolBox;
    dtkAbstractData *filterOutput;
    QString importUuid;
};

medViewerConfigurationFiltering::medViewerConfigurationFiltering ( QWidget *parent ) : medViewerConfiguration ( parent ), d ( new medViewerConfigurationFilteringPrivate )
{
    d->viewPropertiesToolBox = new medViewerToolBoxViewProperties ( parent );

    this->addToolBox ( d->viewPropertiesToolBox );

    d->filteringToolBox = new medToolBoxFiltering ( parent );

    connect(d->filteringToolBox, SIGNAL(addToolBox(medToolBox *)), this, SLOT(addToolBox(medToolBox *)));
    connect(d->filteringToolBox, SIGNAL(removeToolBox(medToolBox *)), this, SLOT(removeToolBox(medToolBox *)));
    connect(d->filteringToolBox,SIGNAL(processFinished()),this,SLOT(onProcessSuccess()));

    this->addToolBox( d->filteringToolBox );
}

medViewerConfigurationFiltering::~medViewerConfigurationFiltering ( void )
{
    delete d;
    d = NULL;
}

void medViewerConfigurationFiltering::setupViewContainerStack()
{
    if ( !this->stackedViewContainers()->count() )
    {
        medViewContainerFiltering *filteringContainer = new medViewContainerFiltering ( this->stackedViewContainers() );

        connect(filteringContainer,SIGNAL(droppedInput(medDataIndex)), d->filteringToolBox,SLOT(onInputSelected(medDataIndex)));
        connect(this,SIGNAL(outputDataChanged(dtkAbstractData *)),
                filteringContainer,SLOT(updateOutput(dtkAbstractData *)));
        connect(filteringContainer, SIGNAL(inputViewRemoved()),
                this, SLOT(onViewRemoved()));

        this->stackedViewContainers()->addContainer ( "Filtering",filteringContainer );

        setCurrentViewContainer ( "Filtering" );

        this->stackedViewContainers()->lockTabs();
        this->stackedViewContainers()->hideTabBar();
    }
}

void medViewerConfigurationFiltering::patientChanged ( int patientId )
{
    d->filteringToolBox->clear();
}

void medViewerConfigurationFiltering::onProcessSuccess()
{
    d->filterOutput = d->filteringToolBox->customToolbox()->processOutput();
    if ( !d->filterOutput )
        return;

    dtkAbstractData *inputData = d->filteringToolBox->data();

    if (! d->filterOutput->hasMetaData(medMetaDataKeys::SeriesDescription.key()))
      {
        QString newSeriesDescription = inputData->metadata ( medMetaDataKeys::SeriesDescription.key() );
        newSeriesDescription += " filtered";
        d->filterOutput->addMetaData ( medMetaDataKeys::SeriesDescription.key(), newSeriesDescription );
      }

    foreach ( QString metaData, inputData->metaDataList() )
      if (!d->filterOutput->hasMetaData(metaData))
        d->filterOutput->addMetaData ( metaData, inputData->metaDataValues ( metaData ) );

    foreach ( QString property, inputData->propertyList() )
      d->filterOutput->addProperty ( property,inputData->propertyValues ( property ) );

//     QString newSeriesDescription = d->filterOutput->metadata ( medMetaDataKeys::SeriesDescription.key() );
//     newSeriesDescription += " filtered";

//     d->filterOutput->setMetaData ( medMetaDataKeys::SeriesDescription.key(), newSeriesDescription );

    QString generatedID = QUuid::createUuid().toString().replace("{","").replace("}","");
    d->filterOutput->setMetaData ( medMetaDataKeys::SeriesID.key(), generatedID );

    //     d->filteringToolBox->setDataIndex(medDataManager::instance()->importNonPersistent(d->filterOutput));

    QObject::connect ( medDatabaseNonPersistentController::instance(),
                       SIGNAL ( updated ( const medDataIndex&,const QString& ) ),
                       this, SLOT ( onOutputImported ( const medDataIndex&,const QString& ) ) );

    //Create a uniqueId for the request.
    d->importUuid = QUuid::createUuid().toString();
    medDataManager::instance()->importNonPersistent ( d->filterOutput, d->importUuid );

    emit outputDataChanged ( d->filterOutput );
}

void medViewerConfigurationFiltering::onOutputImported ( const medDataIndex& dataIndex,
        const QString& uuid )
{
    if ( !uuid.isEmpty() && uuid == d->importUuid )
    {
        d->filteringToolBox->setDataIndex ( dataIndex );
        d->importUuid = QString();
    }
}

QString medViewerConfigurationFiltering::identifier() const {
    return "Filtering";
}

void medViewerConfigurationFiltering::onViewRemoved ()
{
    d->filteringToolBox->clear();
}

QString medViewerConfigurationFiltering::description(void) const
{
    return "Filtering";
}
<commit_msg>use of smartpointers ot handle data<commit_after>/* medViewerConfigurationFiltering.cpp ---
 *
 * @author Clément Philipot <clement.philipot@inria.fr>
 *
 */

#include "medViewerConfigurationFiltering.h"
#include <medViewContainerFiltering.h>

#include <medDatabaseNonPersistentController.h>
#include <medMetaDataKeys.h>
#include <medStorage.h>

#include <medViewerToolBoxViewProperties.h>
#include <medToolBoxFiltering.h>

#include <medViewContainer.h>
#include <medViewContainerMulti.h>
#include <medTabbedViewContainers.h>
#include <medToolBoxFilteringCustom.h>

#include <dtkCore/dtkAbstractData.h>
#include <dtkCore/dtkAbstractView.h>
#include <dtkCore/dtkAbstractViewFactory.h>
#include <dtkCore/dtkSmartPointer.h>

#include <medCore/medDataManager.h>

class medViewerConfigurationFilteringPrivate
{
public:
    medViewerToolBoxViewProperties      *viewPropertiesToolBox;
    medToolBoxFiltering *filteringToolBox;
    dtkSmartPointer<dtkAbstractData> filterOutput;
    QString importUuid;
};

medViewerConfigurationFiltering::medViewerConfigurationFiltering ( QWidget *parent ) : medViewerConfiguration ( parent ), d ( new medViewerConfigurationFilteringPrivate )
{
    d->viewPropertiesToolBox = new medViewerToolBoxViewProperties ( parent );

    this->addToolBox ( d->viewPropertiesToolBox );

    d->filteringToolBox = new medToolBoxFiltering ( parent );

    connect(d->filteringToolBox, SIGNAL(addToolBox(medToolBox *)), this, SLOT(addToolBox(medToolBox *)));
    connect(d->filteringToolBox, SIGNAL(removeToolBox(medToolBox *)), this, SLOT(removeToolBox(medToolBox *)));
    connect(d->filteringToolBox,SIGNAL(processFinished()),this,SLOT(onProcessSuccess()));

    this->addToolBox( d->filteringToolBox );
}

medViewerConfigurationFiltering::~medViewerConfigurationFiltering ( void )
{
    delete d;
    d = NULL;
}

void medViewerConfigurationFiltering::setupViewContainerStack()
{
    if ( !this->stackedViewContainers()->count() )
    {
        medViewContainerFiltering *filteringContainer = new medViewContainerFiltering ( this->stackedViewContainers() );

        connect(filteringContainer,SIGNAL(droppedInput(medDataIndex)), d->filteringToolBox,SLOT(onInputSelected(medDataIndex)));
        connect(this,SIGNAL(outputDataChanged(dtkAbstractData *)),
                filteringContainer,SLOT(updateOutput(dtkAbstractData *)));
        connect(filteringContainer, SIGNAL(inputViewRemoved()),
                this, SLOT(onViewRemoved()));

        this->stackedViewContainers()->addContainer ( "Filtering",filteringContainer );

        setCurrentViewContainer ( "Filtering" );

        this->stackedViewContainers()->lockTabs();
        this->stackedViewContainers()->hideTabBar();
    }
}

void medViewerConfigurationFiltering::patientChanged ( int patientId )
{
    d->filteringToolBox->clear();
}

void medViewerConfigurationFiltering::onProcessSuccess()
{
    d->filterOutput = d->filteringToolBox->customToolbox()->processOutput();
    if ( !d->filterOutput )
        return;

    dtkSmartPointer<dtkAbstractData> inputData(d->filteringToolBox->data());

    if (! d->filterOutput->hasMetaData(medMetaDataKeys::SeriesDescription.key()))
      {
        QString newSeriesDescription = inputData->metadata ( medMetaDataKeys::SeriesDescription.key() );
        newSeriesDescription += " filtered";
        d->filterOutput->addMetaData ( medMetaDataKeys::SeriesDescription.key(), newSeriesDescription );
      }

    foreach ( QString metaData, inputData->metaDataList() )
      if (!d->filterOutput->hasMetaData(metaData))
        d->filterOutput->addMetaData ( metaData, inputData->metaDataValues ( metaData ) );

    foreach ( QString property, inputData->propertyList() )
      d->filterOutput->addProperty ( property,inputData->propertyValues ( property ) );

//     QString newSeriesDescription = d->filterOutput->metadata ( medMetaDataKeys::SeriesDescription.key() );
//     newSeriesDescription += " filtered";

//     d->filterOutput->setMetaData ( medMetaDataKeys::SeriesDescription.key(), newSeriesDescription );

    QString generatedID = QUuid::createUuid().toString().replace("{","").replace("}","");
    d->filterOutput->setMetaData ( medMetaDataKeys::SeriesID.key(), generatedID );

    //     d->filteringToolBox->setDataIndex(medDataManager::instance()->importNonPersistent(d->filterOutput));

    QObject::connect ( medDatabaseNonPersistentController::instance(),
                       SIGNAL ( updated ( const medDataIndex&,const QString& ) ),
                       this, SLOT ( onOutputImported ( const medDataIndex&,const QString& ) ) );

    //Create a uniqueId for the request.
    d->importUuid = QUuid::createUuid().toString();
    medDataManager::instance()->importNonPersistent ( d->filterOutput, d->importUuid );

    emit outputDataChanged ( d->filterOutput );
}

void medViewerConfigurationFiltering::onOutputImported ( const medDataIndex& dataIndex,
        const QString& uuid )
{
    if ( !uuid.isEmpty() && uuid == d->importUuid )
    {
        d->filteringToolBox->setDataIndex ( dataIndex );
        d->importUuid = QString();
    }
}

QString medViewerConfigurationFiltering::identifier() const {
    return "Filtering";
}

void medViewerConfigurationFiltering::onViewRemoved ()
{
    d->filteringToolBox->clear();
}

QString medViewerConfigurationFiltering::description(void) const
{
    return "Filtering";
}
<|endoftext|>


<commit_before>/*
 * Load balancer for AddressList.
 *
 * author: Max Kellermann <mk@cm4all.com>
 */

#include "balancer.hxx"
#include "cache.hxx"
#include "address_list.hxx"
#include "net/SocketAddress.hxx"
#include "failure.hxx"
#include "bulldog.h"
#include "pool.hxx"

#include <assert.h>
#include <stdbool.h>
#include <time.h>

struct Balancer {
    struct Item final : CacheItem {
        struct pool *const pool;

        /** the index of the item that will be returned next */
        unsigned next = 0;

        AddressList addresses;

        Item(struct pool &_pool, const AddressList &_addresses)
            :CacheItem(std::chrono::minutes(30), 1),
             pool(&_pool), addresses(_pool, _addresses) {
        }

        /* virtual methods from class CacheItem */
        void Destroy() override {
            pool_unref(pool);
        }
    };

    struct pool *pool;

    /**
     * This library uses the cache library to store remote host
     * states in a lossy way.
     */
    Cache *cache;

    Balancer(struct pool &_pool, EventLoop &event_loop)
        :pool(&_pool),
         cache(cache_new(_pool, event_loop, 1021, 2048)) {}

    ~Balancer() {
        cache_close(cache);
    }
};

static bool
check_failure(const SocketAddress address, bool allow_fade)
{
    enum failure_status status = failure_get_status(address);
    if (status == FAILURE_FADE && allow_fade)
        status = FAILURE_OK;
    return status == FAILURE_OK;
}

gcc_pure
static bool
check_bulldog(const SocketAddress address, bool allow_fade)
{
    return bulldog_check(address.GetAddress(), address.GetSize()) &&
        (allow_fade ||
         !bulldog_is_fading(address.GetAddress(), address.GetSize()));
}

static bool
CheckAddress(const SocketAddress address, bool allow_fade)
{
    return check_failure(address, allow_fade) &&
        check_bulldog(address, allow_fade);
}

static SocketAddress
next_failover_address(const AddressList &list)
{
    assert(list.GetSize() > 0);

    for (auto i : list)
        if (CheckAddress(i, true))
            return i;

    /* none available - return first node as last resort */
    return list[0];
}

static const SocketAddress &
next_address(Balancer::Item *item)
{
    assert(item->addresses.GetSize() >= 2);
    assert(item->next < item->addresses.GetSize());

    const SocketAddress &address = item->addresses[item->next];

    ++item->next;
    if (item->next >= item->addresses.GetSize())
        item->next = 0;

    return address;
}

static const SocketAddress &
next_address_checked(Balancer::Item *item, bool allow_fade)
{
    const SocketAddress &first = next_address(item);
    const SocketAddress *ret = &first;
    do {
        if (CheckAddress(*ret, allow_fade))
            return *ret;

        ret = &next_address(item);
    } while (ret != &first);

    /* all addresses failed: */
    return first;
}

static const SocketAddress &
next_sticky_address_checked(const AddressList &al, unsigned session)
{
    assert(al.GetSize() >= 2);

    unsigned i = session % al.GetSize();
    bool allow_fade = true;

    const SocketAddress &first = al[i];
    const SocketAddress *ret = &first;
    do {
        if (CheckAddress(*ret, allow_fade))
            return *ret;

        /* only the first iteration is allowed to override
           FAILURE_FADE */
        allow_fade = false;

        ++i;
        if (i >= al.GetSize())
            i = 0;

        ret = &al[i];

    } while (ret != &first);

    /* all addresses failed: */
    return first;
}

/*
 * public API
 *
 */

Balancer *
balancer_new(struct pool &pool, EventLoop &event_loop)
{
    return NewFromPool<Balancer>(pool, pool, event_loop);
}

void
balancer_free(Balancer *balancer)
{
    balancer->~Balancer();
}

SocketAddress
balancer_get(Balancer &balancer, const AddressList &list,
             unsigned session)
{
    struct pool *pool;

    if (list.IsSingle())
        return list[0];

    switch (list.sticky_mode) {
    case StickyMode::NONE:
        break;

    case StickyMode::FAILOVER:
        return next_failover_address(list);

    case StickyMode::SOURCE_IP:
    case StickyMode::SESSION_MODULO:
    case StickyMode::COOKIE:
    case StickyMode::JVM_ROUTE:
        if (session != 0)
            return next_sticky_address_checked(list, session);
        break;
    }

    const char *key = list.GetKey();
    auto *item = (Balancer::Item *)cache_get(balancer.cache, key);

    if (item == nullptr) {
        /* create a new cache item */

        pool = pool_new_linear(balancer.pool, "balancer_item", 1024);
        item = NewFromPool<Balancer::Item>(*pool, *pool, list);

        cache_put(balancer.cache, p_strdup(pool, key), item);
    }

    return next_address_checked(item, list.sticky_mode == StickyMode::NONE);
}

void
balancer_event_add(Balancer &balancer)
{
    cache_event_add(balancer.cache);
}

void
balancer_event_del(Balancer &balancer)
{
    cache_event_del(balancer.cache);
}
<commit_msg>balancer: allocate from heap<commit_after>/*
 * Load balancer for AddressList.
 *
 * author: Max Kellermann <mk@cm4all.com>
 */

#include "balancer.hxx"
#include "cache.hxx"
#include "address_list.hxx"
#include "net/SocketAddress.hxx"
#include "failure.hxx"
#include "bulldog.h"
#include "pool.hxx"

#include <assert.h>
#include <stdbool.h>
#include <time.h>

struct Balancer {
    struct Item final : CacheItem {
        struct pool *const pool;

        /** the index of the item that will be returned next */
        unsigned next = 0;

        AddressList addresses;

        Item(struct pool &_pool, const AddressList &_addresses)
            :CacheItem(std::chrono::minutes(30), 1),
             pool(&_pool), addresses(_pool, _addresses) {
        }

        /* virtual methods from class CacheItem */
        void Destroy() override {
            pool_unref(pool);
        }
    };

    struct pool *pool;

    /**
     * This library uses the cache library to store remote host
     * states in a lossy way.
     */
    Cache *cache;

    Balancer(struct pool &_pool, EventLoop &event_loop)
        :pool(&_pool),
         cache(cache_new(_pool, event_loop, 1021, 2048)) {}

    ~Balancer() {
        cache_close(cache);
    }
};

static bool
check_failure(const SocketAddress address, bool allow_fade)
{
    enum failure_status status = failure_get_status(address);
    if (status == FAILURE_FADE && allow_fade)
        status = FAILURE_OK;
    return status == FAILURE_OK;
}

gcc_pure
static bool
check_bulldog(const SocketAddress address, bool allow_fade)
{
    return bulldog_check(address.GetAddress(), address.GetSize()) &&
        (allow_fade ||
         !bulldog_is_fading(address.GetAddress(), address.GetSize()));
}

static bool
CheckAddress(const SocketAddress address, bool allow_fade)
{
    return check_failure(address, allow_fade) &&
        check_bulldog(address, allow_fade);
}

static SocketAddress
next_failover_address(const AddressList &list)
{
    assert(list.GetSize() > 0);

    for (auto i : list)
        if (CheckAddress(i, true))
            return i;

    /* none available - return first node as last resort */
    return list[0];
}

static const SocketAddress &
next_address(Balancer::Item *item)
{
    assert(item->addresses.GetSize() >= 2);
    assert(item->next < item->addresses.GetSize());

    const SocketAddress &address = item->addresses[item->next];

    ++item->next;
    if (item->next >= item->addresses.GetSize())
        item->next = 0;

    return address;
}

static const SocketAddress &
next_address_checked(Balancer::Item *item, bool allow_fade)
{
    const SocketAddress &first = next_address(item);
    const SocketAddress *ret = &first;
    do {
        if (CheckAddress(*ret, allow_fade))
            return *ret;

        ret = &next_address(item);
    } while (ret != &first);

    /* all addresses failed: */
    return first;
}

static const SocketAddress &
next_sticky_address_checked(const AddressList &al, unsigned session)
{
    assert(al.GetSize() >= 2);

    unsigned i = session % al.GetSize();
    bool allow_fade = true;

    const SocketAddress &first = al[i];
    const SocketAddress *ret = &first;
    do {
        if (CheckAddress(*ret, allow_fade))
            return *ret;

        /* only the first iteration is allowed to override
           FAILURE_FADE */
        allow_fade = false;

        ++i;
        if (i >= al.GetSize())
            i = 0;

        ret = &al[i];

    } while (ret != &first);

    /* all addresses failed: */
    return first;
}

/*
 * public API
 *
 */

Balancer *
balancer_new(struct pool &pool, EventLoop &event_loop)
{
    return new Balancer(pool, event_loop);
}

void
balancer_free(Balancer *balancer)
{
    delete balancer;
}

SocketAddress
balancer_get(Balancer &balancer, const AddressList &list,
             unsigned session)
{
    struct pool *pool;

    if (list.IsSingle())
        return list[0];

    switch (list.sticky_mode) {
    case StickyMode::NONE:
        break;

    case StickyMode::FAILOVER:
        return next_failover_address(list);

    case StickyMode::SOURCE_IP:
    case StickyMode::SESSION_MODULO:
    case StickyMode::COOKIE:
    case StickyMode::JVM_ROUTE:
        if (session != 0)
            return next_sticky_address_checked(list, session);
        break;
    }

    const char *key = list.GetKey();
    auto *item = (Balancer::Item *)cache_get(balancer.cache, key);

    if (item == nullptr) {
        /* create a new cache item */

        pool = pool_new_linear(balancer.pool, "balancer_item", 1024);
        item = NewFromPool<Balancer::Item>(*pool, *pool, list);

        cache_put(balancer.cache, p_strdup(pool, key), item);
    }

    return next_address_checked(item, list.sticky_mode == StickyMode::NONE);
}

void
balancer_event_add(Balancer &balancer)
{
    cache_event_add(balancer.cache);
}

void
balancer_event_del(Balancer &balancer)
{
    cache_event_del(balancer.cache);
}
<|endoftext|>


<commit_before>/* Copyright 2015 The TensorFlow 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.
==============================================================================*/

#ifdef INTEL_MKL

#include <memory>
#include "tensorflow/core/framework/op_kernel.h"
#include "tensorflow/core/framework/register_types.h"
#include "tensorflow/core/framework/tensor.h"
#include "tensorflow/core/framework/tensor_shape.h"
#include "tensorflow/core/framework/types.h"
#include "tensorflow/core/lib/core/status.h"
#include "tensorflow/core/platform/logging.h"

#include "mkl_dnn.h"
#include "mkl_dnn_types.h"
#include "tensorflow/core/util/mkl_util.h"

namespace tensorflow {
using CPUDevice = Eigen::ThreadPoolDevice;
template <typename Device, typename T>
class MklReshapeOp : public OpKernel {
 public:
  explicit MklReshapeOp(OpKernelConstruction* context) : OpKernel(context) {}

  void Compute(OpKernelContext* context) override {
    const Tensor& input = MklGetInput(context, 0);
    const Tensor& sizes = MklGetInput(context, 1);

    // Preliminary validation of sizes.
    OP_REQUIRES(context, IsLegacyVector(sizes.shape()),
                errors::InvalidArgument("sizes input must be 1-D, not shape ",
                                        sizes.shape().DebugString()));

    // Compute the output shape.  Determine product of specified
    // dimensions, and find the index of the unspecified one.
    TensorShape shape;
    int64 product = 1;
    int unknown_index = -1;
    switch (sizes.dtype()) {
      case DT_INT32:
        OP_REQUIRES_OK(context, ValidateSizes<int32>(sizes, &product,
                                                     &unknown_index, &shape));
        break;
      case DT_INT64:
        OP_REQUIRES_OK(context, ValidateSizes<int64>(sizes, &product,
                                                     &unknown_index, &shape));
        break;
      default:
        context->CtxFailure(errors::InvalidArgument(
            "desired shape must be a DT_INT32 or DT_INT64 vector, not a ",
            DataTypeString(sizes.dtype())));
        return;
    }
    if (unknown_index != -1) {
      OP_REQUIRES(
          context, product > 0,
          errors::InvalidArgument("Reshape cannot infer the missing input size "
                                  "for an empty tensor unless all specified "
                                  "input sizes are non-zero"));
      const int64 missing = input.NumElements() / product;
      OP_REQUIRES(
          context, product * missing == input.NumElements(),
          errors::InvalidArgument(
              "Input to reshape is a tensor with ", input.NumElements(),
              " values, but the requested shape requires a multiple of ",
              product));
      shape.set_dim(unknown_index, missing);
    }
    OP_REQUIRES(context, shape.num_elements() == input.NumElements(),
                errors::InvalidArgument("Input to reshape is a tensor with ",
                                        input.NumElements(),
                                        " values, but the requested shape has ",
                                        shape.num_elements()));

    MklShape mkl_shape_input;
    GetMklShape(context, 0, &mkl_shape_input);
    bool input_in_mkl_format = mkl_shape_input.IsMklTensor();
    if (input_in_mkl_format) {
      TensorShape& shape_to = shape;
      TensorShape shape_from;
      for (size_t i = 0; i < mkl_shape_input.GetDimension(); i++) {
        // Outermost to innermost dimension
        shape_from.AddDim(
            mkl_shape_input.GetSizes()[mkl_shape_input.tf_dim_idx(i)]);
      }

      if (shape_from == shape_to) {
        CopyMklTensorInToOut(context, 0, 0);
        return;
      } else {
        // Allocate output tensor.
        Tensor* output_tensor = NULL;
        MklShape mkl_shape_output;
        mkl_shape_output.SetMklTensor(false);
        AllocateOutputSetMklShape(context, 0, &output_tensor, shape_to,
                                  mkl_shape_output);

        // Get output layout pointer.
        dnnLayout_t output_layout =
            static_cast<dnnLayout_t>(mkl_shape_input.GetTfLayout());

        // Execute DNNConversion.
        // Note: we  assume an MKL tensor always have float as its data type.
        void* input_buffer =
            static_cast<void*>(const_cast<float*>(input.flat<float>().data()));
        void* output_buffer = static_cast<void*>(
            const_cast<float*>(output_tensor->flat<float>().data()));
        mkl_shape_input.GetConvertedFlatData(output_layout, input_buffer,
                                             output_buffer);

        VLOG(1) << "MKLToTFConversion complete successfully.";
        return;
      }
    } else {
      CopyTfTensorInToOutWithShape(context, 0, 0, shape);
    }
  }

 private:
  template <typename Tshape>
  Status ValidateSizes(const Tensor& sizes, int64* product, int* unknown_index,
                       TensorShape* shape) {
    *product = 1;
    *unknown_index = -1;
    const int64 num_dims = sizes.NumElements();
    auto Svec = sizes.flat<Tshape>();
    for (int d = 0; d < num_dims; ++d) {
      const Tshape size = Svec(d);
      if (size == -1) {
        if (*unknown_index != -1) {
          return errors::InvalidArgument(
              "Only one input size may be -1, not both ", *unknown_index,
              " and ", d);
        }
        *unknown_index = d;
        shape->AddDim(1);
      } else if (size < 0) {
        return errors::InvalidArgument("Size ", d,
                                       " must be non-negative, not ", size);
      } else {
        shape->AddDim(size);
        (*product) *= size;
      }
    }
    return Status::OK();
  }
};

#define REGISTER_MKL_CPU(T)                                         \
  REGISTER_KERNEL_BUILDER(Name("_MklReshape")                       \
                              .Device(DEVICE_CPU)                   \
                              .HostMemory("shape")                  \
                              .TypeConstraint<T>("T")               \
                              .TypeConstraint<int32>("Tshape")      \
                              .Label(mkl_op_registry::kMklOpLabel), \
                          MklReshapeOp<CPUDevice, T>);              \
  REGISTER_KERNEL_BUILDER(Name("_MklReshape")                       \
                              .Device(DEVICE_CPU)                   \
                              .HostMemory("shape")                  \
                              .TypeConstraint<T>("T")               \
                              .TypeConstraint<int64>("Tshape")      \
                              .Label(mkl_op_registry::kMklOpLabel), \
                          MklReshapeOp<CPUDevice, T>);
TF_CALL_float(REGISTER_MKL_CPU);
#undef REGISTER_MKL_CPU
}  // namespace tensorflow

#endif  // INTEL_MKL
<commit_msg>Adding MKL-DNN Reshape op (#14682)<commit_after>/* Copyright 2015 The TensorFlow 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.
==============================================================================*/

#ifdef INTEL_MKL

#include <memory>
#include "tensorflow/core/framework/op_kernel.h"
#include "tensorflow/core/framework/register_types.h"
#include "tensorflow/core/framework/tensor.h"
#include "tensorflow/core/framework/tensor_shape.h"
#include "tensorflow/core/framework/types.h"
#include "tensorflow/core/lib/core/status.h"
#include "tensorflow/core/platform/logging.h"

#include "mkl_dnn.h"
#include "mkl_dnn_types.h"
#include "tensorflow/core/util/mkl_util.h"

#ifdef INTEL_MKL_DNN
#include "mkldnn.hpp"
using mkldnn::stream;
#endif

namespace tensorflow {
using CPUDevice = Eigen::ThreadPoolDevice;
template <typename Device, typename T>
class MklReshapeOp : public OpKernel {
 public:
  explicit MklReshapeOp(OpKernelConstruction* context) : OpKernel(context) {}

#ifndef INTEL_MKL_DNN
  void Compute(OpKernelContext* context) override {
    const Tensor& input = MklGetInput(context, 0);
    const Tensor& sizes = MklGetInput(context, 1);

    // Preliminary validation of sizes.
    OP_REQUIRES(context, IsLegacyVector(sizes.shape()),
                errors::InvalidArgument("sizes input must be 1-D, not shape ",
                                        sizes.shape().DebugString()));

    // Compute the output shape.  Determine product of specified
    // dimensions, and find the index of the unspecified one.
    TensorShape shape;
    int64 product = 1;
    int unknown_index = -1;
    switch (sizes.dtype()) {
      case DT_INT32:
        OP_REQUIRES_OK(context, ValidateSizes<int32>(sizes, &product,
                                                     &unknown_index, &shape));
        break;
      case DT_INT64:
        OP_REQUIRES_OK(context, ValidateSizes<int64>(sizes, &product,
                                                     &unknown_index, &shape));
        break;
      default:
        context->CtxFailure(errors::InvalidArgument(
            "desired shape must be a DT_INT32 or DT_INT64 vector, not a ",
            DataTypeString(sizes.dtype())));
        return;
    }
    if (unknown_index != -1) {
      OP_REQUIRES(
          context, product > 0,
          errors::InvalidArgument("Reshape cannot infer the missing input size "
                                  "for an empty tensor unless all specified "
                                  "input sizes are non-zero"));
      const int64 missing = input.NumElements() / product;
      OP_REQUIRES(
          context, product * missing == input.NumElements(),
          errors::InvalidArgument(
              "Input to reshape is a tensor with ", input.NumElements(),
              " values, but the requested shape requires a multiple of ",
              product));
      shape.set_dim(unknown_index, missing);
    }
    OP_REQUIRES(context, shape.num_elements() == input.NumElements(),
                errors::InvalidArgument("Input to reshape is a tensor with ",
                                        input.NumElements(),
                                        " values, but the requested shape has ",
                                        shape.num_elements()));

    MklShape mkl_shape_input;
    GetMklShape(context, 0, &mkl_shape_input);
    bool input_in_mkl_format = mkl_shape_input.IsMklTensor();
    if (input_in_mkl_format) {
      TensorShape& shape_to = shape;
      TensorShape shape_from;
      for (size_t i = 0; i < mkl_shape_input.GetDimension(); i++) {
        // Outermost to innermost dimension
        shape_from.AddDim(
            mkl_shape_input.GetSizes()[mkl_shape_input.tf_dim_idx(i)]);
      }

      if (shape_from == shape_to) {
        CopyMklTensorInToOut(context, 0, 0);
        return;
      } else {
        // Allocate output tensor.
        Tensor* output_tensor = NULL;
        MklShape mkl_shape_output;
        mkl_shape_output.SetMklTensor(false);
        AllocateOutputSetMklShape(context, 0, &output_tensor, shape_to,
                                  mkl_shape_output);

        // Get output layout pointer.
        dnnLayout_t output_layout =
            static_cast<dnnLayout_t>(mkl_shape_input.GetTfLayout());

        // Execute DNNConversion.
        // Note: we  assume an MKL tensor always have float as its data type.
        void* input_buffer =
            static_cast<void*>(const_cast<float*>(input.flat<float>().data()));
        void* output_buffer = static_cast<void*>(
            const_cast<float*>(output_tensor->flat<float>().data()));
        mkl_shape_input.GetConvertedFlatData(output_layout, input_buffer,
                                             output_buffer);

        VLOG(1) << "MKLToTFConversion complete successfully.";
        return;
      }
    } else {
      CopyTfTensorInToOutWithShape(context, 0, 0, shape);
    }
  }

#else

 private:
  // When the input tensor is in MKL layout and we are reshaping the tensor to a
  // different shape than its actual shape, then we use MKLDNN reorder primitive
  // to put tensor back in Tensorflow layout. But we can skip this reordering
  // some times. This function checks for all such cases.
  bool SkipReorder(const MklDnnShape& mkl_shape_input,
                   const TensorShape& reshape_to) {
    CHECK_EQ(mkl_shape_input.IsMklTensor(), true);
    bool ret = false;

    // If Tensorflow's data format and the underlying format maintained by
    // MKLDNN are equivalent (both are NHWC or both are NCHW), then we can
    // safely return true.
    auto input_mkl_md = mkl_shape_input.GetMklLayout();
    if (mkl_shape_input.GetTfDataFormat() == input_mkl_md.data.format) {
      ret = true;
    }

    return ret;
  }

 public:
  void Compute(OpKernelContext* context) override {
    const Tensor& input_tensor = MklGetInput(context, 0);
    const Tensor& sizes = MklGetInput(context, 1);

    MklDnnShape mkl_shape_input;
    GetMklShape(context, kInputSlotIdx, &mkl_shape_input);
    bool input_in_mkl_format = mkl_shape_input.IsMklTensor();
    const int64 nelems = input_in_mkl_format ?
                         mkl_shape_input.GetTfShape().num_elements()
                         : input_tensor.NumElements();

    // Preliminary validation of sizes.
    OP_REQUIRES(context, IsLegacyVector(sizes.shape()),
                errors::InvalidArgument("sizes input must be 1-D, not shape ",
                                        sizes.shape().DebugString()));

    // Compute the output shape.  Determine product of specified
    // dimensions, and find the index of the unspecified one.
    TensorShape shape;
    int64 product = 1;
    int unknown_index = -1;
    switch (sizes.dtype()) {
      case DT_INT32:
        OP_REQUIRES_OK(context, ValidateSizes<int32>(sizes, &product,
                                                     &unknown_index, &shape));
        break;
      case DT_INT64:
        OP_REQUIRES_OK(context, ValidateSizes<int64>(sizes, &product,
                                                     &unknown_index, &shape));
        break;
      default:
        context->CtxFailure(errors::InvalidArgument(
            "desired shape must be a DT_INT32 or DT_INT64 vector, not a ",
            DataTypeString(sizes.dtype())));
        return;
    }
    if (unknown_index != -1) {
      OP_REQUIRES(
          context, product > 0,
          errors::InvalidArgument("Reshape cannot infer the missing input size "
                                  "for an empty tensor unless all specified "
                                  "input sizes are non-zero"));
      const int64 missing = nelems / product;
      OP_REQUIRES(
          context, product * missing == nelems,
          errors::InvalidArgument(
              "Input to reshape is a tensor with ", nelems,
              " values, but the requested shape requires a multiple of ",
              product));
      shape.set_dim(unknown_index, missing);
    }
    OP_REQUIRES(context, shape.num_elements() == nelems,
                errors::InvalidArgument("Input to reshape is a tensor with ",
                                        nelems,
                                        " values, but the requested shape has ",
                                        shape.num_elements()));

    if (input_in_mkl_format) {
      TensorShape& shape_to = shape;
      TensorShape shape_from = mkl_shape_input.GetTfShape();
      if (shape_from == shape_to) {
        CopyMklTensorInToOut(context, kInputSlotIdx, kOutputSlotIdx);
        return;
      } else {
        try {
          auto cpu_engine = engine(engine::cpu, 0);
          MklDnnData<T> dnn_data_input(&cpu_engine);
          // Reshape is just a logical view change operation for a tensor.
          // It does not change underlying layout. But MKLDNN may maintain
          // tensor data in different layout than that specified by Tensorflow.
          // If MKLDNN maintains input tensor in different layout than that
          // specified by Tensorflow, we will need to reorder tensor and then
          // put it in the shape expected by Tensorflow. But if MKLDNN has
          // maintained input tensor in the same layout as it is expected by
          // Tensorflow, we don't need to reorder tensor contents, we just
          // need to update MklDnnShape object associated with the input
          // tensor to reflect the shape change expected by reshape.
          if (!SkipReorder(mkl_shape_input, shape_to)) {
              // If dimensions that are being expanded or collapsed are not
              // maintained contiguously by MKLDNN, then we use reorder.

              // Get Mkl layout of input tensor.
              auto input_mkl_md = mkl_shape_input.GetMklLayout();
              // Set input Mkl layout as the user layout.
              dnn_data_input.SetUsrMem(input_mkl_md, &input_tensor);
              // Get expected Tensorflow layout of input tensor.
              auto output_tf_md = mkl_shape_input.GetTfLayout();
              auto output_tf_pd = memory::primitive_desc(output_tf_md,
                                                         cpu_engine);

              Tensor* output_tensor = nullptr;
              MklShape mkl_shape_output;
              mkl_shape_output.SetMklTensor(false);
              // We allocate output tensor in the shape expected by Reshape.
              AllocateOutputSetMklShape(context, kOutputSlotIdx, &output_tensor,
                                        shape_to, mkl_shape_output);

              // Insert reorder between Mkl layout and TensorFlow layout.
              std::vector<primitive> net;
              CHECK_EQ(dnn_data_input.CheckReorderToOpMem(output_tf_pd,
                       output_tensor, &net), true);
              stream(stream::kind::eager).submit(net).wait();
              return;
          } else {
            // If dimensions that are being expanded or collapsed are
            // maintained contiguously by MKLDNN, then we skip reorder, just
            // update MklDnnShape object for the tensorflow tensor, and forward
            // Tensorflow tensor as it is to the output.
            auto output_dims = TFShapeToMklDnnDims(shape_to);
            auto output_strides = CalculateTFStrides(output_dims);
            auto output_tf_md = MklDnnData<T>::CreateBlockedMemDesc(output_dims,
                                                               output_strides);
            auto output_tf_pd = memory::primitive_desc(output_tf_md,
                                                       cpu_engine);

            // Set MklDnnShape
            MklDnnShape mkl_shape_output;
            mkl_shape_output.SetMklTensor(true);
            mkl_shape_output.SetMklLayout(&output_tf_pd);
            mkl_shape_output.SetElemType(MklDnnType<T>());
            mkl_shape_output.SetTfLayout(output_dims.size(), output_dims,
                                         memory::format::blocked);

            // We now simply forward input Mkl tensor to output and change its
            // output MklDnnShape object.
            ForwardMklTensorInToOutWithMklShape(context, kInputSlotIdx,
                                              kOutputSlotIdx, mkl_shape_output);
            return;
          }
        } catch (mkldnn::error &e) {
          string error_msg = "Status: " + std::to_string(e.status) +
                       ", message: " + string(e.message) +
                       ", in file " + string(__FILE__) + ":" +
                       std::to_string(__LINE__);
          OP_REQUIRES_OK(context,
                   errors::Aborted("Operation received an exception:",
                      error_msg));
        }
      }
    } else {
      // If input tensor is not in Mkl format, then just copy Tensorflow tensor
      // to output with specified shape.
      CopyTfTensorInToOutWithShape(context, kInputSlotIdx, kOutputSlotIdx,
                                   shape);
    }
  }

#endif  // INTEL_MKL_DNN

 private:
  const int kInputSlotIdx = 0;
  const int kOutputSlotIdx = 0;

  template <typename Tshape>
  Status ValidateSizes(const Tensor& sizes, int64* product, int* unknown_index,
                       TensorShape* shape) {
    *product = 1;
    *unknown_index = -1;
    const int64 num_dims = sizes.NumElements();
    auto Svec = sizes.flat<Tshape>();
    for (int d = 0; d < num_dims; ++d) {
      const Tshape size = Svec(d);
      if (size == -1) {
        if (*unknown_index != -1) {
          return errors::InvalidArgument(
              "Only one input size may be -1, not both ", *unknown_index,
              " and ", d);
        }
        *unknown_index = d;
        shape->AddDim(1);
      } else if (size < 0) {
        return errors::InvalidArgument("Size ", d,
                                       " must be non-negative, not ", size);
      } else {
        shape->AddDim(size);
        (*product) *= size;
      }
    }
    return Status::OK();
  }
};

#define REGISTER_MKL_CPU(T)                                         \
  REGISTER_KERNEL_BUILDER(Name("_MklReshape")                       \
                              .Device(DEVICE_CPU)                   \
                              .HostMemory("shape")                  \
                              .TypeConstraint<T>("T")               \
                              .TypeConstraint<int32>("Tshape")      \
                              .Label(mkl_op_registry::kMklOpLabel), \
                          MklReshapeOp<CPUDevice, T>);              \
  REGISTER_KERNEL_BUILDER(Name("_MklReshape")                       \
                              .Device(DEVICE_CPU)                   \
                              .HostMemory("shape")                  \
                              .TypeConstraint<T>("T")               \
                              .TypeConstraint<int64>("Tshape")      \
                              .Label(mkl_op_registry::kMklOpLabel), \
                          MklReshapeOp<CPUDevice, T>);
TF_CALL_float(REGISTER_MKL_CPU);
#undef REGISTER_MKL_CPU
}  // namespace tensorflow

#endif  // INTEL_MKL
<|endoftext|>


<commit_before>/* Copyright 2019 The TensorFlow 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 "tensorflow/lite/kernels/internal/reference/integer_ops/logistic.h"

#include "tensorflow/lite/c/builtin_op_data.h"
#include "tensorflow/lite/c/common.h"
#include "tensorflow/lite/kernels/internal/common.h"
#include "tensorflow/lite/kernels/internal/quantization_util.h"
#include "tensorflow/lite/kernels/internal/reference/logistic.h"
#include "tensorflow/lite/kernels/internal/tensor_ctypes.h"
#include "tensorflow/lite/kernels/kernel_util.h"
#include "tensorflow/lite/kernels/op_macros.h"

namespace tflite {
namespace ops {
namespace micro {
namespace activations {
namespace {
constexpr int kInputTensor = 0;
constexpr int kOutputTensor = 0;

struct OpData {
  int32_t input_zero_point;
  int32_t input_range_radius;
  int32_t input_multiplier;
  int input_left_shift;
};

TfLiteStatus CalculateArithmeticOpData(TfLiteContext* context, TfLiteNode* node,
                                       OpData* data) {
  const TfLiteTensor* input = GetInput(context, node, kInputTensor);
  TfLiteTensor* output = GetOutput(context, node, kOutputTensor);

  TF_LITE_ENSURE_TYPES_EQ(context, input->type, output->type);
  if (input->type == kTfLiteInt8) {
    TF_LITE_ENSURE_EQ(context, output->params.zero_point,
                      std::numeric_limits<int8_t>::min());

    static constexpr int kInputIntegerBits = 4;
    const double input_real_multiplier =
        static_cast<double>(input->params.scale) *
        static_cast<double>(1 << (31 - kInputIntegerBits));

    const double q = std::frexp(input_real_multiplier, &data->input_left_shift);
    data->input_multiplier = static_cast<int32_t>(TfLiteRound(q * (1ll << 31)));

    data->input_range_radius =
        CalculateInputRadius(kInputIntegerBits, data->input_left_shift, 31);
  }
  return kTfLiteOk;
}
}  // namespace

TfLiteStatus LogisticEval(TfLiteContext* context, TfLiteNode* node) {
  const TfLiteTensor* input = GetInput(context, node, kInputTensor);
  TfLiteTensor* output = GetOutput(context, node, kOutputTensor);
  OpData data;
  CalculateArithmeticOpData(context, node, &data);

  if (input->type == kTfLiteFloat32) {
    switch (output->type) {
      case kTfLiteFloat32: {
        reference_ops::Logistic(
            GetTensorShape(input), GetTensorData<float>(input),
            GetTensorShape(output), GetTensorData<float>(output));
        return kTfLiteOk;
      }
      default:
        TF_LITE_KERNEL_LOG(context, "Input %s, output %s not supported.",
                           TfLiteTypeGetName(input->type),
                           TfLiteTypeGetName(output->type));
        return kTfLiteError;
    }
  } else if (input->type == kTfLiteInt8) {
    switch (output->type) {
      case kTfLiteInt8: {
        reference_integer_ops::Logistic(
            input->params.zero_point, data.input_range_radius,
            data.input_multiplier, data.input_left_shift,
            NumElements(input->dims), GetTensorData<int8_t>(input),
            GetTensorData<int8_t>(output));
        return kTfLiteOk;
      }
      default:
        TF_LITE_KERNEL_LOG(context, "Input %s, output %s not supported.",
                           TfLiteTypeGetName(input->type),
                           TfLiteTypeGetName(output->type));
        return kTfLiteError;
    }
  } else {
    // TODO(b/141211002): Also support other data types once we have supported
    // temporary tensors in TFLM.
    TF_LITE_KERNEL_LOG(context, "Input %s, output %s not supported.",
                       TfLiteTypeGetName(input->type),
                       TfLiteTypeGetName(output->type));
    return kTfLiteError;
  }
  return kTfLiteOk;
}

}  // namespace activations

TfLiteRegistration Register_LOGISTIC() {
  return {/*init=*/nullptr,
          /*free=*/nullptr,
          /*prepare=*/nullptr,
          /*invoke=*/activations::LogisticEval,
          /*profiling_string=*/nullptr,
          /*builtin_code=*/0,
          /*custom_name=*/nullptr,
          /*version=*/0};
}
}  // namespace micro
}  // namespace ops
}  // namespace tflite
<commit_msg>Move OpData calculation from Eval() into a stored persistent buffer in the Logistic kernel.<commit_after>/* Copyright 2019 The TensorFlow 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 "tensorflow/lite/kernels/internal/reference/integer_ops/logistic.h"

#include "tensorflow/lite/c/builtin_op_data.h"
#include "tensorflow/lite/c/common.h"
#include "tensorflow/lite/kernels/internal/common.h"
#include "tensorflow/lite/kernels/internal/quantization_util.h"
#include "tensorflow/lite/kernels/internal/reference/logistic.h"
#include "tensorflow/lite/kernels/internal/tensor_ctypes.h"
#include "tensorflow/lite/kernels/kernel_util.h"
#include "tensorflow/lite/kernels/op_macros.h"

namespace tflite {
namespace ops {
namespace micro {
namespace activations {
namespace {
constexpr int kInputTensor = 0;
constexpr int kOutputTensor = 0;

struct OpData {
  int32_t input_zero_point;
  int32_t input_range_radius;
  int32_t input_multiplier;
  int input_left_shift;
};

TfLiteStatus CalculateArithmeticOpData(TfLiteContext* context, TfLiteNode* node,
                                       OpData* data) {
  const TfLiteTensor* input = GetInput(context, node, kInputTensor);
  TfLiteTensor* output = GetOutput(context, node, kOutputTensor);

  TF_LITE_ENSURE_TYPES_EQ(context, input->type, output->type);
  if (input->type == kTfLiteInt8) {
    TF_LITE_ENSURE_EQ(context, output->params.zero_point,
                      std::numeric_limits<int8_t>::min());

    static constexpr int kInputIntegerBits = 4;
    const double input_real_multiplier =
        static_cast<double>(input->params.scale) *
        static_cast<double>(1 << (31 - kInputIntegerBits));

    data->input_zero_point = input->params.zero_point;

    const double q = std::frexp(input_real_multiplier, &data->input_left_shift);
    data->input_multiplier = static_cast<int32_t>(TfLiteRound(q * (1ll << 31)));

    data->input_range_radius =
        CalculateInputRadius(kInputIntegerBits, data->input_left_shift, 31);
  }
  return kTfLiteOk;
}
}  // namespace

void* LogisticInit(TfLiteContext* context, const char* buffer, size_t length) {
  TFLITE_DCHECK(context->AllocatePersistentBuffer != nullptr);
  void* data = nullptr;
  if (context->AllocatePersistentBuffer(context, sizeof(OpData), &data) ==
      kTfLiteError) {
    return nullptr;
  }
  return data;
}

TfLiteStatus LogisticPrepare(TfLiteContext* context, TfLiteNode* node) {
  TFLITE_DCHECK(node->user_data != nullptr);
  OpData* data = static_cast<OpData*>(node->user_data);

  return CalculateArithmeticOpData(context, node, data);
}

TfLiteStatus LogisticEval(TfLiteContext* context, TfLiteNode* node) {
  const TfLiteTensor* input = GetInput(context, node, kInputTensor);
  TfLiteTensor* output = GetOutput(context, node, kOutputTensor);

  TFLITE_DCHECK(node->user_data != nullptr);
  OpData* data = static_cast<OpData*>(node->user_data);

  if (input->type == kTfLiteFloat32) {
    switch (output->type) {
      case kTfLiteFloat32: {
        reference_ops::Logistic(
            GetTensorShape(input), GetTensorData<float>(input),
            GetTensorShape(output), GetTensorData<float>(output));
        return kTfLiteOk;
      }
      default:
        TF_LITE_KERNEL_LOG(context, "Input %s, output %s not supported.",
                           TfLiteTypeGetName(input->type),
                           TfLiteTypeGetName(output->type));
        return kTfLiteError;
    }
  } else if (input->type == kTfLiteInt8) {
    switch (output->type) {
      case kTfLiteInt8: {
        reference_integer_ops::Logistic(
            data->input_zero_point, data->input_range_radius,
            data->input_multiplier, data->input_left_shift,
            NumElements(input->dims), GetTensorData<int8_t>(input),
            GetTensorData<int8_t>(output));
        return kTfLiteOk;
      }
      default:
        TF_LITE_KERNEL_LOG(context, "Input %s, output %s not supported.",
                           TfLiteTypeGetName(input->type),
                           TfLiteTypeGetName(output->type));
        return kTfLiteError;
    }
  } else {
    // TODO(b/141211002): Also support other data types once we have supported
    // temporary tensors in TFLM.
    TF_LITE_KERNEL_LOG(context, "Input %s, output %s not supported.",
                       TfLiteTypeGetName(input->type),
                       TfLiteTypeGetName(output->type));
    return kTfLiteError;
  }
  return kTfLiteOk;
}

}  // namespace activations

TfLiteRegistration Register_LOGISTIC() {
  return {/*init=*/activations::LogisticInit,
          /*free=*/nullptr,
          /*prepare=*/activations::LogisticPrepare,
          /*invoke=*/activations::LogisticEval,
          /*profiling_string=*/nullptr,
          /*builtin_code=*/0,
          /*custom_name=*/nullptr,
          /*version=*/0};
}
}  // namespace micro
}  // namespace ops
}  // namespace tflite
<|endoftext|>


<commit_before>/*****************************************************************************
 * PoCRangefinder.cpp
 *
 * Take images at varying distances from target to calibrate laser stick
 *
 ******************************************************************************/

#include "PoCRangefinder.h"

using namespace cv;
using namespace std;

////////////////
// Parameters //
////////////////

// Saved image params
#define IMAGE_PREFIX    "images/image"
#define IMAGE_EXTENSION ".jpg"

#define BRIGHT_EXPOSURE 100
#define DARK_EXPOSURE   5
#define ISO_VALUE       4

// Image Size
//#define FRAME_WIDTH     3280  // 8 megapixels
//#define FRAME_HEIGHT    2464  // 8 megapixels
#define FRAME_WIDTH       1280  // 720 HD
#define FRAME_HEIGHT      720   // 720 HD
// Rangefinder Constants
#define RANGE_K0          -567.7
#define RANGE_K1          0.09943
#define RANGE_K2          -330.0

//////////////////////
// Global Variables //
//////////////////////

// Global State Variable
sub_state_t substate;

// Global Variables
string source_window = "Bright Image";
Mat darkframe, brightframe;
VideoCapture cap;
int redbalance = 20;
int bluebalance = 20;
int exposure = 5;
int brightness = 50;
int contrast = 50;
int saturation = 50;
int cropleft = 420;
int croptop = 0;
int cropwidth = 320;
int cropheight = 720;
Mat hsv_frame;

// V4L2 Global Device Object
V4L2Control picamctrl;

////////////////////////
// Callback Functions //
////////////////////////

/*******************************************************************************
 * void whiteBalanceCallback(int, void*)
 *
 * Sets white balance values (from 1-7999)
 * Changing position of trackbar calls this function
 ******************************************************************************/
void whiteBalanceCallback(int, void*)
{
  picamctrl.set(V4L2_CID_RED_BALANCE,redbalance*80);
  picamctrl.set(V4L2_CID_BLUE_BALANCE,bluebalance*80);
}

/*******************************************************************************
 * void mouseCallback(int event, int x, int y, int flags, void* userdata)
 *
 * Write HSV and RGB values of point clicked on to terminal
 * Any mouse movement will call this function
 ******************************************************************************/
void mouseCallback(int event, int x, int y, int flags, void* userdata)
{
  if  ( event == EVENT_LBUTTONDOWN ) // Only run when left button is pressed
  {
   // How do we know what we're looking at?
    Vec3b intensity = hsv_frame.at<Vec3b>(y, x);
    int hue = intensity.val[0];
    int sat = intensity.val[1];
    int val = intensity.val[2];
    // print out HSV values (sanity check)
    cout << "H: " << hue << ",\tS:" << sat << ",\tV:" << val << endl;
    // Can we change this to Dark Frame?
    Vec3b bgr = darkframe.at<Vec3b>(y, x);
    int b = bgr.val[0];
    int g = bgr.val[1];
    int r = bgr.val[2];
    // print out RGB values (sanity check)
    cout << "B: " << b << ",\tG:" << g << ",\tR:" << r << endl;
  }
}

/*******************************************************************************
 * void bcsCallback(int, void*)
 *
 * Sets brightness, contrast and saturation values (1-100)
 ******************************************************************************/
void bcsCallback(int, void*)
{
  picamctrl.set(V4L2_CID_BRIGHTNESS,brightness);
  picamctrl.set(V4L2_CID_CONTRAST,contrast);
  picamctrl.set(V4L2_CID_SATURATION,saturation);
  // sanity checks: print out brightness, contrast, and saturation values
  cout << "B: " << picamctrl.get(V4L2_CID_BRIGHTNESS) << "\t";
  cout << "C: " << picamctrl.get(V4L2_CID_CONTRAST) << "\t";
  cout << "S: " << picamctrl.get(V4L2_CID_SATURATION) << endl;
}
// Did this work???
/*******************************************************************************
 * void exposureCallback(int, void*)
 *
 * Sets Sets the exposure, white balance, and Image Sensitivity
 *******************************************************************************/
// void exposureCallback(int, void*)
// {
  // picamcrl.set(V4L2_CID_
//////////////
// Threads! //
//////////////

/*******************************************************************************
 * void *takePictures(void*)
 *
 * Camera-handling thread: continuously save images as soon as they come in
 ******************************************************************************/
void *takePictures(void*)
{
  // Initialize exposure settings
  picamctrl.set(V4L2_CID_EXPOSURE_ABSOLUTE, BRIGHT_EXPOSURE );

  // Grab all 5 images from the frame buffer in order to clear the buffer
  for(int i=0; i<5; i++)
  {
    cap.grab();
  }

  // Loop quickly to pick up images as soon as they are taken
  while(substate.mode != STOPPED)
  {
    // 'Grab' bright frame from webcam's image buffer
    cap.grab();
    // Set exposure now (rather than later)
    picamctrl.set(V4L2_CID_EXPOSURE_ABSOLUTE, DARK_EXPOSURE );
    // Retrieve encodes image from grab buffer to 'brightframe' variable
    cap.retrieve( brightframe );

    // 'Grab' dark frame from webcam's image buffer
    cap.grab();
    // Set exposure now (rather than later)
    picamctrl.set(V4L2_CID_EXPOSURE_ABSOLUTE, BRIGHT_EXPOSURE );
    // Retrieve encodes image from grab buffer to 'darkframe' variable
    cap.retrieve( darkframe );
  }

  // End thread
  pthread_exit(NULL);
}

//////////
// Main //
//////////
int main(int argc, char** argv)
{
  // We're initializing!
  substate.mode = INITIALIZING;

  // Open the camera!
  cap.open(0); // opens first video device
  picamctrl.open("/dev/video0");

  // check to make sure device properly opened
  if ( !cap.isOpened() )
  {
    cerr << "Error opening the camera (OpenCV)" << endl;
    return -1;
  }
 // Can all of these Parameters be set in a Thread?
  // Set framerate (OpenCV capture property)
  cap.set(CV_CAP_PROP_FPS,2);

  // Set camera exposure control to manual (driver property)
  picamctrl.set(V4L2_CID_EXPOSURE_AUTO, V4L2_EXPOSURE_MANUAL);

  // Set camera autowhitebalance to manual
  picamctrl.set(V4L2_CID_AUTO_N_PRESET_WHITE_BALANCE,V4L2_WHITE_BALANCE_MANUAL);

  // Set camera iso to manual
  picamctrl.set(V4L2_CID_ISO_SENSITIVITY_AUTO, 0);

  // Initialize exposure, iso values
  picamctrl.set(V4L2_CID_EXPOSURE_ABSOLUTE, BRIGHT_EXPOSURE);
  picamctrl.set(V4L2_CID_ISO_SENSITIVITY, ISO_VALUE);

  // Set capture camera size (resolution)
  cap.set(CV_CAP_PROP_FRAME_WIDTH,FRAME_WIDTH);
  cap.set(CV_CAP_PROP_FRAME_HEIGHT,FRAME_HEIGHT);

  // Fill images w/ initial images
  cap.read( brightframe );
  cap.read( darkframe );

  // Open windows on your monitor
  namedWindow( source_window, CV_WINDOW_AUTOSIZE ); // How Do we know which Images?
 // We Probably want to look at dark image values.....

  // Create trackbars for white balancing
//   createTrackbar( " Red: ", source_window, &redbalance, 100, whiteBalanceCallback );
//   createTrackbar( " Blue:", source_window, &bluebalance, 100, whiteBalanceCallback );

  // Create trackbar for exposure setting
//   createTrackbar( " Exposure:", source_window, &exposure, 100, NULL);

  // Create brightness, saturation and contrast trackbars
//   createTrackbar( " Brightness:", source_window, &brightness, 100, bcsCallback);
//   createTrackbar( " Contrast:", source_window, &contrast, 100, bcsCallback);
//   createTrackbar( " Saturation:", source_window, &saturation, 100, bcsCallback);

  // set the callback function for any mouse event
  setMouseCallback(source_window, mouseCallback, NULL);

  // set default white balance
  whiteBalanceCallback(0,0);

  // Start multithreading!
  pthread_t cameraThread;

  // Setting Priorities
  pthread_attr_t tattr;
  sched_param param;

  // Initialize attributes with defaults
  pthread_attr_init (&tattr);
  // Save the parameters to "param"
  pthread_attr_getschedparam (&tattr, &param);
  // Set the priority parameter of "param", leaving others at default
  param.sched_priority = sched_get_priority_max(SCHED_RR) - 1;
  // Set attributes to modified parameters
  pthread_attr_setschedparam (&tattr, &param);

  // Create thread using modified attributes
  pthread_create (&cameraThread, &tattr, takePictures, NULL);

  // Pause for 2 seconds to let everything initialize
  sleep(2);

  // Announce that we're done initializing
  cout << "Done Initializing." << endl;

  // Set mode to RUNNING
  substate.mode = RUNNING;

  int key = 0;

  // Take a bunch of pictures
  while(key != 27) // 27 is keycode for escape key
//   for(int i=1; i<=10; i++)
  {
    // Save most recent bright frame to local variables
    Mat localbrightframe, localdarkframe;
    brightframe.copyTo(localbrightframe);
    darkframe.copyTo(localdarkframe);

    // Convert from BGR to HSV using CV_BGR2HSV conversion
//    Mat hsv_frame;
    cvtColor(localdarkframe, hsv_frame, CV_BGR2HSV);
//  crop the local darkframe and brightframe images
    Rect roi(cropleft,croptop,cropwidth,cropheight);
    Mat hsvframeroi = hsv_frame(roi);
    Mat brightframeroi = localbrightframe(roi);
    Mat darkframeroi = localdarkframe(roi);

    // Find laser dot
    Mat1b mask; // b/w matrix for laser detection

    // if hsv_frame is in scalar range, set that pixel to white and store in mask

    // White
//     inRange(hsv_frame, Scalar(0, 0, 40), Scalar(180, 255, 255), mask);

    // Green
   // inRange(hsv_frame, Scalar(61, 50, 50), Scalar(89, 250, 250), mask);
   // inRange(hsvframeroi, Scalar(60, 50, 50), Scalar(89, 255, 255), mask);

    // Red
    Mat1b mask1, mask2;
    inRange(hsvframeroi, Scalar(1, 50, 50), Scalar(15, 250, 250), mask1);
    inRange(hsvframeroi, Scalar(165, 50, 50), Scalar(179, 250, 250), mask2);
    mask = mask1 | mask2;

    // Locate centroid of laser dot
    Moments m = moments(mask, false);
    Point p1(m.m10/m.m00+cropleft, m.m01/m.m00);

    // Draw red circle w/ center at centroid on original image
    circle( localbrightframe, p1, 10.0, Scalar( 0, 0, 255 ));
    //circle( brightframeroi, p1, 10.0, Scalar( 0, 0, 255 ));
   // circle( darkframeroi, p1, 10.0, Scalar( 0, 0, 255 ));

    // Write coordinates in top left corner
    stringstream coordinates;
    coordinates << "(" << p1.x << ", " << p1.y << ")";
    Point org;
    org.x = 10;
    org.y = 40;
    putText( localbrightframe, coordinates.str(), org, 1, 1, Scalar(0,0,255));
    //putText( brightframeroi, coordinates.str(), org, 1, 1, Scalar(0,0,255));

    // Calculate range
    stringstream rangestring;
    if(p1.x !=0)
    {
      float range = (RANGE_K0 + RANGE_K1*p1.y) / (RANGE_K2 + p1.y);
//       cout << "Calculated Range: " << range << endl;
      rangestring << range << " ft";
    }
    else  // If coordinates are (0,0), we haven't detected anything.
    {
      rangestring << "------ ft";
    }

    // Write range in top left corner
    Point pnt;
    pnt.x = 10;
    pnt.y = 20;
    putText( localbrightframe, rangestring.str(), pnt, 1, 1, Scalar(0,0,255));
    //putText( brightframeroi, rangestring.str(), pnt, 1, 1, Scalar(0,0,255));

    // Display image on current open window
    imshow( source_window, localbrightframe );
   // imshow( source_window, brightframeroi );
   // imshow( source_window, darkframeroi );
   // imshow( source_window, mask );

   // wait 1 ms to check for press of escape key
   key = waitKey(1);
  } // end while

  // Set mode to STOPPED
  substate.mode = STOPPED;

  // Wait a second to let the threads stop
  sleep(1);

  // close camera
  cap.release();
  picamctrl.close();
}// end main
<commit_msg>eliminated underscores from variable names<commit_after>/*****************************************************************************
 * PoCRangefinder.cpp
 *
 * Take images at varying distances from target to calibrate laser stick
 *
 ******************************************************************************/

#include "PoCRangefinder.h"

using namespace cv;
using namespace std;

////////////////
// Parameters //
////////////////

// Saved image params
#define IMAGE_PREFIX    "images/image"
#define IMAGE_EXTENSION ".jpg"

#define BRIGHT_EXPOSURE 100
#define DARK_EXPOSURE   5
#define ISO_VALUE       4

// Image Size
//#define FRAME_WIDTH     3280  // 8 megapixels
//#define FRAME_HEIGHT    2464  // 8 megapixels
#define FRAME_WIDTH       1280  // 720 HD
#define FRAME_HEIGHT      720   // 720 HD

// Rangefinder Constants
#define RANGE_K0          -567.7
#define RANGE_K1          0.09943
#define RANGE_K2          -330.0

// Window Names
#define SOURCE_WINDOW     "Bright Image"

//////////////////////
// Global Variables //
//////////////////////

// Global State Variable
sub_state_t substate;

// Global Variables
Mat darkframe, brightframe;
VideoCapture cap;
int redbalance = 20;
int bluebalance = 20;
int exposure = 5;
int brightness = 50;
int contrast = 50;
int saturation = 50;
int cropleft = 420;
int croptop = 0;
int cropwidth = 320;
int cropheight = 720;
Mat hsvframe;

// V4L2 Global Device Object
V4L2Control picamctrl;

////////////////////////
// Callback Functions //
////////////////////////

/*******************************************************************************
 * void whiteBalanceCallback(int, void*)
 *
 * Sets white balance values (from 1-7999)
 * Changing position of trackbar calls this function
 ******************************************************************************/
void whiteBalanceCallback(int, void*)
{
  picamctrl.set(V4L2_CID_RED_BALANCE,redbalance*80);
  picamctrl.set(V4L2_CID_BLUE_BALANCE,bluebalance*80);
}

/*******************************************************************************
 * void mouseCallback(int event, int x, int y, int flags, void* userdata)
 *
 * Write HSV and RGB values of point clicked on to terminal
 * Any mouse movement will call this function
 ******************************************************************************/
void mouseCallback(int event, int x, int y, int flags, void* userdata)
{
  if  ( event == EVENT_LBUTTONDOWN ) // Only run when left button is pressed
  {
   // How do we know what we're looking at?
    Vec3b intensity = hsvframe.at<Vec3b>(y, x);
    int hue = intensity.val[0];
    int sat = intensity.val[1];
    int val = intensity.val[2];
    // print out HSV values (sanity check)
    cout << "H: " << hue << ",\tS:" << sat << ",\tV:" << val << endl;
    // Can we change this to Dark Frame?
    Vec3b bgr = darkframe.at<Vec3b>(y, x);
    int b = bgr.val[0];
    int g = bgr.val[1];
    int r = bgr.val[2];
    // print out RGB values (sanity check)
    cout << "B: " << b << ",\tG:" << g << ",\tR:" << r << endl;
  }
}

/*******************************************************************************
 * void bcsCallback(int, void*)
 *
 * Sets brightness, contrast and saturation values (1-100)
 ******************************************************************************/
void bcsCallback(int, void*)
{
  picamctrl.set(V4L2_CID_BRIGHTNESS,brightness);
  picamctrl.set(V4L2_CID_CONTRAST,contrast);
  picamctrl.set(V4L2_CID_SATURATION,saturation);
  // sanity checks: print out brightness, contrast, and saturation values
  cout << "B: " << picamctrl.get(V4L2_CID_BRIGHTNESS) << "\t";
  cout << "C: " << picamctrl.get(V4L2_CID_CONTRAST) << "\t";
  cout << "S: " << picamctrl.get(V4L2_CID_SATURATION) << endl;
}
// Did this work???
/*******************************************************************************
 * void exposureCallback(int, void*)
 *
 * Sets Sets the exposure, white balance, and Image Sensitivity
 *******************************************************************************/
// void exposureCallback(int, void*)
// {
  // picamcrl.set(V4L2_CID_
//////////////
// Threads! //
//////////////

/*******************************************************************************
 * void *takePictures(void*)
 *
 * Camera-handling thread: continuously save images as soon as they come in
 ******************************************************************************/
void *takePictures(void*)
{
  // Initialize exposure settings
  picamctrl.set(V4L2_CID_EXPOSURE_ABSOLUTE, BRIGHT_EXPOSURE );

  // Grab all 5 images from the frame buffer in order to clear the buffer
  for(int i=0; i<5; i++)
  {
    cap.grab();
  }

  // Loop quickly to pick up images as soon as they are taken
  while(substate.mode != STOPPED)
  {
    // 'Grab' bright frame from webcam's image buffer
    cap.grab();
    // Set exposure now (rather than later)
    picamctrl.set(V4L2_CID_EXPOSURE_ABSOLUTE, DARK_EXPOSURE );
    // Retrieve encodes image from grab buffer to 'brightframe' variable
    cap.retrieve( brightframe );

    // 'Grab' dark frame from webcam's image buffer
    cap.grab();
    // Set exposure now (rather than later)
    picamctrl.set(V4L2_CID_EXPOSURE_ABSOLUTE, BRIGHT_EXPOSURE );
    // Retrieve encodes image from grab buffer to 'darkframe' variable
    cap.retrieve( darkframe );
  }

  // End thread
  pthread_exit(NULL);
}

//////////
// Main //
//////////
int main(int argc, char** argv)
{
  // We're initializing!
  substate.mode = INITIALIZING;

  // Open the camera!
  cap.open(0); // opens first video device
  picamctrl.open("/dev/video0");

  // check to make sure device properly opened
  if ( !cap.isOpened() )
  {
    cerr << "Error opening the camera (OpenCV)" << endl;
    return -1;
  }
 // Can all of these Parameters be set in a Thread?
  // Set framerate (OpenCV capture property)
  cap.set(CV_CAP_PROP_FPS,2);

  // Set camera exposure control to manual (driver property)
  picamctrl.set(V4L2_CID_EXPOSURE_AUTO, V4L2_EXPOSURE_MANUAL);

  // Set camera autowhitebalance to manual
  picamctrl.set(V4L2_CID_AUTO_N_PRESET_WHITE_BALANCE,V4L2_WHITE_BALANCE_MANUAL);

  // Set camera iso to manual
  picamctrl.set(V4L2_CID_ISO_SENSITIVITY_AUTO, 0);

  // Initialize exposure, iso values
  picamctrl.set(V4L2_CID_EXPOSURE_ABSOLUTE, BRIGHT_EXPOSURE);
  picamctrl.set(V4L2_CID_ISO_SENSITIVITY, ISO_VALUE);

  // Set capture camera size (resolution)
  cap.set(CV_CAP_PROP_FRAME_WIDTH,FRAME_WIDTH);
  cap.set(CV_CAP_PROP_FRAME_HEIGHT,FRAME_HEIGHT);

  // Fill images w/ initial images
  cap.read( brightframe );
  cap.read( darkframe );

  // Open windows on your monitor
  namedWindow( SOURCE_WINDOW, CV_WINDOW_AUTOSIZE ); // How Do we know which Images?
 // We Probably want to look at dark image values.....

  // Create trackbars for white balancing
//   createTrackbar( " Red: ", SOURCE_WINDOW, &redbalance, 100, whiteBalanceCallback );
//   createTrackbar( " Blue:", SOURCE_WINDOW, &bluebalance, 100, whiteBalanceCallback );

  // Create trackbar for exposure setting
//   createTrackbar( " Exposure:", SOURCE_WINDOW, &exposure, 100, NULL);

  // Create brightness, saturation and contrast trackbars
//   createTrackbar( " Brightness:", SOURCE_WINDOW, &brightness, 100, bcsCallback);
//   createTrackbar( " Contrast:", SOURCE_WINDOW, &contrast, 100, bcsCallback);
//   createTrackbar( " Saturation:", SOURCE_WINDOW, &saturation, 100, bcsCallback);

  // set the callback function for any mouse event
  setMouseCallback(SOURCE_WINDOW, mouseCallback, NULL);

  // set default white balance
  whiteBalanceCallback(0,0);

  // Start multithreading!
  pthread_t cameraThread;

  // Setting Priorities
  pthread_attr_t tattr;
  sched_param param;

  // Initialize attributes with defaults
  pthread_attr_init (&tattr);
  // Save the parameters to "param"
  pthread_attr_getschedparam (&tattr, &param);
  // Set the priority parameter of "param", leaving others at default
  param.sched_priority = sched_get_priority_max(SCHED_RR) - 1;
  // Set attributes to modified parameters
  pthread_attr_setschedparam (&tattr, &param);

  // Create thread using modified attributes
  pthread_create (&cameraThread, &tattr, takePictures, NULL);

  // Pause for 2 seconds to let everything initialize
  sleep(2);

  // Announce that we're done initializing
  cout << "Done Initializing." << endl;

  // Set mode to RUNNING
  substate.mode = RUNNING;

  int key = 0;

  // Take a bunch of pictures
  while(key != 27) // 27 is keycode for escape key
//   for(int i=1; i<=10; i++)
  {
    // Save most recent bright frame to local variables
    Mat localbrightframe, localdarkframe;
    brightframe.copyTo(localbrightframe);
    darkframe.copyTo(localdarkframe);

    // Convert from BGR to HSV using CV_BGR2HSV conversion
//    Mat hsvframe;
    cvtColor(localdarkframe, hsvframe, CV_BGR2HSV);
//  crop the local darkframe and brightframe images
    Rect roi(cropleft,croptop,cropwidth,cropheight);
    Mat hsvframeroi = hsvframe(roi);
    Mat brightframeroi = localbrightframe(roi);
    Mat darkframeroi = localdarkframe(roi);

    // Find laser dot
    Mat1b mask; // b/w matrix for laser detection

    // if hsvframe is in scalar range, set that pixel to white and store in mask

    // White
//     inRange(hsvframe, Scalar(0, 0, 40), Scalar(180, 255, 255), mask);

    // Green
   // inRange(hsvframe, Scalar(61, 50, 50), Scalar(89, 250, 250), mask);
   // inRange(hsvframeroi, Scalar(60, 50, 50), Scalar(89, 255, 255), mask);

    // Red
    Mat1b mask1, mask2;
    inRange(hsvframeroi, Scalar(1, 50, 50), Scalar(15, 250, 250), mask1);
    inRange(hsvframeroi, Scalar(165, 50, 50), Scalar(179, 250, 250), mask2);
    mask = mask1 | mask2;

    // Locate centroid of laser dot
    Moments m = moments(mask, false);
    Point p1(m.m10/m.m00+cropleft, m.m01/m.m00);

    // Draw red circle w/ center at centroid on original image
    circle( localbrightframe, p1, 10.0, Scalar( 0, 0, 255 ));
    //circle( brightframeroi, p1, 10.0, Scalar( 0, 0, 255 ));
   // circle( darkframeroi, p1, 10.0, Scalar( 0, 0, 255 ));

    // Write coordinates in top left corner
    stringstream coordinates;
    coordinates << "(" << p1.x << ", " << p1.y << ")";
    Point org;
    org.x = 10;
    org.y = 40;
    putText( localbrightframe, coordinates.str(), org, 1, 1, Scalar(0,0,255));
    //putText( brightframeroi, coordinates.str(), org, 1, 1, Scalar(0,0,255));

    // Calculate range
    stringstream rangestring;
    if(p1.x !=0)
    {
      float range = (RANGE_K0 + RANGE_K1*p1.y) / (RANGE_K2 + p1.y);
//       cout << "Calculated Range: " << range << endl;
      rangestring << range << " ft";
    }
    else  // If coordinates are (0,0), we haven't detected anything.
    {
      rangestring << "------ ft";
    }

    // Write range in top left corner
    Point pnt;
    pnt.x = 10;
    pnt.y = 20;
    putText( localbrightframe, rangestring.str(), pnt, 1, 1, Scalar(0,0,255));
    //putText( brightframeroi, rangestring.str(), pnt, 1, 1, Scalar(0,0,255));

    // Display image on current open window
    imshow( SOURCE_WINDOW, localbrightframe );
   // imshow( SOURCE_WINDOW, brightframeroi );
   // imshow( SOURCE_WINDOW, darkframeroi );
   // imshow( SOURCE_WINDOW, mask );

   // wait 1 ms to check for press of escape key
   key = waitKey(1);
  } // end while

  // Set mode to STOPPED
  substate.mode = STOPPED;

  // Wait a second to let the threads stop
  sleep(1);

  // close camera
  cap.release();
  picamctrl.close();
}// end main
<|endoftext|>


<commit_before>/*
 * Copyright 2013-2016  Rinat Ibragimov
 *
 * This file is part of libvdpau-va-gl
 *
 * Permission is hereby granted, free of charge, to any person obtaining a copy
 * of this software and associated documentation files (the "Software"), to deal
 * in the Software without restriction, including without limitation the rights
 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
 * copies of the Software, and to permit persons to whom the Software is
 * furnished to do so, subject to the following conditions:
 *
 * The above copyright notice and this permission notice shall be included in all
 * copies or substantial portions of the Software.
 *
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
 * SOFTWARE.
 */

#pragma once

#include <stdint.h>
#include <unistd.h>
#include <vector>
#include <stdexcept>

namespace vdp {

/// Raw byte sequence payload state
///
/// throws ByteReader::error()

class RBSPState
{
public:
    class error: public std::logic_error
    {
    public:
        error(const char *descr)
            : std::logic_error(descr)
        {}
    };

private:
    class ByteReader
    {
    public:

        ByteReader(const std::vector<uint8_t> &buffer)
            : data_{buffer}
            , byte_ofs_{0}
            , zeros_in_row_{0}
        {}

        ByteReader(const ByteReader &other)
            : data_{other.data_}
            , byte_ofs_{other.byte_ofs_}
            , zeros_in_row_{other.zeros_in_row_}
        {}

        uint8_t
        get_byte()
        {
            if (byte_ofs_ >= data_.size())
                throw error("ByteReader: trying to read beyond bounds");

            const uint8_t current_byte = data_[byte_ofs_ ++];

            if (zeros_in_row_ >= 2 && current_byte == 3) {
                if (byte_ofs_ >= data_.size())
                    throw error("ByteReader: trying to read beyond bounds");

                const uint8_t another_byte = data_[byte_ofs_ ++];
                zeros_in_row_ = (another_byte == 0) ? 1 : 0;

                return another_byte;
            }

            if (current_byte == 0) {
                zeros_in_row_ += 1;
            } else {
                zeros_in_row_ = 0;
            }

            return current_byte;
        }

        size_t
        get_ofs() const
        {
            return byte_ofs_;
        }

        int64_t
        navigate_to_nal_unit()
        {
            const size_t prev_ofs = byte_ofs_;

            uint32_t window = ~0u;
            do {
                if (byte_ofs_ >= data_.size())
                    throw error("ByteReader: no more bytes");

                const uint32_t c = data_[byte_ofs_++];
                window = (window << 8) | c;

            } while ((window & 0xffffff) != 0x000001);

            return byte_ofs_ - prev_ofs;
        }

    private:
        ByteReader &
        operator=(const ByteReader &) = delete;

        const std::vector<uint8_t>  &data_;
        size_t byte_ofs_;
        size_t zeros_in_row_;
    };

public:
    RBSPState(const std::vector<uint8_t> &buffer)
        : byte_reader_{buffer}
        , bits_eaten_{0}
        , current_byte_{0}
        , bit_ofs_{7}
    {}

    ~RBSPState() = default;

    RBSPState(const RBSPState &other)
        : byte_reader_{other.byte_reader_}
        , bits_eaten_{other.bits_eaten_}
        , current_byte_{other.current_byte_}
        , bit_ofs_{other.bit_ofs_}
    {}

    int64_t
    navigate_to_nal_unit()
    {
        // reset bit position to ensure next read will fetch a fresh byte from byte_reader_
        bit_ofs_ = 7;

        return byte_reader_.navigate_to_nal_unit();
    }

    void
    reset_bit_counter()
    {
        bits_eaten_ = 0;
    }

    size_t
    bits_eaten() const
    {
        return bits_eaten_;
    }

    uint32_t
    get_u(size_t bitcount)
    {
        uint32_t res = 0;

        for (size_t k = 0; k < bitcount; k ++)
            res = (res << 1) + get_bit();

        return res;
    }

    uint32_t
    get_uev()
    {
        size_t zeros = 0;

        while (get_bit() == 0)
            zeros ++;

        if (zeros == 0)
            return 0;

        return (1 << zeros) - 1 + get_u(zeros);
    }

    int32_t
    get_sev()
    {
        size_t zeros = 0;

        while (get_bit() == 0)
            zeros ++;

        if (zeros == 0)
            return 0;

        const int32_t val = (1 << zeros) + get_u(zeros);

        if (val & 1)
            return -(val / 2);

        return val / 2;
    }

private:
    RBSPState &
    operator=(const RBSPState &) = delete;

    uint32_t
    get_bit()
    {
        if (bit_ofs_ == 7)
            current_byte_ = byte_reader_.get_byte();

        const uint32_t val = (current_byte_ >> bit_ofs_) & 1;

        if (bit_ofs_ > 0) {
            bit_ofs_ -= 1;
        } else {
            bit_ofs_ = 7; // most significant bit in a 8-bit byte
        }

        bits_eaten_ += 1;

        return val;
    }

    ByteReader  byte_reader_;
    size_t      bits_eaten_;
    uint8_t     current_byte_;
    uint8_t     bit_ofs_;
};

} // namespace vdp
<commit_msg>bitstream: update comments<commit_after>/*
 * Copyright 2013-2016  Rinat Ibragimov
 *
 * This file is part of libvdpau-va-gl
 *
 * Permission is hereby granted, free of charge, to any person obtaining a copy
 * of this software and associated documentation files (the "Software"), to deal
 * in the Software without restriction, including without limitation the rights
 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
 * copies of the Software, and to permit persons to whom the Software is
 * furnished to do so, subject to the following conditions:
 *
 * The above copyright notice and this permission notice shall be included in all
 * copies or substantial portions of the Software.
 *
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
 * SOFTWARE.
 */

#pragma once

#include <stdint.h>
#include <unistd.h>
#include <vector>
#include <stdexcept>

namespace vdp {

/// Raw byte sequence payload state
///
/// throws ByteReader::error()

class RBSPState
{
public:
    class error: public std::logic_error
    {
    public:
        error(const char *descr)
            : std::logic_error(descr)
        {}
    };

private:
    /// encapsulates handling of emulation prevention bytes (EPB)
    class ByteReader
    {
    public:
        ByteReader(const std::vector<uint8_t> &buffer)
            : data_{buffer}
            , byte_ofs_{0}
            , zeros_in_row_{0}
        {}

        ByteReader(const ByteReader &other)
            : data_{other.data_}
            , byte_ofs_{other.byte_ofs_}
            , zeros_in_row_{other.zeros_in_row_}
        {}

        uint8_t
        get_byte()
        {
            if (byte_ofs_ >= data_.size())
                throw error("ByteReader: trying to read beyond bounds");

            const uint8_t current_byte = data_[byte_ofs_ ++];

            if (zeros_in_row_ >= 2 && current_byte == 3) {
                if (byte_ofs_ >= data_.size())
                    throw error("ByteReader: trying to read beyond bounds");

                const uint8_t another_byte = data_[byte_ofs_ ++];
                zeros_in_row_ = (another_byte == 0) ? 1 : 0;

                return another_byte;
            }

            if (current_byte == 0) {
                zeros_in_row_ += 1;
            } else {
                zeros_in_row_ = 0;
            }

            return current_byte;
        }

        size_t
        get_ofs() const
        {
            return byte_ofs_;
        }

        /// rewind to the next NAL unit begin marker (0x00 0x00 0x01)
        int64_t
        navigate_to_nal_unit()
        {
            const size_t prev_ofs = byte_ofs_;

            uint32_t window = ~0u;
            do {
                if (byte_ofs_ >= data_.size())
                    throw error("ByteReader: no more bytes");

                const uint32_t c = data_[byte_ofs_++];
                window = (window << 8) | c;

            } while ((window & 0xffffff) != 0x000001);

            return byte_ofs_ - prev_ofs;
        }

    private:
        ByteReader &
        operator=(const ByteReader &) = delete;

        const std::vector<uint8_t>  &data_;
        size_t byte_ofs_;
        size_t zeros_in_row_;
    };

public:
    RBSPState(const std::vector<uint8_t> &buffer)
        : byte_reader_{buffer}
        , bits_eaten_{0}
        , current_byte_{0}
        , bit_ofs_{7}
    {}

    ~RBSPState() = default;

    RBSPState(const RBSPState &other)
        : byte_reader_{other.byte_reader_}
        , bits_eaten_{other.bits_eaten_}
        , current_byte_{other.current_byte_}
        , bit_ofs_{other.bit_ofs_}
    {}

    int64_t
    navigate_to_nal_unit()
    {
        // reset bit position to ensure next read will fetch a fresh byte from byte_reader_
        bit_ofs_ = 7;

        return byte_reader_.navigate_to_nal_unit();
    }

    void
    reset_bit_counter()
    {
        bits_eaten_ = 0;
    }

    size_t
    bits_eaten() const
    {
        return bits_eaten_;
    }

    uint32_t
    get_u(size_t bitcount)
    {
        uint32_t res = 0;

        for (size_t k = 0; k < bitcount; k ++)
            res = (res << 1) + get_bit();

        return res;
    }

    uint32_t
    get_uev()
    {
        size_t zeros = 0;

        while (get_bit() == 0)
            zeros ++;

        if (zeros == 0)
            return 0;

        return (1 << zeros) - 1 + get_u(zeros);
    }

    int32_t
    get_sev()
    {
        size_t zeros = 0;

        while (get_bit() == 0)
            zeros ++;

        if (zeros == 0)
            return 0;

        const int32_t val = (1 << zeros) + get_u(zeros);

        if (val & 1)
            return -(val / 2);

        return val / 2;
    }

private:
    RBSPState &
    operator=(const RBSPState &) = delete;

    uint32_t
    get_bit()
    {
        if (bit_ofs_ == 7)
            current_byte_ = byte_reader_.get_byte();

        const uint32_t val = (current_byte_ >> bit_ofs_) & 1;

        if (bit_ofs_ > 0) {
            bit_ofs_ -= 1;
        } else {
            bit_ofs_ = 7; // most significant bit in a 8-bit byte
        }

        bits_eaten_ += 1;

        return val;
    }

    ByteReader  byte_reader_;
    size_t      bits_eaten_;
    uint8_t     current_byte_;
    uint8_t     bit_ofs_;
};

} // namespace vdp
<|endoftext|>