<commit_before>#ifdef __linux__
#include <signal.h>
#include <string.h>
#include <unistd.h>
#include <stdint.h>
#include <errno.h>

#include <ws2811.h>
#include <wiringPi.h>
#include <wiringSerial.h>

#include "definitions.h"
#include "main_rpi.h"
#include "SerialPort.h"
#include "LedStripController.h"
#include "LayerController.h"

#define NUM_LEDS 300
#define GPIO_PIN 18
#define DMA 5
#define TARGET_FREQ     WS2811_TARGET_FREQ
#define STRIP_TYPE      SK6812_STRIP_GRBW

ws2811_t ledStrip {
    .render_wait_time = 0,
    .device = nullptr,
    .rpi_hw = nullptr,
    .freq = TARGET_FREQ,
    .dmanum = DMA,
    .channel =
    {
        {
            .gpionum = GPIO_PIN,
            .invert = 0,
            .count = NUM_LEDS,
            .strip_type = STRIP_TYPE,
            .leds = nullptr,
            .brightness = 255,
            .wshift = 0,
            .rshift = 0,
            .gshift = 0,
            .bshift = 0,
            .gamma = 0
        }
    },
};

SerialPort serial;
LedStripController controller;

int main(int argc, char **argv) {
    char *virtSerial = 0;
    if ((argc > 2) && (strcmp(argv[1], "-D") == 0)) {
        virtSerial = argv[2];
        print("Override serial port: %s\n", virtSerial);
    }
    if (!setup(virtSerial)) {
        return 1;
    }
    while (running) {
        loop();
    }
    cleanup();
    return 0;
}

static void ctrl_c_handler(int signum) {
    (void)(signum);
    printf("Terminating...\n");
    running = false;
}

static void setup_handlers(void) {
    struct sigaction sa;
    sa.sa_handler = ctrl_c_handler;

    sigaction(SIGINT, &sa, NULL);
    sigaction(SIGTERM, &sa, NULL);
}

bool setup(char *virtSerial) {
    if (virtSerial) {
        serial.begin(virtSerial, 9600);
    } else {
        serial.begin("/dev/ttyAMA0", 9600);
    }

    if (wiringPiSetup () == -1) {
        logerr("Unable to start wiringPi: %s\n", strerror (errno)) ;
        return false;
    }

    ws2811_return_t errCode;
    if ((errCode = ws2811_init(&ledStrip)) != WS2811_SUCCESS) {
        fprintf(stderr, "ws2811_init failed: %s\n", ws2811_get_return_t_str(errCode));
        return false;
    }

    LayerController &layerControl = controller.layerController();
    layerControl.addColorLayer(0, 0, 0, 0, 0);
    layerControl.addColorLayer(1, 60, 40, 5, 100);
    layerControl.addFadeLayer(2, 0, 1, 0, FadeLayer::InterpolatorAccelerate, 5000);
    layerControl.setAsRootLayer(2);

    setup_handlers();
    return true;
}

void cleanup() {
    ws2811_fini(&ledStrip);
    printf("Finished\n");
}

void loop() {
    if (serial.available()) {
        char c = serial.read();
        print("%c", c);
        controller.writeChar(c);
    }

    controller.draw(static_cast<uint32 *>(ledStrip.channel[0].leds), NUM_LEDS);

    ws2811_return_t errCode;
    if ((errCode = ws2811_render(&ledStrip)) != WS2811_SUCCESS) {
        fprintf(stderr, "ws2811_render failed: %s\n", ws2811_get_return_t_str(errCode));
        running = false;
    }

    // 90 frames /sec
    usleep(1000000 / 90);
}

#endif

<commit_msg>Fix compile bug<commit_after>#ifdef __linux__
#include <signal.h>
#include <string.h>
#include <unistd.h>
#include <stdint.h>
#include <errno.h>

#include <ws2811.h>
#include <wiringPi.h>
#include <wiringSerial.h>

#include "definitions.h"
#include "main_rpi.h"
#include "SerialPort.h"
#include "LedStripController.h"
#include "LayerController.h"

#define NUM_LEDS 300
#define GPIO_PIN 18
#define DMA 5
#define TARGET_FREQ     WS2811_TARGET_FREQ
#define STRIP_TYPE      SK6812_STRIP_GRBW

ws2811_t ledStrip {
    .render_wait_time = 0,
    .device = nullptr,
    .rpi_hw = nullptr,
    .freq = TARGET_FREQ,
    .dmanum = DMA,
    .channel =
    {
        {
            .gpionum = GPIO_PIN,
            .invert = 0,
            .count = NUM_LEDS,
            .strip_type = STRIP_TYPE,
            .leds = nullptr,
            .brightness = 255,
            .wshift = 0,
            .rshift = 0,
            .gshift = 0,
            .bshift = 0,
            .gamma = 0
        }
    },
};

SerialPort serial;
LedStripController controller;

int main(int argc, char **argv) {
    char *virtSerial = 0;
    if ((argc > 2) && (strcmp(argv[1], "-D") == 0)) {
        virtSerial = argv[2];
        print("Override serial port: %s\n", virtSerial);
    }
    if (!setup(virtSerial)) {
        return 1;
    }
    while (running) {
        loop();
    }
    cleanup();
    return 0;
}

static void ctrl_c_handler(int signum) {
    (void)(signum);
    printf("Terminating...\n");

    LayerController &layerControl = controller.layerController();
    layerControl.addColorLayer(0, 60, 40, 5, 100);
    layerControl.addColorLayer(1, 0, 0, 0, 0);
    layerControl.addFadeLayer(2, 0, 1, 0, FadeLayer::InterpolatorDecelerate, 2000);
    layerControl.setAsRootLayer(2);
    sleep(2100);

    running = false;
}

static void setup_handlers(void) {
    struct sigaction sa;
    sa.sa_handler = ctrl_c_handler;

    sigaction(SIGINT, &sa, NULL);
    sigaction(SIGTERM, &sa, NULL);
}

bool setup(char *virtSerial) {
    if (virtSerial) {
        serial.begin(virtSerial, 9600);
    } else {
        serial.begin("/dev/ttyAMA0", 9600);
    }

    if (wiringPiSetup () == -1) {
        logerr("Unable to start wiringPi: %s\n", strerror (errno)) ;
        return false;
    }

    ws2811_return_t errCode;
    if ((errCode = ws2811_init(&ledStrip)) != WS2811_SUCCESS) {
        fprintf(stderr, "ws2811_init failed: %s\n", ws2811_get_return_t_str(errCode));
        return false;
    }

    LayerController &layerControl = controller.layerController();
    layerControl.addColorLayer(0, 0, 0, 0, 0);
    layerControl.addColorLayer(1, 60, 40, 5, 100);
    layerControl.addFadeLayer(2, 0, 1, 0, FadeLayer::InterpolatorAccelerate, 5000);
    layerControl.setAsRootLayer(2);

    setup_handlers();
    return true;
}

void cleanup() {
    ws2811_fini(&ledStrip);
    printf("Finished\n");
}

void loop() {
    if (serial.available()) {
        char c = serial.read();
        print("%c", c);
        controller.writeChar(c);
    }

    controller.draw(static_cast<uint32 *>(ledStrip.channel[0].leds), NUM_LEDS);

    ws2811_return_t errCode;
    if ((errCode = ws2811_render(&ledStrip)) != WS2811_SUCCESS) {
        fprintf(stderr, "ws2811_render failed: %s\n", ws2811_get_return_t_str(errCode));
        running = false;
    }

    // 90 frames /sec
    usleep(1000000 / 90);
}

#endif

<|endoftext|>


<commit_before>// //////////////////////////////////////////////////////////////////////
// Import section
// //////////////////////////////////////////////////////////////////////
// STL
#include <cassert>
// Boost
#include <boost/make_shared.hpp>
// StdAir
#include <stdair/stdair_exceptions.hpp>
#include <stdair/basic/BasConst_Event.hpp>
#include <stdair/bom/EventStruct.hpp>
#include <stdair/bom/EventQueue.hpp>
#include <stdair/service/Logger.hpp>

namespace stdair {

  // //////////////////////////////////////////////////////////////////////
  EventQueue::EventQueue ()
    : _key (DEFAULT_EVENT_QUEUE_ID), _parent (NULL),
      _progressStatus (stdair::DEFAULT_PROGRESS_STATUS,
                       stdair::DEFAULT_PROGRESS_STATUS) {
  }

  // //////////////////////////////////////////////////////////////////////
  EventQueue::EventQueue (const Key_T& iKey)
    : _key (iKey), _parent (NULL),
      _progressStatus (stdair::DEFAULT_PROGRESS_STATUS,
                       stdair::DEFAULT_PROGRESS_STATUS) {
  }

  // //////////////////////////////////////////////////////////////////////
  EventQueue::EventQueue (const EventQueue& iEventQueue)
    : _key (DEFAULT_EVENT_QUEUE_ID), _parent (NULL),
      _progressStatus (stdair::DEFAULT_PROGRESS_STATUS,
                       stdair::DEFAULT_PROGRESS_STATUS) {
    assert (false);
  }

  // //////////////////////////////////////////////////////////////////////
  EventQueue::~EventQueue () {
    _eventList.clear();
    _nbOfEvents.clear();
  }

  // //////////////////////////////////////////////////////////////////////
  std::string EventQueue::toString() const {
    std::ostringstream oStr;
    oStr << "(" << _eventList.size() << ") "
         << _progressStatus.first << "/" << _progressStatus.second;
    return oStr.str();
  }

  // //////////////////////////////////////////////////////////////////////
  std::string EventQueue::display() const {
    std::ostringstream oStr;

    oStr << toString();

    /*
     * \note The following can be very consuming (in time, CPU and
     * memory) when there are a lot of demand streams (e.g., several
     * hundreds of thousands). Uncomment it only for debug purposes.
    */
    unsigned int demandStreamIdx = 1;
    for (NbOfEventsByDemandStreamMap_T::const_iterator itNbOfEventsMap =
           _nbOfEvents.begin(); itNbOfEventsMap != _nbOfEvents.end();
         ++itNbOfEventsMap, ++demandStreamIdx) {
      const DemandStreamKeyStr_T& lDemandStreyKeyStr = itNbOfEventsMap->first;
      oStr << ", [" << demandStreamIdx << "][" << lDemandStreyKeyStr << "] ";
      const NbOfEventsPair_T& lNbOfEventsPair = itNbOfEventsMap->second;
      const stdair::Count_T& lCurrentNbOfEvents = lNbOfEventsPair.first;
      const stdair::Count_T& lExpectedTotalNbOfEvents = lNbOfEventsPair.second;
      oStr << lCurrentNbOfEvents << "/" << lExpectedTotalNbOfEvents;
    }

    return oStr.str();
  }

  // //////////////////////////////////////////////////////////////////////
  Count_T EventQueue::getQueueSize() const {
    return _eventList.size();
  }

  // //////////////////////////////////////////////////////////////////////
  bool EventQueue::isQueueEmpty() const {
    return _eventList.empty();
  }

  // //////////////////////////////////////////////////////////////////////
  bool EventQueue::isQueueDone() const {
    const bool isQueueEmpty = _eventList.empty();
    return isQueueEmpty;
  }

  // //////////////////////////////////////////////////////////////////////
  void EventQueue::reset() {
    _progressStatus.first = stdair::DEFAULT_PROGRESS_STATUS;
    _progressStatus.second = stdair::DEFAULT_PROGRESS_STATUS;
    _holderMap.clear();
    _eventList.clear();
    _nbOfEvents.clear();
  }

