<commit_before>//   Copyright (c) 2018 PaddlePaddle Authors. All Rights Reserved.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//     http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

#include "paddle/fluid/operators/assign_value_op.h"
#include <string>
#include <vector>

namespace paddle {
namespace operators {

class AssignValueOp : public framework::OperatorWithKernel {
 public:
  AssignValueOp(const std::string &type,
                const framework::VariableNameMap &inputs,
                const framework::VariableNameMap &outputs,
                const framework::AttributeMap &attrs)
      : OperatorWithKernel(type, inputs, outputs, attrs) {}

  void InferShape(framework::InferShapeContext *ctx) const override {
    PADDLE_ENFORCE(ctx->HasOutput("Out"),
                   "Output(Out) of AssignValueOp should not be null.");
    auto shape = ctx->Attrs().Get<std::vector<int>>("shape");
    ctx->SetOutputDim("Out", framework::make_ddim(shape));
  }

 protected:
  framework::OpKernelType GetExpectedKernelType(
      const framework::ExecutionContext &ctx) const override {
    return framework::OpKernelType(
        framework::proto::VarType::Type(ctx.Attr<int>("dtype")),
        ctx.GetPlace());
  }
};

class AssignValueOpMaker : public framework::OpProtoAndCheckerMaker {
 public:
  void Make() override {
    AddOutput("Out", "(Tensor) Output tensor of assign_value operator.");
    AddAttr<std::vector<int>>("shape",
                              "(vector<int>) "
                              "Shape of values.");
    AddAttr<int>("dtype", "data type of values")
        .InEnum({framework::proto::VarType::INT32,
                 framework::proto::VarType::FP32});
    AddAttr<std::vector<float>>("fp32_values", "store the float values")
        .SetDefault({});
    AddAttr<std::vector<int>>("int32_values", "store the int values")
        .SetDefault({});
    AddComment(R"DOC(
AssignValue operator

$$Out = values$$
)DOC");
  }
};

}  // namespace operators
}  // namespace paddle

namespace ops = paddle::operators;

REGISTER_OPERATOR(assign_value, ops::AssignValueOp, ops::AssignValueOpMaker);
REGISTER_OP_CPU_KERNEL(assign_value, ops::AssignValueKernel<int>,
                       ops::AssignValueKernel<float>);
<commit_msg>Register assign_value_op an empty grad_op<commit_after>//   Copyright (c) 2018 PaddlePaddle Authors. All Rights Reserved.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//     http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

#include "paddle/fluid/operators/assign_value_op.h"
#include <string>
#include <vector>

namespace paddle {
namespace operators {

class AssignValueOp : public framework::OperatorWithKernel {
 public:
  AssignValueOp(const std::string &type,
                const framework::VariableNameMap &inputs,
                const framework::VariableNameMap &outputs,
                const framework::AttributeMap &attrs)
      : OperatorWithKernel(type, inputs, outputs, attrs) {}

  void InferShape(framework::InferShapeContext *ctx) const override {
    PADDLE_ENFORCE(ctx->HasOutput("Out"),
                   "Output(Out) of AssignValueOp should not be null.");
    auto shape = ctx->Attrs().Get<std::vector<int>>("shape");
    ctx->SetOutputDim("Out", framework::make_ddim(shape));
  }

 protected:
  framework::OpKernelType GetExpectedKernelType(
      const framework::ExecutionContext &ctx) const override {
    return framework::OpKernelType(
        framework::proto::VarType::Type(ctx.Attr<int>("dtype")),
        ctx.GetPlace());
  }
};

class AssignValueOpMaker : public framework::OpProtoAndCheckerMaker {
 public:
  void Make() override {
    AddOutput("Out", "(Tensor) Output tensor of assign_value operator.");
    AddAttr<std::vector<int>>("shape",
                              "(vector<int>) "
                              "Shape of values.");
    AddAttr<int>("dtype", "data type of values")
        .InEnum({framework::proto::VarType::INT32,
                 framework::proto::VarType::FP32});
    AddAttr<std::vector<float>>("fp32_values", "store the float values")
        .SetDefault({});
    AddAttr<std::vector<int>>("int32_values", "store the int values")
        .SetDefault({});
    AddComment(R"DOC(
AssignValue operator

$$Out = values$$
)DOC");
  }
};

}  // namespace operators
}  // namespace paddle

namespace ops = paddle::operators;

REGISTER_OPERATOR(assign_value, ops::AssignValueOp, ops::AssignValueOpMaker,
                  paddle::framework::EmptyGradOpMaker);
REGISTER_OP_CPU_KERNEL(assign_value, ops::AssignValueKernel<int>,
                       ops::AssignValueKernel<float>);
<|endoftext|>


<commit_before>#include <vector>

#include <QHBoxLayout>
#include <QVBoxLayout>
#include <QString>
#include <QStandardItemModel>
#include <QAction>
#include <QMenu>
#include <QHeaderView>
#include <QTimer>

#include "common.h"
#include "event.h"
#include "task_board.h"

namespace Plow {
namespace Gui {

QStringList TaskBoardModel::HeaderLabels = QStringList()
    << "Name"
    << "State"
    << "Node"
    << "Duration"
    << "Log";

const int COLUMNS = 5;

// Return this rather than creating empty variants
// all the time.
const QVariant EMPTY_VARIANT;

/* TaskBoardWidget
**------------------------------------------------*/

TaskBoardWidget::TaskBoardWidget(QWidget* parent) :
    QWidget(parent),
    m_filter(new TaskFilterT()),
    m_layers(new QPushButton(this)),
    m_states(new QPushButton(this)),
    m_job_name(new QLabel(this)),
    m_view(new TaskBoardView(this))
{
    m_layers->setText("Layers");
    m_layers->setMenu(new QMenu(this));

    m_states->setText("States");
    m_states->setMenu(new QMenu(this));

    m_view->horizontalHeader()->setStretchLastSection(true);

    std::map<int, const char*>::const_iterator iter;
    for (iter = _TaskState_VALUES_TO_NAMES.begin();
         iter != _TaskState_VALUES_TO_NAMES.end(); ++iter)
    {
        QAction* action = new QAction(
            QString(iter->second), m_states->menu());
        action->setData(iter->first);
        action->setCheckable(true);
        m_states->menu()->addAction(action);
    }

    QHBoxLayout* ctl_layout = new QHBoxLayout();
    ctl_layout->addWidget(m_layers);
    ctl_layout->addWidget(m_states);
    ctl_layout->addStretch();
    ctl_layout->addWidget(m_job_name);

    QVBoxLayout* layout = new QVBoxLayout(this);
    layout->addLayout(ctl_layout);
    layout->addWidget(m_view);

    connect(EventManager::getInstance(), SIGNAL(jobSelected(QString)),
        this, SLOT(handleJobSelected(QString)));

    m_model = 0;
    m_timer = new QTimer(this);
    connect(m_timer, SIGNAL(timeout()), this, SLOT(refreshModel()));
}

TaskBoardWidget::~TaskBoardWidget()
{
    delete m_timer;
}

void TaskBoardWidget::refreshModel()
{
    if (m_model)
    {
        m_model->refresh();
    }
}

void TaskBoardWidget::handleJobSelected(const QString& id)
{
    JobT job;
    getJobById(job, id.toStdString());
    setJob(job);
}

void  TaskBoardWidget::setJob(const JobT& job)
{
    // Stop the timer
    m_timer->stop();

    std::vector<LayerT> layers;
    Plow::getLayers(layers, job);

    // Update the layer display
    m_layers->menu()->clear();
    for (int r = 0; r < layers.size(); ++r)
    {
        QAction* action = new QAction(
            QString::fromStdString(layers[r].name), m_layers->menu());
        action->setCheckable(true);
        m_layers->menu()->addAction(action);
    }

    // Set up a new model
    m_filter->jobId = job.id;
    TaskBoardModel* model = new TaskBoardModel(*m_filter, this);
    model->init();

    m_job_name->setText(QString::fromStdString(job.name));
    m_view->setModel(model);
    m_view->setColumnWidth(0, 350);

    // If we have an old model set, delete it.
    if (m_model) {
        delete m_model;
        m_model = 0;
    }

    // Set the model and restart the timer.
    m_model = model;
    m_timer->start(3000);
}

TaskFilterT* TaskBoardWidget::getTaskFilter() const
{
    return m_filter;
}

/* TaskBoardView
**------------------------------------------------*/

TaskBoardView::TaskBoardView(QWidget* parent) :
    QTableView(parent)
{

    connect(this, SIGNAL(doubleClicked(const QModelIndex&)),
        this, SLOT(taskDoubleClickedHandler(const QModelIndex&)));
}

TaskBoardView::~TaskBoardView()
{

}

void TaskBoardView::taskDoubleClickedHandler(const QModelIndex& index)
{
    QString taskId = model()->data(index, Qt::UserRole).toString();
    //TODO: add log file viewer.
}

/* TaskBoardModel
**------------------------------------------------*/

TaskBoardModel::TaskBoardModel(TaskFilterT filter, QObject* parent) :
    QAbstractTableModel(parent),
    m_filter(filter)
{

}

TaskBoardModel::~TaskBoardModel()
{
    m_timer->stop();
    delete m_timer;
}

void TaskBoardModel::init()
{
    uint64_t qtime = getPlowTime();

    getTasks(m_tasks, m_filter);
    m_filter.lastUpdateTime = qtime;

    for(int i=0; i<m_tasks.size(); i++) {
        m_index[m_tasks[i].id] = i;
    }

    m_timer = new QTimer(this);
    connect(m_timer, SIGNAL(timeout()), this, SLOT(refreshRunningTime()));
    m_timer->start(1000);
}

void TaskBoardModel::refresh()
{

    // Get the time from the server.
    uint64_t plow_time = getPlowTime();

    // Make a query to get the tasks since the last update time.
    std::vector<TaskT> updated;
    getTasks(updated, m_filter);

    // Set the update time for the next query;
    m_filter.lastUpdateTime = plow_time;

    std::vector<TaskT>::iterator iter;
    for (iter = updated.begin(); iter != updated.end(); ++iter)
    {
        int idx = m_index[iter->id];
        m_tasks[idx] = *iter;
        emit dataChanged(index(idx, 0), index(idx, COLUMNS-1));
    }
}

void TaskBoardModel::refreshRunningTime()
{
    std::vector<TaskT>::iterator iter;
    for (iter = m_tasks.begin(); iter != m_tasks.end(); ++iter)
    {
        if (iter->state == TaskState::RUNNING)
        {
            emit dataChanged(index(m_index[iter->id], 0),
                             index(m_index[iter->id], COLUMNS-1));
        }
    }
}

int TaskBoardModel::rowCount(const QModelIndex& parent) const
{
    return m_tasks.size();
}

int TaskBoardModel::columnCount (const QModelIndex& parent) const
{
    return COLUMNS;
}

QVariant TaskBoardModel::headerData(int section, Qt::Orientation orientation, int role) const
{
    if (orientation != Qt::Horizontal) {
        return EMPTY_VARIANT;

    }
    switch(role)
    {
    case Qt::DisplayRole:
        return TaskBoardModel::HeaderLabels[section];
    }

    return EMPTY_VARIANT;
}

QVariant TaskBoardModel::data (const QModelIndex & index, int role) const
{
    int row = index.row();
    int col = index.column();

    const TaskT& task = m_tasks[row];

    switch(role)
    {

    case Qt::DisplayRole:
        if (col == 0)
        {
            return QString(task.name.c_str());
        }
        else if (col == 1)
        {
            int state = task.state;
            return QString(_TaskState_VALUES_TO_NAMES.find(state)->second);
        }
        else if (col == 2)
        {
            return QString(task.lastNodeName.c_str());
        }
        else if (col == 3)
        {
            std::string duration;
            formatDuration(duration, task.startTime, task.stopTime);
            return QString::fromStdString(duration);
        }
        else if (col == 4) {
            return QString(task.lastLogLine.c_str());
        }
        break;

    case Qt::BackgroundRole:
        if (col == 1)
        {
            int state = task.state;
            return PlowStyle::TaskColors[state];
        }
        break;

    case Qt::UserRole:
        return QString::fromStdString(task.id);

    }

    return QVariant();
}

} //
} //<commit_msg>Return a const static empty QVariant rather than creating lots of new ones,<commit_after>#include <vector>

