<commit_before>#include <QtGui>
#include <QtOpenGL>

#include "edititemmanager.h"
#include "rectangle.h"
#include "multiline.h"

class Canvas : public QGLWidget
{
    Q_OBJECT
public:
    Canvas(QWidget *parent = 0)
        : QGLWidget(parent)
        , focus_(false)
    {
        setMouseTracking(true);
        setFocusPolicy(Qt::StrongFocus);
    }

private:
    void initializeGL()
    {
        glEnable(GL_DEPTH_TEST);
    }

    void resizeGL(int w, int h)
    {
        glViewport(0, 0, w, h);
        glMatrixMode(GL_PROJECTION);
        glLoadIdentity();
        glOrtho(0, w, 0, h, -2, 2);
     }

    void paintGL()
    {
        qglClearColor(QColor(204, 204, 204));
        glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
        glMatrixMode(GL_MODELVIEW);
        glLoadIdentity();
        emit paint();
    }

    QMouseEvent flippedYPos(QMouseEvent *event) const
    {
        return QMouseEvent(
            event->type(),
            QPoint(event->pos().x(), height() - event->pos().y()),
            event->globalPos(),
            event->button(),
            event->buttons(),
            event->modifiers()
            );
    }

    void mousePressEvent(QMouseEvent *event)
    {
        QMouseEvent fe = flippedYPos(event);
        emit mousePressed(&fe);
    }

    void mouseReleaseEvent(QMouseEvent *event)
    {
        QMouseEvent fe = flippedYPos(event);
        emit mouseReleased(&fe);
    }

    void mouseMoveEvent(QMouseEvent *event)
    {
        QMouseEvent fe = flippedYPos(event);
        emit mouseMoved(&fe);
    }

    void mouseDoubleClickEvent(QMouseEvent *event)
    {
        QMouseEvent fe = flippedYPos(event);
        emit mouseDoubleClicked(&fe);
    }

    void keyPressEvent(QKeyEvent *event) { emit keyPressed(event); }

    void keyReleaseEvent(QKeyEvent *event) { emit keyReleased(event); }

    void focusInEvent(QFocusEvent *)
    {
        focus_ = true;
        update();
    }

    void focusOutEvent(QFocusEvent *)
    {
        focus_ = false;
        update();
    }

    bool focus_;

signals:
    void mousePressed(QMouseEvent *);
    void mouseReleased(QMouseEvent *);
    void mouseMoved(QMouseEvent *);
    void mouseDoubleClicked(QMouseEvent *);
    void keyPressed(QKeyEvent *);
    void keyReleased(QKeyEvent *);
    void paint();

public slots:
    void doSwapBuffers()
    {
        if (focus_) {
            glColor3ub(0, 128, 0);
            renderText(2, height() - 2, "keyboard focus");
        } else {
            glColor3ub(255, 0, 0);
            renderText(2, height() - 2, "no keyboard focus");
        }

        swapBuffers();
    }

    void doRepaint() { update(); }
};

class Window : public QWidget
{
    Q_OBJECT
public:
    Window(EditItemManager *editItemMgr)
        : editItemMgr_(editItemMgr)
    {
        QHBoxLayout *topLayout = new QHBoxLayout;

        QVBoxLayout *leftLayout = new QVBoxLayout;

        QPushButton *button1 = new QPushButton("create rectangle\n(automatic placement)");
        button1->setSizePolicy(QSizePolicy::Maximum, QSizePolicy::Maximum);
        connect(button1, SIGNAL(clicked()), this, SLOT(addRectangle()));
        leftLayout->addWidget(button1);

        QPushButton *button1_2 = new QPushButton("create rectangle\n(manual placement)");
        button1_2->setSizePolicy(QSizePolicy::Maximum, QSizePolicy::Maximum);
        connect(button1_2, SIGNAL(clicked()), this, SLOT(addRectangleManually()));
        leftLayout->addWidget(button1_2);

        QPushButton *button1_3 = new QPushButton("create rectangle\n(manual placement w/resize)");
        button1_3->setSizePolicy(QSizePolicy::Maximum, QSizePolicy::Maximum);
        connect(button1_3, SIGNAL(clicked()), this, SLOT(addRectangleManuallyWithResize()));
        leftLayout->addWidget(button1_3);

        QPushButton *button2 = new QPushButton("create multiline\n(manual placement)");
        button2->setSizePolicy(QSizePolicy::Maximum, QSizePolicy::Maximum);
        connect(button2, SIGNAL(clicked()), this, SLOT(addMultiLineManually()));
        leftLayout->addWidget(button2);

        QPushButton *button3 = new QPushButton("create polygon");
        button3->setEnabled(false); // for now
        button3->setSizePolicy(QSizePolicy::Maximum, QSizePolicy::Maximum);
        leftLayout->addWidget(button3);

        QPushButton *button4 = new QPushButton("create polygon cutter");
        button4->setEnabled(false); // for now
        button4->setSizePolicy(QSizePolicy::Maximum, QSizePolicy::Maximum);
        leftLayout->addWidget(button4);

        leftLayout->addStretch();
        topLayout->addLayout(leftLayout);

        QVBoxLayout *rightLayout = new QVBoxLayout;
        canvas_ = new Canvas;
        canvas_->show();
        rightLayout->addWidget(canvas_);
        topLayout->addLayout(rightLayout);

        //---------------------------------------------------------------------------

        QHBoxLayout *layout2 = new QHBoxLayout;

        undoButton_ = new QPushButton("undo");
        undoButton_->setEnabled(false);
        undoButton_->setSizePolicy(QSizePolicy::Maximum, QSizePolicy::Maximum);
        connect(undoButton_, SIGNAL(clicked()), editItemMgr_, SLOT(undo()));
        layout2->addWidget(undoButton_);

        redoButton_ = new QPushButton("redo");
        redoButton_->setEnabled(false);
        redoButton_->setSizePolicy(QSizePolicy::Maximum, QSizePolicy::Maximum);
        connect(redoButton_, SIGNAL(clicked()), editItemMgr_, SLOT(redo()));
        layout2->addWidget(redoButton_);

        layout2->addStretch();

        QUndoView *undoView = new QUndoView(editItemMgr_->undoStack());

        QVBoxLayout *bottomLayout = new QVBoxLayout;
        bottomLayout->addLayout(layout2);
        bottomLayout->addWidget(undoView);

        //---------------------------------------------------------------------------

        QVBoxLayout *mainLayout = new QVBoxLayout;
        //mainLayout->setContentsMargins(0, 0, 0, 0);

        QSplitter *splitter = new QSplitter(Qt::Vertical);

        QWidget *topWidget = new QWidget;
        topWidget->setLayout(topLayout);
        splitter->addWidget(topWidget);

        QWidget *bottomWidget = new QWidget;
        bottomWidget->setLayout(bottomLayout);
        splitter->addWidget(bottomWidget);

        splitter->setSizes(QList<int>() << 600 << 300);

        mainLayout->addWidget(splitter);
        setLayout(mainLayout);

        connect(canvas_, SIGNAL(mousePressed(QMouseEvent *)), editItemMgr, SLOT(mousePress(QMouseEvent *)));
        connect(canvas_, SIGNAL(mouseReleased(QMouseEvent *)), editItemMgr, SLOT(mouseRelease(QMouseEvent *)));
        connect(canvas_, SIGNAL(mouseMoved(QMouseEvent *)), editItemMgr, SLOT(mouseMove(QMouseEvent *)));
        connect(canvas_, SIGNAL(mouseDoubleClicked(QMouseEvent *)), editItemMgr, SLOT(mouseDoubleClick(QMouseEvent *)));
        connect(canvas_, SIGNAL(keyPressed(QKeyEvent *)), editItemMgr, SLOT(keyPress(QKeyEvent *)));
        connect(canvas_, SIGNAL(keyReleased(QKeyEvent *)), editItemMgr, SLOT(keyRelease(QKeyEvent *)));
        connect(canvas_, SIGNAL(paint()), editItemMgr, SLOT(draw()));
        connect(editItemMgr, SIGNAL(paintDone()), canvas_, SLOT(doSwapBuffers()));
        connect(editItemMgr, SIGNAL(repaintNeeded()), canvas_, SLOT(doRepaint()));
        connect(editItemMgr, SIGNAL(canUndoChanged(bool)), this, SLOT(handleCanUndoChanged(bool)));
        connect(editItemMgr, SIGNAL(canRedoChanged(bool)), this, SLOT(handleCanRedoChanged(bool)));
        connect(editItemMgr, SIGNAL(incompleteEditing(bool)), this, SLOT(handleIncompleteEditing(bool)));
    }

private:
    Canvas *canvas_;
    EditItemManager *editItemMgr_;
    QPushButton *undoButton_;
    QPushButton *redoButton_;

private slots:
    void addRectangle()
    {
        editItemMgr_->addItem(new EditItem_Rectangle::Rectangle);
        editItemMgr_->repaint();
    }

    void addRectangleManually()
    {
        editItemMgr_->addItem(new EditItem_Rectangle::Rectangle, true);
        editItemMgr_->repaint();
    }

    void addRectangleManuallyWithResize()
    {
        editItemMgr_->addItem(new EditItem_Rectangle::Rectangle(EditItem_Rectangle::Rectangle::Resize), true);
        editItemMgr_->repaint();
    }

    void addMultiLineManually()
    {
        editItemMgr_->addItem(new EditItem_MultiLine::MultiLine, true);
        editItemMgr_->repaint();
    }

    void handleCanUndoChanged(bool canUndo)
    {
        undoButton_->setEnabled(canUndo);
    }

    void handleCanRedoChanged(bool canRedo)
    {
        redoButton_->setEnabled(canRedo);
    }

    void handleIncompleteEditing(bool incomplete)
    {
        if (incomplete) {
            setCursor(Qt::CrossCursor);
            canvas_->setFocus();
        } else {
            unsetCursor();
        }
    }
};

int main(int argc, char *argv[])
{
    QApplication app(argc, argv);
    Window window(new EditItemManager);
    window.resize(800, 900);
    window.show();
    return app.exec();
}

#include "main.moc"
<commit_msg>Added clipboard demo<commit_after>#include <QtGui>
#include <QtOpenGL>

#include "edititemmanager.h"
#include "rectangle.h"
#include "multiline.h"

class Canvas : public QGLWidget
{
    Q_OBJECT
public:
    Canvas(QWidget *parent = 0)
        : QGLWidget(parent)
        , focus_(false)
    {
        setMouseTracking(true);
        setFocusPolicy(Qt::StrongFocus);
    }

private:
    void initializeGL()
    {
        glEnable(GL_DEPTH_TEST);
    }

    void resizeGL(int w, int h)
    {
        glViewport(0, 0, w, h);
        glMatrixMode(GL_PROJECTION);
        glLoadIdentity();
        glOrtho(0, w, 0, h, -2, 2);
     }

    void paintGL()
    {
        qglClearColor(QColor(204, 204, 204));
        glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
        glMatrixMode(GL_MODELVIEW);
        glLoadIdentity();
        emit paint();
    }

    QMouseEvent flippedYPos(QMouseEvent *event) const
    {
        return QMouseEvent(
            event->type(),
            QPoint(event->pos().x(), height() - event->pos().y()),
            event->globalPos(),
            event->button(),
            event->buttons(),
            event->modifiers()
            );
    }

    void mousePressEvent(QMouseEvent *event)
    {
        QMouseEvent fe = flippedYPos(event);
        emit mousePressed(&fe);
    }

    void mouseReleaseEvent(QMouseEvent *event)
    {
        QMouseEvent fe = flippedYPos(event);
        emit mouseReleased(&fe);
    }

    void mouseMoveEvent(QMouseEvent *event)
    {
        QMouseEvent fe = flippedYPos(event);
        emit mouseMoved(&fe);
    }

    void mouseDoubleClickEvent(QMouseEvent *event)
    {
        QMouseEvent fe = flippedYPos(event);
        emit mouseDoubleClicked(&fe);
    }

    void keyPressEvent(QKeyEvent *event) { emit keyPressed(event); }

    void keyReleaseEvent(QKeyEvent *event) { emit keyReleased(event); }

    void focusInEvent(QFocusEvent *)
    {
        focus_ = true;
        update();
    }

    void focusOutEvent(QFocusEvent *)
    {
        focus_ = false;
        update();
    }

    bool focus_;

signals:
    void mousePressed(QMouseEvent *);
    void mouseReleased(QMouseEvent *);
    void mouseMoved(QMouseEvent *);
    void mouseDoubleClicked(QMouseEvent *);
    void keyPressed(QKeyEvent *);
    void keyReleased(QKeyEvent *);
    void paint();

public slots:
    void doSwapBuffers()
    {
        if (focus_) {
            glColor3ub(0, 128, 0);
            renderText(2, height() - 2, "keyboard focus");
        } else {
            glColor3ub(255, 0, 0);
            renderText(2, height() - 2, "no keyboard focus");
        }

        swapBuffers();
    }

    void doRepaint() { update(); }
};