  // //////////////////////////////////////////////////////////////////////
  void EventQueue::
  addStatus (const DemandStreamKeyStr_T& iDemandStreamKeyStr,
             const NbOfRequests_T& iExpectedTotalNbOfEvents) {

    /**
     * \note After the initialisation of the event queue (e.g., by a
     * call to the TRADEMGEN_Service::generateFirstRequests() method),
     * there are, by construction, exactly as many events as distinct
     * demand streams. Indeed, the event queue contains a single event
     * structure for every demand stream.
     */

    // Initialise the progress status object for the current demand stream
    const Count_T lExpectedTotalNbOfEventsInt =
      std::floor (iExpectedTotalNbOfEvents);
    const NbOfEventsPair_T lNbOfEventsPair (1, lExpectedTotalNbOfEventsInt);

    // Insert the (Boost) progress display object into the dedicated map
    const bool hasInsertBeenSuccessful =
      _nbOfEvents.insert (NbOfEventsByDemandStreamMap_T::
                          value_type (iDemandStreamKeyStr,
                                      lNbOfEventsPair)).second;

    if (hasInsertBeenSuccessful == false) {
      STDAIR_LOG_ERROR ("No progress_status can be inserted "
                        << "for the following DemandStream: "
                        << iDemandStreamKeyStr
                        << ". EventQueue: " << toString());
      throw EventException ("No progress_status can be inserted for the "
                            "following DemandStream: " + iDemandStreamKeyStr
                            + ". EventQueue: " + toString());
    }

    // Update the overall progress status
    _progressStatus.second += iExpectedTotalNbOfEvents;
  }

  // //////////////////////////////////////////////////////////////////////
  void EventQueue::
  initProgressDisplays (ProgressDisplayMap_T& ioProgressDisplayMap) {

    ProgressDisplayMap_T::iterator itProgressDisplayMap =
      ioProgressDisplayMap.begin();
    for (NbOfEventsByDemandStreamMap_T::const_iterator itNbOfEventsMap =
           _nbOfEvents.begin();  itNbOfEventsMap != _nbOfEvents.end();
          ++itProgressDisplayMap, ++itNbOfEventsMap) {
      // Demand stream
      const DemandStreamKeyStr_T& lDemandStreamKeyStr = itNbOfEventsMap->first;

      // Expected total number of events for the current demand stream
      const NbOfEventsPair_T& lNbOfEventsPair = itNbOfEventsMap->second;
      const Count_T& lExpectedTotalNbOfEvents = lNbOfEventsPair.second;

      // Initialise the (Boost) progress display object for the
      // current demand stream
      ProgressDisplayPtr lProgressDisplayPtr =
        boost::make_shared<boost::progress_display> (lExpectedTotalNbOfEvents);

      // Insert the (Boost) progress display object into the dedicated map
      const bool hasInsertBeenSuccessful =
        ioProgressDisplayMap.insert (ProgressDisplayMap_T::
                                     value_type (lDemandStreamKeyStr,
                                                 lProgressDisplayPtr)).second;

      if (hasInsertBeenSuccessful == false) {
        STDAIR_LOG_ERROR ("No Boost progress_display can be inserted "
                          << "for the following DemandStream: "
                          << lDemandStreamKeyStr
                          << ". EventQueue: " << toString());
        throw EventException ("No Boost progress_display can be inserted for "
                              "the following DemandStream: "
                              + lDemandStreamKeyStr + ". EventQueue: "
                              + toString());
      }
    }
  }

  // //////////////////////////////////////////////////////////////////////
  NbOfEventsPair_T EventQueue::
  getStatus (const DemandStreamKeyStr_T& iDemandStreamKey) const {

    NbOfEventsByDemandStreamMap_T::const_iterator itNbOfEventsMap =
      _nbOfEvents.find (iDemandStreamKey);
    if (itNbOfEventsMap != _nbOfEvents.end()) {
      const NbOfEventsPair_T& oNbOfEventsPair = itNbOfEventsMap->second;
      return oNbOfEventsPair;
    }

    return NbOfEventsPair_T (stdair::DEFAULT_PROGRESS_STATUS,
                             stdair::DEFAULT_PROGRESS_STATUS);
  }

  // //////////////////////////////////////////////////////////////////////
  EventStruct EventQueue::popEvent() {
    assert (_eventList.empty() == false);

    // Get an iterator on the first event (sorted by date-time stamps)
    EventList_T::iterator itEvent = _eventList.begin();

    // Extract the corresponding Event structure
    EventStruct lEventStruct = itEvent->second;

    // Extract the key of the demand stream
    const DemandStreamKeyStr_T& lDemandStreamKeyStr =
      lEventStruct.getDemandStreamKey();

    // Retrieve the progress status specific to that demand stream
    const NbOfEventsPair_T& lNbOfEventsPair = getStatus (lDemandStreamKeyStr);

    // Update the progress status of the event structure, specific to
    // the demand stream
    lEventStruct.setSpecificStatus (lNbOfEventsPair);

    // Update the overall progress status, to account for the event
    // that is being popped out of the event queue
    ++_progressStatus.first;

    // Update the overall progress status of the event structure
    lEventStruct.setOverallStatus (_progressStatus);

    // Remove the event, which has just been retrieved
    _eventList.erase (itEvent);

    //
    return lEventStruct;
  }

  // //////////////////////////////////////////////////////////////////////
  bool EventQueue::addEvent (EventStruct& ioEventStruct) {
    bool insertionSucceeded =
      _eventList.insert (EventListElement_T (ioEventStruct._eventTimeStamp,
                                             ioEventStruct)).second;

    /**
       If the insertion has not been successful, try repeatedly until the
       insertion becomes successful.
       <br>The date-time is counted in milliseconds (1e-3 second). Hence,
       one thousand (1e3) of attempts correspond to 1 second.
    */
    const unsigned int idx = 0;
    while (insertionSucceeded == false && idx != 1e3) {
      // Retrieve the date-time stamp (expressed in milliseconds)
      LongDuration_T& lEventTimeStamp (ioEventStruct._eventTimeStamp);
      ++lEventTimeStamp;

      // Retry to insert into the event queue
      insertionSucceeded =
        _eventList.insert (EventListElement_T (ioEventStruct._eventTimeStamp,
                                               ioEventStruct)).second;
    }

    // Extract the corresponding demand stream key
    const DemandStreamKeyStr_T& lDemandStreamKeyStr =
      ioEventStruct.getDemandStreamKey();

    // Update the progress status for the corresponding demand stream
    NbOfEventsByDemandStreamMap_T::iterator itNbOfEventsMap =
      _nbOfEvents.find (lDemandStreamKeyStr);
    if (itNbOfEventsMap != _nbOfEvents.end()) {
      NbOfEventsPair_T& lNbOfEventsPair = itNbOfEventsMap->second;
      stdair::Count_T& lCurrentNbOfEvents = lNbOfEventsPair.first;
      ++lCurrentNbOfEvents;
    }

    return insertionSucceeded;
  }

}
<commit_msg>[Dev] Improved a little bit the debugging output of the EventQueue object.<commit_after>// //////////////////////////////////////////////////////////////////////
// Import section
// //////////////////////////////////////////////////////////////////////
// STL
#include <cassert>
// Boost
#include <boost/make_shared.hpp>
// StdAir
#include <stdair/stdair_exceptions.hpp>
#include <stdair/basic/BasConst_Event.hpp>
#include <stdair/bom/EventStruct.hpp>
#include <stdair/bom/EventQueue.hpp>
#include <stdair/service/Logger.hpp>

namespace stdair {

  // //////////////////////////////////////////////////////////////////////
  EventQueue::EventQueue ()
    : _key (DEFAULT_EVENT_QUEUE_ID), _parent (NULL),
      _progressStatus (stdair::DEFAULT_PROGRESS_STATUS,
                       stdair::DEFAULT_PROGRESS_STATUS) {
  }

  // //////////////////////////////////////////////////////////////////////
  EventQueue::EventQueue (const Key_T& iKey)
    : _key (iKey), _parent (NULL),
      _progressStatus (stdair::DEFAULT_PROGRESS_STATUS,
                       stdair::DEFAULT_PROGRESS_STATUS) {
  }

  // //////////////////////////////////////////////////////////////////////
  EventQueue::EventQueue (const EventQueue& iEventQueue)
    : _key (DEFAULT_EVENT_QUEUE_ID), _parent (NULL),
      _progressStatus (stdair::DEFAULT_PROGRESS_STATUS,
                       stdair::DEFAULT_PROGRESS_STATUS) {
    assert (false);
  }

  // //////////////////////////////////////////////////////////////////////
  EventQueue::~EventQueue () {
    _eventList.clear();
    _nbOfEvents.clear();
  }

  // //////////////////////////////////////////////////////////////////////
  std::string EventQueue::toString() const {
    std::ostringstream oStr;
    oStr << "(" << _eventList.size() << ") "
         << _progressStatus.first << "/" << _progressStatus.second;
    return oStr.str();
  }

  // //////////////////////////////////////////////////////////////////////
  std::string EventQueue::display() const {
    std::ostringstream oStr;

    oStr << toString();

    /*
     * \note The following can be very consuming (in time, CPU and
     * memory) when there are a lot of demand streams (e.g., several
     * hundreds of thousands). Uncomment it only for debug purposes.
    */
    unsigned int demandStreamIdx = 1;
    for (NbOfEventsByDemandStreamMap_T::const_iterator itNbOfEventsMap =
           _nbOfEvents.begin(); itNbOfEventsMap != _nbOfEvents.end();
         ++itNbOfEventsMap, ++demandStreamIdx) {
      const DemandStreamKeyStr_T& lDemandStreyKeyStr = itNbOfEventsMap->first;
      oStr << ", [" << demandStreamIdx << "][" << lDemandStreyKeyStr << "] ";
      const NbOfEventsPair_T& lNbOfEventsPair = itNbOfEventsMap->second;
      const stdair::Count_T& lCurrentNbOfEvents = lNbOfEventsPair.first;
      const stdair::Count_T& lExpectedTotalNbOfEvents = lNbOfEventsPair.second;
      oStr << lCurrentNbOfEvents << "/" << lExpectedTotalNbOfEvents;
    }

    return oStr.str();
  }

  // //////////////////////////////////////////////////////////////////////
  Count_T EventQueue::getQueueSize() const {
    return _eventList.size();
  }

  // //////////////////////////////////////////////////////////////////////
  bool EventQueue::isQueueEmpty() const {
    return _eventList.empty();
  }

  // //////////////////////////////////////////////////////////////////////
  bool EventQueue::isQueueDone() const {
    const bool isQueueEmpty = _eventList.empty();
    return isQueueEmpty;
  }

  // //////////////////////////////////////////////////////////////////////
  void EventQueue::reset() {
    _holderMap.clear();
    _eventList.clear();
    _nbOfEvents.clear();
  }

  // //////////////////////////////////////////////////////////////////////
  void EventQueue::
  addStatus (const DemandStreamKeyStr_T& iDemandStreamKeyStr,
             const NbOfRequests_T& iExpectedTotalNbOfEvents) {

    /**
     * \note After the initialisation of the event queue (e.g., by a
     * call to the TRADEMGEN_Service::generateFirstRequests() method),
     * there are, by construction, exactly as many events as distinct
     * demand streams. Indeed, the event queue contains a single event
     * structure for every demand stream.
     */

    // Initialise the progress status object for the current demand stream
    const Count_T lExpectedTotalNbOfEventsInt =
      std::floor (iExpectedTotalNbOfEvents);
    const NbOfEventsPair_T lNbOfEventsPair (1, lExpectedTotalNbOfEventsInt);

    // Insert the (Boost) progress display object into the dedicated map
    const bool hasInsertBeenSuccessful =
      _nbOfEvents.insert (NbOfEventsByDemandStreamMap_T::
                          value_type (iDemandStreamKeyStr,
                                      lNbOfEventsPair)).second;

    if (hasInsertBeenSuccessful == false) {
      STDAIR_LOG_ERROR ("No progress_status can be inserted "
                        << "for the following DemandStream: "
                        << iDemandStreamKeyStr
                        << ". EventQueue: " << toString());
      throw EventException ("No progress_status can be inserted for the "
                            "following DemandStream: " + iDemandStreamKeyStr
                            + ". EventQueue: " + toString());
    }

    // Update the overall progress status
    _progressStatus.second += iExpectedTotalNbOfEvents;
  }