#include <QHBoxLayout>
#include <QVBoxLayout>
#include <QString>
#include <QStandardItemModel>
#include <QAction>
#include <QMenu>
#include <QHeaderView>
#include <QTimer>

#include "common.h"
#include "event.h"
#include "task_board.h"

namespace Plow {
namespace Gui {

QStringList TaskBoardModel::HeaderLabels = QStringList()
    << "Name"
    << "State"
    << "Node"
    << "Duration"
    << "Log";

const int COLUMNS = 5;

// Return this rather than creating empty variants
// all the time.
const QVariant EMPTY_VARIANT;

/* TaskBoardWidget
**------------------------------------------------*/

TaskBoardWidget::TaskBoardWidget(QWidget* parent) :
    QWidget(parent),
    m_filter(new TaskFilterT()),
    m_layers(new QPushButton(this)),
    m_states(new QPushButton(this)),
    m_job_name(new QLabel(this)),
    m_view(new TaskBoardView(this))
{
    m_layers->setText("Layers");
    m_layers->setMenu(new QMenu(this));

    m_states->setText("States");
    m_states->setMenu(new QMenu(this));

    m_view->horizontalHeader()->setStretchLastSection(true);

    std::map<int, const char*>::const_iterator iter;
    for (iter = _TaskState_VALUES_TO_NAMES.begin();
         iter != _TaskState_VALUES_TO_NAMES.end(); ++iter)
    {
        QAction* action = new QAction(
            QString(iter->second), m_states->menu());
        action->setData(iter->first);
        action->setCheckable(true);
        m_states->menu()->addAction(action);
    }

    QHBoxLayout* ctl_layout = new QHBoxLayout();
    ctl_layout->addWidget(m_layers);
    ctl_layout->addWidget(m_states);
    ctl_layout->addStretch();
    ctl_layout->addWidget(m_job_name);

    QVBoxLayout* layout = new QVBoxLayout(this);
    layout->addLayout(ctl_layout);
    layout->addWidget(m_view);

    connect(EventManager::getInstance(), SIGNAL(jobSelected(QString)),
        this, SLOT(handleJobSelected(QString)));

    m_model = 0;
    m_timer = new QTimer(this);
    connect(m_timer, SIGNAL(timeout()), this, SLOT(refreshModel()));
}

TaskBoardWidget::~TaskBoardWidget()
{
    delete m_timer;
}

void TaskBoardWidget::refreshModel()
{
    if (m_model)
    {
        m_model->refresh();
    }
}

void TaskBoardWidget::handleJobSelected(const QString& id)
{
    JobT job;
    getJobById(job, id.toStdString());
    setJob(job);
}

void  TaskBoardWidget::setJob(const JobT& job)
{
    // Stop the timer
    m_timer->stop();

    std::vector<LayerT> layers;
    Plow::getLayers(layers, job);

    // Update the layer display
    m_layers->menu()->clear();
    for (int r = 0; r < layers.size(); ++r)
    {
        QAction* action = new QAction(
            QString::fromStdString(layers[r].name), m_layers->menu());
        action->setCheckable(true);
        m_layers->menu()->addAction(action);
    }

    // Set up a new model
    m_filter->jobId = job.id;
    TaskBoardModel* model = new TaskBoardModel(*m_filter, this);
    model->init();

    m_job_name->setText(QString::fromStdString(job.name));
    m_view->setModel(model);
    m_view->setColumnWidth(0, 350);

    // If we have an old model set, delete it.
    if (m_model) {
        delete m_model;
        m_model = 0;
    }

    // Set the model and restart the timer.
    m_model = model;
    m_timer->start(3000);
}

TaskFilterT* TaskBoardWidget::getTaskFilter() const
{
    return m_filter;
}

/* TaskBoardView
**------------------------------------------------*/

TaskBoardView::TaskBoardView(QWidget* parent) :
    QTableView(parent)
{

    connect(this, SIGNAL(doubleClicked(const QModelIndex&)),
        this, SLOT(taskDoubleClickedHandler(const QModelIndex&)));
}

TaskBoardView::~TaskBoardView()
{

}

void TaskBoardView::taskDoubleClickedHandler(const QModelIndex& index)
{
    QString taskId = model()->data(index, Qt::UserRole).toString();
    //TODO: add log file viewer.
}

/* TaskBoardModel
**------------------------------------------------*/

TaskBoardModel::TaskBoardModel(TaskFilterT filter, QObject* parent) :
    QAbstractTableModel(parent),
    m_filter(filter)
{

}

TaskBoardModel::~TaskBoardModel()
{
    m_timer->stop();
    delete m_timer;
}

void TaskBoardModel::init()
{
    uint64_t qtime = getPlowTime();

    getTasks(m_tasks, m_filter);
    m_filter.lastUpdateTime = qtime;

    for(int i=0; i<m_tasks.size(); i++) {
        m_index[m_tasks[i].id] = i;
    }

    m_timer = new QTimer(this);
    connect(m_timer, SIGNAL(timeout()), this, SLOT(refreshRunningTime()));
    m_timer->start(1000);
}

void TaskBoardModel::refresh()
{

    // Get the time from the server.
    uint64_t plow_time = getPlowTime();

    // Make a query to get the tasks since the last update time.
    std::vector<TaskT> updated;
    getTasks(updated, m_filter);

    // Set the update time for the next query;
    m_filter.lastUpdateTime = plow_time;

    std::vector<TaskT>::iterator iter;
    for (iter = updated.begin(); iter != updated.end(); ++iter)
    {
        int idx = m_index[iter->id];
        m_tasks[idx] = *iter;
        emit dataChanged(index(idx, 0), index(idx, COLUMNS-1));
    }
}

void TaskBoardModel::refreshRunningTime()
{
    std::vector<TaskT>::iterator iter;
    for (iter = m_tasks.begin(); iter != m_tasks.end(); ++iter)
    {
        if (iter->state == TaskState::RUNNING)
        {
            emit dataChanged(index(m_index[iter->id], 0),
                             index(m_index[iter->id], COLUMNS-1));
        }
    }
}

int TaskBoardModel::rowCount(const QModelIndex& parent) const
{
    return m_tasks.size();
}

int TaskBoardModel::columnCount (const QModelIndex& parent) const
{
    return COLUMNS;
}

QVariant TaskBoardModel::headerData(int section, Qt::Orientation orientation, int role) const
{
    if (orientation != Qt::Horizontal) {
        return EMPTY_VARIANT;

    }
    switch(role)
    {
    case Qt::DisplayRole:
        return TaskBoardModel::HeaderLabels[section];
    }

    return EMPTY_VARIANT;
}

QVariant TaskBoardModel::data (const QModelIndex & index, int role) const
{
    int row = index.row();
    int col = index.column();

    const TaskT& task = m_tasks[row];

    switch(role)
    {

    case Qt::DisplayRole:
        if (col == 0)
        {
            return QString(task.name.c_str());
        }
        else if (col == 1)
        {
            int state = task.state;
            return QString(_TaskState_VALUES_TO_NAMES.find(state)->second);
        }
        else if (col == 2)
        {
            return QString(task.lastNodeName.c_str());
        }
        else if (col == 3)
        {
            std::string duration;
            formatDuration(duration, task.startTime, task.stopTime);
            return QString::fromStdString(duration);
        }
        else if (col == 4) {
            return QString(task.lastLogLine.c_str());
        }
        break;

    case Qt::BackgroundRole:
        if (col == 1)
        {
            int state = task.state;
            return PlowStyle::TaskColors[state];
        }
        break;

    case Qt::UserRole:
        return QString::fromStdString(task.id);

    }

    return EMPTY_VARIANT;
}

} //
} //<|endoftext|>


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

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

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

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

#include "paddle/fluid/operators/cvm_op.h"
#include <memory>
#include "paddle/fluid/operators/math/math_function.h"

namespace paddle {
namespace operators {

using Tensor = framework::Tensor;

class CVMOp : public framework::OperatorWithKernel {
 public:
  using framework::OperatorWithKernel::OperatorWithKernel;

  void InferShape(framework::InferShapeContext* ctx) const override {
    PADDLE_ENFORCE(ctx->HasInput("X"), "Input(X) should be not null.");
    PADDLE_ENFORCE(ctx->HasInput("CVM"), "Input(CVM) should be not null.");
    PADDLE_ENFORCE(ctx->HasOutput("Y"), "Output(Y) should be not null.");

    auto x_dims = ctx->GetInputDim("X");
    auto cvm_dims = ctx->GetInputDim("CVM");
    PADDLE_ENFORCE_EQ(x_dims.size(), 2UL, "Input(X)'s rank should be 2.");
    PADDLE_ENFORCE_EQ(cvm_dims.size(), 2UL, "Input(CVM)'s rank should be 2.");
    PADDLE_ENFORCE_EQ(cvm_dims[1], 2UL,
                      "The 2nd dimension of "
                      "Input(CVM) should be 2.");

    if (ctx->Attrs().Get<bool>("use_cvm")) {
      ctx->SetOutputDim("Y", {x_dims[0], x_dims[1]});
    } else {
      ctx->SetOutputDim("Y", {x_dims[0], x_dims[1] - 2});
    }
    ctx->ShareLoD("X", /*->*/ "Y");
  }

 protected:
  // Explicitly set that the data type of computation kernel of
  // cvm
  // is determined by its input "X".
  framework::OpKernelType GetExpectedKernelType(
      const framework::ExecutionContext& ctx) const override {
    return framework::OpKernelType(ctx.Input<Tensor>("X")->type(),
                                   ctx.device_context());
  }
};

class CVMGradientOp : public framework::OperatorWithKernel {
 public:
  using framework::OperatorWithKernel::OperatorWithKernel;

  void InferShape(framework::InferShapeContext* ctx) const override {
    PADDLE_ENFORCE(ctx->HasInput("X"), "Input(X) should be not null.");
    PADDLE_ENFORCE(ctx->HasInput("CVM"), "Input(CVM) should be not null.");
    PADDLE_ENFORCE(ctx->HasInput(framework::GradVarName("Y")),
                   "Input(Y@GRAD) should be not null.");
    PADDLE_ENFORCE(ctx->HasOutput(framework::GradVarName("X")),
                   "Output(X@GRAD) should be not null.");

    auto x_dims = ctx->GetInputDim("X");
    auto cvm_dims = ctx->GetInputDim("CVM");
    auto dy_dims = ctx->GetInputDim(framework::GradVarName("Y"));
    PADDLE_ENFORCE_EQ(x_dims.size(), 2, "Input(X)'s rank should be 2.");
    PADDLE_ENFORCE_EQ(dy_dims.size(), 2, "Input(Y@Grad)'s rank should be 2.");
    PADDLE_ENFORCE_EQ(cvm_dims.size(), 2, "Input(CVM)'s rank should be 2.");

    PADDLE_ENFORCE_EQ(x_dims[0], dy_dims[0],
                      "The 1st dimension of Input(X) and Input(Y@Grad) should "
                      "be equal.");

    PADDLE_ENFORCE_EQ(cvm_dims[1], 2,
                      "When Attr(soft_label) == false, the 2nd dimension of "
                      "Input(CVM) should be 2.");
    ctx->SetOutputDim(framework::GradVarName("X"), x_dims);
    ctx->ShareLoD("X", framework::GradVarName("X"));
  }