class Window : public QWidget
{
    Q_OBJECT
public:
    Window(EditItemManager *editItemMgr)
        : editItemMgr_(editItemMgr)
    {
        QHBoxLayout *topLayout = new QHBoxLayout;

        QVBoxLayout *leftLayout = new QVBoxLayout;

        QPushButton *button1 = new QPushButton("create rectangle\n(automatic placement)");
        button1->setSizePolicy(QSizePolicy::Maximum, QSizePolicy::Maximum);
        connect(button1, SIGNAL(clicked()), this, SLOT(addRectangle()));
        leftLayout->addWidget(button1);

        QPushButton *button1_2 = new QPushButton("create rectangle\n(manual placement)");
        button1_2->setSizePolicy(QSizePolicy::Maximum, QSizePolicy::Maximum);
        connect(button1_2, SIGNAL(clicked()), this, SLOT(addRectangleManually()));
        leftLayout->addWidget(button1_2);

        QPushButton *button1_3 = new QPushButton("create rectangle\n(manual placement w/resize)");
        button1_3->setSizePolicy(QSizePolicy::Maximum, QSizePolicy::Maximum);
        connect(button1_3, SIGNAL(clicked()), this, SLOT(addRectangleManuallyWithResize()));
        leftLayout->addWidget(button1_3);

        QPushButton *button2 = new QPushButton("create multiline\n(manual placement)");
        button2->setSizePolicy(QSizePolicy::Maximum, QSizePolicy::Maximum);
        connect(button2, SIGNAL(clicked()), this, SLOT(addMultiLineManually()));
        leftLayout->addWidget(button2);

        QPushButton *button3 = new QPushButton("create polygon");
        button3->setEnabled(false); // for now
        button3->setSizePolicy(QSizePolicy::Maximum, QSizePolicy::Maximum);
        leftLayout->addWidget(button3);

        QPushButton *button4 = new QPushButton("create polygon cutter");
        button4->setEnabled(false); // for now
        button4->setSizePolicy(QSizePolicy::Maximum, QSizePolicy::Maximum);
        leftLayout->addWidget(button4);

        QLabel *cblabel = new QLabel("CLIPBOARD DEMO");
        cblabel->setStyleSheet("QLabel { background-color : yellow }");
        cblabel->setSizePolicy(QSizePolicy::Maximum, QSizePolicy::Maximum);
        leftLayout->addWidget(cblabel);

        cbTextEdit_ = new QTextEdit;
        cbTextEdit_->setSizePolicy(QSizePolicy::Maximum, QSizePolicy::Maximum);
        leftLayout->addWidget(cbTextEdit_);

        QPushButton *button5 = new QPushButton("copy to clipboard");
        button5->setSizePolicy(QSizePolicy::Maximum, QSizePolicy::Maximum);
        connect(button5, SIGNAL(clicked()), this, SLOT(copyToClipboard()));
        leftLayout->addWidget(button5);

        QPushButton *button6 = new QPushButton("paste from clipboard");
        button6->setSizePolicy(QSizePolicy::Maximum, QSizePolicy::Maximum);
        connect(button6, SIGNAL(clicked()), this, SLOT(pasteFromClipboard()));
        leftLayout->addWidget(button6);

        leftLayout->addStretch();
        topLayout->addLayout(leftLayout);

        QVBoxLayout *rightLayout = new QVBoxLayout;
        canvas_ = new Canvas;
        canvas_->show();
        rightLayout->addWidget(canvas_);
        topLayout->addLayout(rightLayout);

        //---------------------------------------------------------------------------

        QHBoxLayout *layout2 = new QHBoxLayout;

        undoButton_ = new QPushButton("undo");
        undoButton_->setEnabled(false);
        undoButton_->setSizePolicy(QSizePolicy::Maximum, QSizePolicy::Maximum);
        connect(undoButton_, SIGNAL(clicked()), editItemMgr_, SLOT(undo()));
        layout2->addWidget(undoButton_);

        redoButton_ = new QPushButton("redo");
        redoButton_->setEnabled(false);
        redoButton_->setSizePolicy(QSizePolicy::Maximum, QSizePolicy::Maximum);
        connect(redoButton_, SIGNAL(clicked()), editItemMgr_, SLOT(redo()));
        layout2->addWidget(redoButton_);

        layout2->addStretch();

        QUndoView *undoView = new QUndoView(editItemMgr_->undoStack());

        QVBoxLayout *bottomLayout = new QVBoxLayout;
        bottomLayout->addLayout(layout2);
        bottomLayout->addWidget(undoView);

        //---------------------------------------------------------------------------

        QVBoxLayout *mainLayout = new QVBoxLayout;
        //mainLayout->setContentsMargins(0, 0, 0, 0);

        QSplitter *splitter = new QSplitter(Qt::Vertical);

        QWidget *topWidget = new QWidget;
        topWidget->setLayout(topLayout);
        splitter->addWidget(topWidget);

        QWidget *bottomWidget = new QWidget;
        bottomWidget->setLayout(bottomLayout);
        splitter->addWidget(bottomWidget);

        splitter->setSizes(QList<int>() << 600 << 300);

        mainLayout->addWidget(splitter);
        setLayout(mainLayout);

        connect(canvas_, SIGNAL(mousePressed(QMouseEvent *)), editItemMgr, SLOT(mousePress(QMouseEvent *)));
        connect(canvas_, SIGNAL(mouseReleased(QMouseEvent *)), editItemMgr, SLOT(mouseRelease(QMouseEvent *)));
        connect(canvas_, SIGNAL(mouseMoved(QMouseEvent *)), editItemMgr, SLOT(mouseMove(QMouseEvent *)));
        connect(canvas_, SIGNAL(mouseDoubleClicked(QMouseEvent *)), editItemMgr, SLOT(mouseDoubleClick(QMouseEvent *)));
        connect(canvas_, SIGNAL(keyPressed(QKeyEvent *)), editItemMgr, SLOT(keyPress(QKeyEvent *)));
        connect(canvas_, SIGNAL(keyReleased(QKeyEvent *)), editItemMgr, SLOT(keyRelease(QKeyEvent *)));
        connect(canvas_, SIGNAL(paint()), editItemMgr, SLOT(draw()));
        connect(editItemMgr, SIGNAL(paintDone()), canvas_, SLOT(doSwapBuffers()));
        connect(editItemMgr, SIGNAL(repaintNeeded()), canvas_, SLOT(doRepaint()));
        connect(editItemMgr, SIGNAL(canUndoChanged(bool)), this, SLOT(handleCanUndoChanged(bool)));
        connect(editItemMgr, SIGNAL(canRedoChanged(bool)), this, SLOT(handleCanRedoChanged(bool)));
        connect(editItemMgr, SIGNAL(incompleteEditing(bool)), this, SLOT(handleIncompleteEditing(bool)));
    }

private:
    Canvas *canvas_;
    EditItemManager *editItemMgr_;
    QPushButton *undoButton_;
    QPushButton *redoButton_;
    QTextEdit *cbTextEdit_;

private slots:
    void addRectangle()
    {
        editItemMgr_->addItem(new EditItem_Rectangle::Rectangle);
        editItemMgr_->repaint();
    }

    void addRectangleManually()
    {
        editItemMgr_->addItem(new EditItem_Rectangle::Rectangle, true);
        editItemMgr_->repaint();
    }

    void addRectangleManuallyWithResize()
    {
        editItemMgr_->addItem(new EditItem_Rectangle::Rectangle(EditItem_Rectangle::Rectangle::Resize), true);
        editItemMgr_->repaint();
    }

    void addMultiLineManually()
    {
        editItemMgr_->addItem(new EditItem_MultiLine::MultiLine, true);
        editItemMgr_->repaint();
    }

    void copyToClipboard()
    {
        QClipboard *clipboard = QApplication::clipboard();
        clipboard->setText(cbTextEdit_->toPlainText());
    }

    void pasteFromClipboard()
    {
        const QClipboard *clipboard = QApplication::clipboard();
        const QMimeData *mimeData = clipboard->mimeData();

        if (mimeData->hasImage()) {
            qDebug() << "mimeData->hasImage() ...";
            const QPixmap pixmap = qvariant_cast<QPixmap>(mimeData->imageData());
        } else if (mimeData->hasHtml()) {
            qDebug() << "mimeData->hasHtml() ...";
            const QString html = mimeData->html();
            qDebug() << "   html:" << html;
        } else if (mimeData->hasText()) {
            cbTextEdit_->setPlainText(mimeData->text());
        } else {
            qDebug() << "supported formats:" << mimeData->formats();
        }
    }
    void handleCanUndoChanged(bool canUndo)
    {
        undoButton_->setEnabled(canUndo);
    }

    void handleCanRedoChanged(bool canRedo)
    {
        redoButton_->setEnabled(canRedo);
    }

    void handleIncompleteEditing(bool incomplete)
    {
        if (incomplete) {
            setCursor(Qt::CrossCursor);
            canvas_->setFocus();
        } else {
            unsetCursor();
        }
    }
};

int main(int argc, char *argv[])
{
    QApplication app(argc, argv);
    Window window(new EditItemManager);
    window.resize(800, 900);
    window.show();
    return app.exec();
}

#include "main.moc"
<|endoftext|>


<commit_before>// Copyright (c) 2010 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include "base/environment.h"
#include "base/basictypes.h"
#include "base/logging.h"
#include "base/task.h"
#include "base/synchronization/waitable_event.h"
#include "media/audio/audio_output_controller.h"
#include "testing/gmock/include/gmock/gmock.h"
#include "testing/gtest/include/gtest/gtest.h"

using ::testing::_;
using ::testing::AtLeast;
using ::testing::Exactly;
using ::testing::InvokeWithoutArgs;
using ::testing::NotNull;
using ::testing::Return;

static const int kSampleRate = AudioParameters::kAudioCDSampleRate;
static const int kBitsPerSample = 16;
static const int kChannels = 2;
static const int kSamplesPerPacket = kSampleRate / 10;
static const int kHardwareBufferSize = kSamplesPerPacket * kChannels *
    kBitsPerSample / 8;
static const int kBufferCapacity = 3 * kHardwareBufferSize;