  // //////////////////////////////////////////////////////////////////////
  void EventQueue::
  initProgressDisplays (ProgressDisplayMap_T& ioProgressDisplayMap) {

    ProgressDisplayMap_T::iterator itProgressDisplayMap =
      ioProgressDisplayMap.begin();
    for (NbOfEventsByDemandStreamMap_T::const_iterator itNbOfEventsMap =
           _nbOfEvents.begin();  itNbOfEventsMap != _nbOfEvents.end();
          ++itProgressDisplayMap, ++itNbOfEventsMap) {
      // Demand stream
      const DemandStreamKeyStr_T& lDemandStreamKeyStr = itNbOfEventsMap->first;

      // Expected total number of events for the current demand stream
      const NbOfEventsPair_T& lNbOfEventsPair = itNbOfEventsMap->second;
      const Count_T& lExpectedTotalNbOfEvents = lNbOfEventsPair.second;

      // Initialise the (Boost) progress display object for the
      // current demand stream
      ProgressDisplayPtr lProgressDisplayPtr =
        boost::make_shared<boost::progress_display> (lExpectedTotalNbOfEvents);

      // Insert the (Boost) progress display object into the dedicated map
      const bool hasInsertBeenSuccessful =
        ioProgressDisplayMap.insert (ProgressDisplayMap_T::
                                     value_type (lDemandStreamKeyStr,
                                                 lProgressDisplayPtr)).second;

      if (hasInsertBeenSuccessful == false) {
        STDAIR_LOG_ERROR ("No Boost progress_display can be inserted "
                          << "for the following DemandStream: "
                          << lDemandStreamKeyStr
                          << ". EventQueue: " << toString());
        throw EventException ("No Boost progress_display can be inserted for "
                              "the following DemandStream: "
                              + lDemandStreamKeyStr + ". EventQueue: "
                              + toString());
      }
    }
  }

  // //////////////////////////////////////////////////////////////////////
  NbOfEventsPair_T EventQueue::
  getStatus (const DemandStreamKeyStr_T& iDemandStreamKey) const {

    NbOfEventsByDemandStreamMap_T::const_iterator itNbOfEventsMap =
      _nbOfEvents.find (iDemandStreamKey);
    if (itNbOfEventsMap != _nbOfEvents.end()) {
      const NbOfEventsPair_T& oNbOfEventsPair = itNbOfEventsMap->second;
      return oNbOfEventsPair;
    }

    return NbOfEventsPair_T (stdair::DEFAULT_PROGRESS_STATUS,
                             stdair::DEFAULT_PROGRESS_STATUS);
  }

  // //////////////////////////////////////////////////////////////////////
  EventStruct EventQueue::popEvent() {
    assert (_eventList.empty() == false);

    // Get an iterator on the first event (sorted by date-time stamps)
    EventList_T::iterator itEvent = _eventList.begin();

    // Extract the corresponding Event structure
    EventStruct lEventStruct = itEvent->second;

    // Extract the key of the demand stream
    const DemandStreamKeyStr_T& lDemandStreamKeyStr =
      lEventStruct.getDemandStreamKey();

    // Retrieve the progress status specific to that demand stream
    const NbOfEventsPair_T& lNbOfEventsPair = getStatus (lDemandStreamKeyStr);

    // Update the progress status of the event structure, specific to
    // the demand stream
    lEventStruct.setSpecificStatus (lNbOfEventsPair);

    // Update the overall progress status, to account for the event
    // that is being popped out of the event queue
    ++_progressStatus.first;

    // Update the overall progress status of the event structure
    lEventStruct.setOverallStatus (_progressStatus);

    // Remove the event, which has just been retrieved
    _eventList.erase (itEvent);

    //
    return lEventStruct;
  }

  // //////////////////////////////////////////////////////////////////////
  bool EventQueue::addEvent (EventStruct& ioEventStruct) {
    bool insertionSucceeded =
      _eventList.insert (EventListElement_T (ioEventStruct._eventTimeStamp,
                                             ioEventStruct)).second;

    /**
       If the insertion has not been successful, try repeatedly until the
       insertion becomes successful.
       <br>The date-time is counted in milliseconds (1e-3 second). Hence,
       one thousand (1e3) of attempts correspond to 1 second.
    */
    const unsigned int idx = 0;
    while (insertionSucceeded == false && idx != 1e3) {
      // Retrieve the date-time stamp (expressed in milliseconds)
      LongDuration_T& lEventTimeStamp (ioEventStruct._eventTimeStamp);
      ++lEventTimeStamp;

      // Retry to insert into the event queue
      insertionSucceeded =
        _eventList.insert (EventListElement_T (ioEventStruct._eventTimeStamp,
                                               ioEventStruct)).second;
    }

    // Extract the corresponding demand stream key
    const DemandStreamKeyStr_T& lDemandStreamKeyStr =
      ioEventStruct.getDemandStreamKey();

    // Update the progress status for the corresponding demand stream
    NbOfEventsByDemandStreamMap_T::iterator itNbOfEventsMap =
      _nbOfEvents.find (lDemandStreamKeyStr);
    if (itNbOfEventsMap != _nbOfEvents.end()) {
      NbOfEventsPair_T& lNbOfEventsPair = itNbOfEventsMap->second;
      stdair::Count_T& lCurrentNbOfEvents = lNbOfEventsPair.first;
      ++lCurrentNbOfEvents;
    }

    return insertionSucceeded;
  }

}
<|endoftext|>


<commit_before>/*****************************************************************************
 *
 * This file is part of Mapnik (c++ mapping toolkit)
 *
 * Copyright (C) 2010 Artem Pavlenko
 *
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Lesser General Public
 * License as published by the Free Software Foundation; either
 * version 2.1 of the License, or (at your option) any later version.
 *
 * This library is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public
 * License along with this library; if not, write to the Free Software
 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
 *
 *****************************************************************************/

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

#include <mapnik/version.hpp>
#include <mapnik/debug.hpp>
#include <mapnik/marker.hpp>
#include <mapnik/marker_cache.hpp>
#include <mapnik/image_util.hpp>
#include <mapnik/graphics.hpp>
#include <mapnik/svg/svg_path_adapter.hpp>
#include <mapnik/svg/svg_renderer_agg.hpp>
#include <mapnik/svg/svg_path_attributes.hpp>

#include <boost/algorithm/string.hpp>
#include <boost/filesystem/operations.hpp>
#include <boost/program_options.hpp>

#include "agg_rasterizer_scanline_aa.h"
#include "agg_basics.h"
#include "agg_rendering_buffer.h"
#include "agg_renderer_base.h"
#include "agg_pixfmt_rgba.h"
#include "agg_scanline_u.h"

#include <libxml/parser.h> // for xmlInitParser(), xmlCleanupParser()

int main (int argc,char** argv)
{
    namespace po = boost::program_options;

    bool verbose = false;
    bool auto_open = false;
    int return_value = 0;
    std::vector<std::string> svg_files;
    mapnik::logger logger;
    logger.set_severity(mapnik::logger::error);

    try
    {
        po::options_description desc("svg2png utility");
        desc.add_options()
            ("help,h", "produce usage message")
            ("version,V","print version string")
            ("verbose,v","verbose output")
            ("open","automatically open the file after rendering (os x only)")
            ("svg",po::value<std::vector<std::string> >(),"svg file to read")
            ;

        po::positional_options_description p;
        p.add("svg",-1);
        po::variables_map vm;
        po::store(po::command_line_parser(argc, argv).options(desc).positional(p).run(), vm);
        po::notify(vm);

        if (vm.count("version"))
        {
            std::clog <<"version " << MAPNIK_VERSION_STRING << std::endl;
            return 1;
        }

        if (vm.count("help"))
        {
            std::clog << desc << std::endl;
            return 1;
        }

        if (vm.count("verbose"))
        {
            verbose = true;
        }

        if (vm.count("open"))
        {
            auto_open = true;
        }

        if (vm.count("svg"))
        {
            svg_files=vm["svg"].as< std::vector<std::string> >();
        }
        else
        {
            std::clog << "please provide an svg file!" << std::endl;
            return -1;
        }

        std::vector<std::string>::const_iterator itr = svg_files.begin();
        if (itr == svg_files.end())
        {
            std::clog << "no svg files to render" << std::endl;
            return 0;
        }

        xmlInitParser();

        while (itr != svg_files.end())
        {
            std::string svg_name (*itr++);
            if (verbose)
            {
                std::clog << "found: " << svg_name << "\n";
            }

            boost::optional<mapnik::marker_ptr> marker_ptr =
                mapnik::marker_cache::instance().find(svg_name, false);
            if (!marker_ptr)
            {
                std::clog << "svg2png error: could not open: '" << svg_name << "'\n";
                return_value = -1;
                continue;
            }
            mapnik::marker marker = **marker_ptr;
            if (!marker.is_vector())
            {
                std::clog << "svg2png error: '" << svg_name << "' is not a valid vector!\n";
                return_value = -1;
                continue;
            }

            typedef agg::pixfmt_rgba32_pre pixfmt;
            typedef agg::renderer_base<pixfmt> renderer_base;
            typedef agg::renderer_scanline_aa_solid<renderer_base> renderer_solid;
            agg::rasterizer_scanline_aa<> ras_ptr;
            agg::scanline_u8 sl;

            double opacity = 1;
            int w = marker.width();
            int h = marker.height();
            if (verbose)
            {
                std::clog << "found width of '" << w << "' and height of '" << h << "'\n";
            }
            // 10 pixel buffer to avoid edge clipping of 100% svg's
            mapnik::image_32 im(w+10,h+10);
            agg::rendering_buffer buf(im.raw_data(), im.width(), im.height(), im.width() * 4);
            pixfmt pixf(buf);
            renderer_base renb(pixf);

            mapnik::box2d<double> const& bbox = (*marker.get_vector_data())->bounding_box();
            mapnik::coord<double,2> c = bbox.center();
            // center the svg marker on '0,0'
            agg::trans_affine mtx = agg::trans_affine_translation(-c.x,-c.y);
            // render the marker at the center of the marker box
            mtx.translate(0.5 * im.width(), 0.5 * im.height());

            mapnik::svg::vertex_stl_adapter<mapnik::svg::svg_path_storage> stl_storage((*marker.get_vector_data())->source());
            mapnik::svg::svg_path_adapter svg_path(stl_storage);
            mapnik::svg::svg_renderer_agg<mapnik::svg::svg_path_adapter,
                agg::pod_bvector<mapnik::svg::path_attributes>,
                renderer_solid,
                agg::pixfmt_rgba32_pre > svg_renderer_this(svg_path,
                                                             (*marker.get_vector_data())->attributes());

            svg_renderer_this.render(ras_ptr, sl, renb, mtx, opacity, bbox);

            boost::algorithm::ireplace_last(svg_name,".svg",".png");
            im.demultiply();
            mapnik::save_to_file<mapnik::image_data_32>(im.data(),svg_name,"png");
            if (auto_open)
            {
                std::ostringstream s;
#ifdef DARWIN
                s << "open " << svg_name;
#else
                s << "xdg-open " << svg_name;
#endif
                int ret = system(s.str().c_str());
                if (ret != 0)
                    return_value = ret;
            }
            std::clog << "rendered to: " << svg_name << "\n";
        }
    }
    catch (...)
    {
        std::clog << "Exception of unknown type!" << std::endl;
        xmlCleanupParser();
        return -1;
    }

    // only call this once, on exit
    // to make sure valgrind output is clean
    // http://xmlsoft.org/xmlmem.html
    xmlCleanupParser();
    return return_value;
}
<commit_msg>formatting<commit_after>/*****************************************************************************
 *
 * This file is part of Mapnik (c++ mapping toolkit)
 *
 * Copyright (C) 2010 Artem Pavlenko
 *
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Lesser General Public
 * License as published by the Free Software Foundation; either
 * version 2.1 of the License, or (at your option) any later version.
 *
 * This library is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public
 * License along with this library; if not, write to the Free Software
 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
 *
 *****************************************************************************/

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

#include <mapnik/version.hpp>
#include <mapnik/debug.hpp>
#include <mapnik/marker.hpp>
#include <mapnik/marker_cache.hpp>
#include <mapnik/image_util.hpp>
#include <mapnik/graphics.hpp>
#include <mapnik/svg/svg_path_adapter.hpp>
#include <mapnik/svg/svg_renderer_agg.hpp>
#include <mapnik/svg/svg_path_attributes.hpp>

#include <boost/algorithm/string.hpp>
#include <boost/filesystem/operations.hpp>
#include <boost/program_options.hpp>