 protected:
  // Explicitly set that the data type of computation kernel of
  // cvm
  // is determined by its input "X".
  framework::OpKernelType GetExpectedKernelType(
      const framework::ExecutionContext& ctx) const override {
    return framework::OpKernelType(ctx.Input<Tensor>("X")->type(),
                                   ctx.device_context());
  }
};

class CVMOpMaker : public framework::OpProtoAndCheckerMaker {
 public:
  void Make() override {
    AddInput("X",
             "(LodTensor, default LodTensor<float>), a 2-D tensor with shape "
             "[N x D],"
             " where N is the batch size and D is the emebdding dim. ");
    AddInput("CVM",
             "(Tensor),  a 2-D Tensor with shape [N x 2], where N is the batch "
             "size, 2 is show and click.");
    AddOutput("Y",
              "(LodTensor, default LodTensor<float>), a 2-D tensor with shape "
              "[N x K].");
    AddAttr<bool>("use_cvm", "bool, use cvm or not").SetDefault(true);
    AddComment(R"DOC(
CVM Operator.
      We assume that input is a embedding vector with cvm_feature(show and click), which shape is [N * D] (D is 2(cvm_feature) + embedding dim, N is batch_size)
      if use_cvm is True, we will log(cvm_feature), and output shape is [N * D].
      if use_cvm is False, we will remove cvm_feature from input, and output shape is [N * (D - 2)].

      Example:
          input = fluid.layers.data(name=\"input\", shape=[-1, 1], lod_level=1, append_batch_size=False, dtype=\"int64\")
          label = fluid.layers.data(name=\"label\", shape=[-1, 1], append_batch_size=False, dtype=\"int64\")

          embed = fluid.layers.embedding(
                            input=input,
                            size=[100, 11],
                            dtype='float32')

          ones = fluid.layers.fill_constant_batch_size_like(input=label, shape=[-1, 1], dtype=\"int64\", value=1)
          show_clk = fluid.layers.cast(fluid.layers.concat([ones, label], axis=1), dtype='float32')
          show_clk.stop_gradient = True

          input_with_cvm = fluid.layers.continuous_value_model(embed, show_clk, True)

)DOC");
  }
};

class CVMGradOpDescMaker : public framework::SingleGradOpDescMaker {
 public:
  using framework::SingleGradOpDescMaker::SingleGradOpDescMaker;

 protected:
  std::unique_ptr<framework::OpDesc> Apply() const override {
    std::unique_ptr<framework::OpDesc> op(new framework::OpDesc());
    op->SetType("cvm_grad");
    op->SetInput("X", Input("X"));
    op->SetInput("CVM", Input("CVM"));
    op->SetInput(framework::GradVarName("Y"), OutputGrad("Y"));
    op->SetOutput(framework::GradVarName("X"), InputGrad("X"));
    op->SetOutput(framework::GradVarName("CVM"), InputGrad("CVM"));
    op->SetAttrMap(Attrs());
    return op;
  }
};

}  // namespace operators
}  // namespace paddle

namespace ops = paddle::operators;
REGISTER_OPERATOR(cvm, ops::CVMOp, ops::CVMOpMaker, ops::CVMGradOpDescMaker);

REGISTER_OPERATOR(cvm_grad, ops::CVMGradientOp);

REGISTER_OP_CPU_KERNEL(cvm, ops::CVMOpKernel<float>, ops::CVMOpKernel<double>);

REGISTER_OP_CPU_KERNEL(cvm_grad, ops::CVMGradOpKernel<float>,
                       ops::CVMGradOpKernel<double>);
<commit_msg>add doc test=develop<commit_after>/* Copyright (c) 2018 PaddlePaddle Authors. All Rights Reserve.

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

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

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

#include "paddle/fluid/operators/cvm_op.h"
#include <memory>
#include "paddle/fluid/operators/math/math_function.h"

namespace paddle {
namespace operators {

using Tensor = framework::Tensor;

class CVMOp : public framework::OperatorWithKernel {
 public:
  using framework::OperatorWithKernel::OperatorWithKernel;

  void InferShape(framework::InferShapeContext* ctx) const override {
    PADDLE_ENFORCE(ctx->HasInput("X"), "Input(X) should be not null.");
    PADDLE_ENFORCE(ctx->HasInput("CVM"), "Input(CVM) should be not null.");
    PADDLE_ENFORCE(ctx->HasOutput("Y"), "Output(Y) should be not null.");

    auto x_dims = ctx->GetInputDim("X");
    auto cvm_dims = ctx->GetInputDim("CVM");
    PADDLE_ENFORCE_EQ(x_dims.size(), 2UL, "Input(X)'s rank should be 2.");
    PADDLE_ENFORCE_EQ(cvm_dims.size(), 2UL, "Input(CVM)'s rank should be 2.");
    PADDLE_ENFORCE_EQ(cvm_dims[1], 2UL,
                      "The 2nd dimension of "
                      "Input(CVM) should be 2.");

    if (ctx->Attrs().Get<bool>("use_cvm")) {
      ctx->SetOutputDim("Y", {x_dims[0], x_dims[1]});
    } else {
      ctx->SetOutputDim("Y", {x_dims[0], x_dims[1] - 2});
    }
    ctx->ShareLoD("X", /*->*/ "Y");
  }

 protected:
  // Explicitly set that the data type of computation kernel of
  // cvm
  // is determined by its input "X".
  framework::OpKernelType GetExpectedKernelType(
      const framework::ExecutionContext& ctx) const override {
    return framework::OpKernelType(ctx.Input<Tensor>("X")->type(),
                                   ctx.device_context());
  }
};

class CVMGradientOp : public framework::OperatorWithKernel {
 public:
  using framework::OperatorWithKernel::OperatorWithKernel;

  void InferShape(framework::InferShapeContext* ctx) const override {
    PADDLE_ENFORCE(ctx->HasInput("X"), "Input(X) should be not null.");
    PADDLE_ENFORCE(ctx->HasInput("CVM"), "Input(CVM) should be not null.");
    PADDLE_ENFORCE(ctx->HasInput(framework::GradVarName("Y")),
                   "Input(Y@GRAD) should be not null.");
    PADDLE_ENFORCE(ctx->HasOutput(framework::GradVarName("X")),
                   "Output(X@GRAD) should be not null.");

    auto x_dims = ctx->GetInputDim("X");
    auto cvm_dims = ctx->GetInputDim("CVM");
    auto dy_dims = ctx->GetInputDim(framework::GradVarName("Y"));
    PADDLE_ENFORCE_EQ(x_dims.size(), 2, "Input(X)'s rank should be 2.");
    PADDLE_ENFORCE_EQ(dy_dims.size(), 2, "Input(Y@Grad)'s rank should be 2.");
    PADDLE_ENFORCE_EQ(cvm_dims.size(), 2, "Input(CVM)'s rank should be 2.");

    PADDLE_ENFORCE_EQ(x_dims[0], dy_dims[0],
                      "The 1st dimension of Input(X) and Input(Y@Grad) should "
                      "be equal.");

    PADDLE_ENFORCE_EQ(cvm_dims[1], 2,
                      "When Attr(soft_label) == false, the 2nd dimension of "
                      "Input(CVM) should be 2.");
    ctx->SetOutputDim(framework::GradVarName("X"), x_dims);
    ctx->ShareLoD("X", framework::GradVarName("X"));
  }

 protected:
  // Explicitly set that the data type of computation kernel of
  // cvm
  // is determined by its input "X".
  framework::OpKernelType GetExpectedKernelType(
      const framework::ExecutionContext& ctx) const override {
    return framework::OpKernelType(ctx.Input<Tensor>("X")->type(),
                                   ctx.device_context());
  }
};