namespace media {

class MockAudioOutputControllerEventHandler
    : public AudioOutputController::EventHandler {
 public:
  MockAudioOutputControllerEventHandler() {}

  MOCK_METHOD1(OnCreated, void(AudioOutputController* controller));
  MOCK_METHOD1(OnPlaying, void(AudioOutputController* controller));
  MOCK_METHOD1(OnPaused, void(AudioOutputController* controller));
  MOCK_METHOD2(OnError, void(AudioOutputController* controller,
                             int error_code));
  MOCK_METHOD2(OnMoreData, void(AudioOutputController* controller,
                                AudioBuffersState buffers_state));

 private:
  DISALLOW_COPY_AND_ASSIGN(MockAudioOutputControllerEventHandler);
};

class MockAudioOutputControllerSyncReader
    : public AudioOutputController::SyncReader {
 public:
  MockAudioOutputControllerSyncReader() {}

  MOCK_METHOD1(UpdatePendingBytes, void(uint32 bytes));
  MOCK_METHOD2(Read, uint32(void* data, uint32 size));
  MOCK_METHOD0(Close, void());

 private:
  DISALLOW_COPY_AND_ASSIGN(MockAudioOutputControllerSyncReader);
};

static bool HasAudioOutputDevices() {
  AudioManager* audio_man = AudioManager::GetAudioManager();
  CHECK(audio_man);
  return audio_man->HasAudioOutputDevices();
}

static bool IsRunningHeadless() {
  scoped_ptr<base::Environment> env(base::Environment::Create());
  if (env->HasVar("CHROME_HEADLESS"))
    return true;
  return false;
}

ACTION_P(SignalEvent, event) {
  event->Signal();
}

// Helper functions used to close audio controller.
static void SignalClosedEvent(base::WaitableEvent* event) {
  event->Signal();
}

// Closes AudioOutputController synchronously.
static void CloseAudioController(AudioOutputController* controller) {
  base::WaitableEvent closed_event(true, false);
  controller->Close(NewRunnableFunction(&SignalClosedEvent, &closed_event));
  closed_event.Wait();
}

TEST(AudioOutputControllerTest, CreateAndClose) {
  if (!HasAudioOutputDevices() || IsRunningHeadless())
    return;

  MockAudioOutputControllerEventHandler event_handler;

  EXPECT_CALL(event_handler, OnCreated(NotNull()))
      .Times(1);
  EXPECT_CALL(event_handler, OnMoreData(NotNull(), _));

  AudioParameters params(AudioParameters::AUDIO_PCM_LINEAR, kChannels,
                         kSampleRate, kBitsPerSample, kSamplesPerPacket);
  scoped_refptr<AudioOutputController> controller =
      AudioOutputController::Create(&event_handler, params, kBufferCapacity);
  ASSERT_TRUE(controller.get());

  // Close the controller immediately.
  CloseAudioController(controller);
}

TEST(AudioOutputControllerTest, PlayAndClose) {
  if (!HasAudioOutputDevices() || IsRunningHeadless())
    return;

  MockAudioOutputControllerEventHandler event_handler;
  base::WaitableEvent event(false, false);

  // If OnCreated is called then signal the event.
  EXPECT_CALL(event_handler, OnCreated(NotNull()))
      .WillOnce(SignalEvent(&event));

  // OnPlaying() will be called only once.
  EXPECT_CALL(event_handler, OnPlaying(NotNull()))
      .Times(Exactly(1));

  // If OnMoreData is called enough then signal the event.
  EXPECT_CALL(event_handler, OnMoreData(NotNull(), _))
      .Times(AtLeast(10))
      .WillRepeatedly(SignalEvent(&event));

  AudioParameters params(AudioParameters::AUDIO_PCM_LINEAR, kChannels,
                         kSampleRate, kBitsPerSample, kSamplesPerPacket);
  scoped_refptr<AudioOutputController> controller =
      AudioOutputController::Create(&event_handler, params, kBufferCapacity);
  ASSERT_TRUE(controller.get());

  // Wait for OnCreated() to be called.
  event.Wait();

  controller->Play();

  // Wait until the date is requested at least 10 times.
  for (int i = 0; i < 10; i++) {
    event.Wait();
    uint8 buf[1];
    controller->EnqueueData(buf, 0);
  }

  // Now stop the controller.
  CloseAudioController(controller);
}

TEST(AudioOutputControllerTest, PlayPauseClose) {
  if (!HasAudioOutputDevices() || IsRunningHeadless())
    return;

  MockAudioOutputControllerEventHandler event_handler;
  base::WaitableEvent event(false, false);
  base::WaitableEvent pause_event(false, false);

  // If OnCreated is called then signal the event.
  EXPECT_CALL(event_handler, OnCreated(NotNull()))
      .Times(Exactly(1))
      .WillOnce(InvokeWithoutArgs(&event, &base::WaitableEvent::Signal));

  // OnPlaying() will be called only once.
  EXPECT_CALL(event_handler, OnPlaying(NotNull()))
      .Times(Exactly(1));

  // If OnMoreData is called enough then signal the event.
  EXPECT_CALL(event_handler, OnMoreData(NotNull(), _))
      .Times(AtLeast(10))
      .WillRepeatedly(SignalEvent(&event));

  // And then OnPaused() will be called.
  EXPECT_CALL(event_handler, OnPaused(NotNull()))
      .Times(Exactly(1))
      .WillOnce(InvokeWithoutArgs(&pause_event, &base::WaitableEvent::Signal));

  AudioParameters params(AudioParameters::AUDIO_PCM_LINEAR, kChannels,
                         kSampleRate, kBitsPerSample, kSamplesPerPacket);
  scoped_refptr<AudioOutputController> controller =
      AudioOutputController::Create(&event_handler, params, kBufferCapacity);
  ASSERT_TRUE(controller.get());

  // Wait for OnCreated() to be called.
  event.Wait();

  controller->Play();

  // Wait until the date is requested at least 10 times.
  for (int i = 0; i < 10; i++) {
    event.Wait();
    uint8 buf[1];
    controller->EnqueueData(buf, 0);
  }

  // And then wait for pause to complete.
  ASSERT_FALSE(pause_event.IsSignaled());
  controller->Pause();
  pause_event.Wait();

  // Now stop the controller.
  CloseAudioController(controller);
}

TEST(AudioOutputControllerTest, PlayPausePlay) {
  if (!HasAudioOutputDevices() || IsRunningHeadless())
    return;

  MockAudioOutputControllerEventHandler event_handler;
  base::WaitableEvent event(false, false);
  base::WaitableEvent pause_event(false, false);

  // If OnCreated is called then signal the event.
  EXPECT_CALL(event_handler, OnCreated(NotNull()))
      .Times(Exactly(1))
      .WillOnce(InvokeWithoutArgs(&event, &base::WaitableEvent::Signal));

  // OnPlaying() will be called only once.
  EXPECT_CALL(event_handler, OnPlaying(NotNull()))
      .Times(Exactly(1))
      .RetiresOnSaturation();

  // If OnMoreData() is called enough then signal the event.
  EXPECT_CALL(event_handler, OnMoreData(NotNull(), _))
      .Times(AtLeast(1))
      .WillRepeatedly(SignalEvent(&event));

  // And then OnPaused() will be called.
  EXPECT_CALL(event_handler, OnPaused(NotNull()))
      .Times(Exactly(1))
      .WillOnce(InvokeWithoutArgs(&pause_event, &base::WaitableEvent::Signal));

  // OnPlaying() will be called only once.
  EXPECT_CALL(event_handler, OnPlaying(NotNull()))
    .Times(Exactly(1))
    .RetiresOnSaturation();

  AudioParameters params(AudioParameters::AUDIO_PCM_LINEAR, kChannels,
                         kSampleRate, kBitsPerSample, kSamplesPerPacket);
  scoped_refptr<AudioOutputController> controller =
      AudioOutputController::Create(&event_handler, params, kBufferCapacity);
  ASSERT_TRUE(controller.get());

  // Wait for OnCreated() to be called.
  event.Wait();

  controller->Play();

  // Wait until the date is requested at least 10 times.
  for (int i = 0; i < 10; i++) {
    event.Wait();
    uint8 buf[1];
    controller->EnqueueData(buf, 0);
  }

  // And then wait for pause to complete.
  ASSERT_FALSE(pause_event.IsSignaled());
  controller->Pause();
  pause_event.Wait();

  // Then we play again.
  controller->Play();

  // Wait until the date is requested at least 10 times.
  for (int i = 0; i < 10; i++) {
    event.Wait();
    uint8 buf[1];
    controller->EnqueueData(buf, 0);
  }

  // Now stop the controller.
  CloseAudioController(controller);
}

TEST(AudioOutputControllerTest, HardwareBufferTooLarge) {
  if (!HasAudioOutputDevices() || IsRunningHeadless())
    return;

  // Create an audio device with a very large hardware buffer size.
  MockAudioOutputControllerEventHandler event_handler;
  AudioParameters params(AudioParameters::AUDIO_PCM_LINEAR, kChannels,
                         kSampleRate, kBitsPerSample,
                         kSamplesPerPacket * 1000);
  scoped_refptr<AudioOutputController> controller =
      AudioOutputController::Create(&event_handler, params,
                                    kBufferCapacity);

  // Use assert because we don't stop the device and assume we can't
  // create one.
  ASSERT_FALSE(controller);
}

TEST(AudioOutputControllerTest, CloseTwice) {
  if (!HasAudioOutputDevices() || IsRunningHeadless())
    return;

  MockAudioOutputControllerEventHandler event_handler;
  base::WaitableEvent event(false, false);

  // If OnCreated is called then signal the event.
  EXPECT_CALL(event_handler, OnCreated(NotNull()))
      .WillOnce(SignalEvent(&event));

  // One OnMoreData() is expected.
  EXPECT_CALL(event_handler, OnMoreData(NotNull(), _))
      .Times(AtLeast(1))
      .WillRepeatedly(SignalEvent(&event));

  AudioParameters params(AudioParameters::AUDIO_PCM_LINEAR, kChannels,
                         kSampleRate, kBitsPerSample, kSamplesPerPacket);
  scoped_refptr<AudioOutputController> controller =
      AudioOutputController::Create(&event_handler, params, kBufferCapacity);
  ASSERT_TRUE(controller.get());

  // Wait for OnCreated() to be called.
  event.Wait();

  // Wait for OnMoreData() to be called.
  event.Wait();

  base::WaitableEvent closed_event_1(true, false);
  controller->Close(NewRunnableFunction(&SignalClosedEvent, &closed_event_1));

  base::WaitableEvent closed_event_2(true, false);
  controller->Close(NewRunnableFunction(&SignalClosedEvent, &closed_event_2));

  closed_event_1.Wait();
  closed_event_2.Wait();
}

}  // namespace media
<commit_msg>Disable AudioOutputControllerTest.CreateAndClose since it crashes on Windows in release.<commit_after>// Copyright (c) 2010 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include "base/environment.h"
#include "base/basictypes.h"
#include "base/logging.h"
#include "base/task.h"
#include "base/synchronization/waitable_event.h"
#include "media/audio/audio_output_controller.h"
#include "testing/gmock/include/gmock/gmock.h"
#include "testing/gtest/include/gtest/gtest.h"

using ::testing::_;
using ::testing::AtLeast;
using ::testing::Exactly;
using ::testing::InvokeWithoutArgs;
using ::testing::NotNull;
using ::testing::Return;

static const int kSampleRate = AudioParameters::kAudioCDSampleRate;
static const int kBitsPerSample = 16;
static const int kChannels = 2;
static const int kSamplesPerPacket = kSampleRate / 10;
static const int kHardwareBufferSize = kSamplesPerPacket * kChannels *
    kBitsPerSample / 8;
static const int kBufferCapacity = 3 * kHardwareBufferSize;

namespace media {

class MockAudioOutputControllerEventHandler
    : public AudioOutputController::EventHandler {
 public:
  MockAudioOutputControllerEventHandler() {}

  MOCK_METHOD1(OnCreated, void(AudioOutputController* controller));
  MOCK_METHOD1(OnPlaying, void(AudioOutputController* controller));
  MOCK_METHOD1(OnPaused, void(AudioOutputController* controller));
  MOCK_METHOD2(OnError, void(AudioOutputController* controller,
                             int error_code));
  MOCK_METHOD2(OnMoreData, void(AudioOutputController* controller,
                                AudioBuffersState buffers_state));

 private:
  DISALLOW_COPY_AND_ASSIGN(MockAudioOutputControllerEventHandler);
};

class MockAudioOutputControllerSyncReader
    : public AudioOutputController::SyncReader {
 public:
  MockAudioOutputControllerSyncReader() {}

  MOCK_METHOD1(UpdatePendingBytes, void(uint32 bytes));
  MOCK_METHOD2(Read, uint32(void* data, uint32 size));
  MOCK_METHOD0(Close, void());

 private:
  DISALLOW_COPY_AND_ASSIGN(MockAudioOutputControllerSyncReader);
};

static bool HasAudioOutputDevices() {
  AudioManager* audio_man = AudioManager::GetAudioManager();
  CHECK(audio_man);
  return audio_man->HasAudioOutputDevices();
}

static bool IsRunningHeadless() {
  scoped_ptr<base::Environment> env(base::Environment::Create());
  if (env->HasVar("CHROME_HEADLESS"))
    return true;
  return false;
}

ACTION_P(SignalEvent, event) {
  event->Signal();
}

// Helper functions used to close audio controller.
static void SignalClosedEvent(base::WaitableEvent* event) {
  event->Signal();
}

// Closes AudioOutputController synchronously.
static void CloseAudioController(AudioOutputController* controller) {
  base::WaitableEvent closed_event(true, false);
  controller->Close(NewRunnableFunction(&SignalClosedEvent, &closed_event));
  closed_event.Wait();
}

// This test fails in Release on Windows.
// http://crbug.com/72718
#if defined(OS_WIN) && defined(NDEBUG)
#define CreateAndClose DISABLED_CreateAndClose
#endif
TEST(AudioOutputControllerTest, CreateAndClose) {
  if (!HasAudioOutputDevices() || IsRunningHeadless())
    return;

  MockAudioOutputControllerEventHandler event_handler;

  EXPECT_CALL(event_handler, OnCreated(NotNull()))
      .Times(1);
  EXPECT_CALL(event_handler, OnMoreData(NotNull(), _));

  AudioParameters params(AudioParameters::AUDIO_PCM_LINEAR, kChannels,
                         kSampleRate, kBitsPerSample, kSamplesPerPacket);
  scoped_refptr<AudioOutputController> controller =
      AudioOutputController::Create(&event_handler, params, kBufferCapacity);
  ASSERT_TRUE(controller.get());

  // Close the controller immediately.
  CloseAudioController(controller);
}

TEST(AudioOutputControllerTest, PlayAndClose) {
  if (!HasAudioOutputDevices() || IsRunningHeadless())
    return;

  MockAudioOutputControllerEventHandler event_handler;
  base::WaitableEvent event(false, false);

  // If OnCreated is called then signal the event.
  EXPECT_CALL(event_handler, OnCreated(NotNull()))
      .WillOnce(SignalEvent(&event));

  // OnPlaying() will be called only once.
  EXPECT_CALL(event_handler, OnPlaying(NotNull()))
      .Times(Exactly(1));

  // If OnMoreData is called enough then signal the event.
  EXPECT_CALL(event_handler, OnMoreData(NotNull(), _))
      .Times(AtLeast(10))
      .WillRepeatedly(SignalEvent(&event));

  AudioParameters params(AudioParameters::AUDIO_PCM_LINEAR, kChannels,
                         kSampleRate, kBitsPerSample, kSamplesPerPacket);
  scoped_refptr<AudioOutputController> controller =
      AudioOutputController::Create(&event_handler, params, kBufferCapacity);
  ASSERT_TRUE(controller.get());

  // Wait for OnCreated() to be called.
  event.Wait();

  controller->Play();

  // Wait until the date is requested at least 10 times.
  for (int i = 0; i < 10; i++) {
    event.Wait();
    uint8 buf[1];
    controller->EnqueueData(buf, 0);
  }

  // Now stop the controller.
  CloseAudioController(controller);
}

TEST(AudioOutputControllerTest, PlayPauseClose) {
  if (!HasAudioOutputDevices() || IsRunningHeadless())
    return;

  MockAudioOutputControllerEventHandler event_handler;
  base::WaitableEvent event(false, false);
  base::WaitableEvent pause_event(false, false);

  // If OnCreated is called then signal the event.
  EXPECT_CALL(event_handler, OnCreated(NotNull()))
      .Times(Exactly(1))
      .WillOnce(InvokeWithoutArgs(&event, &base::WaitableEvent::Signal));

  // OnPlaying() will be called only once.
  EXPECT_CALL(event_handler, OnPlaying(NotNull()))
      .Times(Exactly(1));

  // If OnMoreData is called enough then signal the event.
  EXPECT_CALL(event_handler, OnMoreData(NotNull(), _))
      .Times(AtLeast(10))
      .WillRepeatedly(SignalEvent(&event));

  // And then OnPaused() will be called.
  EXPECT_CALL(event_handler, OnPaused(NotNull()))
      .Times(Exactly(1))
      .WillOnce(InvokeWithoutArgs(&pause_event, &base::WaitableEvent::Signal));

  AudioParameters params(AudioParameters::AUDIO_PCM_LINEAR, kChannels,
                         kSampleRate, kBitsPerSample, kSamplesPerPacket);
  scoped_refptr<AudioOutputController> controller =
      AudioOutputController::Create(&event_handler, params, kBufferCapacity);
  ASSERT_TRUE(controller.get());

  // Wait for OnCreated() to be called.
  event.Wait();

  controller->Play();

  // Wait until the date is requested at least 10 times.
  for (int i = 0; i < 10; i++) {
    event.Wait();
    uint8 buf[1];
    controller->EnqueueData(buf, 0);
  }

  // And then wait for pause to complete.
  ASSERT_FALSE(pause_event.IsSignaled());
  controller->Pause();
  pause_event.Wait();

  // Now stop the controller.
  CloseAudioController(controller);
}

TEST(AudioOutputControllerTest, PlayPausePlay) {
  if (!HasAudioOutputDevices() || IsRunningHeadless())
    return;

  MockAudioOutputControllerEventHandler event_handler;
  base::WaitableEvent event(false, false);
  base::WaitableEvent pause_event(false, false);

  // If OnCreated is called then signal the event.
  EXPECT_CALL(event_handler, OnCreated(NotNull()))
      .Times(Exactly(1))
      .WillOnce(InvokeWithoutArgs(&event, &base::WaitableEvent::Signal));

  // OnPlaying() will be called only once.
  EXPECT_CALL(event_handler, OnPlaying(NotNull()))
      .Times(Exactly(1))
      .RetiresOnSaturation();

  // If OnMoreData() is called enough then signal the event.
  EXPECT_CALL(event_handler, OnMoreData(NotNull(), _))
      .Times(AtLeast(1))
      .WillRepeatedly(SignalEvent(&event));

  // And then OnPaused() will be called.
  EXPECT_CALL(event_handler, OnPaused(NotNull()))
      .Times(Exactly(1))
      .WillOnce(InvokeWithoutArgs(&pause_event, &base::WaitableEvent::Signal));

  // OnPlaying() will be called only once.
  EXPECT_CALL(event_handler, OnPlaying(NotNull()))
    .Times(Exactly(1))
    .RetiresOnSaturation();

  AudioParameters params(AudioParameters::AUDIO_PCM_LINEAR, kChannels,
                         kSampleRate, kBitsPerSample, kSamplesPerPacket);
  scoped_refptr<AudioOutputController> controller =
      AudioOutputController::Create(&event_handler, params, kBufferCapacity);
  ASSERT_TRUE(controller.get());

  // Wait for OnCreated() to be called.
  event.Wait();

  controller->Play();

  // Wait until the date is requested at least 10 times.
  for (int i = 0; i < 10; i++) {
    event.Wait();
    uint8 buf[1];
    controller->EnqueueData(buf, 0);
  }

  // And then wait for pause to complete.
  ASSERT_FALSE(pause_event.IsSignaled());
  controller->Pause();
  pause_event.Wait();

  // Then we play again.
  controller->Play();

  // Wait until the date is requested at least 10 times.
  for (int i = 0; i < 10; i++) {
    event.Wait();
    uint8 buf[1];
    controller->EnqueueData(buf, 0);
  }

  // Now stop the controller.
  CloseAudioController(controller);
}

TEST(AudioOutputControllerTest, HardwareBufferTooLarge) {
  if (!HasAudioOutputDevices() || IsRunningHeadless())
    return;

  // Create an audio device with a very large hardware buffer size.
  MockAudioOutputControllerEventHandler event_handler;
  AudioParameters params(AudioParameters::AUDIO_PCM_LINEAR, kChannels,
                         kSampleRate, kBitsPerSample,
                         kSamplesPerPacket * 1000);
  scoped_refptr<AudioOutputController> controller =
      AudioOutputController::Create(&event_handler, params,
                                    kBufferCapacity);

  // Use assert because we don't stop the device and assume we can't
  // create one.
  ASSERT_FALSE(controller);
}

TEST(AudioOutputControllerTest, CloseTwice) {
  if (!HasAudioOutputDevices() || IsRunningHeadless())
    return;

  MockAudioOutputControllerEventHandler event_handler;
  base::WaitableEvent event(false, false);

  // If OnCreated is called then signal the event.
  EXPECT_CALL(event_handler, OnCreated(NotNull()))
      .WillOnce(SignalEvent(&event));

  // One OnMoreData() is expected.
  EXPECT_CALL(event_handler, OnMoreData(NotNull(), _))
      .Times(AtLeast(1))
      .WillRepeatedly(SignalEvent(&event));

  AudioParameters params(AudioParameters::AUDIO_PCM_LINEAR, kChannels,
                         kSampleRate, kBitsPerSample, kSamplesPerPacket);
  scoped_refptr<AudioOutputController> controller =
      AudioOutputController::Create(&event_handler, params, kBufferCapacity);
  ASSERT_TRUE(controller.get());

  // Wait for OnCreated() to be called.
  event.Wait();

  // Wait for OnMoreData() to be called.
  event.Wait();

  base::WaitableEvent closed_event_1(true, false);
  controller->Close(NewRunnableFunction(&SignalClosedEvent, &closed_event_1));

  base::WaitableEvent closed_event_2(true, false);
  controller->Close(NewRunnableFunction(&SignalClosedEvent, &closed_event_2));

  closed_event_1.Wait();
  closed_event_2.Wait();
}

}  // namespace media
<|endoftext|>