#include "agg_rasterizer_scanline_aa.h"
#include "agg_basics.h"
#include "agg_rendering_buffer.h"
#include "agg_renderer_base.h"
#include "agg_pixfmt_rgba.h"
#include "agg_scanline_u.h"

#include <libxml/parser.h> // for xmlInitParser(), xmlCleanupParser()

int main (int argc,char** argv)
{
    namespace po = boost::program_options;

    bool verbose = false;
    bool auto_open = false;
    int return_value = 0;
    std::vector<std::string> svg_files;
    mapnik::logger logger;
    logger.set_severity(mapnik::logger::error);

    try
    {
        po::options_description desc("svg2png utility");
        desc.add_options()
            ("help,h", "produce usage message")
            ("version,V","print version string")
            ("verbose,v","verbose output")
            ("open","automatically open the file after rendering (os x only)")
            ("svg",po::value<std::vector<std::string> >(),"svg file to read")
            ;

        po::positional_options_description p;
        p.add("svg",-1);
        po::variables_map vm;
        po::store(po::command_line_parser(argc, argv).options(desc).positional(p).run(), vm);
        po::notify(vm);

        if (vm.count("version"))
        {
            std::clog <<"version " << MAPNIK_VERSION_STRING << std::endl;
            return 1;
        }

        if (vm.count("help"))
        {
            std::clog << desc << std::endl;
            return 1;
        }

        if (vm.count("verbose"))
        {
            verbose = true;
        }

        if (vm.count("open"))
        {
            auto_open = true;
        }

        if (vm.count("svg"))
        {
            svg_files=vm["svg"].as< std::vector<std::string> >();
        }
        else
        {
            std::clog << "please provide an svg file!" << std::endl;
            return -1;
        }

        std::vector<std::string>::const_iterator itr = svg_files.begin();
        if (itr == svg_files.end())
        {
            std::clog << "no svg files to render" << std::endl;
            return 0;
        }

        xmlInitParser();

        while (itr != svg_files.end())
        {
            std::string svg_name (*itr++);
            if (verbose)
            {
                std::clog << "found: " << svg_name << "\n";
            }

            boost::optional<mapnik::marker_ptr> marker_ptr =
                mapnik::marker_cache::instance().find(svg_name, false);
            if (!marker_ptr)
            {
                std::clog << "svg2png error: could not open: '" << svg_name << "'\n";
                return_value = -1;
                continue;
            }
            mapnik::marker marker = **marker_ptr;
            if (!marker.is_vector())
            {
                std::clog << "svg2png error: '" << svg_name << "' is not a valid vector!\n";
                return_value = -1;
                continue;
            }

            typedef agg::pixfmt_rgba32_pre pixfmt;
            typedef agg::renderer_base<pixfmt> renderer_base;
            typedef agg::renderer_scanline_aa_solid<renderer_base> renderer_solid;
            agg::rasterizer_scanline_aa<> ras_ptr;
            agg::scanline_u8 sl;

            double opacity = 1;
            int w = marker.width();
            int h = marker.height();
            if (verbose)
            {
                std::clog << "found width of '" << w << "' and height of '" << h << "'\n";
            }
            // 10 pixel buffer to avoid edge clipping of 100% svg's
            mapnik::image_32 im(w+10,h+10);
            agg::rendering_buffer buf(im.raw_data(), im.width(), im.height(), im.width() * 4);
            pixfmt pixf(buf);
            renderer_base renb(pixf);

            mapnik::box2d<double> const& bbox = (*marker.get_vector_data())->bounding_box();
            mapnik::coord<double,2> c = bbox.center();
            // center the svg marker on '0,0'
            agg::trans_affine mtx = agg::trans_affine_translation(-c.x,-c.y);
            // render the marker at the center of the marker box
            mtx.translate(0.5 * im.width(), 0.5 * im.height());

            mapnik::svg::vertex_stl_adapter<mapnik::svg::svg_path_storage> stl_storage((*marker.get_vector_data())->source());
            mapnik::svg::svg_path_adapter svg_path(stl_storage);
            mapnik::svg::svg_renderer_agg<mapnik::svg::svg_path_adapter,
                agg::pod_bvector<mapnik::svg::path_attributes>,
                renderer_solid,
                agg::pixfmt_rgba32_pre > svg_renderer_this(svg_path,
                                                           (*marker.get_vector_data())->attributes());

            svg_renderer_this.render(ras_ptr, sl, renb, mtx, opacity, bbox);

            boost::algorithm::ireplace_last(svg_name,".svg",".png");
            im.demultiply();
            mapnik::save_to_file<mapnik::image_data_32>(im.data(),svg_name,"png");
            if (auto_open)
            {
                std::ostringstream s;
#ifdef DARWIN
                s << "open " << svg_name;
#else
                s << "xdg-open " << svg_name;
#endif
                int ret = system(s.str().c_str());
                if (ret != 0)
                    return_value = ret;
            }
            std::clog << "rendered to: " << svg_name << "\n";
        }
    }
    catch (...)
    {
        std::clog << "Exception of unknown type!" << std::endl;
        xmlCleanupParser();
        return -1;
    }

    // only call this once, on exit
    // to make sure valgrind output is clean
    // http://xmlsoft.org/xmlmem.html
    xmlCleanupParser();
    return return_value;
}
<|endoftext|>


<commit_before>#include "ghost/config.h"
#include "ghost/types.h"
#include "ghost/densemat.h"
#include "ghost/util.h"
#include "ghost/sell.h"
#include "ghost/sell_kernel_avx_gen.h"
#include "ghost/sell_kernel_sse_gen.h"

#include <map>

using namespace std;

bool operator<(const ghost_sellspmv_parameters_t &a, const ghost_sellspmv_parameters_t &b)
{
    return ghost_hash(ghost_hash(a.mdt,a.blocksz,a.storage),ghost_hash(a.vdt,a.impl,a.chunkheight),0) < ghost_hash(ghost_hash(b.mdt,b.blocksz,b.storage),ghost_hash(b.vdt,b.impl,b.chunkheight),0);
}

static ghost_error_t (*SELL_kernels_plain[4][4]) (ghost_sparsemat_t *, ghost_densemat_t *, ghost_densemat_t *, ghost_spmv_flags_t, va_list argp) =
{{&ss_SELL_kernel_plain,&sd_SELL_kernel_plain,&sc_SELL_kernel_plain,&sz_SELL_kernel_plain},
    {&ds_SELL_kernel_plain,&dd_SELL_kernel_plain,&dc_SELL_kernel_plain,&dz_SELL_kernel_plain},
    {&cs_SELL_kernel_plain,&cd_SELL_kernel_plain,&cc_SELL_kernel_plain,&cz_SELL_kernel_plain},
    {&zs_SELL_kernel_plain,&zd_SELL_kernel_plain,&zc_SELL_kernel_plain,&zz_SELL_kernel_plain}};

static map<ghost_sellspmv_parameters_t, sellspmv_kernel> ghost_sellspmv_kernels;

void ghost_sellspmv_kernelmap_generate() {
#include "sell_kernel_avx.def"
#include "sell_kernel_sse.def"

    int mdt, vdt;
    for (mdt = 0; mdt<4; mdt++) {
        for (vdt = 0; vdt<4; vdt++) {
            ghost_datatype_t mdt_t, vdt_t;
            ghost_idx2datatype(&mdt_t,(ghost_datatype_idx_t)mdt);
            ghost_idx2datatype(&vdt_t,(ghost_datatype_idx_t)vdt);
            ghost_sellspmv_parameters_t p;
            p.mdt = mdt_t;
            p.vdt = vdt_t;
            p.blocksz = -1;
            p.storage = (ghost_densemat_storage_t)-1;
            p.impl = GHOST_IMPLEMENTATION_PLAIN;
            p.chunkheight = -1;
            ghost_sellspmv_kernels[p] =  SELL_kernels_plain[mdt][vdt];
        }
    }
}