class CVMOpMaker : public framework::OpProtoAndCheckerMaker {
 public:
  void Make() override {
    AddInput("X",
             "(LodTensor, default LodTensor<float>), a 2-D tensor with shape "
             "[N x D],"
             " where N is the batch size and D is the emebdding dim. ");
    AddInput("CVM",
             "(Tensor),  a 2-D Tensor with shape [N x 2], where N is the batch "
             "size, 2 is show and click.");
    AddOutput("Y",
              "(LodTensor, default LodTensor<float>), a 2-D tensor with shape "
              "[N x K].");
    AddAttr<bool>("use_cvm", "bool, use cvm or not").SetDefault(true);
    AddComment(R"DOC(
CVM Operator.

      We assume that input is a embedding vector with cvm_feature(show and click), which shape is [N * D] (D is 2(cvm_feature) + embedding dim, N is batch_size)
      if use_cvm is True, we will log(cvm_feature), and output shape is [N * D].
      if use_cvm is False, we will remove cvm_feature from input, and output shape is [N * (D - 2)].

  Example:
          input = fluid.layers.data(name=\"input\", shape=[-1, 1], lod_level=1, append_batch_size=False, dtype=\"int64\")
          label = fluid.layers.data(name=\"label\", shape=[-1, 1], append_batch_size=False, dtype=\"int64\")

          embed = fluid.layers.embedding(
                            input=input,
                            size=[100, 11],
                            dtype='float32')

          ones = fluid.layers.fill_constant_batch_size_like(input=label, shape=[-1, 1], dtype=\"int64\", value=1)
          show_clk = fluid.layers.cast(fluid.layers.concat([ones, label], axis=1), dtype='float32')
          show_clk.stop_gradient = True

          input_with_cvm = fluid.layers.continuous_value_model(embed, show_clk, True)

)DOC");
  }
};

class CVMGradOpDescMaker : public framework::SingleGradOpDescMaker {
 public:
  using framework::SingleGradOpDescMaker::SingleGradOpDescMaker;

 protected:
  std::unique_ptr<framework::OpDesc> Apply() const override {
    std::unique_ptr<framework::OpDesc> op(new framework::OpDesc());
    op->SetType("cvm_grad");
    op->SetInput("X", Input("X"));
    op->SetInput("CVM", Input("CVM"));
    op->SetInput(framework::GradVarName("Y"), OutputGrad("Y"));
    op->SetOutput(framework::GradVarName("X"), InputGrad("X"));
    op->SetOutput(framework::GradVarName("CVM"), InputGrad("CVM"));
    op->SetAttrMap(Attrs());
    return op;
  }
};

}  // namespace operators
}  // namespace paddle

namespace ops = paddle::operators;
REGISTER_OPERATOR(cvm, ops::CVMOp, ops::CVMOpMaker, ops::CVMGradOpDescMaker);

REGISTER_OPERATOR(cvm_grad, ops::CVMGradientOp);

REGISTER_OP_CPU_KERNEL(cvm, ops::CVMOpKernel<float>, ops::CVMOpKernel<double>);

REGISTER_OP_CPU_KERNEL(cvm_grad, ops::CVMGradOpKernel<float>,
                       ops::CVMGradOpKernel<double>);
<|endoftext|>


<commit_before>// Copyright 2020 The XLS Authors
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//      http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

#include "xls/common/file/get_runfile_path.h"

#include <cstdlib>

#include "absl/base/const_init.h"
#include "absl/status/status.h"
#include "absl/status/statusor.h"
#include "absl/synchronization/mutex.h"
#include "xls/common/file/filesystem.h"
#include "xls/common/logging/logging.h"
#include "xls/common/module_initializer.h"
#include "xls/common/status/ret_check.h"
#include "tools/cpp/runfiles/runfiles.h"

namespace xls {
namespace {

using ::bazel::tools::cpp::runfiles::Runfiles;

static absl::Mutex mutex(absl::kConstInit);
static Runfiles* runfiles;

absl::StatusOr<Runfiles*> GetRunfiles(
    const std::string& argv0 = "/proc/self/exe") {
  absl::MutexLock lock(&mutex);
  if (runfiles == nullptr) {
    // Need to dereference the path, in case it's a link (as with the default).
    XLS_ASSIGN_OR_RETURN(auto path, GetRealPath(argv0));

    std::string error;
    runfiles = Runfiles::Create(path.string(), &error);
    XLS_RET_CHECK(runfiles != nullptr)
        << "Failed to initialize Runfiles: " << error;
  }

  return runfiles;
}

}  // namespace

absl::StatusOr<std::filesystem::path> GetXlsRunfilePath(
    const std::filesystem::path& path) {
  Runfiles* runfiles = GetRunfiles().value();
  return runfiles->Rlocation("com_google_xls" / path);
}

absl::Status InitRunfilesDir(const std::string& argv0) {
  return GetRunfiles(argv0).status();
}

}  // namespace xls
<commit_msg>[COMMON] Replace assertion in GetRunfiles with a status return to follow API and comment of funtion.<commit_after>// Copyright 2020 The XLS Authors
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//      http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

#include "xls/common/file/get_runfile_path.h"

#include <cstdlib>

#include "absl/base/const_init.h"
#include "absl/status/status.h"
#include "absl/status/statusor.h"
#include "absl/synchronization/mutex.h"
#include "xls/common/file/filesystem.h"
#include "xls/common/logging/logging.h"
#include "xls/common/module_initializer.h"
#include "xls/common/status/ret_check.h"
#include "tools/cpp/runfiles/runfiles.h"

namespace xls {
namespace {

using ::bazel::tools::cpp::runfiles::Runfiles;

static absl::Mutex mutex(absl::kConstInit);
static Runfiles* runfiles;

absl::StatusOr<Runfiles*> GetRunfiles(
    const std::string& argv0 = "/proc/self/exe") {
  absl::MutexLock lock(&mutex);
  if (runfiles == nullptr) {
    // Need to dereference the path, in case it's a link (as with the default).
    XLS_ASSIGN_OR_RETURN(auto path, GetRealPath(argv0));

    std::string error;
    runfiles = Runfiles::Create(path.string(), &error);
    if (runfiles == nullptr) {
      return absl::UnknownError(
          absl::StrCat("Failed to initialize Runfiles: ", error));
    }
  }

  return runfiles;
}

}  // namespace

absl::StatusOr<std::filesystem::path> GetXlsRunfilePath(
    const std::filesystem::path& path) {
  XLS_ASSIGN_OR_RETURN(Runfiles * runfiles, GetRunfiles());
  return runfiles->Rlocation("com_google_xls" / path);
}

absl::Status InitRunfilesDir(const std::string& argv0) {
  return GetRunfiles(argv0).status();
}

}  // namespace xls
<|endoftext|>


<commit_before>#include "sorter_threaded.hpp"
#include <algorithm>
#include <assert.h>
#include <fstream>

int main(int argc, char **argv) {
  size_t testSize = 10000;
  std::vector<double> orderedVector(testSize);
  SorterThreaded st;

  for (size_t i = 0; i < testSize; i++) {
    orderedVector[i] = static_cast<double>(i);
  }
  std::vector<double> testVector(orderedVector);

  random_shuffle(testVector.begin(), testVector.end());

  st.sort(testVector.begin(), testVector.end());

  assert(testVector == orderedVector);

}
<commit_msg>got rid of unnessary includes and increased the test size to 1M<commit_after>#include "sorter_threaded.hpp"
#include <assert.h>

int main(int argc, char **argv) {
  size_t testSize = 1000000;
  std::vector<double> orderedVector(testSize);
  SorterThreaded st;

  for (size_t i = 0; i < testSize; i++) {
    orderedVector[i] = static_cast<double>(i);
  }
  std::vector<double> testVector(orderedVector);

  random_shuffle(testVector.begin(), testVector.end());

  st.sort(testVector.begin(), testVector.end());

  assert(testVector == orderedVector);

}
<|endoftext|>


<commit_before>/*************************************************************************
 *
 *  OpenOffice.org - a multi-platform office productivity suite
 *
 *  $RCSfile: Block.cxx,v $
 *
 *  $Revision: 1.4 $
 *
 *  last change: $Author: rt $ $Date: 2005-09-09 12:16:40 $
 *
 *  The Contents of this file are made available subject to
 *  the terms of GNU Lesser General Public License Version 2.1.
 *
 *
 *    GNU Lesser General Public License Version 2.1
 *    =============================================
 *    Copyright 2005 by Sun Microsystems, Inc.
 *    901 San Antonio Road, Palo Alto, CA 94303, USA
 *
 *    This library is free software; you can redistribute it and/or
 *    modify it under the terms of the GNU Lesser General Public
 *    License version 2.1, as published by the Free Software Foundation.
 *
 *    This library is distributed in the hope that it will be useful,
 *    but WITHOUT ANY WARRANTY; without even the implied warranty of
 *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 *    Lesser General Public License for more details.
 *
 *    You should have received a copy of the GNU Lesser General Public
 *    License along with this library; if not, write to the Free Software
 *    Foundation, Inc., 59 Temple Place, Suite 330, Boston,
 *    MA  02111-1307  USA
 *
 ************************************************************************/
#ifndef _RTL_MEMORY_H_
#include <rtl/memory.h>
#endif
#ifndef _XMLSEARCH_DB_BLOCK_HXX_
#include <db/Block.hxx>
#endif
#ifndef _XMLSEARCH_UTIL_RANDOMACCESSSTREAM_HXX_
#include <util/RandomAccessStream.hxx>
#endif
#ifndef _XMLSEARCH_DB_DBENV_HXX_
#include <db/DBEnv.hxx>
#endif

using namespace xmlsearch;
using namespace xmlsearch::db;

/******************************************************************************/
/*                                                                            */
/*                              Block                                         */
/*                                                                            */
/******************************************************************************/

Block::Block( const DBEnv* dbenv )
  : dbenv_( dbenv ),
    isLeaf_( true ),
    free_( 0 ),
    num_( 0 ),
    dataL_( dbenv->getDataLen() ),
    data_( new sal_Int8[ dbenv->getDataLen() ] )
{
    rtl_zeroMemory( data_,dataL_ );
}

Block::~Block()
{
  delete[] data_;
}

void Block::read( util::RandomAccessStream* in )
{
  sal_Int8 buffer[4];
  in->readBytes( buffer,4 );
  num_ = getInteger_( buffer );

  in->readBytes( buffer,4 );
  sal_Int32 twoFields = getInteger_( buffer );

  isLeaf_ = ( twoFields & 0x80000000 ) != 0;
  free_ = twoFields & 0x7FFFFFFF;

  in->readBytes( data_,dbenv_->getDataLen() );
}

void Block::write( util::RandomAccessStream* out ) const
{
  out->writeBytes( (sal_Int8*)(&num_),4 );
  sal_Int32 twoFields = ( free_ | ( isLeaf_ ? 0x80000000 : 0 ) );
  out->writeBytes( (sal_Int8*)(&twoFields),4 );
  out->writeBytes( data_,dbenv_->getDataLen() );
}

void Block::setInteger( sal_Int32 i,sal_Int32 value ) throw( excep::IllegalIndexException )
{
  if( i < 0 || dbenv_->getDataLen() <= i  )
    throw excep::IllegalIndexException(
                       rtl::OUString::createFromAscii( "Block::setInteger -> index out of range" ) );

  ::setInteger_( &data_[i],value );
}

sal_Int32 Block::getInteger( sal_Int32 i ) const throw( excep::IllegalIndexException )
{
  if( i < 0 || dbenv_->getDataLen() <= i  )
    throw excep::IllegalIndexException(
                       rtl::OUString::createFromAscii( "Block::setInteger -> index out of range" ) );

    sal_Int32 ret = ::getInteger_( &data_[i] );
  return ret;
}

<commit_msg>INTEGRATION: CWS pchfix02 (1.4.40); FILE MERGED 2006/09/01 17:58:30 kaib 1.4.40.1: #i68856# Added header markers and pch files<commit_after>/*************************************************************************
 *
 *  OpenOffice.org - a multi-platform office productivity suite
 *
 *  $RCSfile: Block.cxx,v $
 *
 *  $Revision: 1.5 $
 *
 *  last change: $Author: obo $ $Date: 2006-09-17 01:14:40 $
 *
 *  The Contents of this file are made available subject to
 *  the terms of GNU Lesser General Public License Version 2.1.
 *
 *
 *    GNU Lesser General Public License Version 2.1
 *    =============================================
 *    Copyright 2005 by Sun Microsystems, Inc.
 *    901 San Antonio Road, Palo Alto, CA 94303, USA
 *
 *    This library is free software; you can redistribute it and/or
 *    modify it under the terms of the GNU Lesser General Public
 *    License version 2.1, as published by the Free Software Foundation.
 *
 *    This library is distributed in the hope that it will be useful,
 *    but WITHOUT ANY WARRANTY; without even the implied warranty of
 *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 *    Lesser General Public License for more details.
 *
 *    You should have received a copy of the GNU Lesser General Public
 *    License along with this library; if not, write to the Free Software
 *    Foundation, Inc., 59 Temple Place, Suite 330, Boston,
 *    MA  02111-1307  USA
 *
 ************************************************************************/

// MARKER(update_precomp.py): autogen include statement, do not remove
#include "precompiled_xmlhelp.hxx"
#ifndef _RTL_MEMORY_H_
#include <rtl/memory.h>
#endif
#ifndef _XMLSEARCH_DB_BLOCK_HXX_
#include <db/Block.hxx>
#endif
#ifndef _XMLSEARCH_UTIL_RANDOMACCESSSTREAM_HXX_
#include <util/RandomAccessStream.hxx>
#endif
#ifndef _XMLSEARCH_DB_DBENV_HXX_
#include <db/DBEnv.hxx>
#endif

using namespace xmlsearch;
using namespace xmlsearch::db;

/******************************************************************************/
/*                                                                            */
/*                              Block                                         */
/*                                                                            */
/******************************************************************************/

Block::Block( const DBEnv* dbenv )
  : dbenv_( dbenv ),
    isLeaf_( true ),
    free_( 0 ),
    num_( 0 ),
    dataL_( dbenv->getDataLen() ),
    data_( new sal_Int8[ dbenv->getDataLen() ] )
{
    rtl_zeroMemory( data_,dataL_ );
}

Block::~Block()
{
  delete[] data_;
}

void Block::read( util::RandomAccessStream* in )
{
  sal_Int8 buffer[4];
  in->readBytes( buffer,4 );
  num_ = getInteger_( buffer );

  in->readBytes( buffer,4 );
  sal_Int32 twoFields = getInteger_( buffer );

  isLeaf_ = ( twoFields & 0x80000000 ) != 0;
  free_ = twoFields & 0x7FFFFFFF;

  in->readBytes( data_,dbenv_->getDataLen() );
}

void Block::write( util::RandomAccessStream* out ) const
{
  out->writeBytes( (sal_Int8*)(&num_),4 );
  sal_Int32 twoFields = ( free_ | ( isLeaf_ ? 0x80000000 : 0 ) );
  out->writeBytes( (sal_Int8*)(&twoFields),4 );
  out->writeBytes( data_,dbenv_->getDataLen() );
}

void Block::setInteger( sal_Int32 i,sal_Int32 value ) throw( excep::IllegalIndexException )
{
  if( i < 0 || dbenv_->getDataLen() <= i  )
    throw excep::IllegalIndexException(
                       rtl::OUString::createFromAscii( "Block::setInteger -> index out of range" ) );

  ::setInteger_( &data_[i],value );
}

sal_Int32 Block::getInteger( sal_Int32 i ) const throw( excep::IllegalIndexException )
{
  if( i < 0 || dbenv_->getDataLen() <= i  )
    throw excep::IllegalIndexException(
                       rtl::OUString::createFromAscii( "Block::setInteger -> index out of range" ) );

    sal_Int32 ret = ::getInteger_( &data_[i] );
  return ret;
}

<|endoftext|>


<commit_before>//===- Miscompilation.cpp - Debug program miscompilations -----------------===//
//
// This file implements program miscompilation debugging support.
//
//===----------------------------------------------------------------------===//

#include "BugDriver.h"
#include "ListReducer.h"
#include "llvm/Module.h"
#include "llvm/Pass.h"
#include "llvm/Transforms/Utils/Cloning.h"
#include "llvm/Transforms/Utils/Linker.h"
#include "Support/FileUtilities.h"

class ReduceMiscompilingPasses : public ListReducer<const PassInfo*> {
  BugDriver &BD;
public:
  ReduceMiscompilingPasses(BugDriver &bd) : BD(bd) {}