<commit_before>// Copyright (c) Microsoft Corporation. All rights reserved.
// Licensed under the MIT License.

#include "gtest/gtest.h"
#include "test/common/cuda_op_test_utils.h"
#include "test/common/quantization_test_utils.h"
#include "test/providers/provider_test_utils.h"

#include "core/common/common.h"
#include "core/common/safeint.h"
#include "core/framework/op_kernel.h"
#include "core/quantization/quantization.h"
#include "core/util/math_cpuonly.h"
#include "core/util/qmath.h"

#include <algorithm>
#include <random>
#include <type_traits>

namespace onnxruntime {
namespace test {

template <typename ActType, typename WeightType, typename ScalarOutput>
void RunQuantGemmU8X8Test(const int M,
                          const int N,
                          const int K,
                          bool is_A_trans,
                          bool is_B_trans,
                          bool has_C,
                          bool B_is_initializer,
                          bool per_column = false) {
  static std::default_random_engine e(123);
  static std::uniform_int_distribution<int> random_A(std::numeric_limits<ActType>::min(),
                                                     std::numeric_limits<ActType>::max());

  constexpr int overflow_adjust = std::is_signed_v<WeightType> ? 2 : 1;
  constexpr int random_B_min = std::numeric_limits<WeightType>::min() / overflow_adjust;
  constexpr int random_B_max = std::numeric_limits<WeightType>::min() / overflow_adjust;
  static std::uniform_int_distribution<int> random_B(random_B_min,
                                                     random_B_max);
  static std::uniform_real_distribution<float> n_apha(1.0f, 2.0f);
  static std::uniform_real_distribution<float> n_scale(0.003f, 0.004f);

  Eigen::MatrixXi matrix_a = Eigen::MatrixXi::Random(K, M)
                                 .unaryExpr([](int) { return random_A(e); });
  std::vector<ActType> matrix_a_data;
  if (is_A_trans) {
    Eigen::MatrixXi matrix_a_trans = matrix_a.transpose().eval();
    matrix_a_data = ToVector<ActType>(matrix_a_trans.data(), M * K);
  } else {
    matrix_a_data = ToVector<ActType>(matrix_a.data(), M * K);
  }
  ActType a_zero_point = GetMiddle(matrix_a_data);
  Eigen::MatrixXi matrix_a_offset = matrix_a - a_zero_point * Eigen::MatrixXi::Ones(K, M);
  float a_scale = n_scale(e);

  Eigen::MatrixXi matrix_b = Eigen::MatrixXi::Random(N, K)
                                 .unaryExpr([](int) { return random_B(e); });
  std::vector<WeightType> matrix_b_data;
  if (is_B_trans) {
    Eigen::MatrixXi matrix_b_trans = matrix_b.transpose().eval();
    matrix_b_data = ToVector<WeightType>(matrix_b_trans.data(), N * K);
  } else {
    matrix_b_data = ToVector<WeightType>(matrix_b.data(), N * K);
  }
  WeightType b_zero_point = GetMiddle(matrix_b_data);
  std::vector<float> b_scale({n_scale(e)});
  std::vector<WeightType> b_zp_per_column({b_zero_point});
  Eigen::MatrixXi b_zp_matrix = b_zero_point * Eigen::MatrixXi::Ones(N, K);
  Eigen::MatrixXf b_scale_matrix = b_scale[0] * Eigen::MatrixXf::Ones(N, M);
  if (per_column) {
    b_zp_per_column.resize(N);
    b_scale.resize(N);
    for (int i = 0; i < N; i++) {
      b_zp_per_column[i] = b_zero_point + i % 2 == 0 ? 1 : -1;
      b_zp_matrix.row(i).setConstant(b_zp_per_column[i]);
      b_scale[i] = n_scale(e);
      b_scale_matrix.row(i).setConstant(b_scale[i]);
    }
  }
  float alpha = n_apha(e);

  Eigen::MatrixXi matrix_c = Eigen::MatrixXi::Random(N, M)
                                 .unaryExpr([](int) { return random_A(e); });

  Eigen::MatrixXi matrix_int32 = (matrix_b - b_zp_matrix) * matrix_a_offset;
  if (has_C) {
    matrix_int32 = matrix_int32 + matrix_c;
  }
  Eigen::MatrixXf matrix_output = alpha * a_scale * (b_scale_matrix.cwiseProduct((matrix_int32.eval().cast<float>())));

  OpTester test("QGemm", 1, onnxruntime::kMSDomain);
  test.AddAttribute<int64_t>("transA", is_A_trans ? 1 : 0);
  test.AddAttribute<int64_t>("transB", is_B_trans ? 1 : 0);
  test.AddAttribute<float>("alpha", alpha);
  test.AddInput<ActType>("A", is_A_trans ? std::vector<int64_t>({K, M}) : std::vector<int64_t>({M, K}), std::move(matrix_a_data));
  test.AddInput<float>("a_scale", {}, {a_scale});
  test.AddInput<ActType>("a_zero_point", {}, {a_zero_point});
  test.AddInput<WeightType>("B", is_B_trans ? std::vector<int64_t>({N, K}) : std::vector<int64_t>({K, N}), std::move(matrix_b_data), B_is_initializer);
  test.AddInput<float>("b_scale", {SafeInt<int64_t>(b_scale.size())}, b_scale);
  test.AddInput<WeightType>("b_zero_point", {SafeInt<int64_t>(b_zp_per_column.size())}, b_zp_per_column);

  if (has_C) {
    test.AddInput<int32_t>("C", {M, N}, ToVector<int32_t>(matrix_c.data(), M * N));
  } else {
    test.AddOptionalInputEdge<int32_t>();
  }

  if constexpr (std::is_same_v<ScalarOutput, float>) {
    test.AddOptionalInputEdge<float>();
    test.AddOptionalInputEdge<ActType>();
    test.AddOutput<float>("Y", {M, N}, std::vector<float>(matrix_output.data(), matrix_output.data() + M * N));
  } else {
    std::vector<ActType> quant_output(M * N);
    quantization::Params<ActType> quant_param = quantization::QuantizeLinear(matrix_output.data(), quant_output.data(), M * N);
    test.AddInput<float>("y_scale", {}, {quant_param.scale});
    test.AddInput<ActType>("y_zero_point", {}, {quant_param.zero_point});
    test.AddOutput<ActType>("Y", {M, N}, quant_output);
  }

  test.Run();
}

void RunQuantGemmTest(const int M,
                      const int N,
                      const int K,
                      bool is_A_trans,
                      bool is_B_trans,
                      bool has_C,
                      bool B_is_initializer,
                      bool per_column = false) {
  RunQuantGemmU8X8Test<uint8_t, int8_t, float>(M, N, K, is_A_trans, is_B_trans, has_C, B_is_initializer, per_column);
  RunQuantGemmU8X8Test<uint8_t, int8_t, uint8_t>(M, N, K, is_A_trans, is_B_trans, has_C, B_is_initializer, per_column);
  RunQuantGemmU8X8Test<uint8_t, uint8_t, float>(M, N, K, is_A_trans, is_B_trans, has_C, B_is_initializer, per_column);
  RunQuantGemmU8X8Test<uint8_t, uint8_t, uint8_t>(M, N, K, is_A_trans, is_B_trans, has_C, B_is_initializer, per_column);

  RunQuantGemmU8X8Test<int8_t, int8_t, float>(M, N, K, is_A_trans, is_B_trans, has_C, B_is_initializer, per_column);
  RunQuantGemmU8X8Test<int8_t, int8_t, int8_t>(M, N, K, is_A_trans, is_B_trans, has_C, B_is_initializer, per_column);
}

void RunQuantGemmTestBatch(const int M, const int N, const int K) {
  // No Trans
  RunQuantGemmTest(M, N, K,
                   false /*is_A_trans*/, false /*is_B_trans*/,
                   false /*has_C*/, false /*B_is_initializer*/,
                   false /*per_column*/);
  RunQuantGemmTest(M, N, K,
                   false /*is_A_trans*/, false /*is_B_trans*/,
                   true /*has_C*/, true /*B_is_initializer*/,
                   true /*per_column*/);

  // A Trans
  RunQuantGemmTest(M, N, K,
                   true /*is_A_trans*/, false /*is_B_trans*/,
                   false /*has_C*/, true /*B_is_initializer*/,
                   false /*per_column*/);
  RunQuantGemmTest(M, N, K,
                   true /*is_A_trans*/, false /*is_B_trans*/,
                   true /*has_C*/, false /*B_is_initializer*/,
                   true /*per_column*/);

  // B Trans
  RunQuantGemmTest(M, N, K,
                   false /*is_A_trans*/, true /*is_B_trans*/,
                   false /*has_C*/, false /*B_is_initializer*/,
                   false /*per_column*/);
  RunQuantGemmTest(M, N, K,
                   false /*is_A_trans*/, true /*is_B_trans*/,
                   true /*has_C*/, true /*B_is_initializer*/,  // B uses prepacking
                   true /*per_column*/);

  // A and B Trans
  RunQuantGemmTest(M, N, K,
                   true /*is_A_trans*/, true /*is_B_trans*/,
                   false /*has_C*/, true /*B_is_initializer*/,
                   true /*per_column*/);
  RunQuantGemmTest(M, N, K,
                   true /*is_A_trans*/, true /*is_B_trans*/,
                   true /*has_C*/, false /*B_is_initializer*/,
                   false /*per_column*/);
}

TEST(QuantGemmTest, Scalar) {
  RunQuantGemmTestBatch(1, 1, 32);
  RunQuantGemmTestBatch(1, 1, 260);
  RunQuantGemmTestBatch(1, 1, 288);
}

TEST(QuantGemmTest, GEMV) {
  RunQuantGemmTestBatch(1, 2, 16);
  RunQuantGemmTestBatch(1, 2, 64);
  RunQuantGemmTestBatch(1, 8, 36);
  RunQuantGemmTestBatch(1, 8, 68);
  RunQuantGemmTestBatch(1, 8, 400);
  RunQuantGemmTestBatch(1, 512, 1024);
}

TEST(QuantGemmTest, GEMM) {
  RunQuantGemmTestBatch(2, 2, 40);
  RunQuantGemmTestBatch(2, 48, 33);
  RunQuantGemmTestBatch(2, 51, 40);
  RunQuantGemmTestBatch(4, 8, 68);
}

}  // namespace test
}  // namespace onnxruntime
<commit_msg>fix unit test of quant gemm (#10469)<commit_after>// Copyright (c) Microsoft Corporation. All rights reserved.
// Licensed under the MIT License.

#include "gtest/gtest.h"
#include "test/common/cuda_op_test_utils.h"
#include "test/common/quantization_test_utils.h"
#include "test/providers/provider_test_utils.h"

#include "core/common/common.h"
#include "core/common/safeint.h"
#include "core/framework/op_kernel.h"
#include "core/quantization/quantization.h"
#include "core/util/math_cpuonly.h"
#include "core/util/qmath.h"

#include <algorithm>
#include <random>
#include <type_traits>

namespace onnxruntime {
namespace test {

template <typename ActType, typename WeightType, typename ScalarOutput>
void RunQuantGemmU8X8Test(const int M,
                          const int N,
                          const int K,
                          bool is_A_trans,
                          bool is_B_trans,
                          bool has_C,
                          bool B_is_initializer,
                          bool per_column = false) {
  static std::default_random_engine e(123);
  static std::uniform_int_distribution<int> random_A(std::numeric_limits<ActType>::min(),
                                                     std::numeric_limits<ActType>::max());

  constexpr int overflow_adjust = std::is_signed_v<WeightType> ? 2 : 1;
  constexpr int random_B_min = std::numeric_limits<WeightType>::min() / overflow_adjust;
  constexpr int random_B_max = std::numeric_limits<WeightType>::max() / overflow_adjust;
  static std::uniform_int_distribution<int> random_B(random_B_min,
                                                     random_B_max);
  static std::uniform_real_distribution<float> n_apha(1.0f, 2.0f);
  static std::uniform_real_distribution<float> n_scale(0.003f, 0.004f);

  Eigen::MatrixXi matrix_a = Eigen::MatrixXi::Random(K, M)
                                 .unaryExpr([](int) { return random_A(e); });
  std::vector<ActType> matrix_a_data;
  if (is_A_trans) {
    Eigen::MatrixXi matrix_a_trans = matrix_a.transpose().eval();
    matrix_a_data = ToVector<ActType>(matrix_a_trans.data(), M * K);
  } else {
    matrix_a_data = ToVector<ActType>(matrix_a.data(), M * K);
  }
  ActType a_zero_point = GetMiddle(matrix_a_data);
  Eigen::MatrixXi matrix_a_offset = matrix_a - a_zero_point * Eigen::MatrixXi::Ones(K, M);
  float a_scale = n_scale(e);

  Eigen::MatrixXi matrix_b = Eigen::MatrixXi::Random(N, K)
                                 .unaryExpr([](int) { return random_B(e); });
  std::vector<WeightType> matrix_b_data;
  if (is_B_trans) {
    Eigen::MatrixXi matrix_b_trans = matrix_b.transpose().eval();
    matrix_b_data = ToVector<WeightType>(matrix_b_trans.data(), N * K);
  } else {
    matrix_b_data = ToVector<WeightType>(matrix_b.data(), N * K);
  }
  WeightType b_zero_point = GetMiddle(matrix_b_data);
  std::vector<float> b_scale({n_scale(e)});
  std::vector<WeightType> b_zp_per_column({b_zero_point});
  Eigen::MatrixXi b_zp_matrix = b_zero_point * Eigen::MatrixXi::Ones(N, K);
  Eigen::MatrixXf b_scale_matrix = b_scale[0] * Eigen::MatrixXf::Ones(N, M);
  if (per_column) {
    b_zp_per_column.resize(N);
    b_scale.resize(N);
    for (int i = 0; i < N; i++) {
      b_zp_per_column[i] = b_zero_point + i % 2 == 0 ? 1 : -1;
      b_zp_matrix.row(i).setConstant(b_zp_per_column[i]);
      b_scale[i] = n_scale(e);
      b_scale_matrix.row(i).setConstant(b_scale[i]);
    }
  }
  float alpha = n_apha(e);

  Eigen::MatrixXi matrix_c = Eigen::MatrixXi::Random(N, M)
                                 .unaryExpr([](int) { return random_A(e); });

  Eigen::MatrixXi matrix_int32 = (matrix_b - b_zp_matrix) * matrix_a_offset;
  if (has_C) {
    matrix_int32 = matrix_int32 + matrix_c;
  }
  Eigen::MatrixXf matrix_output = alpha * a_scale * (b_scale_matrix.cwiseProduct((matrix_int32.eval().cast<float>())));

  OpTester test("QGemm", 1, onnxruntime::kMSDomain);
  test.AddAttribute<int64_t>("transA", is_A_trans ? 1 : 0);
  test.AddAttribute<int64_t>("transB", is_B_trans ? 1 : 0);
  test.AddAttribute<float>("alpha", alpha);
  test.AddInput<ActType>("A", is_A_trans ? std::vector<int64_t>({K, M}) : std::vector<int64_t>({M, K}), std::move(matrix_a_data));
  test.AddInput<float>("a_scale", {}, {a_scale});
  test.AddInput<ActType>("a_zero_point", {}, {a_zero_point});
  test.AddInput<WeightType>("B", is_B_trans ? std::vector<int64_t>({N, K}) : std::vector<int64_t>({K, N}), std::move(matrix_b_data), B_is_initializer);
  test.AddInput<float>("b_scale", {SafeInt<int64_t>(b_scale.size())}, b_scale);
  test.AddInput<WeightType>("b_zero_point", {SafeInt<int64_t>(b_zp_per_column.size())}, b_zp_per_column);

  if (has_C) {
    test.AddInput<int32_t>("C", {M, N}, ToVector<int32_t>(matrix_c.data(), M * N));
  } else {
    test.AddOptionalInputEdge<int32_t>();
  }

  if constexpr (std::is_same_v<ScalarOutput, float>) {
    test.AddOptionalInputEdge<float>();
    test.AddOptionalInputEdge<ActType>();
    test.AddOutput<float>("Y", {M, N}, std::vector<float>(matrix_output.data(), matrix_output.data() + M * N));
  } else {
    std::vector<ActType> quant_output(M * N);
    quantization::Params<ActType> quant_param = quantization::QuantizeLinear(matrix_output.data(), quant_output.data(), M * N);
    test.AddInput<float>("y_scale", {}, {quant_param.scale});
    test.AddInput<ActType>("y_zero_point", {}, {quant_param.zero_point});
    test.AddOutput<ActType>("Y", {M, N}, quant_output);
  }

  test.Run();
}

void RunQuantGemmTest(const int M,
                      const int N,
                      const int K,
                      bool is_A_trans,
                      bool is_B_trans,
                      bool has_C,
                      bool B_is_initializer,
                      bool per_column = false) {
  RunQuantGemmU8X8Test<uint8_t, int8_t, float>(M, N, K, is_A_trans, is_B_trans, has_C, B_is_initializer, per_column);
  RunQuantGemmU8X8Test<uint8_t, int8_t, uint8_t>(M, N, K, is_A_trans, is_B_trans, has_C, B_is_initializer, per_column);
  RunQuantGemmU8X8Test<uint8_t, uint8_t, float>(M, N, K, is_A_trans, is_B_trans, has_C, B_is_initializer, per_column);
  RunQuantGemmU8X8Test<uint8_t, uint8_t, uint8_t>(M, N, K, is_A_trans, is_B_trans, has_C, B_is_initializer, per_column);

  RunQuantGemmU8X8Test<int8_t, int8_t, float>(M, N, K, is_A_trans, is_B_trans, has_C, B_is_initializer, per_column);
  RunQuantGemmU8X8Test<int8_t, int8_t, int8_t>(M, N, K, is_A_trans, is_B_trans, has_C, B_is_initializer, per_column);
}

void RunQuantGemmTestBatch(const int M, const int N, const int K) {
  // No Trans
  RunQuantGemmTest(M, N, K,
                   false /*is_A_trans*/, false /*is_B_trans*/,
                   false /*has_C*/, false /*B_is_initializer*/,
                   false /*per_column*/);
  RunQuantGemmTest(M, N, K,
                   false /*is_A_trans*/, false /*is_B_trans*/,
                   true /*has_C*/, true /*B_is_initializer*/,
                   true /*per_column*/);

  // A Trans
  RunQuantGemmTest(M, N, K,
                   true /*is_A_trans*/, false /*is_B_trans*/,
                   false /*has_C*/, true /*B_is_initializer*/,
                   false /*per_column*/);
  RunQuantGemmTest(M, N, K,
                   true /*is_A_trans*/, false /*is_B_trans*/,
                   true /*has_C*/, false /*B_is_initializer*/,
                   true /*per_column*/);

  // B Trans
  RunQuantGemmTest(M, N, K,
                   false /*is_A_trans*/, true /*is_B_trans*/,
                   false /*has_C*/, false /*B_is_initializer*/,
                   false /*per_column*/);
  RunQuantGemmTest(M, N, K,
                   false /*is_A_trans*/, true /*is_B_trans*/,
                   true /*has_C*/, true /*B_is_initializer*/,  // B uses prepacking
                   true /*per_column*/);

  // A and B Trans
  RunQuantGemmTest(M, N, K,
                   true /*is_A_trans*/, true /*is_B_trans*/,
                   false /*has_C*/, true /*B_is_initializer*/,
                   true /*per_column*/);
  RunQuantGemmTest(M, N, K,
                   true /*is_A_trans*/, true /*is_B_trans*/,
                   true /*has_C*/, false /*B_is_initializer*/,
                   false /*per_column*/);
}

TEST(QuantGemmTest, Scalar) {
  RunQuantGemmTestBatch(1, 1, 32);
  RunQuantGemmTestBatch(1, 1, 260);
  RunQuantGemmTestBatch(1, 1, 288);
}

TEST(QuantGemmTest, GEMV) {
  RunQuantGemmTestBatch(1, 2, 16);
  RunQuantGemmTestBatch(1, 2, 64);
  RunQuantGemmTestBatch(1, 8, 36);
  RunQuantGemmTestBatch(1, 8, 68);
  RunQuantGemmTestBatch(1, 8, 400);
  RunQuantGemmTestBatch(1, 512, 1024);
}

TEST(QuantGemmTest, GEMM) {
  RunQuantGemmTestBatch(2, 2, 40);
  RunQuantGemmTestBatch(2, 48, 33);
  RunQuantGemmTestBatch(2, 51, 40);
  RunQuantGemmTestBatch(4, 8, 68);
}

}  // namespace test
}  // namespace onnxruntime
<|endoftext|>


<commit_before>/**
 * Shader.cxx
 *
 * Author
 *     Andrew Brown <adb1413@rit.edu>
 */
#include "config.h"
#include <stdexcept>
#include "glycerin/Shader.hxx"
using namespace std;
namespace Glycerin {

/**
 * Constructs a shader.
 *
 * @param handle OpenGL identifier for shader
 */
Shader::Shader(const GLuint handle) : _handle(handle) {
    // pass
}

/**
 * Constructs a shader by copying another shader.
 *
 * @param shader Shader to copy
 */
Shader::Shader(const Shader& shader) : _handle(shader._handle) {
    // pass
}

/**
 * Destroys the shader.
 */
Shader::~Shader() {
    // pass
}

/**
 * Compiles the shader.
 */
void Shader::compile() {
    glCompileShader(_handle);
}

/**
 * Creates a new shader of a particular type.
 *
 * @param type Kind of shader, e.g. `GL_VERTEX_SHADER` or `GL_FRAGMENT_SHADER`
 * @return New shader of specified type
 * @throw std::runtime_error if shader could not be created
 */
Shader Shader::create(const GLenum type) {

    // Create a handle
    const GLuint handle = glCreateShader(type);
    if (handle == 0) {
        throw runtime_error("[Shader] Could not create shader!");
    }

    // Make the shader
    return Shader(handle);
}

/**
 * Deletes the shader.
 */
void Shader::dispose() {
    glDeleteShader(_handle);
}

/**
 * Returns the OpenGL identifier for the shader.
 */
GLuint Shader::handle() const {
    return _handle;
}

/**
 * Copies the handle of another shader.
 *
 * @param shader Shader to copy
 * @return Reference to this shader to support chaining
 */
Shader& Shader::operator=(const Shader &shader) {
    _handle = shader._handle;
}

/**
 * Checks if another shader is equal to this one.
 *
 * @param shader Shader to check
 * @return `true` if shaders represent same OpenGL shader
 */
bool Shader::operator==(const Shader &shader) const {
    return _handle == shader._handle;
}

/**
 * Checks if another shader is not equal to this one.
 *
 * @param shader Shader to check
 * @return `true` if shaders do not represent same OpenGL shader
 */
bool Shader::operator!=(const Shader &shader) const {
    return _handle != shader._handle;
}

/**
 * Returns the shader's source code.
 */
string Shader::source() const {

    // Get the size of the source code
    GLint len;
    glGetShaderiv(_handle, GL_SHADER_SOURCE_LENGTH, &len);
    if (len == 0) {
        return "";
    }

    // Put the source code into a buffer and make a string from it
    char* const buf = new char[len];
    glGetShaderSource(_handle, len, NULL, buf);
    const string str(buf);

    // Delete the buffer
    delete[] buf;

    // Return the string
    return str;
}

/**
 * Returns the shader's log.
 */
string Shader::log() const {

    // Allocate a character buffer large enough for the log
    GLsizei count;
    glGetShaderiv(_handle, GL_INFO_LOG_LENGTH, &count);
    GLchar* buf = new GLchar[count + 1];

    // Put the log into the buffer and make a string from it
    GLsizei returned;
    glGetShaderInfoLog(_handle, count, &returned, buf);
    buf[returned] = '\0';
    string str(buf);

    // Delete the buffer
    delete[] buf;

    // Return the string
    return str;
}

/**
 * Returns the kind of this shader, e.g. `GL_VERTEX_SHADER` or `GL_FRAGMENT_SHADER`.
 */
GLenum Shader::type() const {
    GLint type;
    glGetShaderiv(_handle, GL_SHADER_TYPE, &type);
    return type;
}

/**
 * Returns `true` if shader is compiled.
 */
bool Shader::compiled() const {
    GLint compiled;
    glGetShaderiv(_handle, GL_COMPILE_STATUS, &compiled);
    return compiled;
}

/**
 * Changes the shader's source code.
 *
 * @param source Code for shader
 * @throws invalid_argument if source code is empty
 */
void Shader::source(const std::string& source) {
    const char* buf = source.c_str();
    const char** ptr = &buf;
    glShaderSource(_handle, 1, ptr, NULL);
}

/**
 * Wraps an existing OpenGL shader.
 *
 * @param handle OpenGL identifier for shader
 * @return Wrapper for OpenGL shader
 * @throws std::invalid_argument if handle is not a valid OpenGL shader
 */
Shader Shader::wrap(const GLuint handle) {
    if (!glIsShader(handle)) {
        throw invalid_argument("[Shader] Handle is not a valid shader!");
    }
    return Shader(handle);
}

} /* namespace Glycerin */
<commit_msg>Prefer 'this' to 'the' in Shader documentation (ref #56)<commit_after>/**
 * Shader.cxx
 *
 * Author
 *     Andrew Brown <adb1413@rit.edu>
 */
#include "config.h"
#include <stdexcept>
#include "glycerin/Shader.hxx"
using namespace std;
namespace Glycerin {

/**
 * Constructs a shader.
 *
 * @param handle OpenGL identifier for shader
 */
Shader::Shader(const GLuint handle) : _handle(handle) {
    // pass
}

/**
 * Constructs a shader by copying another shader.
 *
 * @param shader Shader to copy
 */
Shader::Shader(const Shader& shader) : _handle(shader._handle) {
    // pass
}

/**
 * Destroys this shader.
 */
Shader::~Shader() {
    // pass
}

/**
 * Compiles this shader.
 */
void Shader::compile() {
    glCompileShader(_handle);
}

/**
 * Creates a new shader of a particular type.
 *
 * @param type Kind of shader, e.g. `GL_VERTEX_SHADER` or `GL_FRAGMENT_SHADER`
 * @return New shader of specified type
 * @throw std::runtime_error if shader could not be created
 */
Shader Shader::create(const GLenum type) {

    // Create a handle
    const GLuint handle = glCreateShader(type);
    if (handle == 0) {
        throw runtime_error("[Shader] Could not create shader!");
    }

    // Make the shader
    return Shader(handle);
}

/**
 * Deletes this shader.
 */
void Shader::dispose() {
    glDeleteShader(_handle);
}

/**
 * Returns the OpenGL identifier for this shader.
 */
GLuint Shader::handle() const {
    return _handle;
}

/**
 * Copies the handle of another shader.
 *
 * @param shader Shader to copy
 * @return Reference to this shader to support chaining
 */
Shader& Shader::operator=(const Shader &shader) {
    _handle = shader._handle;
}

/**
 * Checks if another shader is equal to this one.
 *
 * @param shader Shader to check
 * @return `true` if shaders represent same OpenGL shader
 */
bool Shader::operator==(const Shader &shader) const {
    return _handle == shader._handle;
}

/**
 * Checks if another shader is not equal to this one.
 *
 * @param shader Shader to check
 * @return `true` if shaders do not represent same OpenGL shader
 */
bool Shader::operator!=(const Shader &shader) const {
    return _handle != shader._handle;
}

/**
 * Returns this shader's source code.
 */
string Shader::source() const {

    // Get the size of the source code
    GLint len;
    glGetShaderiv(_handle, GL_SHADER_SOURCE_LENGTH, &len);
    if (len == 0) {
        return "";
    }

    // Put the source code into a buffer and make a string from it
    char* const buf = new char[len];
    glGetShaderSource(_handle, len, NULL, buf);
    const string str(buf);

    // Delete the buffer
    delete[] buf;

    // Return the string
    return str;
}

/**
 * Returns this shader's log.
 */
string Shader::log() const {

    // Allocate a character buffer large enough for the log
    GLsizei count;
    glGetShaderiv(_handle, GL_INFO_LOG_LENGTH, &count);
    GLchar* buf = new GLchar[count + 1];

    // Put the log into the buffer and make a string from it
    GLsizei returned;
    glGetShaderInfoLog(_handle, count, &returned, buf);
    buf[returned] = '\0';
    string str(buf);

    // Delete the buffer
    delete[] buf;

    // Return the string
    return str;
}

/**
 * Returns the kind of this shader, e.g. `GL_VERTEX_SHADER` or `GL_FRAGMENT_SHADER`.
 */
GLenum Shader::type() const {
    GLint type;
    glGetShaderiv(_handle, GL_SHADER_TYPE, &type);
    return type;
}

/**
 * Returns `true` if shader is compiled.
 */
bool Shader::compiled() const {
    GLint compiled;
    glGetShaderiv(_handle, GL_COMPILE_STATUS, &compiled);
    return compiled;
}

/**
 * Changes this shader's source code.
 *
 * @param source Code for shader
 * @throws invalid_argument if source code is empty
 */
void Shader::source(const std::string& source) {
    const char* buf = source.c_str();
    const char** ptr = &buf;
    glShaderSource(_handle, 1, ptr, NULL);
}

/**
 * Wraps an existing OpenGL shader.
 *
 * @param handle OpenGL identifier for shader
 * @return Wrapper for OpenGL shader
 * @throws std::invalid_argument if handle is not a valid OpenGL shader
 */
Shader Shader::wrap(const GLuint handle) {
    if (!glIsShader(handle)) {
        throw invalid_argument("[Shader] Handle is not a valid shader!");
    }
    return Shader(handle);
}

} /* namespace Glycerin */
<|endoftext|>


<commit_before>/*
 * Copyright 2011 Google Inc.
 *
 * Use of this source code is governed by a BSD-style license that can be
 * found in the LICENSE file.
 */

#include "gm.h"
#include "SkGradientShader.h"

#include "SkTypeface.h"
#include "SkImageDecoder.h"
#include "SkStream.h"

static void setTypeface(SkPaint* paint, const char name[], SkTypeface::Style style) {
    SkSafeUnref(paint->setTypeface(SkTypeface::CreateFromName(name, style)));
}

static SkSize computeSize(const SkBitmap& bm, const SkMatrix& mat) {
    SkRect bounds = SkRect::MakeWH(SkIntToScalar(bm.width()),
                                   SkIntToScalar(bm.height()));
    mat.mapRect(&bounds);
    return SkSize::Make(bounds.width(), bounds.height());
}

static void draw_col(SkCanvas* canvas, const SkBitmap& bm, const SkMatrix& mat,
                     SkScalar dx) {
    SkPaint paint;

    SkAutoCanvasRestore acr(canvas, true);

    canvas->drawBitmapMatrix(bm, mat, &paint);

    paint.setFilterBitmap(true);
    canvas->translate(dx, 0);
    canvas->drawBitmapMatrix(bm, mat, &paint);

    paint.setFlags(paint.getFlags() | SkPaint::kBicubicFilterBitmap_Flag);
    canvas->translate(dx, 0);
    canvas->drawBitmapMatrix(bm, mat, &paint);
}

class FilterBitmapGM : public skiagm::GM {
    void onOnceBeforeDraw() {

        make_bitmap();

        SkScalar cx = SkScalarHalf(fBM.width());
        SkScalar cy = SkScalarHalf(fBM.height());
        SkScalar scale = get_scale();

        fMatrix[0].setScale(scale, scale);
        fMatrix[1].setRotate(30, cx, cy); fMatrix[1].postScale(scale, scale);
    }

public:
    SkBitmap    fBM;
    SkMatrix    fMatrix[2];
    SkString    fName;

    FilterBitmapGM()
    {
        this->setBGColor(0xFFDDDDDD);
    }

    void setName( const char name[] ) {
        fName.set(name);
    }

protected:
    virtual SkString onShortName() SK_OVERRIDE {
        return fName;
    }

    virtual SkISize onISize() SK_OVERRIDE {
        return SkISize::Make(920, 480);
    }

    virtual void make_bitmap() = 0;
    virtual SkScalar get_scale() = 0;

    virtual void onDraw(SkCanvas* canvas) SK_OVERRIDE {

        canvas->translate(10, 10);
        for (size_t i = 0; i < SK_ARRAY_COUNT(fMatrix); ++i) {
            SkSize size = computeSize(fBM, fMatrix[i]);
            size.fWidth += 20;
            size.fHeight += 20;

            draw_col(canvas, fBM, fMatrix[i], size.fWidth);
            canvas->translate(0, size.fHeight);
        }
    }

private:
    typedef skiagm::GM INHERITED;
};

class FilterBitmapTextGM: public FilterBitmapGM {
  public:
      FilterBitmapTextGM( float textSize )
      : fTextSize( textSize )
        {
            char name[1024];
            sprintf( name, "filterbitmap_text_%.2fpt", fTextSize );
            setName( name );
        }

  protected:
      float fTextSize;

      SkScalar get_scale() SK_OVERRIDE {
          return 32.f/fTextSize;
      }

      void make_bitmap() SK_OVERRIDE {
          fBM.setConfig(SkBitmap::kARGB_8888_Config, fTextSize * 8, fTextSize * 6);
          fBM.allocPixels();
          SkCanvas canvas(fBM);
          canvas.drawColor(SK_ColorWHITE);

          SkPaint paint;
          paint.setAntiAlias(true);
          paint.setSubpixelText(true);
          paint.setTextSize(fTextSize);

          setTypeface(&paint, "Times", SkTypeface::kNormal);
          canvas.drawText("Hamburgefons", 12, fTextSize/2, 1.2*fTextSize, paint);
          setTypeface(&paint, "Times", SkTypeface::kBold);
          canvas.drawText("Hamburgefons", 12, fTextSize/2, 2.4*fTextSize, paint);
          setTypeface(&paint, "Times", SkTypeface::kItalic);
          canvas.drawText("Hamburgefons", 12, fTextSize/2, 3.6*fTextSize, paint);
          setTypeface(&paint, "Times", SkTypeface::kBoldItalic);
          canvas.drawText("Hamburgefons", 12, fTextSize/2, 4.8*fTextSize, paint);
      }
  private:
      typedef FilterBitmapGM INHERITED;
};

class FilterBitmapCheckerboardGM: public FilterBitmapGM {
  public:
      FilterBitmapCheckerboardGM( int size, int num_checks )
      : fSize( size ), fNumChecks( num_checks )
        {
            char name[1024];
            sprintf( name, "filterbitmap_checkerboard_%d_%d", fSize, fNumChecks );
            setName( name );
        }

  protected:
      int fSize;
      int fNumChecks;

      SkScalar get_scale() SK_OVERRIDE {
          return 192.f/fSize;
      }

      void make_bitmap() SK_OVERRIDE {
          fBM.setConfig(SkBitmap::kARGB_8888_Config, fSize, fSize);
          fBM.allocPixels();
          SkAutoLockPixels lock(fBM);
          for (int y = 0; y < fSize; y ++) {
              for (int x = 0; x < fSize; x ++) {
                  SkPMColor* s = fBM.getAddr32(x, y);
                  int cx = (x * fNumChecks) / fSize;
                  int cy = (y * fNumChecks) / fSize;
                  if ((cx+cy)%2) {
                      *s = 0xFFFFFFFF;
                  } else {
                      *s = 0xFF000000;
                  }
              }
          }
      }
  private:
      typedef FilterBitmapGM INHERITED;
};

class FilterBitmapImageGM: public FilterBitmapGM {
  public:
      FilterBitmapImageGM( const char filename[] )
      : fFilename( filename )
        {
            char name[1024];
            sprintf( name, "filterbitmap_image_%s", filename );
            setName( name );
        }

  protected:
      SkString fFilename;
      int fSize;

      SkScalar get_scale() SK_OVERRIDE {
          return 192.f/fSize;
      }

      void make_bitmap() SK_OVERRIDE {
          SkString path(skiagm::GM::gResourcePath);
          path.append( "/" );
          path.append(fFilename);

          SkImageDecoder *codec = NULL;
          SkFILEStream stream(path.c_str());
          if (stream.isValid()) {
              codec = SkImageDecoder::Factory(&stream);
          }
          if (codec) {
              stream.rewind();
              codec->decode(&stream, &fBM, SkBitmap::kARGB_8888_Config,
                  SkImageDecoder::kDecodePixels_Mode);
              SkDELETE(codec);
          } else {
              fBM.setConfig(SkBitmap::kARGB_8888_Config, 1, 1);
              fBM.allocPixels();
              *(fBM.getAddr32(0,0)) = 0xFF0000FF; // red == bad
          }
          fSize = fBM.height();
      }
  private:
      typedef FilterBitmapGM INHERITED;
};

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

DEF_GM( return new FilterBitmapTextGM(3); )
DEF_GM( return new FilterBitmapTextGM(7); )
DEF_GM( return new FilterBitmapTextGM(10); )
DEF_GM( return new FilterBitmapCheckerboardGM(4,4); )
DEF_GM( return new FilterBitmapCheckerboardGM(32,32); )
DEF_GM( return new FilterBitmapCheckerboardGM(32,8); )
DEF_GM( return new FilterBitmapCheckerboardGM(32,2); )
DEF_GM( return new FilterBitmapCheckerboardGM(192,192); )
DEF_GM( return new FilterBitmapImageGM("mandrill_16.png"); )
DEF_GM( return new FilterBitmapImageGM("mandrill_32.png"); )
DEF_GM( return new FilterBitmapImageGM("mandrill_64.png"); )
DEF_GM( return new FilterBitmapImageGM("mandrill_128.png"); )
DEF_GM( return new FilterBitmapImageGM("mandrill_256.png"); )
DEF_GM( return new FilterBitmapImageGM("mandrill_512.png"); )
<commit_msg>fix warnings on MacOS 10.6<commit_after>/*
 * Copyright 2011 Google Inc.
 *
 * Use of this source code is governed by a BSD-style license that can be
 * found in the LICENSE file.
 */

#include "gm.h"
#include "SkGradientShader.h"

#include "SkTypeface.h"
#include "SkImageDecoder.h"
#include "SkStream.h"

static void setTypeface(SkPaint* paint, const char name[], SkTypeface::Style style) {
    SkSafeUnref(paint->setTypeface(SkTypeface::CreateFromName(name, style)));
}

static SkSize computeSize(const SkBitmap& bm, const SkMatrix& mat) {
    SkRect bounds = SkRect::MakeWH(SkIntToScalar(bm.width()),
                                   SkIntToScalar(bm.height()));
    mat.mapRect(&bounds);
    return SkSize::Make(bounds.width(), bounds.height());
}

static void draw_col(SkCanvas* canvas, const SkBitmap& bm, const SkMatrix& mat,
                     SkScalar dx) {
    SkPaint paint;

    SkAutoCanvasRestore acr(canvas, true);

    canvas->drawBitmapMatrix(bm, mat, &paint);

    paint.setFilterBitmap(true);
    canvas->translate(dx, 0);
    canvas->drawBitmapMatrix(bm, mat, &paint);

    paint.setFlags(paint.getFlags() | SkPaint::kBicubicFilterBitmap_Flag);
    canvas->translate(dx, 0);
    canvas->drawBitmapMatrix(bm, mat, &paint);
}

class FilterBitmapGM : public skiagm::GM {
    void onOnceBeforeDraw() {

        make_bitmap();

        SkScalar cx = SkScalarHalf(fBM.width());
        SkScalar cy = SkScalarHalf(fBM.height());
        SkScalar scale = get_scale();

        fMatrix[0].setScale(scale, scale);
        fMatrix[1].setRotate(30, cx, cy); fMatrix[1].postScale(scale, scale);
    }

public:
    SkBitmap    fBM;
    SkMatrix    fMatrix[2];
    SkString    fName;

    FilterBitmapGM()
    {
        this->setBGColor(0xFFDDDDDD);
    }

    void setName( const char name[] ) {
        fName.set(name);
    }

protected:
    virtual SkString onShortName() SK_OVERRIDE {
        return fName;
    }

    virtual SkISize onISize() SK_OVERRIDE {
        return SkISize::Make(920, 480);
    }

    virtual void make_bitmap() = 0;
    virtual SkScalar get_scale() = 0;

    virtual void onDraw(SkCanvas* canvas) SK_OVERRIDE {

        canvas->translate(10, 10);
        for (size_t i = 0; i < SK_ARRAY_COUNT(fMatrix); ++i) {
            SkSize size = computeSize(fBM, fMatrix[i]);
            size.fWidth += 20;
            size.fHeight += 20;

            draw_col(canvas, fBM, fMatrix[i], size.fWidth);
            canvas->translate(0, size.fHeight);
        }
    }

private:
    typedef skiagm::GM INHERITED;
};

class FilterBitmapTextGM: public FilterBitmapGM {
  public:
      FilterBitmapTextGM( float textSize )
      : fTextSize( textSize )
        {
            char name[1024];
            sprintf( name, "filterbitmap_text_%.2fpt", fTextSize );
            setName( name );
        }

  protected:
      float fTextSize;

      SkScalar get_scale() SK_OVERRIDE {
          return 32.f/fTextSize;
      }

      void make_bitmap() SK_OVERRIDE {
          fBM.setConfig(SkBitmap::kARGB_8888_Config, int(fTextSize * 8), int(fTextSize * 6));
          fBM.allocPixels();
          SkCanvas canvas(fBM);
          canvas.drawColor(SK_ColorWHITE);

          SkPaint paint;
          paint.setAntiAlias(true);
          paint.setSubpixelText(true);
          paint.setTextSize(fTextSize);

          setTypeface(&paint, "Times", SkTypeface::kNormal);
          canvas.drawText("Hamburgefons", 12, fTextSize/2, 1.2f*fTextSize, paint);
          setTypeface(&paint, "Times", SkTypeface::kBold);
          canvas.drawText("Hamburgefons", 12, fTextSize/2, 2.4f*fTextSize, paint);
          setTypeface(&paint, "Times", SkTypeface::kItalic);
          canvas.drawText("Hamburgefons", 12, fTextSize/2, 3.6f*fTextSize, paint);
          setTypeface(&paint, "Times", SkTypeface::kBoldItalic);
          canvas.drawText("Hamburgefons", 12, fTextSize/2, 4.8f*fTextSize, paint);
      }
  private:
      typedef FilterBitmapGM INHERITED;
};

class FilterBitmapCheckerboardGM: public FilterBitmapGM {
  public:
      FilterBitmapCheckerboardGM( int size, int num_checks )
      : fSize( size ), fNumChecks( num_checks )
        {
            char name[1024];
            sprintf( name, "filterbitmap_checkerboard_%d_%d", fSize, fNumChecks );
            setName( name );
        }

  protected:
      int fSize;
      int fNumChecks;

      SkScalar get_scale() SK_OVERRIDE {
          return 192.f/fSize;
      }

      void make_bitmap() SK_OVERRIDE {
          fBM.setConfig(SkBitmap::kARGB_8888_Config, fSize, fSize);
          fBM.allocPixels();
          SkAutoLockPixels lock(fBM);
          for (int y = 0; y < fSize; y ++) {
              for (int x = 0; x < fSize; x ++) {
                  SkPMColor* s = fBM.getAddr32(x, y);
                  int cx = (x * fNumChecks) / fSize;
                  int cy = (y * fNumChecks) / fSize;
                  if ((cx+cy)%2) {
                      *s = 0xFFFFFFFF;
                  } else {
                      *s = 0xFF000000;
                  }
              }
          }
      }
  private:
      typedef FilterBitmapGM INHERITED;
};

class FilterBitmapImageGM: public FilterBitmapGM {
  public:
      FilterBitmapImageGM( const char filename[] )
      : fFilename( filename )
        {
            char name[1024];
            sprintf( name, "filterbitmap_image_%s", filename );
            setName( name );
        }

  protected:
      SkString fFilename;
      int fSize;

      SkScalar get_scale() SK_OVERRIDE {
          return 192.f/fSize;
      }

      void make_bitmap() SK_OVERRIDE {
          SkString path(skiagm::GM::gResourcePath);
          path.append( "/" );
          path.append(fFilename);

          SkImageDecoder *codec = NULL;
          SkFILEStream stream(path.c_str());
          if (stream.isValid()) {
              codec = SkImageDecoder::Factory(&stream);
          }
          if (codec) {
              stream.rewind();
              codec->decode(&stream, &fBM, SkBitmap::kARGB_8888_Config,
                  SkImageDecoder::kDecodePixels_Mode);
              SkDELETE(codec);
          } else {
              fBM.setConfig(SkBitmap::kARGB_8888_Config, 1, 1);
              fBM.allocPixels();
              *(fBM.getAddr32(0,0)) = 0xFF0000FF; // red == bad
          }
          fSize = fBM.height();
      }
  private:
      typedef FilterBitmapGM INHERITED;
};

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

DEF_GM( return new FilterBitmapTextGM(3); )
DEF_GM( return new FilterBitmapTextGM(7); )
DEF_GM( return new FilterBitmapTextGM(10); )
DEF_GM( return new FilterBitmapCheckerboardGM(4,4); )
DEF_GM( return new FilterBitmapCheckerboardGM(32,32); )
DEF_GM( return new FilterBitmapCheckerboardGM(32,8); )
DEF_GM( return new FilterBitmapCheckerboardGM(32,2); )
DEF_GM( return new FilterBitmapCheckerboardGM(192,192); )
DEF_GM( return new FilterBitmapImageGM("mandrill_16.png"); )
DEF_GM( return new FilterBitmapImageGM("mandrill_32.png"); )
DEF_GM( return new FilterBitmapImageGM("mandrill_64.png"); )
DEF_GM( return new FilterBitmapImageGM("mandrill_128.png"); )
DEF_GM( return new FilterBitmapImageGM("mandrill_256.png"); )
DEF_GM( return new FilterBitmapImageGM("mandrill_512.png"); )
<|endoftext|>


<commit_before>#include "gui_main_window.h"
#include "ui_gui_main_window.h"
#include "parse_batch.h"

#include "../decompose_imf_lib/optimization_task.h"

#include "../qt_utils/exception_handling.h"
#include "../qt_utils/invoke_in_thread.h"
#include "../qt_utils/loop_thread.h"

#include "../cpp_utils/locking.h"
#include "../cpp_utils/exception_handling.h"
#include "../cpp_utils/scope_guard.h"
#include "../cpp_utils/std_make_unique.h"

#include <QSettings>

#include <iostream>

static const char * tasksTextName = "tasksText";

namespace gui {

static void printImfs( const std::vector<std::vector<double> > & imfs )
{
    auto i = size_t(0);
    for ( const auto & imf : imfs )
    {
        std::cout << "IMF " << (i++) << ": ";
        std::copy( begin(imf), end(imf),
                   std::ostream_iterator<double>(std::cout," ") );
        std::cout << std::endl;
    }
}

struct MainWindow::Impl
{
    Ui::MainWindow ui;
    qu::LoopThread optimizationWorker;

    struct SharedData
    {
        bool cancelled{};
        bool isRunning{};
    };
    cu::Monitor<SharedData> shared;

};

MainWindow::MainWindow(QWidget *parent)
    : QMainWindow{parent}
    , m{ std::make_unique<Impl>() }
{
    m->ui.setupUi(this);
    m->ui.textEditor->setPlainText(
                QSettings().value( tasksTextName ).toString() );
}

MainWindow::~MainWindow()
{
    CU_SWALLOW_ALL_EXCEPTIONS_FROM
    {
        cancelRun();
        QSettings().setValue(
                    tasksTextName,
                    m->ui.textEditor->toPlainText() );
    };
}

void MainWindow::cancelRun()
{
    m->shared( []( Impl::SharedData & shared )
    {
        shared.cancelled = true;
    });
}

void MainWindow::runBatch()
{
    // parse script, produce optimization parameters.
    const auto optParams = parseBatch( std::istringstream(
        m->ui.textEditor->toPlainText().toStdString()) );

    // check if an optimization is already running. Throw, if so.
    m->shared( [this]( Impl::SharedData & shared )
    {
        if ( shared.isRunning )
            CU_THROW( "Batch processing is already in progress." );
    });

    // start optimization in worker thread.
    qu::invokeInThread( &m->optimizationWorker, [=]()
    { QU_HANDLE_ALL_EXCEPTIONS_FROM {
        // set cancelled flag and running flag.
        m->shared( [this]( Impl::SharedData & shared )
        {
            shared.cancelled = false;
            shared.isRunning = true;
        });
        CU_SCOPE_EXIT {
            m->shared( [this]( Impl::SharedData & shared )
            { shared.isRunning = false; });
        };

        // set gui push buttons' enabled state
        qu    ::invokeInGuiThread( [this](){ m->ui.cancelRunButton->setEnabled(true); } );
        CU_SCOPE_EXIT {
            qu::invokeInGuiThread( [this](){ m->ui.cancelRunButton->setEnabled(false); } );
        };

        // run script in loop.
        auto i = size_t{};
        for ( auto optParam : optParams )
        {
            ++i;
            const auto n = optParams.size();
            // Notify user about progress.
            qu::invokeInGuiThread( [this,i,n]()
            {
                m->ui.statusbar->showMessage(
                            QString("Optimization %1 of %2 is running ...")
                            .arg(i)
                            .arg(n) );
            } );
            // contains the indexes of the imfs that shall be optimized
            // in order.
            auto imfIndexes = std::vector<size_t>{};
            // contains the step numbers when the index of the imf
            // to be optimized shall change.
            auto imfPartSums = std::vector<size_t>{};
            auto totalImfOptSteps = size_t{0};
            for ( const auto & imfOptimization : optParam.imfOptimizations )
            {
                imfIndexes.push_back( imfOptimization.first );
                imfPartSums.push_back( totalImfOptSteps += imfOptimization.second );
            }
            optParam.howToContinue =
                    [this,imfIndexes,imfPartSums]( size_t nIter )
            {
                const auto isCancelled = m->shared(
                    []( Impl::SharedData & shared )
                {
                    return shared.cancelled;
                });
                if ( isCancelled )
                    return ~size_t{0};
                const auto it = std::lower_bound(
                        begin(imfPartSums),
                        end(imfPartSums),
                        nIter );
                if ( it == end(imfPartSums) )
                    return ~size_t{0};
                return imfIndexes.at( it - begin(imfPartSums) );
            };
            const auto imfs = dimf::runOptimization(optParam);
            printImfs( imfs );
            const auto isCancelled = m->shared(
                []( Impl::SharedData & shared )
            {
                return shared.cancelled;
            });
            if ( isCancelled )
            {
                qu::invokeInGuiThread( [this]()
                {
                    m->ui.statusbar->showMessage(
                        QString("Optimization run was cancelled.")
                        , 5000 );
                } );
                return;
            }
        }
        qu::invokeInGuiThread( [this]()
        {
            m->ui.statusbar->showMessage(
                QString("All optimization runs finished successfully.")
                , 5000 );
        } );
    }; } );
}

} // namespace gui
<commit_msg>Progress is displayed during batch processing now.<commit_after>#include "gui_main_window.h"
#include "ui_gui_main_window.h"
#include "parse_batch.h"

#include "../decompose_imf_lib/optimization_task.h"

#include "../qt_utils/exception_handling.h"
#include "../qt_utils/gui_progress_manager.h"
#include "../qt_utils/invoke_in_thread.h"
#include "../qt_utils/loop_thread.h"

#include "../cpp_utils/exception_handling.h"
#include "../cpp_utils/locking.h"
#include "../cpp_utils/progress_interface.h"
#include "../cpp_utils/scope_guard.h"
#include "../cpp_utils/std_make_unique.h"

#include <QSettings>

#include <iostream>

static const char * tasksTextName = "tasksText";

namespace gui {

static void printImfs( const std::vector<std::vector<double> > & imfs )
{
    auto i = size_t(0);
    for ( const auto & imf : imfs )
    {
        std::cout << "IMF " << (i++) << ": ";
        std::copy( begin(imf), end(imf),
                   std::ostream_iterator<double>(std::cout," ") );
        std::cout << std::endl;
    }
}

struct MainWindow::Impl
{
    Ui::MainWindow ui;
    qu::LoopThread optimizationWorker;

    struct SharedData
    {
        bool cancelled{};
        bool isRunning{};
    };
    cu::Monitor<SharedData> shared;

};

MainWindow::MainWindow(QWidget *parent)
    : QMainWindow{parent}
    , m{ std::make_unique<Impl>() }
{
    auto progressManager = std::make_unique<qu::ProgressWidgetContainer>();
    qu::setGlobalProgressManager( &progressManager->getProgressManagerInterface() );
    m->ui.setupUi(this);
    m->ui.statusbar->addWidget( progressManager.get() );
    progressManager.release();
    m->ui.textEditor->setPlainText(
                QSettings().value( tasksTextName ).toString() );
}

MainWindow::~MainWindow()
{
    CU_SWALLOW_ALL_EXCEPTIONS_FROM
    {
        cancelRun();
        QSettings().setValue(
                    tasksTextName,
                    m->ui.textEditor->toPlainText() );
    };
}

void MainWindow::cancelRun()
{
    m->shared( []( Impl::SharedData & shared )
    {
        shared.cancelled = true;
    });
}

void MainWindow::runBatch()
{
    // parse script, produce optimization parameters.
    const auto optParams = parseBatch( std::istringstream(
        m->ui.textEditor->toPlainText().toStdString()) );

    // check if an optimization is already running. Throw, if so.
    m->shared( [this]( Impl::SharedData & shared )
    {
        if ( shared.isRunning )
            CU_THROW( "Batch processing is already in progress." );
    });

    // start optimization in worker thread.
    qu::invokeInThread( &m->optimizationWorker, [=]()
    { QU_HANDLE_ALL_EXCEPTIONS_FROM {
        // set cancelled flag and running flag.
        m->shared( [this]( Impl::SharedData & shared )
        {
            shared.cancelled = false;
            shared.isRunning = true;
        });
        CU_SCOPE_EXIT {
            m->shared( [this]( Impl::SharedData & shared )
            { shared.isRunning = false; });
        };

        // set gui push buttons' enabled state
        qu    ::invokeInGuiThread( [this](){ m->ui.cancelRunButton->setEnabled(true); } );
        CU_SCOPE_EXIT {
            qu::invokeInGuiThread( [this](){ m->ui.cancelRunButton->setEnabled(false); } );
        };

        // run script in loop.
        auto i = size_t{};
        const auto progress = qu::createProgress( "Batch Run" );
        for ( auto optParam : optParams )
        {
            // Notify user about progress.
            const auto n = optParams.size();
            progress->setProgress( static_cast<double>(i)/n );
            ++i;
            qu::invokeInGuiThread( [this,i,n]()
            {
                m->ui.statusbar->showMessage(
                            QString("Optimization %1 of %2 is running ...")
                            .arg(i)
                            .arg(n) );
            } );
            // contains the indexes of the imfs that shall be optimized
            // in order.
            auto imfIndexes = std::vector<size_t>{};
            // contains the step numbers when the index of the imf
            // to be optimized shall change.
            auto imfPartSums = std::vector<size_t>{};
            auto totalImfOptSteps = size_t{0};
            for ( const auto & imfOptimization : optParam.imfOptimizations )
            {
                imfIndexes.push_back( imfOptimization.first );
                imfPartSums.push_back( totalImfOptSteps += imfOptimization.second );
            }
            optParam.howToContinue =
                    [this,imfIndexes,imfPartSums,&progress]( size_t nIter )
            {
                const auto isCancelled = m->shared(
                    []( Impl::SharedData & shared )
                {
                    return shared.cancelled;
                });
                if ( isCancelled || progress->shallAbort() )
                    return ~size_t{0};
                const auto it = std::lower_bound(
                        begin(imfPartSums),
                        end(imfPartSums),
                        nIter );
                if ( it == end(imfPartSums) )
                    return ~size_t{0};
                return imfIndexes.at( it - begin(imfPartSums) );
            };
            const auto imfs = dimf::runOptimization(optParam);
            printImfs( imfs );
            const auto isCancelled = m->shared(
                []( Impl::SharedData & shared )
            {
                return shared.cancelled;
            });
            if ( isCancelled || progress->shallAbort() )
            {
                qu::invokeInGuiThread( [this]()
                {
                    m->ui.statusbar->showMessage(
                        QString("Optimization run was cancelled.")
                        , 5000 );
                } );
                return;
            }
        }
        qu::invokeInGuiThread( [this]()
        {
            m->ui.statusbar->showMessage(
                QString("All optimization runs finished successfully.")
                , 5000 );
        } );
    }; } );
}

} // namespace gui
<|endoftext|>


<commit_before>#include <iostream>

#include "dstar_lite/dstar.h"

int main(int argc, char **argv) {
  // Check that there are 3 arguments, aka argc == 4.
  if (argc != 4) {
    std::cerr << "Terminating. Incorrect number of arguments."
              << "Expected 3." << std::endl;
    return EXIT_FAILURE;
  }

  // Parse grid.
  std::string flat_grid = argv[3];

  // Construct a grid.
  const uint grid_size = (uint)std::sqrt(flat_grid.size());
  std::vector<std::vector<int>>
      occupancy_grid (grid_size, vector<int>(grid_size));

  // Parse input
  // Retrieve start position
  const uint start = std::atoi(argv[1]);
  std::array<uint, 2> start_indices;
  start_indices[0] = std::floor(start / grid_size); //x index
  start_indices[1] = start - start_indices[0] * grid_size; //y index

  // Retrieve goal position
  const uint goal = std::atoi(argv[2]);
  std::array<uint, 2> goal_indices;
  goal_indices[0] = std::floor(goal / grid_size); //x index
  goal_indices[1] = goal - goal_indices[0] * grid_size; //y index

  // Reshape input to a grid with x, y coordinates
  for (uint i = 0, j = 0, k = 0; k < flat_grid.size(); k++) {
    j = k % grid_size;

    // Check that we are not out of bounds.
    if ( i < grid_size && j < grid_size) {
      const int a = 1 - ((int)flat_grid.at(k) - 48);
      occupancy_grid[i][j] = a;
    } else {
      std::cerr << "Index out of bounds, check that"
                   " input grid is squared." << std::endl;
      return EXIT_FAILURE;
    }

    if (j == (grid_size - 1)) {
      i++;
    }
  }

  Dstar* dstar = new Dstar();
  dstar->init(start_indices[0], start_indices[1], goal_indices[0], goal_indices[1]);
  for (uint i = 0; i < occupancy_grid.size(); i++) {
    for (uint j = 0; j < occupancy_grid.at(i).size(); j++) {
      std::cout << "Occ grid vals: " << occupancy_grid[i][j] << '\n';
      if (occupancy_grid.at(i).at(j) == 1) {
        dstar->updateCell(i+1, j+1, -1);
      }
    }
  }

  if (!dstar->replan()) {
    std::cerr << "No found path to goal" << std::endl;
    return EXIT_FAILURE;
  }

  list<state> path = dstar->getPath();
  for(const state& waypoint: path) {
    std::cout << "Waypoint: "
              << waypoint.x << ", "
              << waypoint.y << std::endl;
  }

  return EXIT_SUCCESS;
}
<commit_msg>Change response format in cout<commit_after>#include <iostream>

#include "dstar_lite/dstar.h"

int main(int argc, char **argv) {
  // Check that there are 3 arguments, aka argc == 4.
  if (argc != 4) {
    std::cerr << "Terminating. Incorrect number of arguments."
              << "Expected 3." << std::endl;
    return EXIT_FAILURE;
  }

  // Parse grid.
  std::string flat_grid = argv[3];

  // Construct a grid.
  const uint grid_size = (uint)std::sqrt(flat_grid.size());
  std::vector<std::vector<int>>
      occupancy_grid (grid_size, vector<int>(grid_size));

  // Parse input
  // Retrieve start position
  const uint start = std::atoi(argv[1]);
  std::array<uint, 2> start_indices;
  start_indices[0] = std::floor(start / grid_size); //x index
  start_indices[1] = start - start_indices[0] * grid_size; //y index

  // Retrieve goal position
  const uint goal = std::atoi(argv[2]);
  std::array<uint, 2> goal_indices;
  goal_indices[0] = std::floor(goal / grid_size); //x index
  goal_indices[1] = goal - goal_indices[0] * grid_size; //y index

  // Reshape input to a grid with x, y coordinates
  for (uint i = 0, j = 0, k = 0; k < flat_grid.size(); k++) {
    j = k % grid_size;

    // Check that we are not out of bounds.
    if ( i < grid_size && j < grid_size) {
      const int a = 1 - ((int)flat_grid.at(k) - 48);
      occupancy_grid[i][j] = a;
    } else {
      std::cerr << "Index out of bounds, check that"
                   " input grid is squared." << std::endl;
      return EXIT_FAILURE;
    }

    if (j == (grid_size - 1)) {
      i++;
    }
  }

  Dstar* dstar = new Dstar();
  dstar->init(start_indices[0], start_indices[1], goal_indices[0], goal_indices[1]);
  for (uint i = 0; i < occupancy_grid.size(); i++) {
    for (uint j = 0; j < occupancy_grid.at(i).size(); j++) {
      std::cout << "Occ grid vals: " << occupancy_grid[i][j] << '\n';
      if (occupancy_grid.at(i).at(j) == 1) {
        dstar->updateCell(i+1, j+1, -1);
      }
    }
  }

  if (!dstar->replan()) {
    std::cerr << "No found path to goal" << std::endl;
    return EXIT_FAILURE;
  }

  list<state> path = dstar->getPath();
  for(const state& waypoint: path) {
    // Send path to cout.
    std::cout << waypoint.x * grid_size + waypoint.y << std::endl;
  }

  if (debug_gui) {
    glutInit(&argc, argv);
    glutInitDisplayMode(GLUT_RGBA | GLUT_DOUBLE | GLUT_DEPTH);
    glutInitWindowSize(1000, 800);
    glutInitWindowPosition(50, 20);

    window = glutCreateWindow("Dstar Visualizer");

    glutDisplayFunc(&DrawGLScene);
    glutIdleFunc(&DrawGLScene);
    glutReshapeFunc(&ReSizeGLScene);
    glutKeyboardFunc(&keyPressed);
    glutMouseFunc(&mouseFunc);
    glutMotionFunc(&mouseMotionFunc);

    InitGL(800, 600);

    dstar->draw();

    glutMainLoop();
  }

  return EXIT_SUCCESS;
}
<|endoftext|>