sellspmv_kernel ghost_sellspmv_kernel(ghost_sellspmv_parameters_t p, ghost_densemat_t *lhs, ghost_densemat_t *rhs)
{

    if (p.storage == GHOST_DENSEMAT_ROWMAJOR && p.blocksz == 1 && rhs->traits.ncolsorig == 1 && lhs->traits.ncolsorig== 1) {
        INFO_LOG("Chose col-major kernel for row-major densemat with 1 column");
        p.storage = GHOST_DENSEMAT_COLMAJOR;
    }

    if (p.impl == GHOST_IMPLEMENTATION_AVX && p.storage == GHOST_DENSEMAT_ROWMAJOR && p.blocksz <= 2) {
        INFO_LOG("Chose SSE over AVX for blocksz=2");
        p.impl = GHOST_IMPLEMENTATION_SSE;
    }
    sellspmv_kernel kernel = ghost_sellspmv_kernels[p];

    if (!kernel) {
        INFO_LOG("Try kernel with arbitrary blocksz");
        p.blocksz = -1;
    }
    kernel = ghost_sellspmv_kernels[p];
    if (!kernel) {
        INFO_LOG("Try plain C kernel");
        p.impl = GHOST_IMPLEMENTATION_PLAIN;
        p.storage = (ghost_densemat_storage_t)-1;
        p.chunkheight = -1;
    }
    kernel = ghost_sellspmv_kernels[p];

    return kernel;

}
<commit_msg>choose plain kernel for scattered views (may not be necessary in all cases, but let's make it safe firstly...)<commit_after>#include "ghost/config.h"
#include "ghost/types.h"
#include "ghost/densemat.h"
#include "ghost/util.h"
#include "ghost/sell.h"
#include "ghost/sell_kernel_avx_gen.h"
#include "ghost/sell_kernel_sse_gen.h"

#include <map>

using namespace std;

bool operator<(const ghost_sellspmv_parameters_t &a, const ghost_sellspmv_parameters_t &b)
{
    return ghost_hash(ghost_hash(a.mdt,a.blocksz,a.storage),ghost_hash(a.vdt,a.impl,a.chunkheight),0) < ghost_hash(ghost_hash(b.mdt,b.blocksz,b.storage),ghost_hash(b.vdt,b.impl,b.chunkheight),0);
}

static ghost_error_t (*SELL_kernels_plain[4][4]) (ghost_sparsemat_t *, ghost_densemat_t *, ghost_densemat_t *, ghost_spmv_flags_t, va_list argp) =
{{&ss_SELL_kernel_plain,&sd_SELL_kernel_plain,&sc_SELL_kernel_plain,&sz_SELL_kernel_plain},
    {&ds_SELL_kernel_plain,&dd_SELL_kernel_plain,&dc_SELL_kernel_plain,&dz_SELL_kernel_plain},
    {&cs_SELL_kernel_plain,&cd_SELL_kernel_plain,&cc_SELL_kernel_plain,&cz_SELL_kernel_plain},
    {&zs_SELL_kernel_plain,&zd_SELL_kernel_plain,&zc_SELL_kernel_plain,&zz_SELL_kernel_plain}};

static map<ghost_sellspmv_parameters_t, sellspmv_kernel> ghost_sellspmv_kernels;

void ghost_sellspmv_kernelmap_generate() {
#include "sell_kernel_avx.def"
#include "sell_kernel_sse.def"

    int mdt, vdt;
    for (mdt = 0; mdt<4; mdt++) {
        for (vdt = 0; vdt<4; vdt++) {
            ghost_datatype_t mdt_t, vdt_t;
            ghost_idx2datatype(&mdt_t,(ghost_datatype_idx_t)mdt);
            ghost_idx2datatype(&vdt_t,(ghost_datatype_idx_t)vdt);
            ghost_sellspmv_parameters_t p;
            p.mdt = mdt_t;
            p.vdt = vdt_t;
            p.blocksz = -1;
            p.storage = (ghost_densemat_storage_t)-1;
            p.impl = GHOST_IMPLEMENTATION_PLAIN;
            p.chunkheight = -1;
            ghost_sellspmv_kernels[p] =  SELL_kernels_plain[mdt][vdt];
        }
    }
}

sellspmv_kernel ghost_sellspmv_kernel(ghost_sellspmv_parameters_t p, ghost_densemat_t *lhs, ghost_densemat_t *rhs)
{

    if (p.storage == GHOST_DENSEMAT_ROWMAJOR && p.blocksz == 1 && rhs->traits.ncolsorig == 1 && lhs->traits.ncolsorig== 1) {
        INFO_LOG("Chose col-major kernel for row-major densemat with 1 column");
        p.storage = GHOST_DENSEMAT_COLMAJOR;
    }

    if (p.impl == GHOST_IMPLEMENTATION_AVX && p.storage == GHOST_DENSEMAT_ROWMAJOR && p.blocksz <= 2) {
        INFO_LOG("Chose SSE over AVX for blocksz=2");
        p.impl = GHOST_IMPLEMENTATION_SSE;
    }

    if (lhs->traits.flags & GHOST_DENSEMAT_SCATTERED || rhs->traits.flags & GHOST_DENSEMAT_SCATTERED) {
        INFO_LOG("Use plain implementation for scattered views");
        p.impl = GHOST_IMPLEMENTATION_PLAIN;
    }

    sellspmv_kernel kernel = ghost_sellspmv_kernels[p];

    if (!kernel) {
        INFO_LOG("Try kernel with arbitrary blocksz");
        p.blocksz = -1;
    }
    kernel = ghost_sellspmv_kernels[p];

    if (!kernel) {
        INFO_LOG("Try plain C kernel");
        p.impl = GHOST_IMPLEMENTATION_PLAIN;
        p.storage = (ghost_densemat_storage_t)-1;
        p.chunkheight = -1;
    }
    kernel = ghost_sellspmv_kernels[p];

    return kernel;

}
<|endoftext|>


<commit_before>// Copyright 2021 Fabian Meumertzheim
//
// 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 <jni.h>
#include <rules_jni.h>
#ifdef _WIN32
#include <windows.h>
#endif

#include <codecvt>
#include <cstdlib>
#include <iostream>
#include <locale>

#include "tools/cpp/runfiles/runfiles.h"

#define HELLO_FROM_JAVA_MSG "Hello_from_Java!"

void clear_env(const char* name) {
#ifdef _WIN32
  SetEnvironmentVariable(name, nullptr);
#else
  unsetenv(name);
#endif
}

int main(int argc, const char** argv) {
  // Override PATH with PATH_OVERRIDE, if set.
  if (getenv("PATH_OVERRIDE") != nullptr) {
    const char* path_override = getenv("PATH_OVERRIDE");
#ifdef _WIN32
    _putenv_s("PATH", path_override);
#else
    setenv("PATH", path_override, 1);
#endif
  }

  // Set up the Bazel runfiles library to get the path to the JAR.
  using ::bazel::tools::cpp::runfiles::Runfiles;
  std::string runfiles_error;
  Runfiles* runfiles = Runfiles::CreateForTest(&runfiles_error);
  if (runfiles == nullptr) {
    runfiles = Runfiles::Create(argv[0], &runfiles_error);
    if (runfiles == nullptr) {
      std::cerr << "Runfiles::CreateForTest and ::Create failed: "
                << runfiles_error << std::endl;
      return EXIT_FAILURE;
    }
  }

  // If we do not want to test finding the Bazel Java toolchain in the runfiles,
  // we have to ensure that runfiles cannot be detected when calling into
  // libjvm. Else, ensure that they are found.
  if (getenv("HERMETIC") != nullptr) {
    rules_jni_init(argv[0]);
  } else {
    clear_env("RUNFILES_MANIFEST_FILE");
    clear_env("RUNFILES_DIR");
    clear_env("TEST_SRCDIR");
    rules_jni_init("does_not_exist");
  }

  // Configure the JVM by adding the test JAR to the classpath and passing a
  // message via a property.
  std::string class_path =
      "-Djava.class.path=" + runfiles->Rlocation(
                                 "fmeum_rules_jni_tests/libjvm_stub/"
                                 "HelloFromJava_deploy.jar");
  JavaVM* jvm = nullptr;
  JNIEnv* env = nullptr;
  JavaVMInitArgs vm_args;
  JavaVMOption options[] = {
      JavaVMOption{const_cast<char*>(class_path.c_str())},
      JavaVMOption{const_cast<char*>("-Dmsg.hello=" HELLO_FROM_JAVA_MSG)},
      JavaVMOption{const_cast<char*>("-Djdk.attach.allowAttachSelf=true")},
  };
  vm_args.version = JNI_VERSION_1_8;
  vm_args.nOptions = 3;
  vm_args.options = options;
  vm_args.ignoreUnrecognized = false;
  jint ret = JNI_GetDefaultJavaVMInitArgs(&vm_args);
  if (ret != JNI_OK) {
    std::cerr << "Failed to get default JVM init args" << std::endl;
    return EXIT_FAILURE;
  }

  // Create a JVM with the given options.
  ret = JNI_CreateJavaVM(&jvm, (void**)&env, &vm_args);
  if (ret != JNI_OK || env == nullptr) {
    std::cerr << "Failed to create JVM" << std::endl;
    return EXIT_FAILURE;
  }

  // Verify that JNI_GetCreatedJavaVMs returns the created VM.
  JavaVM* created_jvm = nullptr;
  jsize num_vms = 0;
  ret = JNI_GetCreatedJavaVMs(&created_jvm, 1, &num_vms);
  if (ret != JNI_OK || num_vms != 1 || created_jvm != jvm) {
    std::cerr << "Failed to get created Java VM" << std::endl;
    return EXIT_FAILURE;
  }

  // Call a Java method that returns a String.
  jclass hello_from_java_class = env->FindClass("com/example/HelloFromJava");
  if (env->ExceptionCheck()) {
    env->ExceptionDescribe();
    return EXIT_FAILURE;
  }
  jmethodID hello_from_java_method = env->GetStaticMethodID(
      hello_from_java_class, "helloFromJava", "()Ljava/lang/String;");
  if (env->ExceptionCheck()) {
    env->ExceptionDescribe();
    return EXIT_FAILURE;
  }
  auto hello_from_java_jni =
      reinterpret_cast<jstring>(env->CallStaticObjectMethod(
          hello_from_java_class, hello_from_java_method));
  if (env->ExceptionCheck()) {
    env->ExceptionDescribe();
    return EXIT_FAILURE;
  }

  // Convert the returned string from UTF-16 to UTF-8 and verify it.
  static_assert(sizeof(jchar) == sizeof(char16_t),
                "jchar cannot be converted to char16_t");
  const jchar* hello_from_java_cstr =
      env->GetStringChars(hello_from_java_jni, nullptr);
  std::wstring_convert<std::codecvt_utf8_utf16<char16_t>, char16_t>
      utf16_to_utf8;
  std::string hello_from_java = utf16_to_utf8.to_bytes(
      reinterpret_cast<const char16_t*>(hello_from_java_cstr));
  env->ReleaseStringChars(hello_from_java_jni, hello_from_java_cstr);
  if (hello_from_java != HELLO_FROM_JAVA_MSG) {
    std::cerr << "helloFromJava() returned unexpected value: "
              << hello_from_java << std::endl;
    return EXIT_FAILURE;
  }

  // Verify that the JVM was destroyed correctly.
  ret = jvm->DestroyJavaVM();
  if (ret != JNI_OK) {
    std::cerr << "Failed to destroy JVM" << std::endl;
    return EXIT_FAILURE;
  }

  return EXIT_SUCCESS;
}
<commit_msg>Work around repo mapping issue in runfiles discovery<commit_after>// Copyright 2021 Fabian Meumertzheim
//
// 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 <jni.h>
#include <rules_jni.h>
#ifdef _WIN32
#include <windows.h>
#endif

#include <codecvt>
#include <cstdlib>
#include <iostream>
#include <locale>

#include "tools/cpp/runfiles/runfiles.h"

#define HELLO_FROM_JAVA_JAR_PATH "libjvm_stub/HelloFromJava_deploy.jar"
#define HELLO_FROM_JAVA_MSG "Hello_from_Java!"
#ifdef _WIN32
#define CLASSPATH_SEPARATOR ";"
#else
#define CLASSPATH_SEPARATOR ":"
#endif

void clear_env(const char* name) {
#ifdef _WIN32
  SetEnvironmentVariable(name, nullptr);
#else
  unsetenv(name);
#endif
}

int main(int argc, const char** argv) {
  // Override PATH with PATH_OVERRIDE, if set.
  if (getenv("PATH_OVERRIDE") != nullptr) {
    const char* path_override = getenv("PATH_OVERRIDE");
#ifdef _WIN32
    _putenv_s("PATH", path_override);
#else
    setenv("PATH", path_override, 1);
#endif
  }

  // Set up the Bazel runfiles library to get the path to the JAR.
  using ::bazel::tools::cpp::runfiles::Runfiles;
  std::string runfiles_error;
  Runfiles* runfiles = Runfiles::CreateForTest(&runfiles_error);
  if (runfiles == nullptr) {
    runfiles = Runfiles::Create(argv[0], &runfiles_error);
    if (runfiles == nullptr) {
      std::cerr << "Runfiles::CreateForTest and ::Create failed: "
                << runfiles_error << std::endl;
      return EXIT_FAILURE;
    }
  }

  // If we do not want to test finding the Bazel Java toolchain in the runfiles,
  // we have to ensure that runfiles cannot be detected when calling into
  // libjvm. Else, ensure that they are found.
  if (getenv("HERMETIC") != nullptr) {
    rules_jni_init(argv[0]);
  } else {
    clear_env("RUNFILES_MANIFEST_FILE");
    clear_env("RUNFILES_DIR");
    clear_env("TEST_SRCDIR");
    rules_jni_init("does_not_exist");
  }

  // Configure the JVM by adding the test JAR to the classpath and passing a
  // message via a property.
  // TODO: Since the name of the current repository differs when the tests are
  //       loaded as a module extension, we pass in multiple paths of which only
  //       ever one will be valid. Use rules_runfiles instead once it becomes
  //       available as a Bazel module.
  std::string jar_path_workspace =
      runfiles->Rlocation("fmeum_rules_jni_tests/" HELLO_FROM_JAVA_JAR_PATH);
  std::string jar_path_module = runfiles->Rlocation(
      ".install_dev_dependencies.fmeum_rules_jni_"
      "tests/" HELLO_FROM_JAVA_JAR_PATH);
  std::string class_path = "-Djava.class.path=" + jar_path_workspace +
                           CLASSPATH_SEPARATOR + jar_path_module;
  JavaVM* jvm = nullptr;
  JNIEnv* env = nullptr;
  JavaVMInitArgs vm_args;
  JavaVMOption options[] = {
      JavaVMOption{const_cast<char*>(class_path.c_str())},
      JavaVMOption{const_cast<char*>("-Dmsg.hello=" HELLO_FROM_JAVA_MSG)},
      JavaVMOption{const_cast<char*>("-Djdk.attach.allowAttachSelf=true")},
  };
  vm_args.version = JNI_VERSION_1_8;
  vm_args.nOptions = 3;
  vm_args.options = options;
  vm_args.ignoreUnrecognized = false;
  jint ret = JNI_GetDefaultJavaVMInitArgs(&vm_args);
  if (ret != JNI_OK) {
    std::cerr << "Failed to get default JVM init args" << std::endl;
    return EXIT_FAILURE;
  }

  // Create a JVM with the given options.
  ret = JNI_CreateJavaVM(&jvm, (void**)&env, &vm_args);
  if (ret != JNI_OK || env == nullptr) {
    std::cerr << "Failed to create JVM" << std::endl;
    return EXIT_FAILURE;
  }

  // Verify that JNI_GetCreatedJavaVMs returns the created VM.
  JavaVM* created_jvm = nullptr;
  jsize num_vms = 0;
  ret = JNI_GetCreatedJavaVMs(&created_jvm, 1, &num_vms);
  if (ret != JNI_OK || num_vms != 1 || created_jvm != jvm) {
    std::cerr << "Failed to get created Java VM" << std::endl;
    return EXIT_FAILURE;
  }

  // Call a Java method that returns a String.
  jclass hello_from_java_class = env->FindClass("com/example/HelloFromJava");
  if (env->ExceptionCheck()) {
    env->ExceptionDescribe();
    return EXIT_FAILURE;
  }
  jmethodID hello_from_java_method = env->GetStaticMethodID(
      hello_from_java_class, "helloFromJava", "()Ljava/lang/String;");
  if (env->ExceptionCheck()) {
    env->ExceptionDescribe();
    return EXIT_FAILURE;
  }
  auto hello_from_java_jni =
      reinterpret_cast<jstring>(env->CallStaticObjectMethod(
          hello_from_java_class, hello_from_java_method));
  if (env->ExceptionCheck()) {
    env->ExceptionDescribe();
    return EXIT_FAILURE;
  }

  // Convert the returned string from UTF-16 to UTF-8 and verify it.
  static_assert(sizeof(jchar) == sizeof(char16_t),
                "jchar cannot be converted to char16_t");
  const jchar* hello_from_java_cstr =
      env->GetStringChars(hello_from_java_jni, nullptr);
  std::wstring_convert<std::codecvt_utf8_utf16<char16_t>, char16_t>
      utf16_to_utf8;
  std::string hello_from_java = utf16_to_utf8.to_bytes(
      reinterpret_cast<const char16_t*>(hello_from_java_cstr));
  env->ReleaseStringChars(hello_from_java_jni, hello_from_java_cstr);
  if (hello_from_java != HELLO_FROM_JAVA_MSG) {
    std::cerr << "helloFromJava() returned unexpected value: "
              << hello_from_java << std::endl;
    return EXIT_FAILURE;
  }

  // Verify that the JVM was destroyed correctly.
  ret = jvm->DestroyJavaVM();
  if (ret != JNI_OK) {
    std::cerr << "Failed to destroy JVM" << std::endl;
    return EXIT_FAILURE;
  }

  return EXIT_SUCCESS;
}
<|endoftext|>


<commit_before>#ifndef MATLIB_PML_BCPM_H
#define MATLIB_PML_BCPM_H

#include "pml.hpp"
#include "pml_rand.hpp"

#include <algorithm>

namespace pml {
  // ----------- POTENTIALS ----------- //

  class Potential {

    public:
      explicit Potential(double log_c_) : log_c(log_c_) {}

    public:
      bool operator<(const Potential &other) const{
        return this->log_c < other.log_c;
      }

      virtual Vector rand() const = 0;

      virtual Vector mean() const = 0;

    public:
      double log_c;
  };

  class DirichletPotential : public Potential {

    public:
      DirichletPotential(size_t K, double log_c_ = 0) : Potential(log_c_) {
        alpha = Vector::ones(K);
      }

      DirichletPotential(const Vector& alpha_, double log_c_ = 0)
          : Potential(log_c_), alpha(alpha_) {}

    public:
      void operator*=(const DirichletPotential &p){
        *this = this->operator*(p);
      }

      DirichletPotential operator*(const DirichletPotential &p) const{

        double delta = std::lgamma(sum(alpha)) - sum(lgamma(alpha)) +
                       std::lgamma(sum(p.alpha)) - sum(lgamma(p.alpha)) +
                       sum(lgamma(alpha + p.alpha-1)) -
                       std::lgamma(sum(alpha + p.alpha -1));

        return DirichletPotential(alpha + p.alpha - 1,
                                  log_c + p.log_c + delta);
      }

      Vector rand() const override {
        return dirichlet::rand(alpha);
      }

      Vector mean() const override {
        return normalize(alpha);
      }

    public:
      Vector alpha;
  };

  class GammaPotential : public Potential {

    public:
      GammaPotential(double a_ = 1, double b_ = 1, double log_c_ = 0)
              : Potential(log_c_), a(a_), b(b_){}

    public:
      void operator*=(const GammaPotential &other){
        *this = this->operator*(other);
      }

      GammaPotential operator*(const GammaPotential &other) const{
        double delta = std::lgamma(a + other.a - 1)
                       - std::lgamma(a) - std::lgamma(other.a)
                       + std::log(b + other.b)
                       + a * std::log(b/(b + other.b))
                       + other.a * std::log(other.b/(b + other.b));
        return GammaPotential(a + other.a - 1,
                              b + other.b,
                              log_c + other.log_c + delta);
      }

      Vector rand() const override {
        return gamma::rand(a, b, 1);
      }

      Vector mean() const override {
        return Vector(1, a / b);
      }

    public:
      double a;
      double b;
  };

  // ----------- OBSERVATION MODELS ----------- //

  template <class P>
  class ObservationModel{

    public:
      ObservationModel(const P &prior_) : prior(prior_) {}

    public:
      void reset(){
        lambda = prior.rand();
      }
      virtual Vector rand() const  = 0;

      virtual void update(P &p, const Vector &obs) const = 0;

    public:
      P prior;
      Vector lambda;
  };

  class PoissonRandom : public ObservationModel<GammaPotential> {

    public:
      PoissonRandom(const GammaPotential &prior_) : ObservationModel(prior_){
        reset();
      }

      Vector rand() const override{
        return poisson::rand(lambda.first(), 1);
      }

      void update(GammaPotential &gp, const Vector &obs) const override{
        gp *= GammaPotential(obs.first()+1, 1);
      }
  };

  class MultinomialRandom : public ObservationModel<DirichletPotential> {

    public:
      MultinomialRandom(const DirichletPotential &prior_)
              : ObservationModel(prior_){
        reset();
      }

      Vector rand() const override {
        return multinomial::rand(lambda, 100);
      }

      void update(DirichletPotential &dp, const Vector &obs) const override {
        double log_c = std::lgamma(sum(obs)+1) - std::lgamma(sum(obs+1));
        dp *= DirichletPotential(obs+1, log_c);
      }
  };

  // ----------- MESSAGE----------- //

  template <class P>
  class Message {

    public:
      size_t size() const {
        return components.size();
      }

      void add_component(const P &potential){
        components.push_back(potential);
      }

      void add_component(const P &potential, double log_c){
        components.push_back(potential);
        components.back().log_c = log_c;
      }

      friend Message<P> operator*(const Message<P> &m1, const Message<P> &m2){
        Message<P> msg;
        for(auto &component1 : m1.components)
          for(auto &component2 : m2.components)
            msg.add_component(component1 * component2);
        return msg;
      }

      // Returns mean and cpp (Maybe renamed)
      std::pair<Vector, double> evaluate(int N = 1){
        Vector consts;
        Matrix params;
        for(auto &potential: components){
          consts.append(potential.log_c);
          params.appendColumn(potential.mean());
        }
        consts = normalizeExp(consts);
        // Calculate mean
        Vector mean = sumRows(transpose(transpose(params)*consts));
        // Calculate cpp as the sum of last N probabilities
        double cpp = 0;
        for(int i=0; i < N; ++i)
          cpp += consts(consts.size() - i - 1);
        return {mean, cpp};
      };

      void prune(size_t max_components){
        while(components.size() > max_components){
          // Find mininum no-change element
          auto iter = std::min_element(components.begin(), components.end()-1);
          // Swap the last two elements to save the order of the change comp.
          std::swap(*(components.end()-1), *(components.end()-2));
          // Swap last element with the minimum compoment.
          std::swap(*iter, components.back());
          // Delete minimum component.
          components.pop_back();
        }
      }

    public:
      std::vector<P> components;
  };

  // ----------- MODEL----------- //
  template <class P, class Obs>
  class Model{
    public:
      Model(const P &prior_, double p1_)
              : prior(prior_), observation(prior_), p1(p1_){
        log_p1 = std::log(p1);
        log_p0 = std::log(1-p1);
      }

    public:
      // returns  "states" as first matrix and "obervations" as second
      std::pair<Matrix, Matrix> generateData(size_t T){
        Matrix states, obs;

        for (size_t t=0; t<T; t++) {
          if (t > 0 && uniform::rand() < p1) {
            observation.reset();
          }
          states.appendColumn(observation.lambda);
          obs.appendColumn(observation.rand());
        }
        return {states, obs};
      }

      Message<P> initialMessage(){
        Message<P> message;
        message.add_component(prior, log_p0);
        message.add_component(prior, log_p1);
        return message;
      }

      Message<P> predict(const Message<P> &prev){
        Message<P> message = prev;
        Vector consts;
        for(auto &component : message.components){
          consts.append(component.log_c);
          component.log_c += log_p0;
        }
        message.add_component(prior, log_p1 + logSumExp(consts));
        return message;
      }

      void update(Message<P> &message, const Vector &obs){
        for(auto &component : message.components)
          observation.update(component, obs);
      }

    private:
      P prior;
      Obs observation;
      double p1;                //  probability of change
      double log_p1, log_p0;
  };

  template <class P, class Obs>
  class ForwardBackward {
    public:
      ForwardBackward(const Model<P, Obs> &model_,
                      int lag_ = 0, int max_components_ = 100)
              : model(model_), lag(lag_), max_components(max_components_) {}

    public:
      void oneStepForward(std::vector<Message<P>> &alpha, const Vector& obs) {
        // predict step
        if (alpha.size() == 0)
          alpha.push_back(model.initialMessage());
        else
          alpha.push_back(model.predict(alpha.back()));
        // update step
        model.update(alpha.back(), obs);
      }

      void oneStepBackward(std::vector<Message<P>> &beta, const Vector& obs) {
        // predict step
        if (beta.size()==0)
          beta.push_back(model.initialMessage());
        else
          beta.push_back(model.predict(beta.back()));
        // update step
        model.update(beta.back(), obs);
      }

      std::vector<Message<P>> forward(const Matrix& obs){
        std::vector<Message<P>> alpha;
        for (size_t i=0; i<obs.ncols(); i++) {
          oneStepForward(alpha, obs.getColumn(i));
          alpha.back().prune(max_components);
        }
        return alpha;
      }

      std::vector<Message<P>> backward(const Matrix& obs){
        std::vector<Message<P>> beta;
        for (size_t i=obs.ncols(); i>0; i--) {
          oneStepBackward(beta, obs.getColumn(i-1));
          beta.back().prune(max_components);
        }
        // We calculated Beta backwards, we need to reverse the list.
        std::reverse(beta.begin(), beta.end());
        return beta;
      }

      // Returns mean and cpp
      std::pair<Matrix, Vector> filtering(const Matrix& obs) {
        // Run forward
        auto alpha = forward(obs);

        // Calculate mean and cpp
        Matrix mean;
        Vector cpp;
        for(auto &message : alpha){
          auto result = message.evaluate();
          mean.appendColumn(result.first);
          cpp.append(result.second);
        }
        return {mean, cpp};
      }

      // Returns mean and cpp
      std::pair<Matrix, Vector> smoothing(const Matrix& obs) {
        Matrix mean;
        Vector cpp;
        // Run Forward and Backward
        auto alpha = forward(obs);
        auto beta = backward(obs);

        // Calculate Smoothed density
        Message<P> gamma;
        for(size_t i=0; i < obs.ncols(); ++i) {
          gamma = alpha[i] * beta[i];
          auto result = gamma.evaluate(beta[i].size());
          mean.appendColumn(result.first);
          cpp.append(result.second);
        }
        return {mean, cpp};
      }

      // a.k.a. fixed-lag smoothing
      std::pair<Matrix, Vector> online_smoothing(const Matrix& obs) {
        if( lag == 0){
          return filtering(obs);
        }
        Matrix mean;
        Vector cpp;
        std::vector<Message<P>> alpha = forward(obs);
        Message<P> gamma;
        for (size_t t=0; t<obs.ncols()-lag+1; t++) {
          auto beta = backward(obs.getColumns(Range(t, t+lag)));
          gamma = alpha[t] * beta[0];
          auto result = gamma.evaluate(beta[0].size());
          mean.appendColumn(result.first);
          cpp.append(result.second);
          // if T-lag is reached, smooth the rest
          if(t == obs.ncols()-lag){
            for(int i = 1; i < lag; ++i){
              gamma = alpha[t+i] * beta[i];
              auto result = gamma.evaluate(beta[i].size());
              mean.appendColumn(result.first);
              cpp.append(result.second);
            }
          }
        }
        return {mean, cpp};
      }

    public:
      Model<P, Obs> model;
      int lag;
      int max_components;
  };
}

#endif //MATLIB_PML_BCPM_H
<commit_msg>beta message in the backward function now stores postdict messages<commit_after>#ifndef MATLIB_PML_BCPM_H
#define MATLIB_PML_BCPM_H

#include "pml.hpp"
#include "pml_rand.hpp"

#include <algorithm>

namespace pml {
  // ----------- POTENTIALS ----------- //

  class Potential {

    public:
      explicit Potential(double log_c_) : log_c(log_c_) {}

    public:
      bool operator<(const Potential &other) const{
        return this->log_c < other.log_c;
      }

      virtual Vector rand() const = 0;

      virtual Vector mean() const = 0;

    public:
      double log_c;
  };

  class DirichletPotential : public Potential {

    public:
      DirichletPotential(size_t K, double log_c_ = 0) : Potential(log_c_) {
        alpha = Vector::ones(K);
      }

      DirichletPotential(const Vector& alpha_, double log_c_ = 0)
          : Potential(log_c_), alpha(alpha_) {}

    public:
      void operator*=(const DirichletPotential &p){
        *this = this->operator*(p);
      }

      DirichletPotential operator*(const DirichletPotential &p) const{

        double delta = std::lgamma(sum(alpha)) - sum(lgamma(alpha)) +
                       std::lgamma(sum(p.alpha)) - sum(lgamma(p.alpha)) +
                       sum(lgamma(alpha + p.alpha-1)) -
                       std::lgamma(sum(alpha + p.alpha -1));

        return DirichletPotential(alpha + p.alpha - 1,
                                  log_c + p.log_c + delta);
      }

      Vector rand() const override {
        return dirichlet::rand(alpha);
      }

      Vector mean() const override {
        return normalize(alpha);
      }

    public:
      Vector alpha;
  };

  class GammaPotential : public Potential {

    public:
      GammaPotential(double a_ = 1, double b_ = 1, double log_c_ = 0)
              : Potential(log_c_), a(a_), b(b_){}

    public:
      void operator*=(const GammaPotential &other){
        *this = this->operator*(other);
      }

      GammaPotential operator*(const GammaPotential &other) const{
        double delta = std::lgamma(a + other.a - 1)
                       - std::lgamma(a) - std::lgamma(other.a)
                       + std::log(b + other.b)
                       + a * std::log(b/(b + other.b))
                       + other.a * std::log(other.b/(b + other.b));
        return GammaPotential(a + other.a - 1,
                              b + other.b,
                              log_c + other.log_c + delta);
      }

      Vector rand() const override {
        return gamma::rand(a, b, 1);
      }

      Vector mean() const override {
        return Vector(1, a / b);
      }

    public:
      double a;
      double b;
  };

  // ----------- OBSERVATION MODELS ----------- //

  template <class P>
  class ObservationModel{

    public:
      ObservationModel(const P &prior_) : prior(prior_) {}

    public:
      void reset(){
        lambda = prior.rand();
      }
      virtual Vector rand() const  = 0;

      virtual void update(P &p, const Vector &obs) const = 0;

    public:
      P prior;
      Vector lambda;
  };

  class PoissonRandom : public ObservationModel<GammaPotential> {

    public:
      PoissonRandom(const GammaPotential &prior_) : ObservationModel(prior_){
        reset();
      }

      Vector rand() const override{
        return poisson::rand(lambda.first(), 1);
      }

      void update(GammaPotential &gp, const Vector &obs) const override{
        gp *= GammaPotential(obs.first()+1, 1);
      }
  };

  class MultinomialRandom : public ObservationModel<DirichletPotential> {

    public:
      MultinomialRandom(const DirichletPotential &prior_)
              : ObservationModel(prior_){
        reset();
      }

      Vector rand() const override {
        return multinomial::rand(lambda, 100);
      }

      void update(DirichletPotential &dp, const Vector &obs) const override {
        double log_c = std::lgamma(sum(obs)+1) - std::lgamma(sum(obs+1));
        dp *= DirichletPotential(obs+1, log_c);
      }
  };

  // ----------- MESSAGE----------- //

  template <class P>
  class Message {

    public:
      size_t size() const {
        return components.size();
      }

      void add_component(const P &potential){
        components.push_back(potential);
      }

      void add_component(const P &potential, double log_c){
        components.push_back(potential);
        components.back().log_c = log_c;
      }

      friend Message<P> operator*(const Message<P> &m1, const Message<P> &m2){
        Message<P> msg;
        for(auto &component1 : m1.components)
          for(auto &component2 : m2.components)
            msg.add_component(component1 * component2);
        return msg;
      }

      // Returns mean and cpp (Maybe renamed)
      std::pair<Vector, double> evaluate(int N = 1){
        Vector consts;
        Matrix params;
        for(auto &potential: components){
          consts.append(potential.log_c);
          params.appendColumn(potential.mean());
        }
        consts = normalizeExp(consts);
        // Calculate mean
        Vector mean = sumRows(transpose(transpose(params)*consts));
        // Calculate cpp as the sum of last N probabilities
        double cpp = 0;
        for(int i=0; i < N; ++i)
          cpp += consts(consts.size() - i - 1);
        return {mean, cpp};
      };

      void prune(size_t max_components){
        while(components.size() > max_components){
          // Find mininum no-change element
          auto iter = std::min_element(components.begin(), components.end()-1);
          // Swap the last two elements to save the order of the change comp.
          std::swap(*(components.end()-1), *(components.end()-2));
          // Swap last element with the minimum compoment.
          std::swap(*iter, components.back());
          // Delete minimum component.
          components.pop_back();
        }
      }

    public:
      std::vector<P> components;
  };

  // ----------- MODEL----------- //
  template <class P, class Obs>
  class Model{
    public:
      Model(const P &prior_, double p1_)
              : prior(prior_), observation(prior_), p1(p1_){
        log_p1 = std::log(p1);
        log_p0 = std::log(1-p1);
      }

    public:
      // returns  "states" as first matrix and "obervations" as second
      std::pair<Matrix, Matrix> generateData(size_t T){
        Matrix states, obs;

        for (size_t t=0; t<T; t++) {
          if (t > 0 && uniform::rand() < p1) {
            observation.reset();
          }
          states.appendColumn(observation.lambda);
          obs.appendColumn(observation.rand());
        }
        return {states, obs};
      }

      Message<P> initialMessage(){
        Message<P> message;
        message.add_component(prior, log_p0);
        message.add_component(prior, log_p1);
        return message;
      }

      Message<P> predict(const Message<P> &prev){
        Message<P> message = prev;
        Vector consts;
        for(auto &component : message.components){
          consts.append(component.log_c);
          component.log_c += log_p0;
        }
        message.add_component(prior, log_p1 + logSumExp(consts));
        return message;
      }

      void update(Message<P> &message, const Vector &obs){
        for(auto &component : message.components)
          observation.update(component, obs);
      }

    private:
      P prior;
      Obs observation;
      double p1;                //  probability of change
      double log_p1, log_p0;
  };

  template <class P, class Obs>
  class ForwardBackward {
    public:
      ForwardBackward(const Model<P, Obs> &model_,
                      int lag_ = 0, int max_components_ = 100)
              : model(model_), lag(lag_), max_components(max_components_) {}

    public:
      void oneStepForward(std::vector<Message<P>> &alpha, const Vector& obs) {
        // predict step
        if (alpha.size() == 0)
          alpha.push_back(model.initialMessage());
        else
          alpha.push_back(model.predict(alpha.back()));
        // update step
        model.update(alpha.back(), obs);
      }

      void oneStepBackward(std::vector<Message<P>> &beta, const Vector& obs) {
        // predict step
        if (beta.size()==0)
          beta.push_back(model.initialMessage());
        else
          model.update(beta.back(), obs);
          beta.push_back(model.predict(beta.back()));
      }

      std::vector<Message<P>> forward(const Matrix& obs){
        std::vector<Message<P>> alpha;
        for (size_t i=0; i<obs.ncols(); i++) {
          oneStepForward(alpha, obs.getColumn(i));
          alpha.back().prune(max_components);
        }
        return alpha;
      }

      std::vector<Message<P>> backward(const Matrix& obs){
        std::vector<Message<P>> beta;
        beta.push_back(model.initialMessage());
        for (size_t i=obs.ncols(); i>1; i--) {
          oneStepBackward(beta, obs.getColumn(i-1));
          beta.back().prune(max_components);
        }
        // We calculated Beta backwards, we need to reverse the list.
        std::reverse(beta.begin(), beta.end());
        return beta;
      }

      // Returns mean and cpp
      std::pair<Matrix, Vector> filtering(const Matrix& obs) {
        // Run forward
        auto alpha = forward(obs);

        // Calculate mean and cpp
        Matrix mean;
        Vector cpp;
        for(auto &message : alpha){
          auto result = message.evaluate();
          mean.appendColumn(result.first);
          cpp.append(result.second);
        }
        return {mean, cpp};
      }

      // Returns mean and cpp
      std::pair<Matrix, Vector> smoothing(const Matrix& obs) {
        Matrix mean;
        Vector cpp;
        // Run Forward and Backward
        auto alpha = forward(obs);
        auto beta = backward(obs);

        // Calculate Smoothed density
        Message<P> gamma;
        for(size_t i=0; i < obs.ncols(); ++i) {
          gamma = alpha[i] * beta[i];
          auto result = gamma.evaluate(beta[i].size());
          mean.appendColumn(result.first);
          cpp.append(result.second);
        }
        return {mean, cpp};
      }

      // a.k.a. fixed-lag smoothing
      std::pair<Matrix, Vector> online_smoothing(const Matrix& obs) {
        if( lag == 0){
          return filtering(obs);
        }
        Matrix mean;
        Vector cpp;
        std::vector<Message<P>> alpha = forward(obs);
        Message<P> gamma;
        for (size_t t=0; t<obs.ncols()-lag+1; t++) {
          auto beta = backward(obs.getColumns(Range(t, t+lag)));
          gamma = alpha[t] * beta[0];
          auto result = gamma.evaluate(beta[0].size());
          mean.appendColumn(result.first);
          cpp.append(result.second);
          // if T-lag is reached, smooth the rest
          if(t == obs.ncols()-lag){
            for(int i = 1; i < lag; ++i){
              gamma = alpha[t+i] * beta[i];
              auto result = gamma.evaluate(beta[i].size());
              mean.appendColumn(result.first);
              cpp.append(result.second);
            }
          }
        }
        return {mean, cpp};
      }

    public:
      Model<P, Obs> model;
      int lag;
      int max_components;
  };
}

#endif //MATLIB_PML_BCPM_H
<|endoftext|>


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

// MARKER(update_precomp.py): autogen include statement, do not remove
#include "precompiled_svtools.hxx"
#include <svtools/svmedit.hxx>

#ifndef _TXTCMP_HXX //autogen
#include <txtcmp.hxx>
#endif

#ifndef _SV_BUTTON_HXX //autogen
#include <vcl/button.hxx>
#endif

#ifndef _SV_WRKWIN_HXX //autogen
#include <vcl/wrkwin.hxx>
#endif

#ifndef _SV_FIXED_HXX //autogen
#include <vcl/fixed.hxx>
#endif

#ifndef _SV_SVAPP_HXX //autogen
#include <vcl/svapp.hxx>
#endif

class MyApp : public Application
{
public:
    virtual void Main( );
};

class SearchWindow : public WorkWindow
{
    PushButton      aPB;
    FixedText       aFT1, aFT2, aFT3;
    MultiLineEdit   aEText, aESrch;
    RadioButton     aModeN, aModeR, aModeL;
    SearchParam     aParam;

public:
                    SearchWindow();

    DECL_LINK( ClickHdl, Button * );
};

// --- SearchWindow::SearchWindow() ------------------------------------

SearchWindow::SearchWindow() :
                WorkWindow( NULL, WinBits( WB_APP | WB_STDWORK )),
    aPB( this, WinBits( 0 )),
    aFT1( this, WinBits( 0 )),
    aFT2( this, WinBits( 0 )),
    aFT3( this, WinBits( 0 )),
    aEText( this, WinBits( WB_BORDER )),
    aESrch( this, WinBits( WB_BORDER )),
    aModeN( this, WinBits( 0 )),
    aModeR( this, WinBits( 0 )),
    aModeL( this, WinBits( 0 )),
    aParam( "" )
{
    aPB.SetClickHdl( LINK( this, SearchWindow, ClickHdl ));
    aModeN.SetClickHdl( LINK( this, SearchWindow, ClickHdl ));
    aModeR.SetClickHdl( LINK( this, SearchWindow, ClickHdl ));
    aModeL.SetClickHdl( LINK( this, SearchWindow, ClickHdl ));

    SetMapMode( MapMode( MAP_APPFONT ));
    SetSizePixel( LogicToPixel( Size( 300, 180 ) ) );

    aEText.SetPosSizePixel( LogicToPixel( Point( 0, 22 )), LogicToPixel(Size( 270, 32 )) );
    aFT1.SetPosSizePixel( LogicToPixel( Point( 0, 10 )), LogicToPixel(Size( 18, 11 )) );
    aFT2.SetPosSizePixel( LogicToPixel( Point( 0, 60 )), LogicToPixel(Size( 24, 10 )) );
    aESrch.SetPosSizePixel( LogicToPixel( Point( 0, 70 )), LogicToPixel(Size( 270, 24 )) );
    aPB.SetPosSizePixel( LogicToPixel( Point( 223, 139 )), LogicToPixel(Size( 48, 12 )) );
    aFT3.SetPosSizePixel( LogicToPixel( Point( 0, 104 )), LogicToPixel(Size( 270, 15 )) );
    aModeN.SetPosSizePixel( LogicToPixel( Point( 5, 116 ) ), LogicToPixel( Size( 40, 12 ) ) );
    aModeR.SetPosSizePixel( LogicToPixel( Point( 5, 126 ) ), LogicToPixel( Size( 40, 12 ) ) );
    aModeL.SetPosSizePixel( LogicToPixel( Point( 5, 136 ) ), LogicToPixel( Size( 40, 12 ) ) );

    aEText.Show();
    aFT1.Show();
    aFT2.Show();
    aESrch.Show();
    aPB.Show();
    aFT3.Show();
    aModeN.Show();
    aModeR.Show();
    aModeL.Show();

    aFT3.SetText( "gefunden:" );
    aFT1.SetText( "Text:" );
    aFT2.SetText( "Suche:" );
    aPB.SetText( "starte Suche" );
    aModeN.SetText( "normal" );
    aModeR.SetText( "RegExp" );
    aModeL.SetText( "LevDis" );

    SetText( "Such-Demo" );
}

// --- SearchWindow::SearchSelectHdl() ---------------------------------

IMPL_LINK( SearchWindow, ClickHdl, Button *, pButton )
{
    if( pButton == &aPB )
    {
        String sText( aEText.GetText() );
        String sSrch( aESrch.GetText() );

/*      InfoBox( this, String( "T: " ) + sText +
                       String( "\nS: " ) + sSrch ).Execute();
*/
        BOOL bRet = FALSE;
        USHORT nStt = 0, nEnd = sText.Len();

        {
            aParam.SetSrchStr( sSrch );
            SearchText aSrchText( aParam, GetpApp()->GetAppInternational() );
            bRet = aSrchText.SearchFrwrd( sText, &nStt, &nEnd );

//          BOOL SearchBkwrd( const String &rStr, USHORT* pStart, USHORT* pEnde );
        }

        String sFound( "gefunden" );
        if( !bRet )
            sFound.Insert( "nicht ", 0 );

        sFound += ": S<";
        sFound += nStt;
        sFound += "> E<";
        sFound += nEnd;
        sFound += '>';

        if( bRet )
        {
            sFound += '<';
            sFound += sText.Copy( nStt, nEnd - nStt +1 );
            sFound += '>';
        }

        aFT3.SetText( sFound );
    }
    else if( pButton == &aModeN )
    {
        aParam.SetSrchType( SearchParam::SRCH_NORMAL );
    }
    else if( pButton == &aModeR )
    {
        aParam.SetSrchType( SearchParam::SRCH_REGEXP );
    }
    else if( pButton == &aModeL )
    {
        aParam.SetSrchType( SearchParam::SRCH_LEVDIST );
    }
    return 0;
}

// --- MyApp::Main() -----------------------------------------------

void MyApp::Main( )
{
    SearchWindow*   pSearchWindow = new SearchWindow;
    pSearchWindow->Show();
    Execute();
    delete pSearchWindow;

}

// --- aMyApp ------------------------------------------------------

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

// MARKER(update_precomp.py): autogen include statement, do not remove
#include "precompiled_svtools.hxx"
#include <svtools/svmedit.hxx>
#include <txtcmp.hxx>

#ifndef _SV_BUTTON_HXX //autogen
#include <vcl/button.hxx>
#endif
#include <vcl/wrkwin.hxx>
#include <vcl/fixed.hxx>
#include <vcl/svapp.hxx>

class MyApp : public Application
{
public:
    virtual void Main( );
};

class SearchWindow : public WorkWindow
{
    PushButton      aPB;
    FixedText       aFT1, aFT2, aFT3;
    MultiLineEdit   aEText, aESrch;
    RadioButton     aModeN, aModeR, aModeL;
    SearchParam     aParam;

public:
                    SearchWindow();

    DECL_LINK( ClickHdl, Button * );
};

// --- SearchWindow::SearchWindow() ------------------------------------

SearchWindow::SearchWindow() :
                WorkWindow( NULL, WinBits( WB_APP | WB_STDWORK )),
    aPB( this, WinBits( 0 )),
    aFT1( this, WinBits( 0 )),
    aFT2( this, WinBits( 0 )),
    aFT3( this, WinBits( 0 )),
    aEText( this, WinBits( WB_BORDER )),
    aESrch( this, WinBits( WB_BORDER )),
    aModeN( this, WinBits( 0 )),
    aModeR( this, WinBits( 0 )),
    aModeL( this, WinBits( 0 )),
    aParam( "" )
{
    aPB.SetClickHdl( LINK( this, SearchWindow, ClickHdl ));
    aModeN.SetClickHdl( LINK( this, SearchWindow, ClickHdl ));
    aModeR.SetClickHdl( LINK( this, SearchWindow, ClickHdl ));
    aModeL.SetClickHdl( LINK( this, SearchWindow, ClickHdl ));

    SetMapMode( MapMode( MAP_APPFONT ));
    SetSizePixel( LogicToPixel( Size( 300, 180 ) ) );

    aEText.SetPosSizePixel( LogicToPixel( Point( 0, 22 )), LogicToPixel(Size( 270, 32 )) );
    aFT1.SetPosSizePixel( LogicToPixel( Point( 0, 10 )), LogicToPixel(Size( 18, 11 )) );
    aFT2.SetPosSizePixel( LogicToPixel( Point( 0, 60 )), LogicToPixel(Size( 24, 10 )) );
    aESrch.SetPosSizePixel( LogicToPixel( Point( 0, 70 )), LogicToPixel(Size( 270, 24 )) );
    aPB.SetPosSizePixel( LogicToPixel( Point( 223, 139 )), LogicToPixel(Size( 48, 12 )) );
    aFT3.SetPosSizePixel( LogicToPixel( Point( 0, 104 )), LogicToPixel(Size( 270, 15 )) );
    aModeN.SetPosSizePixel( LogicToPixel( Point( 5, 116 ) ), LogicToPixel( Size( 40, 12 ) ) );
    aModeR.SetPosSizePixel( LogicToPixel( Point( 5, 126 ) ), LogicToPixel( Size( 40, 12 ) ) );
    aModeL.SetPosSizePixel( LogicToPixel( Point( 5, 136 ) ), LogicToPixel( Size( 40, 12 ) ) );

    aEText.Show();
    aFT1.Show();
    aFT2.Show();
    aESrch.Show();
    aPB.Show();
    aFT3.Show();
    aModeN.Show();
    aModeR.Show();
    aModeL.Show();

    aFT3.SetText( "gefunden:" );
    aFT1.SetText( "Text:" );
    aFT2.SetText( "Suche:" );
    aPB.SetText( "starte Suche" );
    aModeN.SetText( "normal" );
    aModeR.SetText( "RegExp" );
    aModeL.SetText( "LevDis" );

    SetText( "Such-Demo" );
}

// --- SearchWindow::SearchSelectHdl() ---------------------------------

IMPL_LINK( SearchWindow, ClickHdl, Button *, pButton )
{
    if( pButton == &aPB )
    {
        String sText( aEText.GetText() );
        String sSrch( aESrch.GetText() );

/*      InfoBox( this, String( "T: " ) + sText +
                       String( "\nS: " ) + sSrch ).Execute();
*/
        BOOL bRet = FALSE;
        USHORT nStt = 0, nEnd = sText.Len();

        {
            aParam.SetSrchStr( sSrch );
            SearchText aSrchText( aParam, GetpApp()->GetAppInternational() );
            bRet = aSrchText.SearchFrwrd( sText, &nStt, &nEnd );

//          BOOL SearchBkwrd( const String &rStr, USHORT* pStart, USHORT* pEnde );
        }

        String sFound( "gefunden" );
        if( !bRet )
            sFound.Insert( "nicht ", 0 );

        sFound += ": S<";
        sFound += nStt;
        sFound += "> E<";
        sFound += nEnd;
        sFound += '>';

        if( bRet )
        {
            sFound += '<';
            sFound += sText.Copy( nStt, nEnd - nStt +1 );
            sFound += '>';
        }

        aFT3.SetText( sFound );
    }
    else if( pButton == &aModeN )
    {
        aParam.SetSrchType( SearchParam::SRCH_NORMAL );
    }
    else if( pButton == &aModeR )
    {
        aParam.SetSrchType( SearchParam::SRCH_REGEXP );
    }
    else if( pButton == &aModeL )
    {
        aParam.SetSrchType( SearchParam::SRCH_LEVDIST );
    }
    return 0;
}

// --- MyApp::Main() -----------------------------------------------

void MyApp::Main( )
{
    SearchWindow*   pSearchWindow = new SearchWindow;
    pSearchWindow->Show();
    Execute();
    delete pSearchWindow;

}

// --- aMyApp ------------------------------------------------------

MyApp aMyApp;
<|endoftext|>


<commit_before>#if HAVE_CONFIG_H
#include <config.h>
#endif
#include <stdexcept>
#include <fstream>
#include <xorg/gtest/xorg-gtest.h>

#include "video-driver-test.h"

TEST_P(SimpleVideoDriverTest, DriverDevice)
{
    std::ifstream in_file(server.GetLogFilePath().c_str());
    std::string line;
    std::string error_msg("Failed to load module");
    std::string param(GetParam());

    // grep for error message in the log file...
    error_msg +=  " \"" + param + "\"";
    if(in_file.is_open())
    {
        while (getline (in_file, line))
        {
            size_t found = line.find(error_msg);
            Bool error = (found != std::string::npos);
            ASSERT_FALSE (error) << "Module " << param << " failed to load" << std::endl << line <<  std::endl;
        }
    }

    FAIL();
}

INSTANTIATE_TEST_CASE_P(, SimpleVideoDriverTest, ::testing::Values("dummy", "intel"));

int main(int argc, char **argv) {
    testing::InitGoogleTest(&argc, argv);
    return RUN_ALL_TESTS();
}
<commit_msg>Don't FAIL() for video driver tests<commit_after>#if HAVE_CONFIG_H
#include <config.h>
#endif
#include <stdexcept>
#include <fstream>
#include <xorg/gtest/xorg-gtest.h>

#include "video-driver-test.h"

TEST_P(SimpleVideoDriverTest, DriverDevice)
{
    std::ifstream in_file(server.GetLogFilePath().c_str());
    std::string line;
    std::string error_msg("Failed to load module");
    std::string param(GetParam());

    // grep for error message in the log file...
    error_msg +=  " \"" + param + "\"";
    if(in_file.is_open())
    {
        while (getline (in_file, line))
        {
            size_t found = line.find(error_msg);
            Bool error = (found != std::string::npos);
            ASSERT_FALSE (error) << "Module " << param << " failed to load" << std::endl << line <<  std::endl;
        }
    }
}

INSTANTIATE_TEST_CASE_P(, SimpleVideoDriverTest, ::testing::Values("dummy", "intel"));

int main(int argc, char **argv) {
    testing::InitGoogleTest(&argc, argv);
    return RUN_ALL_TESTS();
}
<|endoftext|>