  virtual TestResult doTest(std::vector<const PassInfo*> &Prefix,
                            std::vector<const PassInfo*> &Suffix);
};

ReduceMiscompilingPasses::TestResult
ReduceMiscompilingPasses::doTest(std::vector<const PassInfo*> &Prefix,
                                 std::vector<const PassInfo*> &Suffix) {
  // First, run the program with just the Suffix passes.  If it is still broken
  // with JUST the kept passes, discard the prefix passes.
  std::cout << "Checking to see if '" << getPassesString(Suffix)
            << "' compile correctly: ";

  std::string BytecodeResult;
  if (BD.runPasses(Suffix, BytecodeResult, false/*delete*/, true/*quiet*/)) {
    std::cerr << " Error running this sequence of passes"
              << " on the input program!\n";
    BD.setPassesToRun(Suffix);
    BD.EmitProgressBytecode("pass-error",  false);
    exit(1);
  }

  // Check to see if the finished program matches the reference output...
  if (BD.diffProgram(BytecodeResult, "", true /*delete bytecode*/)) {
    std::cout << "nope.\n";
    return KeepSuffix;        // Miscompilation detected!
  }
  std::cout << "yup.\n";      // No miscompilation!

  if (Prefix.empty()) return NoFailure;

  // Next, see if the program is broken if we run the "prefix" passes first,
  // then separately run the "kept" passes.
  std::cout << "Checking to see if '" << getPassesString(Prefix)
            << "' compile correctly: ";

  // If it is not broken with the kept passes, it's possible that the prefix
  // passes must be run before the kept passes to break it.  If the program
  // WORKS after the prefix passes, but then fails if running the prefix AND
  // kept passes, we can update our bytecode file to include the result of the
  // prefix passes, then discard the prefix passes.
  //
  if (BD.runPasses(Prefix, BytecodeResult, false/*delete*/, true/*quiet*/)) {
    std::cerr << " Error running this sequence of passes"
              << " on the input program!\n";
    BD.setPassesToRun(Prefix);
    BD.EmitProgressBytecode("pass-error",  false);
    exit(1);
  }

  // If the prefix maintains the predicate by itself, only keep the prefix!
  if (BD.diffProgram(BytecodeResult)) {
    std::cout << "nope.\n";
    removeFile(BytecodeResult);
    return KeepPrefix;
  }
  std::cout << "yup.\n";      // No miscompilation!

  // Ok, so now we know that the prefix passes work, try running the suffix
  // passes on the result of the prefix passes.
  //
  Module *PrefixOutput = BD.ParseInputFile(BytecodeResult);
  if (PrefixOutput == 0) {
    std::cerr << BD.getToolName() << ": Error reading bytecode file '"
              << BytecodeResult << "'!\n";
    exit(1);
  }
  removeFile(BytecodeResult);  // No longer need the file on disk

  std::cout << "Checking to see if '" << getPassesString(Suffix)
            << "' passes compile correctly after the '"
            << getPassesString(Prefix) << "' passes: ";

  Module *OriginalInput = BD.Program;
  BD.Program = PrefixOutput;
  if (BD.runPasses(Suffix, BytecodeResult, false/*delete*/, true/*quiet*/)) {
    std::cerr << " Error running this sequence of passes"
              << " on the input program!\n";
    BD.setPassesToRun(Suffix);
    BD.EmitProgressBytecode("pass-error",  false);
    exit(1);
  }

  // Run the result...
  if (BD.diffProgram(BytecodeResult, "", true/*delete bytecode*/)) {
    std::cout << "nope.\n";
    delete OriginalInput;     // We pruned down the original input...
    return KeepSuffix;
  }

  // Otherwise, we must not be running the bad pass anymore.
  std::cout << "yup.\n";      // No miscompilation!
  BD.Program = OriginalInput; // Restore original program
  delete PrefixOutput;        // Free experiment
  return NoFailure;
}

class ReduceMiscompilingFunctions : public ListReducer<Function*> {
  BugDriver &BD;
public:
  ReduceMiscompilingFunctions(BugDriver &bd) : BD(bd) {}

  virtual TestResult doTest(std::vector<Function*> &Prefix,
                            std::vector<Function*> &Suffix) {
    if (!Suffix.empty() && TestFuncs(Suffix, false))
      return KeepSuffix;
    if (!Prefix.empty() && TestFuncs(Prefix, false))
      return KeepPrefix;
    return NoFailure;
  }

  bool TestFuncs(const std::vector<Function*> &Prefix, bool EmitBytecode);
};

bool ReduceMiscompilingFunctions::TestFuncs(const std::vector<Function*> &Funcs,
                                            bool EmitBytecode) {
  // Test to see if the function is misoptimized if we ONLY run it on the
  // functions listed in Funcs.
  if (!EmitBytecode) {
    std::cout << "Checking to see if the program is misoptimized when these "
              << "functions are run\nthrough the passes: ";
    BD.PrintFunctionList(Funcs);
    std::cout << "\n";
  } else {
    std::cout <<"Outputting reduced bytecode files which expose the problem:\n";
  }

  // First step: clone the module for the two halves of the program we want.
  Module *ToOptimize = CloneModule(BD.Program);

  // Second step: Make sure functions & globals are all external so that linkage
  // between the two modules will work.
  for (Module::iterator I = ToOptimize->begin(), E = ToOptimize->end();I!=E;++I)
    I->setLinkage(GlobalValue::ExternalLinkage);
  for (Module::giterator I = ToOptimize->gbegin(), E = ToOptimize->gend();
       I != E; ++I)
    I->setLinkage(GlobalValue::ExternalLinkage);

  // Third step: make a clone of the externalized program for the non-optimized
  // part.
  Module *ToNotOptimize = CloneModule(ToOptimize);

  // Fourth step: Remove the test functions from the ToNotOptimize module, and
  // all of the global variables.
  for (unsigned i = 0, e = Funcs.size(); i != e; ++i) {
    Function *TNOF = ToNotOptimize->getFunction(Funcs[i]->getName(),
                                                Funcs[i]->getFunctionType());
    assert(TNOF && "Function doesn't exist in module!");
    DeleteFunctionBody(TNOF);       // Function is now external in this module!
  }
  for (Module::giterator I = ToNotOptimize->gbegin(), E = ToNotOptimize->gend();
       I != E; ++I)
    I->setInitializer(0);  // Delete the initializer to make it external

  if (EmitBytecode) {
    std::cout << "  Non-optimized portion: ";
    std::swap(BD.Program, ToNotOptimize);
    BD.EmitProgressBytecode("tonotoptimize", true);
    std::swap(BD.Program, ToNotOptimize);
  }

  // Fifth step: Remove all functions from the ToOptimize module EXCEPT for the
  // ones specified in Funcs.  We know which ones these are because they are
  // non-external in ToOptimize, but external in ToNotOptimize.
  //
  for (Module::iterator I = ToOptimize->begin(), E = ToOptimize->end();I!=E;++I)
    if (!I->isExternal()) {
      Function *TNOF = ToNotOptimize->getFunction(I->getName(),
                                                  I->getFunctionType());
      assert(TNOF && "Function doesn't exist in ToNotOptimize module??");
      if (!TNOF->isExternal())
        DeleteFunctionBody(I);
    }

  if (EmitBytecode) {
    std::cout << "  Portion that is input to optimizer: ";
    std::swap(BD.Program, ToOptimize);
    BD.EmitProgressBytecode("tooptimize");
    std::swap(BD.Program, ToOptimize);
  }

  // Sixth step: Run the optimization passes on ToOptimize, producing a
  // transformed version of the functions being tested.
  Module *OldProgram = BD.Program;
  BD.Program = ToOptimize;

  if (!EmitBytecode)
    std::cout << "  Optimizing functions being tested: ";
  std::string BytecodeResult;
  if (BD.runPasses(BD.PassesToRun, BytecodeResult, false/*delete*/,
                   true/*quiet*/)) {
    std::cerr << " Error running this sequence of passes"
              << " on the input program!\n";
    BD.EmitProgressBytecode("pass-error",  false);
    exit(1);
  }

  if (!EmitBytecode)
    std::cout << "done.\n";

  delete BD.Program;   // Delete the old "ToOptimize" module
  BD.Program = BD.ParseInputFile(BytecodeResult);

  if (EmitBytecode) {
    std::cout << "  'tooptimize' after being optimized: ";
    BD.EmitProgressBytecode("optimized", true);
  }

  if (BD.Program == 0) {
    std::cerr << BD.getToolName() << ": Error reading bytecode file '"
              << BytecodeResult << "'!\n";
    exit(1);
  }
  removeFile(BytecodeResult);  // No longer need the file on disk

  // Seventh step: Link the optimized part of the program back to the
  // unoptimized part of the program.
  //
  if (LinkModules(BD.Program, ToNotOptimize, &BytecodeResult)) {
    std::cerr << BD.getToolName() << ": Error linking modules together:"
              << BytecodeResult << "\n";
    exit(1);
  }
  delete ToNotOptimize;  // We are done with this module...

  if (EmitBytecode) {
    std::cout << "  Program as tested: ";
    BD.EmitProgressBytecode("linked", true);
    delete BD.Program;
    BD.Program = OldProgram;
    return false;   // We don't need to actually execute the program here.
  }

  std::cout << "  Checking to see if the merged program executes correctly: ";

  // Eighth step: Execute the program.  If it does not match the expected
  // output, then 'Funcs' are being misoptimized!
  bool Broken = BD.diffProgram();

  delete BD.Program;  // Delete the hacked up program
  BD.Program = OldProgram;   // Restore the original

  std::cout << (Broken ? "nope.\n" : "yup.\n");
  return Broken;
}

/// debugMiscompilation - This method is used when the passes selected are not
/// crashing, but the generated output is semantically different from the
/// input.
///
bool BugDriver::debugMiscompilation() {
  // Make sure something was miscompiled...
  if (!ReduceMiscompilingPasses(*this).reduceList(PassesToRun)) {
    std::cerr << "*** Optimized program matches reference output!  No problem "
	      << "detected...\nbugpoint can't help you with your problem!\n";
    return false;
  }

  std::cout << "\n*** Found miscompiling pass"
            << (PassesToRun.size() == 1 ? "" : "es") << ": "
            << getPassesString(PassesToRun) << "\n";
  EmitProgressBytecode("passinput");

  // Okay, now that we have reduced the list of passes which are causing the
  // failure, see if we can pin down which functions are being
  // miscompiled... first build a list of all of the non-external functions in
  // the program.
  std::vector<Function*> MiscompiledFunctions;
  for (Module::iterator I = Program->begin(), E = Program->end(); I != E; ++I)
    if (!I->isExternal())
      MiscompiledFunctions.push_back(I);

  // Do the reduction...
  ReduceMiscompilingFunctions(*this).reduceList(MiscompiledFunctions);

  std::cout << "\n*** The following functions are being miscompiled: ";
  PrintFunctionList(MiscompiledFunctions);
  std::cout << "\n";

  // Output a bunch of bytecode files for the user...
  ReduceMiscompilingFunctions(*this).TestFuncs(MiscompiledFunctions, true);

  return false;
}
<commit_msg>If we detect a pass crash during miscompilation testing, immediately enter the crash debugger<commit_after>//===- Miscompilation.cpp - Debug program miscompilations -----------------===//
//
// This file implements program miscompilation debugging support.
//
//===----------------------------------------------------------------------===//

#include "BugDriver.h"
#include "ListReducer.h"
#include "llvm/Module.h"
#include "llvm/Pass.h"
#include "llvm/Transforms/Utils/Cloning.h"
#include "llvm/Transforms/Utils/Linker.h"
#include "Support/FileUtilities.h"

class ReduceMiscompilingPasses : public ListReducer<const PassInfo*> {
  BugDriver &BD;
public:
  ReduceMiscompilingPasses(BugDriver &bd) : BD(bd) {}

  virtual TestResult doTest(std::vector<const PassInfo*> &Prefix,
                            std::vector<const PassInfo*> &Suffix);
};

ReduceMiscompilingPasses::TestResult
ReduceMiscompilingPasses::doTest(std::vector<const PassInfo*> &Prefix,
                                 std::vector<const PassInfo*> &Suffix) {
  // First, run the program with just the Suffix passes.  If it is still broken
  // with JUST the kept passes, discard the prefix passes.
  std::cout << "Checking to see if '" << getPassesString(Suffix)
            << "' compile correctly: ";

  std::string BytecodeResult;
  if (BD.runPasses(Suffix, BytecodeResult, false/*delete*/, true/*quiet*/)) {
    std::cerr << " Error running this sequence of passes"
              << " on the input program!\n";
    BD.setPassesToRun(Suffix);
    BD.EmitProgressBytecode("pass-error",  false);
    exit(BD.debugCrash());
  }

  // Check to see if the finished program matches the reference output...
  if (BD.diffProgram(BytecodeResult, "", true /*delete bytecode*/)) {
    std::cout << "nope.\n";
    return KeepSuffix;        // Miscompilation detected!
  }
  std::cout << "yup.\n";      // No miscompilation!

  if (Prefix.empty()) return NoFailure;

  // Next, see if the program is broken if we run the "prefix" passes first,
  // then separately run the "kept" passes.
  std::cout << "Checking to see if '" << getPassesString(Prefix)
            << "' compile correctly: ";

  // If it is not broken with the kept passes, it's possible that the prefix
  // passes must be run before the kept passes to break it.  If the program
  // WORKS after the prefix passes, but then fails if running the prefix AND
  // kept passes, we can update our bytecode file to include the result of the
  // prefix passes, then discard the prefix passes.
  //
  if (BD.runPasses(Prefix, BytecodeResult, false/*delete*/, true/*quiet*/)) {
    std::cerr << " Error running this sequence of passes"
              << " on the input program!\n";
    BD.setPassesToRun(Prefix);
    BD.EmitProgressBytecode("pass-error",  false);
    exit(BD.debugCrash());
  }

  // If the prefix maintains the predicate by itself, only keep the prefix!
  if (BD.diffProgram(BytecodeResult)) {
    std::cout << "nope.\n";
    removeFile(BytecodeResult);
    return KeepPrefix;
  }
  std::cout << "yup.\n";      // No miscompilation!

  // Ok, so now we know that the prefix passes work, try running the suffix
  // passes on the result of the prefix passes.
  //
  Module *PrefixOutput = BD.ParseInputFile(BytecodeResult);
  if (PrefixOutput == 0) {
    std::cerr << BD.getToolName() << ": Error reading bytecode file '"
              << BytecodeResult << "'!\n";
    exit(1);
  }
  removeFile(BytecodeResult);  // No longer need the file on disk

  std::cout << "Checking to see if '" << getPassesString(Suffix)
            << "' passes compile correctly after the '"
            << getPassesString(Prefix) << "' passes: ";

  Module *OriginalInput = BD.Program;
  BD.Program = PrefixOutput;
  if (BD.runPasses(Suffix, BytecodeResult, false/*delete*/, true/*quiet*/)) {
    std::cerr << " Error running this sequence of passes"
              << " on the input program!\n";
    BD.setPassesToRun(Suffix);
    BD.EmitProgressBytecode("pass-error",  false);
    exit(BD.debugCrash());
  }

  // Run the result...
  if (BD.diffProgram(BytecodeResult, "", true/*delete bytecode*/)) {
    std::cout << "nope.\n";
    delete OriginalInput;     // We pruned down the original input...
    return KeepSuffix;
  }

  // Otherwise, we must not be running the bad pass anymore.
  std::cout << "yup.\n";      // No miscompilation!
  BD.Program = OriginalInput; // Restore original program
  delete PrefixOutput;        // Free experiment
  return NoFailure;
}

class ReduceMiscompilingFunctions : public ListReducer<Function*> {
  BugDriver &BD;
public:
  ReduceMiscompilingFunctions(BugDriver &bd) : BD(bd) {}

  virtual TestResult doTest(std::vector<Function*> &Prefix,
                            std::vector<Function*> &Suffix) {
    if (!Suffix.empty() && TestFuncs(Suffix, false))
      return KeepSuffix;
    if (!Prefix.empty() && TestFuncs(Prefix, false))
      return KeepPrefix;
    return NoFailure;
  }

  bool TestFuncs(const std::vector<Function*> &Prefix, bool EmitBytecode);
};

bool ReduceMiscompilingFunctions::TestFuncs(const std::vector<Function*> &Funcs,
                                            bool EmitBytecode) {
  // Test to see if the function is misoptimized if we ONLY run it on the
  // functions listed in Funcs.
  if (!EmitBytecode) {
    std::cout << "Checking to see if the program is misoptimized when these "
              << "functions are run\nthrough the passes: ";
    BD.PrintFunctionList(Funcs);
    std::cout << "\n";
  } else {
    std::cout <<"Outputting reduced bytecode files which expose the problem:\n";
  }

  // First step: clone the module for the two halves of the program we want.
  Module *ToOptimize = CloneModule(BD.Program);

  // Second step: Make sure functions & globals are all external so that linkage
  // between the two modules will work.
  for (Module::iterator I = ToOptimize->begin(), E = ToOptimize->end();I!=E;++I)
    I->setLinkage(GlobalValue::ExternalLinkage);
  for (Module::giterator I = ToOptimize->gbegin(), E = ToOptimize->gend();
       I != E; ++I)
    I->setLinkage(GlobalValue::ExternalLinkage);

  // Third step: make a clone of the externalized program for the non-optimized
  // part.
  Module *ToNotOptimize = CloneModule(ToOptimize);

  // Fourth step: Remove the test functions from the ToNotOptimize module, and
  // all of the global variables.
  for (unsigned i = 0, e = Funcs.size(); i != e; ++i) {
    Function *TNOF = ToNotOptimize->getFunction(Funcs[i]->getName(),
                                                Funcs[i]->getFunctionType());
    assert(TNOF && "Function doesn't exist in module!");
    DeleteFunctionBody(TNOF);       // Function is now external in this module!
  }
  for (Module::giterator I = ToNotOptimize->gbegin(), E = ToNotOptimize->gend();
       I != E; ++I)
    I->setInitializer(0);  // Delete the initializer to make it external

  if (EmitBytecode) {
    std::cout << "  Non-optimized portion: ";
    std::swap(BD.Program, ToNotOptimize);
    BD.EmitProgressBytecode("tonotoptimize", true);
    std::swap(BD.Program, ToNotOptimize);
  }

  // Fifth step: Remove all functions from the ToOptimize module EXCEPT for the
  // ones specified in Funcs.  We know which ones these are because they are
  // non-external in ToOptimize, but external in ToNotOptimize.
  //
  for (Module::iterator I = ToOptimize->begin(), E = ToOptimize->end();I!=E;++I)
    if (!I->isExternal()) {
      Function *TNOF = ToNotOptimize->getFunction(I->getName(),
                                                  I->getFunctionType());
      assert(TNOF && "Function doesn't exist in ToNotOptimize module??");
      if (!TNOF->isExternal())
        DeleteFunctionBody(I);
    }

  if (EmitBytecode) {
    std::cout << "  Portion that is input to optimizer: ";
    std::swap(BD.Program, ToOptimize);
    BD.EmitProgressBytecode("tooptimize");
    std::swap(BD.Program, ToOptimize);
  }

  // Sixth step: Run the optimization passes on ToOptimize, producing a
  // transformed version of the functions being tested.
  Module *OldProgram = BD.Program;
  BD.Program = ToOptimize;

  if (!EmitBytecode)
    std::cout << "  Optimizing functions being tested: ";
  std::string BytecodeResult;
  if (BD.runPasses(BD.PassesToRun, BytecodeResult, false/*delete*/,
                   true/*quiet*/)) {
    std::cerr << " Error running this sequence of passes"
              << " on the input program!\n";
    BD.EmitProgressBytecode("pass-error",  false);
    exit(BD.debugCrash());
  }

  if (!EmitBytecode)
    std::cout << "done.\n";

  delete BD.Program;   // Delete the old "ToOptimize" module
  BD.Program = BD.ParseInputFile(BytecodeResult);

  if (EmitBytecode) {
    std::cout << "  'tooptimize' after being optimized: ";
    BD.EmitProgressBytecode("optimized", true);
  }

  if (BD.Program == 0) {
    std::cerr << BD.getToolName() << ": Error reading bytecode file '"
              << BytecodeResult << "'!\n";
    exit(1);
  }
  removeFile(BytecodeResult);  // No longer need the file on disk

  // Seventh step: Link the optimized part of the program back to the
  // unoptimized part of the program.
  //
  if (LinkModules(BD.Program, ToNotOptimize, &BytecodeResult)) {
    std::cerr << BD.getToolName() << ": Error linking modules together:"
              << BytecodeResult << "\n";
    exit(1);
  }
  delete ToNotOptimize;  // We are done with this module...

  if (EmitBytecode) {
    std::cout << "  Program as tested: ";
    BD.EmitProgressBytecode("linked", true);
    delete BD.Program;
    BD.Program = OldProgram;
    return false;   // We don't need to actually execute the program here.
  }

  std::cout << "  Checking to see if the merged program executes correctly: ";

  // Eighth step: Execute the program.  If it does not match the expected
  // output, then 'Funcs' are being misoptimized!
  bool Broken = BD.diffProgram();

  delete BD.Program;  // Delete the hacked up program
  BD.Program = OldProgram;   // Restore the original

  std::cout << (Broken ? "nope.\n" : "yup.\n");
  return Broken;
}

/// debugMiscompilation - This method is used when the passes selected are not
/// crashing, but the generated output is semantically different from the
/// input.
///
bool BugDriver::debugMiscompilation() {
  // Make sure something was miscompiled...
  if (!ReduceMiscompilingPasses(*this).reduceList(PassesToRun)) {
    std::cerr << "*** Optimized program matches reference output!  No problem "
	      << "detected...\nbugpoint can't help you with your problem!\n";
    return false;
  }

  std::cout << "\n*** Found miscompiling pass"
            << (PassesToRun.size() == 1 ? "" : "es") << ": "
            << getPassesString(PassesToRun) << "\n";
  EmitProgressBytecode("passinput");

  // Okay, now that we have reduced the list of passes which are causing the
  // failure, see if we can pin down which functions are being
  // miscompiled... first build a list of all of the non-external functions in
  // the program.
  std::vector<Function*> MiscompiledFunctions;
  for (Module::iterator I = Program->begin(), E = Program->end(); I != E; ++I)
    if (!I->isExternal())
      MiscompiledFunctions.push_back(I);

  // Do the reduction...
  ReduceMiscompilingFunctions(*this).reduceList(MiscompiledFunctions);

  std::cout << "\n*** The following functions are being miscompiled: ";
  PrintFunctionList(MiscompiledFunctions);
  std::cout << "\n";

  // Output a bunch of bytecode files for the user...
  ReduceMiscompilingFunctions(*this).TestFuncs(MiscompiledFunctions, true);

  return false;
}
<|endoftext|>


<commit_before>/*
 * ApproxBetweenness.cpp
 *
 *  Created on: 09.04.2014
 *      Author: cls
 */

#include "ApproxBetweenness.h"
#include "../auxiliary/Random.h"
#include "../properties/Diameter.h"
#include "../graph/Sampling.h"
#include "../graph/Dijkstra.h"
#include "../graph/BFS.h"
#include "../graph/SSSP.h"
#include "../auxiliary/Log.h"

#include <math.h>
#include <algorithm>
#include <memory>
#include <omp.h>

namespace NetworKit {

ApproxBetweenness::ApproxBetweenness(const Graph& G, double epsilon, double delta, count diameterSamples) : Centrality(G, true), epsilon(epsilon), delta(delta), diameterSamples(diameterSamples) {

}

void ApproxBetweenness::runImpl() {
	scoreData.clear();
	scoreData.resize(G.upperNodeIdBound());

	double c = 0.5; // universal positive constant - see reference in paper

	edgeweight vd = 0;
	if (diameterSamples == 0) {
		INFO("estimating vertex diameter pedantically");
		vd = Diameter::estimatedVertexDiameterPedantic(G);
	} else {
		/**
		* This is an optimization which deviates from the original algorithm.
		* Instead of getting an estimate for each of possibly thousands of connected component and taking the maximum,
		* we sample the graph and take the maximum diameter found. This has a high chance of  hitting the component with the maximum vertex diameter.
		*/
		INFO("estimating vertex diameter roughly");
		vd = Diameter::estimatedVertexDiameter(G, diameterSamples);
	}

	INFO("estimated diameter: ", vd);
	r = ceil((c / (epsilon * epsilon)) * (floor(log(vd - 2)) + 1 + log(1 / delta)));

	INFO("taking ", r, " path samples");
	// parallelization:
	count maxThreads = omp_get_max_threads();
	DEBUG("max threads: ", maxThreads);
	std::vector<std::vector<double> > scorePerThread(maxThreads, std::vector<double>(G.upperNodeIdBound()));
	DEBUG("score per thread size: ", scorePerThread.size());
	assureRunning();
	#pragma omp parallel for
	for (count i = 1; i <= r; i++) {
		try {
			assureRunning();
		count thread = omp_get_thread_num();
		DEBUG("sample ", i);
		// if (i >= 1000) throw std::runtime_error("too many iterations");
		// DEBUG
		// sample random node pair
		node u, v;
		u = Sampling::randomNode(G);
		do {
			v = Sampling::randomNode(G);
		} while (v == u);

		// runs faster for unweighted graphs
		std::unique_ptr<SSSP> sssp;
		if (G.isWeighted()) {
			sssp.reset(new Dijkstra(G, u));
		} else {
			sssp.reset(new BFS(G, u));
		}
		DEBUG("running shortest path algorithm for node ", u);
		sssp->run(v);
		if (sssp->numberOfPaths(v) > 0) { // at least one path between {u, v} exists
			DEBUG("updating estimate for path ", u, " <-> ", v);
			// random path sampling and estimation update
			// node s = v;
			node t = v;
			while (t != u)  {
				// sample z in P_u(t) with probability sigma_uz / sigma_us
				std::vector<std::pair<node, double> > choices;
				for (node z : sssp->getPredecessors(t)) {
					bigfloat tmp = sssp->numberOfPaths(z) / sssp->numberOfPaths(t);
					double weight;
					tmp.ToDouble(weight);
					choices.emplace_back(z, weight); 	// sigma_uz / sigma_us
				}
				node z = Aux::Random::weightedChoice(choices);
				assert (z <= G.upperNodeIdBound());
				if (z != u) {
					scorePerThread[thread][z] += 1 / (double) r;
				}
				// s = t;
				t = z;
			}
		}
		} catch (std::exception e) {
		ERROR("received something:\t",e.what());
		}
	}

	INFO("adding thread-local scores");
	// add up all thread-local values
	for (auto local : scorePerThread) {
		G.parallelForNodes([&](node v){
			scoreData[v] += local[v];
		});
	}

	hasRun = true;
}

count ApproxBetweenness::numberOfSamples() {
	INFO("Estimated number of samples", r);
	return r;
}

} /* namespace NetworKit */
<commit_msg>Add missing & in ApproxBetweenness to avoid copying data<commit_after>/*
 * ApproxBetweenness.cpp
 *
 *  Created on: 09.04.2014
 *      Author: cls
 */

#include "ApproxBetweenness.h"
#include "../auxiliary/Random.h"
#include "../properties/Diameter.h"
#include "../graph/Sampling.h"
#include "../graph/Dijkstra.h"
#include "../graph/BFS.h"
#include "../graph/SSSP.h"
#include "../auxiliary/Log.h"

#include <math.h>
#include <algorithm>
#include <memory>
#include <omp.h>

namespace NetworKit {

ApproxBetweenness::ApproxBetweenness(const Graph& G, double epsilon, double delta, count diameterSamples) : Centrality(G, true), epsilon(epsilon), delta(delta), diameterSamples(diameterSamples) {

}

void ApproxBetweenness::runImpl() {
	scoreData.clear();
	scoreData.resize(G.upperNodeIdBound());

	double c = 0.5; // universal positive constant - see reference in paper

	edgeweight vd = 0;
	if (diameterSamples == 0) {
		INFO("estimating vertex diameter pedantically");
		vd = Diameter::estimatedVertexDiameterPedantic(G);
	} else {
		/**
		* This is an optimization which deviates from the original algorithm.
		* Instead of getting an estimate for each of possibly thousands of connected component and taking the maximum,
		* we sample the graph and take the maximum diameter found. This has a high chance of  hitting the component with the maximum vertex diameter.
		*/
		INFO("estimating vertex diameter roughly");
		vd = Diameter::estimatedVertexDiameter(G, diameterSamples);
	}

	INFO("estimated diameter: ", vd);
	r = ceil((c / (epsilon * epsilon)) * (floor(log(vd - 2)) + 1 + log(1 / delta)));

	INFO("taking ", r, " path samples");
	// parallelization:
	count maxThreads = omp_get_max_threads();
	DEBUG("max threads: ", maxThreads);
	std::vector<std::vector<double> > scorePerThread(maxThreads, std::vector<double>(G.upperNodeIdBound()));
	DEBUG("score per thread size: ", scorePerThread.size());
	assureRunning();
	#pragma omp parallel for
	for (count i = 1; i <= r; i++) {
		try {
			assureRunning();
		count thread = omp_get_thread_num();
		DEBUG("sample ", i);
		// if (i >= 1000) throw std::runtime_error("too many iterations");
		// DEBUG
		// sample random node pair
		node u, v;
		u = Sampling::randomNode(G);
		do {
			v = Sampling::randomNode(G);
		} while (v == u);

		// runs faster for unweighted graphs
		std::unique_ptr<SSSP> sssp;
		if (G.isWeighted()) {
			sssp.reset(new Dijkstra(G, u));
		} else {
			sssp.reset(new BFS(G, u));
		}
		DEBUG("running shortest path algorithm for node ", u);
		sssp->run(v);
		if (sssp->numberOfPaths(v) > 0) { // at least one path between {u, v} exists
			DEBUG("updating estimate for path ", u, " <-> ", v);
			// random path sampling and estimation update
			// node s = v;
			node t = v;
			while (t != u)  {
				// sample z in P_u(t) with probability sigma_uz / sigma_us
				std::vector<std::pair<node, double> > choices;
				for (node z : sssp->getPredecessors(t)) {
					bigfloat tmp = sssp->numberOfPaths(z) / sssp->numberOfPaths(t);
					double weight;
					tmp.ToDouble(weight);
					choices.emplace_back(z, weight); 	// sigma_uz / sigma_us
				}
				node z = Aux::Random::weightedChoice(choices);
				assert (z <= G.upperNodeIdBound());
				if (z != u) {
					scorePerThread[thread][z] += 1 / (double) r;
				}
				// s = t;
				t = z;
			}
		}
		} catch (std::exception e) {
		ERROR("received something:\t",e.what());
		}
	}

	INFO("adding thread-local scores");
	// add up all thread-local values
	for (auto &local : scorePerThread) {
		G.parallelForNodes([&](node v){
			scoreData[v] += local[v];
		});
	}

	hasRun = true;
}

count ApproxBetweenness::numberOfSamples() {
	INFO("Estimated number of samples", r);
	return r;
}

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


<commit_before><commit_msg>INTEGRATION: CWS aw013 (1.18.24); FILE MERGED 2004/06/24 09:33:10 aw 1.18.24.1: #i29181#<commit_after><|endoftext|>


<commit_before><commit_msg>snprintf fixes and use mountpoint_helpers<commit_after><|endoftext|>


<commit_before>/*
 *   Copyright (C) 2011 Ivan Cukic <ivan.cukic(at)kde.org>
 *
 *   This program is free software; you can redistribute it and/or modify
 *   it under the terms of the GNU General Public License version 2,
 *   or (at your option) any later version, as published by the Free
 *   Software Foundation
 *
 *   This program is distributed in the hope that it will be useful,
 *   but WITHOUT ANY WARRANTY; without even the implied warranty of
 *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 *   GNU General Public License for more details
 *
 *   You should have received a copy of the GNU General Public
 *   License along with this program; if not, write to the
 *   Free Software Foundation, Inc.,
 *   51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
 */

#include "RecommendationScriptEngine.h"
#include "RecommendationScriptEngine_p.h"

#include <QScriptEngine>
#include <QScriptValue>
#include <QTextStream>
#include <QFile>
#include <QTimer>
#include <QDesktopServices>
#include <QUrl>

#include <QtSensors/QSensor>

#include <KDebug>
#include <KStandardDirs>

#include "sensors/dbus/DBusSensor.h"

namespace Contour {

RecommendationScriptEngineConfig::RecommendationScriptEngineConfig(QObject * parent, KConfigGroup * config)
    : QObject(parent), m_config(config)
{
}

RecommendationScriptEngineConfig::~RecommendationScriptEngineConfig()
{
    delete m_config;
}

#define CREATE_CONFIG_METHODS(TYPE, TYPECASE) \
    TYPE RecommendationScriptEngineConfig::TYPECASE##Value(const QString & field, TYPE defaultValue) const \
    { return m_config->readEntry(field, defaultValue); } \
    void RecommendationScriptEngineConfig::Set##TYPECASE##Value(const QString & field, TYPE newValue) const \
    { kDebug() << field << newValue; m_config->writeEntry(field, newValue); m_config->sync(); }

    CREATE_CONFIG_METHODS(bool, Bool)
    CREATE_CONFIG_METHODS(int, Int)
    CREATE_CONFIG_METHODS(QString, String)
    CREATE_CONFIG_METHODS(QStringList, StringList)
#undef CREATE_CONFIG_METHODS

/**
 *
 */
RecommendationScriptEngine::RecommendationScriptEngine(QObject * parent, const QString & script)
    : RecommendationEngine(parent), d(new Private())
{
    d->script = script;

    kDebug() << "RecommendationScriptEngine()" << script << name();

    d->delay.setInterval(300);
    d->delay.setSingleShot(true);

    connect(&(d->delay), SIGNAL(timeout()),
            this, SLOT(sendUpdateNotification()));

}

RecommendationScriptEngine::~RecommendationScriptEngine()
{
    delete d;
}

void RecommendationScriptEngine::init()
{
    Contour::RecommendationEngine::init();

    QFile file(KStandardDirs::locate("data", "contour/scripts/" + d->script + "/main.js"));
    if (!file.open(QIODevice::ReadOnly)) {
        kDebug() << "Failed to open main.js for" << d->script;
        return;
    }

    d->engine = new QScriptEngine(this);
    connect(d->engine, SIGNAL(signalHandlerException(QScriptValue)),
            this, SLOT(signalHandlerException(QScriptValue)));

    d->engine->globalObject().setProperty("self",
            d->engine->newQObject(this));

    const QScriptValue & result = d->engine->evaluate(QTextStream(&file).readAll());
    if (d->engine->hasUncaughtException()) {
        int line = d->engine->uncaughtExceptionLineNumber();
        kDebug() << "uncaught exception at line" << line << ":" << result.toString();
    }

}

void RecommendationScriptEngine::activate(const QString & id, const QString & action)
{
    if (d->autoremove)
        removeRecommendation(id);

    emit activationRequested(id, action);
}

QString RecommendationScriptEngine::name() const
{
    kDebug() << d->script;
    return d->script;
}

QScriptValue RecommendationScriptEngine::getSensor(const QString & sensor)
{
    kDebug() << "sensor" << sensor;

    QObject * result = NULL;

    if (sensor == "DBus") {
        kDebug() << "Returning the D-Bus sensor. This is not in QtMobility";
        result = new DBusSensor();
    } else {
        result = new QtMobility::QSensor(sensor.toAscii());
    }

    return d->engine->newQObject(result, QScriptEngine::AutoOwnership);
}

QScriptValue RecommendationScriptEngine::getConfig()
{
    // d->engine->newQObject(EngineConfig
    kDebug() << "######################### Requested the config for" << name();

    return d->engine->newQObject(new RecommendationScriptEngineConfig(this, config()));
}

QScriptValue RecommendationScriptEngine::getTimer(int msec)
{
    kDebug() << "timer" << msec;

    QTimer * timer = new QTimer();
    timer->setSingleShot(false);
    timer->setInterval(msec);
    timer->start();

    return d->engine->newQObject(timer, QScriptEngine::AutoOwnership);
}

void RecommendationScriptEngine::openUrl(const QString & url)
{
    QDesktopServices::openUrl(QUrl(url));
}

void RecommendationScriptEngine::signalHandlerException(const QScriptValue & exception)
{
    kDebug() << "exception" << exception.toVariant();
}

void RecommendationScriptEngine::addRecommendation(
        double score,
        const QString & id,
        const QString & title,
        const QString & description,
        const QString & icon
    )
{
    // kDebug() << d->script << score << id << title;

    int i = 0;

    while (d->recommendations.size() > i &&
           d->recommendations[i].score > score) {
        ++i;
    }

    RecommendationItem ri;

    ri.score       = score;
    ri.id          = id;
    ri.title       = title;
    ri.description = description;
    ri.icon        = icon;

    d->recommendations.insert(i, ri);

    delayedUpdateNotification();
}

void RecommendationScriptEngine::removeRecommendation(const QString & id)
{
    QMutableListIterator < RecommendationItem > i(d->recommendations);
    while (i.hasNext()) {
        RecommendationItem ri = i.next();

        if (ri.id == id) {
            i.remove();
        }
    }

    delayedUpdateNotification();
}

void RecommendationScriptEngine::removeRecommendations()
{
    d->recommendations.clear();

    delayedUpdateNotification();
}

void RecommendationScriptEngine::delayedUpdateNotification()
{
    d->delay.start();
}

void RecommendationScriptEngine::sendUpdateNotification()
{
    // just in case, although it is a single-shot
    d->delay.stop();

    emit recommendationsUpdated(d->recommendations);
}

} // namespace Contour

// class RecommendationScriptEngine

<commit_msg>removed dbg output<commit_after>/*
 *   Copyright (C) 2011 Ivan Cukic <ivan.cukic(at)kde.org>
 *
 *   This program is free software; you can redistribute it and/or modify
 *   it under the terms of the GNU General Public License version 2,
 *   or (at your option) any later version, as published by the Free
 *   Software Foundation
 *
 *   This program is distributed in the hope that it will be useful,
 *   but WITHOUT ANY WARRANTY; without even the implied warranty of
 *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 *   GNU General Public License for more details
 *
 *   You should have received a copy of the GNU General Public
 *   License along with this program; if not, write to the
 *   Free Software Foundation, Inc.,
 *   51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
 */

#include "RecommendationScriptEngine.h"
#include "RecommendationScriptEngine_p.h"

#include <QScriptEngine>
#include <QScriptValue>
#include <QTextStream>
#include <QFile>
#include <QTimer>
#include <QDesktopServices>
#include <QUrl>

#include <QtSensors/QSensor>

#include <KDebug>
#include <KStandardDirs>

#include "sensors/dbus/DBusSensor.h"

namespace Contour {

RecommendationScriptEngineConfig::RecommendationScriptEngineConfig(QObject * parent, KConfigGroup * config)
    : QObject(parent), m_config(config)
{
}

RecommendationScriptEngineConfig::~RecommendationScriptEngineConfig()
{
    delete m_config;
}

#define CREATE_CONFIG_METHODS(TYPE, TYPECASE) \
    TYPE RecommendationScriptEngineConfig::TYPECASE##Value(const QString & field, TYPE defaultValue) const \
    { return m_config->readEntry(field, defaultValue); } \
    void RecommendationScriptEngineConfig::Set##TYPECASE##Value(const QString & field, TYPE newValue) const \
    { kDebug() << field << newValue; m_config->writeEntry(field, newValue); m_config->sync(); }

    CREATE_CONFIG_METHODS(bool, Bool)
    CREATE_CONFIG_METHODS(int, Int)
    CREATE_CONFIG_METHODS(QString, String)
    CREATE_CONFIG_METHODS(QStringList, StringList)
#undef CREATE_CONFIG_METHODS

/**
 *
 */
RecommendationScriptEngine::RecommendationScriptEngine(QObject * parent, const QString & script)
    : RecommendationEngine(parent), d(new Private())
{
    d->script = script;

    kDebug() << "RecommendationScriptEngine()" << script << name();

    d->delay.setInterval(300);
    d->delay.setSingleShot(true);

    connect(&(d->delay), SIGNAL(timeout()),
            this, SLOT(sendUpdateNotification()));

}

RecommendationScriptEngine::~RecommendationScriptEngine()
{
    delete d;
}

void RecommendationScriptEngine::init()
{
    Contour::RecommendationEngine::init();

    QFile file(KStandardDirs::locate("data", "contour/scripts/" + d->script + "/main.js"));
    if (!file.open(QIODevice::ReadOnly)) {
        kDebug() << "Failed to open main.js for" << d->script;
        return;
    }

    d->engine = new QScriptEngine(this);
    connect(d->engine, SIGNAL(signalHandlerException(QScriptValue)),
            this, SLOT(signalHandlerException(QScriptValue)));

    d->engine->globalObject().setProperty("self",
            d->engine->newQObject(this));

    const QScriptValue & result = d->engine->evaluate(QTextStream(&file).readAll());
    if (d->engine->hasUncaughtException()) {
        int line = d->engine->uncaughtExceptionLineNumber();
        kDebug() << "uncaught exception at line" << line << ":" << result.toString();
    }

}

void RecommendationScriptEngine::activate(const QString & id, const QString & action)
{
    if (d->autoremove)
        removeRecommendation(id);

    emit activationRequested(id, action);
}

QString RecommendationScriptEngine::name() const
{
    kDebug() << d->script;
    return d->script;
}

QScriptValue RecommendationScriptEngine::getSensor(const QString & sensor)
{
    kDebug() << "sensor" << sensor;

    QObject * result = NULL;

    if (sensor == "DBus") {
        kDebug() << "Returning the D-Bus sensor. This is not in QtMobility";
        result = new DBusSensor();
    } else {
        result = new QtMobility::QSensor(sensor.toAscii());
    }

    return d->engine->newQObject(result, QScriptEngine::AutoOwnership);
}

QScriptValue RecommendationScriptEngine::getConfig()
{
    return d->engine->newQObject(new RecommendationScriptEngineConfig(this, config()));
}

QScriptValue RecommendationScriptEngine::getTimer(int msec)
{
    kDebug() << "timer" << msec;

    QTimer * timer = new QTimer();
    timer->setSingleShot(false);
    timer->setInterval(msec);
    timer->start();

    return d->engine->newQObject(timer, QScriptEngine::AutoOwnership);
}

void RecommendationScriptEngine::openUrl(const QString & url)
{
    QDesktopServices::openUrl(QUrl(url));
}

void RecommendationScriptEngine::signalHandlerException(const QScriptValue & exception)
{
    kDebug() << "exception" << exception.toVariant();
}

void RecommendationScriptEngine::addRecommendation(
        double score,
        const QString & id,
        const QString & title,
        const QString & description,
        const QString & icon
    )
{
    // kDebug() << d->script << score << id << title;

    int i = 0;

    while (d->recommendations.size() > i &&
           d->recommendations[i].score > score) {
        ++i;
    }

    RecommendationItem ri;

    ri.score       = score;
    ri.id          = id;
    ri.title       = title;
    ri.description = description;
    ri.icon        = icon;

    d->recommendations.insert(i, ri);

    delayedUpdateNotification();
}

void RecommendationScriptEngine::removeRecommendation(const QString & id)
{
    QMutableListIterator < RecommendationItem > i(d->recommendations);
    while (i.hasNext()) {
        RecommendationItem ri = i.next();

        if (ri.id == id) {
            i.remove();
        }
    }

    delayedUpdateNotification();
}

void RecommendationScriptEngine::removeRecommendations()
{
    d->recommendations.clear();

    delayedUpdateNotification();
}

void RecommendationScriptEngine::delayedUpdateNotification()
{
    d->delay.start();
}

void RecommendationScriptEngine::sendUpdateNotification()
{
    // just in case, although it is a single-shot
    d->delay.stop();

    emit recommendationsUpdated(d->recommendations);
}

} // namespace Contour

// class RecommendationScriptEngine

<|endoftext|>