<commit_before>#include <agency/execution_policy.hpp>
#include <mutex>
#include <iostream>
#include <thread>
#include <cassert>

// this is just like std::mutex, except it has a move constructor
// the move constructor just acts like the default constructor
class movable_mutex
{
  public:
    constexpr movable_mutex() = default;

    movable_mutex(const movable_mutex&) = delete;

    movable_mutex(movable_mutex&&)
      : mut_()
    {}

    void lock()
    {
      mut_.lock();
    }

    void unlock()
    {
      mut_.unlock();
    }

  private:
    std::mutex mut_;
};

// this function implements a single concurrent ping pong match
size_t ping_pong_match(agency::concurrent_agent& self, const std::vector<std::string>& names, int num_volleys, movable_mutex& mut, int& ball)
{
  auto name = names[self.index()];

  for(int next_state = self.index();
      (next_state < num_volleys) && (ball >= 0);
      next_state += 2)
  {
    // wait for the next volley
    while(ball >= 0 && ball != next_state)
    {
      mut.lock();
      std::cout << name << " waiting for return" << std::endl;
      mut.unlock();

      std::this_thread::sleep_for(std::chrono::seconds(1));
    }

    mut.lock();
    if(ball == -1)
    {
      std::cout << name << " wins!" << std::endl;
    }
    else
    {
      // try to return the ball
      if(std::rand() % 10 == 0)
      {
        // whiff -- declare outself the loser
        ball = -self.index() - 1;
        std::cout << "whiff... " << name << " loses!" << std::endl;
      }
      else
      {
        // successful return
        ball += 1;
        std::cout << name << "! ball is now " << ball << std::endl;
      }
    }
    mut.unlock();

    std::this_thread::sleep_for(std::chrono::seconds(1));
  }

  // decode who lost the match
  int loser = (ball > 0) ? 1 : -(ball + 1);

  // return the winner
  return loser ^ 1;
}

// this function implements a two concurrent semifinals ping pong matches
// followed by a single final ping pong match
void ping_pong_tournament(agency::concurrent_group<agency::concurrent_agent>& self,
                          const std::vector<std::vector<std::string>>& semifinal_contestants,
                          int num_volleys,
                          movable_mutex& mut,
                          int& ball,
                          std::vector<std::string>& final_contestants)
{
  if(self.inner().index() == 0)
  {
    if(self.outer().index() == 0)
    {
      std::cout << "Starting semifinal matches..." << std::endl;
    }

    self.outer().wait();
  }

  self.inner().wait();

  // play the semifinals matches
  auto semifinal_winner_idx = ping_pong_match(self.inner(), semifinal_contestants[self.outer().index()], num_volleys, mut, ball);

  if(self.inner().index() == 0)
  {
    // the first agent of each group reports who won the semifinal match
    auto semifinal_winner = semifinal_contestants[self.outer().index()][semifinal_winner_idx];
    final_contestants[self.outer().index()] = semifinal_winner;

    // have the first player of each group wait for the other group
    self.outer().wait();
  }

  // have each inner group wait for each other
  self.inner().wait();

  // group 0 plays the final match
  // group 1 sits it out
  if(self.outer().index() == 0)
  {
    // agent 0 initialzes the shared variables for the final match
    if(self.inner().index() == 0)
    {
      ball = 0;

      std::cout << std::endl << final_contestants[0] << " and " << final_contestants[1] << " starting the final match..." << std::endl;
    }

    // wait until agent 0 initializes the shared variables before starting the final match
    self.inner().wait();

    // play the final match
    auto final_winner_idx = ping_pong_match(self.inner(), final_contestants, num_volleys, mut, ball);

    // have agent 0 of group 0 report the winner
    if(self.inner().index() == 0)
    {
      std::cout << std::endl << final_contestants[final_winner_idx] << " is the champion!" << std::endl;
    }
  }
}

int main()
{
  using namespace agency;
  using namespace std;

  size_t num_volleys = 20;
  vector<vector<string>> names = {{"ping", "pong"}, {"foo", "bar"}};

  bulk_invoke(con(2, con(2)), ping_pong_tournament, names, 20, share<0,movable_mutex>(), share<1,int>(), share<0,vector<string>>(2));

  return 0;
}

<commit_msg>change the names of some variables<commit_after>#include <agency/execution_policy.hpp>
#include <mutex>
#include <iostream>
#include <thread>
#include <cassert>

// this is just like std::mutex, except it has a move constructor
// the move constructor just acts like the default constructor
class movable_mutex
{
  public:
    constexpr movable_mutex() = default;

    movable_mutex(const movable_mutex&) = delete;

    movable_mutex(movable_mutex&&)
      : mut_()
    {}

    void lock()
    {
      mut_.lock();
    }

    void unlock()
    {
      mut_.unlock();
    }

  private:
    std::mutex mut_;
};

// this function implements a single concurrent ping pong match
size_t ping_pong_match(agency::concurrent_agent& self, const std::vector<std::string>& names, int num_volleys, movable_mutex& mut, int& ball)
{
  // agent 0 initializes the ball
  if(self.index() == 0)
  {
    ball = 0;
  }

  self.wait();

  auto name = names[self.index()];

  for(int next_state = self.index();
      (next_state < num_volleys) && (ball >= 0);
      next_state += 2)
  {
    // wait for the next volley
    while(ball >= 0 && ball != next_state)
    {
      mut.lock();
      std::cout << name << " waiting for return" << std::endl;
      mut.unlock();

      std::this_thread::sleep_for(std::chrono::seconds(1));
    }

    mut.lock();
    if(ball == -1)
    {
      std::cout << name << " wins!" << std::endl;
    }
    else
    {
      // try to return the ball
      if(std::rand() % 10 == 0)
      {
        // whiff -- declare outself the loser
        ball = -self.index() - 1;
        std::cout << "whiff... " << name << " loses!" << std::endl;
      }
      else
      {
        // successful return
        ball += 1;
        std::cout << name << "! ball is now " << ball << std::endl;
      }
    }
    mut.unlock();

    std::this_thread::sleep_for(std::chrono::seconds(1));
  }

  // decode who lost the match
  int loser = (ball > 0) ? 1 : -(ball + 1);

  // return the winner
  return loser ^ 1;
}

// this function implements a two concurrent semifinals ping pong matches
// followed by a single final ping pong match
void ping_pong_tournament(agency::concurrent_group<agency::concurrent_agent>& self,
                          const std::vector<std::vector<std::string>>& semifinalists,
                          int num_volleys,
                          movable_mutex& mut,
                          int& ball,
                          std::vector<std::string>& finalists)
{
  if(self.inner().index() == 0)
  {
    if(self.outer().index() == 0)
    {
      std::cout << "Starting semifinal matches..." << std::endl;
    }

    self.outer().wait();
  }

  self.inner().wait();

  // play the semifinals matches
  auto semifinal_winner_idx = ping_pong_match(self.inner(), semifinalists[self.outer().index()], num_volleys, mut, ball);

  if(self.inner().index() == 0)
  {
    // the first agent of each group reports who won the semifinal match
    auto semifinal_winner = semifinalists[self.outer().index()][semifinal_winner_idx];
    finalists[self.outer().index()] = semifinal_winner;

    // have the first player of each group wait for the other group
    self.outer().wait();
  }

  // have each inner group wait for each other
  self.inner().wait();

  // group 0 plays the final match while group 1 sits it out
  if(self.outer().index() == 0)
  {
    // agent 0 initializes the contestant names for the final match
    if(self.inner().index() == 0)
    {
      std::cout << std::endl << finalists[0] << " and " << finalists[1] << " starting the final match..." << std::endl;
    }

    // wait until agent 0 initializes the contestant names before starting the final match
    self.inner().wait();

    // play the final match
    auto final_winner_idx = ping_pong_match(self.inner(), finalists, num_volleys, mut, ball);

    // have agent 0 of group 0 report the winner
    if(self.inner().index() == 0)
    {
      std::cout << std::endl << finalists[final_winner_idx] << " is the tournament champion!" << std::endl;
    }
  }
}

int main()
{
  using namespace agency;
  using namespace std;

  size_t num_volleys = 20;
  vector<vector<string>> semifinalists = {{"ping", "pong"}, {"foo", "bar"}};

  bulk_invoke(con(2, con(2)), ping_pong_tournament, semifinalists, num_volleys, share<0,movable_mutex>(), share<1,int>(), share<0,vector<string>>(2));

  return 0;
}

<|endoftext|>


<commit_before>/****************************************************************************
**
** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies).
** Contact: http://www.qt-project.org/
**
** This file is part of the examples of the Qt Toolkit.
**
** $QT_BEGIN_LICENSE:BSD$
** You may use this file under the terms of the BSD license as follows:
**
** "Redistribution and use in source and binary forms, with or without
** modification, are permitted provided that the following conditions are
** met:
**   * Redistributions of source code must retain the above copyright
**     notice, this list of conditions and the following disclaimer.
**   * Redistributions in binary form must reproduce the above copyright
**     notice, this list of conditions and the following disclaimer in
**     the documentation and/or other materials provided with the
**     distribution.
**   * Neither the name of Nokia Corporation and its Subsidiary(-ies) nor
**     the names of its contributors may be used to endorse or promote
**     products derived from this software without specific prior written
**     permission.
**
** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
**
** $QT_END_LICENSE$
**
****************************************************************************/

#include "playlistmodel.h"

#include <QtCore/qfileinfo.h>
#include <QtCore/qurl.h>

#include <qmediaplaylist.h>

PlaylistModel::PlaylistModel(QObject *parent)
    : QAbstractItemModel(parent)
    , m_playlist(0)
{
}

int PlaylistModel::rowCount(const QModelIndex &parent) const
{
    return m_playlist && !parent.isValid() ? m_playlist->mediaCount() : 0;
}

int PlaylistModel::columnCount(const QModelIndex &parent) const
{
    return !parent.isValid() ? ColumnCount : 0;
}

QModelIndex PlaylistModel::index(int row, int column, const QModelIndex &parent) const
{
    return m_playlist && !parent.isValid()
            && row >= 0 && row < m_playlist->mediaCount()
            && column >= 0 && column < ColumnCount
        ? createIndex(row, column)
        : QModelIndex();
}

QModelIndex PlaylistModel::parent(const QModelIndex &child) const
{
    Q_UNUSED(child);

    return QModelIndex();
}

QVariant PlaylistModel::data(const QModelIndex &index, int role) const
{
    if (index.isValid() && role == Qt::DisplayRole) {
        QVariant value = m_data[index];
        if (!value.isValid() && index.column() == Title) {
            QUrl location = m_playlist->media(index.row()).canonicalUrl();
            return QFileInfo(location.path()).fileName();
        }

        return value;
    }
    return QVariant();
}

QMediaPlaylist *PlaylistModel::playlist() const
{
    return m_playlist;
}

void PlaylistModel::setPlaylist(QMediaPlaylist *playlist)
{
    if (m_playlist) {
        disconnect(m_playlist, SIGNAL(mediaAboutToBeInserted(int,int)), this, SLOT(beginInsertItems(int,int)));
        disconnect(m_playlist, SIGNAL(mediaInserted(int,int)), this, SLOT(endInsertItems()));
        disconnect(m_playlist, SIGNAL(mediaAboutToBeRemoved(int,int)), this, SLOT(beginRemoveItems(int,int)));
        disconnect(m_playlist, SIGNAL(mediaRemoved(int,int)), this, SLOT(endRemoveItems()));
        disconnect(m_playlist, SIGNAL(mediaChanged(int,int)), this, SLOT(changeItems(int,int)));
    }

    m_playlist = playlist;

    if (m_playlist) {
        connect(m_playlist, SIGNAL(mediaAboutToBeInserted(int,int)), this, SLOT(beginInsertItems(int,int)));
        connect(m_playlist, SIGNAL(mediaInserted(int,int)), this, SLOT(endInsertItems()));
        connect(m_playlist, SIGNAL(mediaAboutToBeRemoved(int,int)), this, SLOT(beginRemoveItems(int,int)));
        connect(m_playlist, SIGNAL(mediaRemoved(int,int)), this, SLOT(endRemoveItems()));
        connect(m_playlist, SIGNAL(mediaChanged(int,int)), this, SLOT(changeItems(int,int)));
    }

    reset();
}

bool PlaylistModel::setData(const QModelIndex &index, const QVariant &value, int role)
{
    Q_UNUSED(role);
    m_data[index] = value;
    emit dataChanged(index, index);
    return true;
}

void PlaylistModel::beginInsertItems(int start, int end)
{
    m_data.clear();
    beginInsertRows(QModelIndex(), start, end);
}

void PlaylistModel::endInsertItems()
{
    endInsertRows();
}

void PlaylistModel::beginRemoveItems(int start, int end)
{
    m_data.clear();
    beginRemoveRows(QModelIndex(), start, end);
}

void PlaylistModel::endRemoveItems()
{
    endInsertRows();
}

void PlaylistModel::changeItems(int start, int end)
{
    m_data.clear();
    emit dataChanged(index(start,0), index(end,ColumnCount));
}

<commit_msg>QAbstractItemMode::reset() is deprecated, don't use it<commit_after>/****************************************************************************
**
** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies).
** Contact: http://www.qt-project.org/
**
** This file is part of the examples of the Qt Toolkit.
**
** $QT_BEGIN_LICENSE:BSD$
** You may use this file under the terms of the BSD license as follows:
**
** "Redistribution and use in source and binary forms, with or without
** modification, are permitted provided that the following conditions are
** met:
**   * Redistributions of source code must retain the above copyright
**     notice, this list of conditions and the following disclaimer.
**   * Redistributions in binary form must reproduce the above copyright
**     notice, this list of conditions and the following disclaimer in
**     the documentation and/or other materials provided with the
**     distribution.
**   * Neither the name of Nokia Corporation and its Subsidiary(-ies) nor
**     the names of its contributors may be used to endorse or promote
**     products derived from this software without specific prior written
**     permission.
**
** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
**
** $QT_END_LICENSE$
**
****************************************************************************/

#include "playlistmodel.h"

#include <QtCore/qfileinfo.h>
#include <QtCore/qurl.h>

#include <qmediaplaylist.h>

PlaylistModel::PlaylistModel(QObject *parent)
    : QAbstractItemModel(parent)
    , m_playlist(0)
{
}

int PlaylistModel::rowCount(const QModelIndex &parent) const
{
    return m_playlist && !parent.isValid() ? m_playlist->mediaCount() : 0;
}

int PlaylistModel::columnCount(const QModelIndex &parent) const
{
    return !parent.isValid() ? ColumnCount : 0;
}

QModelIndex PlaylistModel::index(int row, int column, const QModelIndex &parent) const
{
    return m_playlist && !parent.isValid()
            && row >= 0 && row < m_playlist->mediaCount()
            && column >= 0 && column < ColumnCount
        ? createIndex(row, column)
        : QModelIndex();
}

QModelIndex PlaylistModel::parent(const QModelIndex &child) const
{
    Q_UNUSED(child);

    return QModelIndex();
}

QVariant PlaylistModel::data(const QModelIndex &index, int role) const
{
    if (index.isValid() && role == Qt::DisplayRole) {
        QVariant value = m_data[index];
        if (!value.isValid() && index.column() == Title) {
            QUrl location = m_playlist->media(index.row()).canonicalUrl();
            return QFileInfo(location.path()).fileName();
        }

        return value;
    }
    return QVariant();
}

QMediaPlaylist *PlaylistModel::playlist() const
{
    return m_playlist;
}

void PlaylistModel::setPlaylist(QMediaPlaylist *playlist)
{
    if (m_playlist) {
        disconnect(m_playlist, SIGNAL(mediaAboutToBeInserted(int,int)), this, SLOT(beginInsertItems(int,int)));
        disconnect(m_playlist, SIGNAL(mediaInserted(int,int)), this, SLOT(endInsertItems()));
        disconnect(m_playlist, SIGNAL(mediaAboutToBeRemoved(int,int)), this, SLOT(beginRemoveItems(int,int)));
        disconnect(m_playlist, SIGNAL(mediaRemoved(int,int)), this, SLOT(endRemoveItems()));
        disconnect(m_playlist, SIGNAL(mediaChanged(int,int)), this, SLOT(changeItems(int,int)));
    }

    beginResetModel();
    m_playlist = playlist;

    if (m_playlist) {
        connect(m_playlist, SIGNAL(mediaAboutToBeInserted(int,int)), this, SLOT(beginInsertItems(int,int)));
        connect(m_playlist, SIGNAL(mediaInserted(int,int)), this, SLOT(endInsertItems()));
        connect(m_playlist, SIGNAL(mediaAboutToBeRemoved(int,int)), this, SLOT(beginRemoveItems(int,int)));
        connect(m_playlist, SIGNAL(mediaRemoved(int,int)), this, SLOT(endRemoveItems()));
        connect(m_playlist, SIGNAL(mediaChanged(int,int)), this, SLOT(changeItems(int,int)));
    }

    endResetModel();
}

bool PlaylistModel::setData(const QModelIndex &index, const QVariant &value, int role)
{
    Q_UNUSED(role);
    m_data[index] = value;
    emit dataChanged(index, index);
    return true;
}

void PlaylistModel::beginInsertItems(int start, int end)
{
    m_data.clear();
    beginInsertRows(QModelIndex(), start, end);
}

void PlaylistModel::endInsertItems()
{
    endInsertRows();
}

void PlaylistModel::beginRemoveItems(int start, int end)
{
    m_data.clear();
    beginRemoveRows(QModelIndex(), start, end);
}

void PlaylistModel::endRemoveItems()
{
    endInsertRows();
}

void PlaylistModel::changeItems(int start, int end)
{
    m_data.clear();
    emit dataChanged(index(start,0), index(end,ColumnCount));
}

<|endoftext|>


<commit_before>/* Copyright 2019 The TensorFlow Authors. All Rights Reserved.

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

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

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

// This pass optimizes tf_saved_model.global_tensor ops.

#include <map>
#include <set>

#include "llvm/ADT/DenseMap.h"
#include "llvm/ADT/STLExtras.h"
#include "mlir/IR/Builders.h"  // TF:llvm-project
#include "mlir/IR/Module.h"  // TF:llvm-project
#include "mlir/Pass/Pass.h"  // TF:llvm-project
#include "tensorflow/compiler/mlir/tensorflow/ir/tf_ops.h"
#include "tensorflow/compiler/mlir/tensorflow/ir/tf_saved_model.h"

namespace mlir {
namespace tf_saved_model {
namespace {
struct OptimizeGlobalTensorsPass
    : public ModulePass<OptimizeGlobalTensorsPass> {
  void runOnModule() override;
};

// A global tensor is bound to arguments of multiple funcs.
// This struct tracks which funcs (and which argument to that func) the global
// tensor is bound to.
struct GlobalTensorUse {
  mutable FuncOp func;
  size_t arg_index;
};

using GlobalTensorUsesMap =
    std::map<GlobalTensorOp, std::vector<GlobalTensorUse>>;

// TODO(silvasean): Are there other read-only variable ops?
// It would be nice if we eventually had an interface that we could use
// to determine if an op is read-only and how to rewrite it.
// For now, IsReadOnlyVariableOp and RewriteReadOnlyVariableOpToTensorOp need to
// be keep in sync.
bool IsReadOnlyVariableOp(Operation* op) { return isa<TF::ReadVariableOp>(op); }

void RewriteReadOnlyVariableOpToTensorOp(Operation* op, Value tensor_value) {
  auto read_variable = cast<TF::ReadVariableOp>(op);
  read_variable.value().replaceAllUsesWith(tensor_value);
}

bool IsFreezable(GlobalTensorOp global_tensor,
                 ArrayRef<GlobalTensorUse> global_tensor_uses) {
  // If this tensor is already immutable, don't freeze it.
  if (!global_tensor.is_mutable()) {
    return false;
  }
  // Can't freeze if exported.
  if (IsExported(global_tensor)) {
    return false;
  }

  // Can't freeze if it is used by anything that we aren't sure is read-only.
  // Right now, this uses a very simple algorithm that only checks the top-level
  // func for tf.ReadVariableOp. If the resource is passed into other functions
  // or control flow, we fail to prove it is freezable even though we could.
  for (auto& global_tensor_use : global_tensor_uses) {
    auto arg = global_tensor_use.func.getArgument(global_tensor_use.arg_index);
    for (auto user : arg.getUsers()) {
      if (!IsReadOnlyVariableOp(user)) {
        return false;
      }
    }
  }
  return true;
}

static GlobalTensorUsesMap CreateGlobalTensorUsesMap(ModuleOp module) {
  GlobalTensorUsesMap global_tensor_uses;

  SymbolTable symbol_table(module);
  for (auto func : module.getOps<FuncOp>()) {
    for (size_t i = 0, e = func.getNumArguments(); i < e; i++) {
      auto sym =
          func.getArgAttrOfType<SymbolRefAttr>(i, "tf_saved_model.bound_input");
      if (!sym) {
        continue;
      }
      auto global_tensor = symbol_table.lookup<GlobalTensorOp>(
          sym.cast<FlatSymbolRefAttr>().getValue());
      global_tensor_uses[global_tensor].push_back({func, i});
    }
  }

  return global_tensor_uses;
}

void FreezeGlobalTensors(ModuleOp module,
                         const GlobalTensorUsesMap& global_tensor_uses_map) {
  SmallVector<GlobalTensorOp, 4> freezable_global_tensors;
  for (auto& kv : global_tensor_uses_map) {
    auto global_tensor = kv.first;
    const auto& global_tensor_uses = kv.second;
    if (IsFreezable(global_tensor, global_tensor_uses)) {
      freezable_global_tensors.push_back(global_tensor);
    }
  }

  // Remove `is_mutable` attribute from tf_saved_model.global_tensor
  // and update func arguments to match.
  //
  // This amounts to changing the type of the argument to a tensor type, and
  // replacing all the tf.ReadVariableOp's with the new tensor argument value.
  OpBuilder builder(module.getBodyRegion());
  for (const auto& kv : global_tensor_uses_map) {
    auto global_tensor = kv.first;
    const auto& global_tensor_uses = kv.second;
    if (!IsFreezable(global_tensor, global_tensor_uses)) {
      continue;
    }
    for (auto global_tensor_use : global_tensor_uses) {
      auto func = global_tensor_use.func;
      auto arg_index = global_tensor_use.arg_index;
      Value arg = func.getArgument(arg_index);
      for (Operation* user : llvm::make_early_inc_range(arg.getUsers())) {
        RewriteReadOnlyVariableOpToTensorOp(user, arg);
        user->erase();
      }
      Type new_type = global_tensor.value().Attribute::getType();
      arg.setType(new_type);
      auto old_ftype = func.getType();
      auto input_types = old_ftype.getInputs().vec();
      input_types[arg_index] = new_type;
      func.setType(
          builder.getFunctionType(input_types, old_ftype.getResults()));
    }
    global_tensor.removeAttr("is_mutable");
  }
}

void EraseUnusedGlobalTensors(ModuleOp module,
                              const GlobalTensorUsesMap& global_tensor_uses) {
  for (auto global_tensor :
       llvm::make_early_inc_range(module.getOps<GlobalTensorOp>())) {
    // If the tensor is exported, then it is used.
    if (IsExported(global_tensor)) {
      continue;
    }
    // If the tensor is bound to an argument, then it is used.
    if (global_tensor_uses.find(global_tensor) != global_tensor_uses.end()) {
      continue;
    }
    // Erase it.
    global_tensor.erase();
  }
}

void EraseUnusedBoundInputs(ModuleOp module) {
  for (auto func : module.getOps<FuncOp>()) {
    SmallVector<unsigned, 4> args_to_erase;
    for (int i = 0, e = func.getNumArguments(); i < e; i++) {
      if (func.getArgAttr(i, "tf_saved_model.bound_input") &&
          func.getArgument(i).use_empty()) {
        args_to_erase.push_back(i);
      }
    }
    func.eraseArguments(args_to_erase);
  }
}

void OptimizeGlobalTensorsPass::runOnModule() {
  // This analysis could be much more elaborate, including tracking global
  // tensors interprocedurally and uses in a wide variety of ops. But I don't
  // know if we need that complexity.
  auto module = getModule();

  EraseUnusedBoundInputs(module);

  // Figure out which func's use each tf_saved_model.global_tensor.
  GlobalTensorUsesMap global_tensor_uses = CreateGlobalTensorUsesMap(module);

  FreezeGlobalTensors(module, global_tensor_uses);
  EraseUnusedGlobalTensors(module, global_tensor_uses);
}

}  // namespace

// For "opt" to pick up this pass.
static PassRegistration<OptimizeGlobalTensorsPass> pass(
    "tf-saved-model-optimize-global-tensors",
    "Optimize tf_saved_model.global_tensor's.");

std::unique_ptr<OpPassBase<ModuleOp>> CreateOptimizeGlobalTensorsPass() {
  return std::make_unique<OptimizeGlobalTensorsPass>();
}

}  // namespace tf_saved_model
}  // namespace mlir
<commit_msg>Remove dead-code in saved model optimize global tensors pass<commit_after>/* Copyright 2019 The TensorFlow Authors. All Rights Reserved.

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

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

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

// This pass optimizes tf_saved_model.global_tensor ops.

#include <map>
#include <set>

#include "llvm/ADT/DenseMap.h"
#include "llvm/ADT/STLExtras.h"
#include "mlir/IR/Builders.h"  // TF:llvm-project
#include "mlir/IR/Module.h"  // TF:llvm-project
#include "mlir/Pass/Pass.h"  // TF:llvm-project
#include "tensorflow/compiler/mlir/tensorflow/ir/tf_ops.h"
#include "tensorflow/compiler/mlir/tensorflow/ir/tf_saved_model.h"

namespace mlir {
namespace tf_saved_model {
namespace {
struct OptimizeGlobalTensorsPass
    : public ModulePass<OptimizeGlobalTensorsPass> {
  void runOnModule() override;
};

// A global tensor is bound to arguments of multiple funcs.
// This struct tracks which funcs (and which argument to that func) the global
// tensor is bound to.
struct GlobalTensorUse {
  mutable FuncOp func;
  size_t arg_index;
};

using GlobalTensorUsesMap =
    std::map<GlobalTensorOp, std::vector<GlobalTensorUse>>;

// TODO(silvasean): Are there other read-only variable ops?
// It would be nice if we eventually had an interface that we could use
// to determine if an op is read-only and how to rewrite it.
// For now, IsReadOnlyVariableOp and RewriteReadOnlyVariableOpToTensorOp need to
// be keep in sync.
bool IsReadOnlyVariableOp(Operation* op) { return isa<TF::ReadVariableOp>(op); }

void RewriteReadOnlyVariableOpToTensorOp(Operation* op, Value tensor_value) {
  auto read_variable = cast<TF::ReadVariableOp>(op);
  read_variable.value().replaceAllUsesWith(tensor_value);
}

bool IsFreezable(GlobalTensorOp global_tensor,
                 ArrayRef<GlobalTensorUse> global_tensor_uses) {
  // If this tensor is already immutable, don't freeze it.
  if (!global_tensor.is_mutable()) {
    return false;
  }
  // Can't freeze if exported.
  if (IsExported(global_tensor)) {
    return false;
  }

  // Can't freeze if it is used by anything that we aren't sure is read-only.
  // Right now, this uses a very simple algorithm that only checks the top-level
  // func for tf.ReadVariableOp. If the resource is passed into other functions
  // or control flow, we fail to prove it is freezable even though we could.
  for (auto& global_tensor_use : global_tensor_uses) {
    auto arg = global_tensor_use.func.getArgument(global_tensor_use.arg_index);
    for (auto user : arg.getUsers()) {
      if (!IsReadOnlyVariableOp(user)) {
        return false;
      }
    }
  }
  return true;
}

static GlobalTensorUsesMap CreateGlobalTensorUsesMap(ModuleOp module) {
  GlobalTensorUsesMap global_tensor_uses;

  SymbolTable symbol_table(module);
  for (auto func : module.getOps<FuncOp>()) {
    for (size_t i = 0, e = func.getNumArguments(); i < e; i++) {
      auto sym =
          func.getArgAttrOfType<SymbolRefAttr>(i, "tf_saved_model.bound_input");
      if (!sym) {
        continue;
      }
      auto global_tensor = symbol_table.lookup<GlobalTensorOp>(
          sym.cast<FlatSymbolRefAttr>().getValue());
      global_tensor_uses[global_tensor].push_back({func, i});
    }
  }

  return global_tensor_uses;
}

void FreezeGlobalTensors(ModuleOp module,
                         const GlobalTensorUsesMap& global_tensor_uses_map) {
  // Remove `is_mutable` attribute from tf_saved_model.global_tensor
  // and update func arguments to match.
  //
  // This amounts to changing the type of the argument to a tensor type, and
  // replacing all the tf.ReadVariableOp's with the new tensor argument value.
  OpBuilder builder(module.getBodyRegion());
  for (const auto& kv : global_tensor_uses_map) {
    auto global_tensor = kv.first;
    const auto& global_tensor_uses = kv.second;
    if (!IsFreezable(global_tensor, global_tensor_uses)) {
      continue;
    }
    for (auto global_tensor_use : global_tensor_uses) {
      auto func = global_tensor_use.func;
      auto arg_index = global_tensor_use.arg_index;
      Value arg = func.getArgument(arg_index);
      for (Operation* user : llvm::make_early_inc_range(arg.getUsers())) {
        RewriteReadOnlyVariableOpToTensorOp(user, arg);
        user->erase();
      }
      Type new_type = global_tensor.value().Attribute::getType();
      arg.setType(new_type);
      auto old_ftype = func.getType();
      auto input_types = old_ftype.getInputs().vec();
      input_types[arg_index] = new_type;
      func.setType(
          builder.getFunctionType(input_types, old_ftype.getResults()));
    }
    global_tensor.removeAttr("is_mutable");
  }
}

void EraseUnusedGlobalTensors(ModuleOp module,
                              const GlobalTensorUsesMap& global_tensor_uses) {
  for (auto global_tensor :
       llvm::make_early_inc_range(module.getOps<GlobalTensorOp>())) {
    // If the tensor is exported, then it is used.
    if (IsExported(global_tensor)) {
      continue;
    }
    // If the tensor is bound to an argument, then it is used.
    if (global_tensor_uses.find(global_tensor) != global_tensor_uses.end()) {
      continue;
    }
    // Erase it.
    global_tensor.erase();
  }
}

void EraseUnusedBoundInputs(ModuleOp module) {
  for (auto func : module.getOps<FuncOp>()) {
    SmallVector<unsigned, 4> args_to_erase;
    for (int i = 0, e = func.getNumArguments(); i < e; i++) {
      if (func.getArgAttr(i, "tf_saved_model.bound_input") &&
          func.getArgument(i).use_empty()) {
        args_to_erase.push_back(i);
      }
    }
    func.eraseArguments(args_to_erase);
  }
}

void OptimizeGlobalTensorsPass::runOnModule() {
  // This analysis could be much more elaborate, including tracking global
  // tensors interprocedurally and uses in a wide variety of ops. But I don't
  // know if we need that complexity.
  auto module = getModule();

  EraseUnusedBoundInputs(module);

  // Figure out which func's use each tf_saved_model.global_tensor.
  GlobalTensorUsesMap global_tensor_uses = CreateGlobalTensorUsesMap(module);

  FreezeGlobalTensors(module, global_tensor_uses);
  EraseUnusedGlobalTensors(module, global_tensor_uses);
}

}  // namespace

// For "opt" to pick up this pass.
static PassRegistration<OptimizeGlobalTensorsPass> pass(
    "tf-saved-model-optimize-global-tensors",
    "Optimize tf_saved_model.global_tensor's.");

std::unique_ptr<OpPassBase<ModuleOp>> CreateOptimizeGlobalTensorsPass() {
  return std::make_unique<OptimizeGlobalTensorsPass>();
}

}  // namespace tf_saved_model
}  // namespace mlir
<|endoftext|>


<commit_before>#include <string>
#include <utility>

#include <QMessageBox>
#include <QInputDialog>

#include "chatwidget.hpp"

#include "caf/all.hpp"
#include "caf/detail/scope_guard.hpp"

using namespace std;
using namespace caf;

ChatWidget::ChatWidget(QWidget* parent, Qt::WindowFlags f)
: super(parent, f), m_input(nullptr), m_output(nullptr) {
        set_message_handler ([=](local_actor* self) -> message_handler {
        return {
            on(atom("join"), arg_match) >> [=](const group& what) {
                if (m_chatroom) {
                    self->send(m_chatroom, m_name + " has left the chatroom");
                    self->leave(m_chatroom);
                }
                self->join(what);
                print(("*** joined " + to_string(what)).c_str());
                m_chatroom = what;
                self->send(what, m_name + " has entered the chatroom");
            },
            on(atom("setName"), arg_match) >> [=](string& name) {
                self->send(m_chatroom, m_name + " is now known as " + name);
                m_name = std::move(name);
                print("*** changed name to "
                                  + QString::fromUtf8(m_name.c_str()));
            },
            on(atom("quit")) >> [=] {
                close(); // close widget
            },
            [=](const string& txt) {
                // don't print own messages
                if (self != self->current_sender()) {
                    print(QString::fromUtf8(txt.c_str()));
                }
            },
            [=](const group_down_msg& gdm) {
                print("*** chatroom offline: "
                      + QString::fromUtf8(to_string(gdm.source).c_str()));
            }
        };
    });
}

void ChatWidget::sendChatMessage() {
    auto cleanup = detail::make_scope_guard([=] {
        input()->setText(QString());
    });
    QString line = input()->text();
    if (line.startsWith('/')) {
        vector<string> words;
        split(words, line.midRef(1).toUtf8().constData(), is_any_of(" "));
        message_builder(words.begin(), words.end()).apply({
            on("join", arg_match) >> [=](const string& mod, const string& g) {
                group gptr;
                try { gptr = group::get(mod, g); }
                catch (exception& e) {
                    print("*** exception: " + QString::fromUtf8((e.what())));
                }
                if (gptr) {
                    send_as(as_actor(), as_actor(), atom("join"), gptr);
                }
            },
            on("setName", arg_match) >> [=](const string& str) {
                send_as(as_actor(), as_actor(), atom("setName"), str);
            },
            others() >> [=] {
                print("*** list of commands:\n"
                      "/join <module> <group id>\n"
                      "/setName <new name>\n");
            }
        });
        return;
    }
    if (m_name.empty()) {
        print("*** please set a name before sending messages");
        return;
    }
    if (!m_chatroom) {
        print("*** no one is listening... please join a group");
        return;
    }
    string msg = m_name;
    msg += ": ";
    msg += line.toUtf8().constData();
    print("<you>: " + input()->text());
    // NOTE: we have to use send_as(as_actor(), ...) outside of our
    //       message handler, because `self` is *not* set properly
    //       in this context
    send_as(as_actor(), m_chatroom, std::move(msg));
}

void ChatWidget::joinGroup() {
    if (m_name.empty()) {
        QMessageBox::information(this,
                                 "No Name, No Chat",
                                 "Please set a name first.");
        return;
    }
    auto gname = QInputDialog::getText(this,
                                       "Join Group",
                                       "Please enter a group as <module>:<id>",
                                       QLineEdit::Normal,
                                       "remote:chatroom@localhost:4242");
    int pos = gname.indexOf(':');
    if (pos < 0) {
        QMessageBox::warning(this, "Not a Group", "Invalid format");
        return;
    }
    string mod = gname.left(pos).toUtf8().constData();
    string gid = gname.midRef(pos+1).toUtf8().constData();
    try {
        auto gptr = group::get(mod, gid);
        send_as(as_actor(), as_actor(), atom("join"), gptr);
    }
    catch (exception& e) {
        QMessageBox::critical(this, "Exception", e.what());
    }
}

void ChatWidget::changeName() {
    auto name = QInputDialog::getText(this, "Change Name", "Please enter a new name");
    if (!name.isEmpty()) {
        send_as(as_actor(), as_actor(), atom("setName"), name.toUtf8().constData());
    }
}
<commit_msg>Remove outdated comment<commit_after>#include <string>
#include <utility>

#include <QMessageBox>
#include <QInputDialog>

#include "chatwidget.hpp"

#include "caf/all.hpp"
#include "caf/detail/scope_guard.hpp"

using namespace std;
using namespace caf;

ChatWidget::ChatWidget(QWidget* parent, Qt::WindowFlags f)
: super(parent, f), m_input(nullptr), m_output(nullptr) {
        set_message_handler ([=](local_actor* self) -> message_handler {
        return {
            on(atom("join"), arg_match) >> [=](const group& what) {
                if (m_chatroom) {
                    self->send(m_chatroom, m_name + " has left the chatroom");
                    self->leave(m_chatroom);
                }
                self->join(what);
                print(("*** joined " + to_string(what)).c_str());
                m_chatroom = what;
                self->send(what, m_name + " has entered the chatroom");
            },
            on(atom("setName"), arg_match) >> [=](string& name) {
                self->send(m_chatroom, m_name + " is now known as " + name);
                m_name = std::move(name);
                print("*** changed name to "
                                  + QString::fromUtf8(m_name.c_str()));
            },
            on(atom("quit")) >> [=] {
                close(); // close widget
            },
            [=](const string& txt) {
                // don't print own messages
                if (self != self->current_sender()) {
                    print(QString::fromUtf8(txt.c_str()));
                }
            },
            [=](const group_down_msg& gdm) {
                print("*** chatroom offline: "
                      + QString::fromUtf8(to_string(gdm.source).c_str()));
            }
        };
    });
}

void ChatWidget::sendChatMessage() {
    auto cleanup = detail::make_scope_guard([=] {
        input()->setText(QString());
    });
    QString line = input()->text();
    if (line.startsWith('/')) {
        vector<string> words;
        split(words, line.midRef(1).toUtf8().constData(), is_any_of(" "));
        message_builder(words.begin(), words.end()).apply({
            on("join", arg_match) >> [=](const string& mod, const string& g) {
                group gptr;
                try { gptr = group::get(mod, g); }
                catch (exception& e) {
                    print("*** exception: " + QString::fromUtf8((e.what())));
                }
                if (gptr) {
                    send_as(as_actor(), as_actor(), atom("join"), gptr);
                }
            },
            on("setName", arg_match) >> [=](const string& str) {
                send_as(as_actor(), as_actor(), atom("setName"), str);
            },
            others() >> [=] {
                print("*** list of commands:\n"
                      "/join <module> <group id>\n"
                      "/setName <new name>\n");
            }
        });
        return;
    }
    if (m_name.empty()) {
        print("*** please set a name before sending messages");
        return;
    }
    if (!m_chatroom) {
        print("*** no one is listening... please join a group");
        return;
    }
    string msg = m_name;
    msg += ": ";
    msg += line.toUtf8().constData();
    print("<you>: " + input()->text());
    send_as(as_actor(), m_chatroom, std::move(msg));
}

void ChatWidget::joinGroup() {
    if (m_name.empty()) {
        QMessageBox::information(this,
                                 "No Name, No Chat",
                                 "Please set a name first.");
        return;
    }
    auto gname = QInputDialog::getText(this,
                                       "Join Group",
                                       "Please enter a group as <module>:<id>",
                                       QLineEdit::Normal,
                                       "remote:chatroom@localhost:4242");
    int pos = gname.indexOf(':');
    if (pos < 0) {
        QMessageBox::warning(this, "Not a Group", "Invalid format");
        return;
    }
    string mod = gname.left(pos).toUtf8().constData();
    string gid = gname.midRef(pos+1).toUtf8().constData();
    try {
        auto gptr = group::get(mod, gid);
        send_as(as_actor(), as_actor(), atom("join"), gptr);
    }
    catch (exception& e) {
        QMessageBox::critical(this, "Exception", e.what());
    }
}

void ChatWidget::changeName() {
    auto name = QInputDialog::getText(this, "Change Name", "Please enter a new name");
    if (!name.isEmpty()) {
        send_as(as_actor(), as_actor(), atom("setName"), name.toUtf8().constData());
    }
}
<|endoftext|>


<commit_before>/*
 * Copyright (C) 2018 The Android Open Source Project
 *
 * 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 "src/trace_processor/instants_table.h"

#include "src/trace_processor/counters_table.h"

namespace perfetto {
namespace trace_processor {

InstantsTable::InstantsTable(sqlite3*, const TraceStorage* storage)
    : storage_(storage) {
  ref_types_.resize(RefType::kRefMax);
  ref_types_[RefType::kRefNoRef] = "";
  ref_types_[RefType::kRefUtid] = "utid";
  ref_types_[RefType::kRefCpuId] = "cpu";
  ref_types_[RefType::kRefIrq] = "irq";
  ref_types_[RefType::kRefSoftIrq] = "softirq";
  ref_types_[RefType::kRefUpid] = "upid";
};

void InstantsTable::RegisterTable(sqlite3* db, const TraceStorage* storage) {
  Table::Register<InstantsTable>(db, storage, "instants");
}

StorageSchema InstantsTable::CreateStorageSchema() {
  const auto& instants = storage_->instants();
  return StorageSchema::Builder()
      .AddColumn<IdColumn>("id", TableId::kInstants)
      .AddOrderedNumericColumn("ts", &instants.timestamps())
      .AddStringColumn("name", &instants.name_ids(), &storage_->string_pool())
      .AddNumericColumn("value", &instants.values())
      .AddColumn<CountersTable::RefColumn>("ref", &instants.refs(),
                                           &instants.types(), storage_)
      .AddStringColumn("ref_type", &instants.types(), &ref_types_)
      .AddNumericColumn("arg_set_id", &instants.arg_set_ids())
      .Build({"name", "ts", "ref"});
}

uint32_t InstantsTable::RowCount() {
  return static_cast<uint32_t>(storage_->instants().instant_count());
}

int InstantsTable::BestIndex(const QueryConstraints& qc, BestIndexInfo* info) {
  info->estimated_cost =
      static_cast<uint32_t>(storage_->instants().instant_count());

  // Only the string columns are handled by SQLite
  info->order_by_consumed = true;
  size_t name_index = schema().ColumnIndexFromName("name");
  size_t ref_type_index = schema().ColumnIndexFromName("ref_type");
  for (size_t i = 0; i < qc.constraints().size(); i++) {
    info->omit[i] =
        qc.constraints()[i].iColumn != static_cast<int>(name_index) &&
        qc.constraints()[i].iColumn != static_cast<int>(ref_type_index);
  }

  return SQLITE_OK;
}
}  // namespace trace_processor
}  // namespace perfetto
<commit_msg>trace_processor: add missing ref type on instants table am: 116dd318a6 am: 3e455e726e<commit_after>/*
 * Copyright (C) 2018 The Android Open Source Project
 *
 * 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 "src/trace_processor/instants_table.h"

#include "src/trace_processor/counters_table.h"

namespace perfetto {
namespace trace_processor {

InstantsTable::InstantsTable(sqlite3*, const TraceStorage* storage)
    : storage_(storage) {
  ref_types_.resize(RefType::kRefMax);
  ref_types_[RefType::kRefNoRef] = "";
  ref_types_[RefType::kRefUtid] = "utid";
  ref_types_[RefType::kRefUpid] = "upid";
  ref_types_[RefType::kRefCpuId] = "cpu";
  ref_types_[RefType::kRefIrq] = "irq";
  ref_types_[RefType::kRefSoftIrq] = "softirq";
  ref_types_[RefType::kRefUtidLookupUpid] = "upid";
};

void InstantsTable::RegisterTable(sqlite3* db, const TraceStorage* storage) {
  Table::Register<InstantsTable>(db, storage, "instants");
}

StorageSchema InstantsTable::CreateStorageSchema() {
  const auto& instants = storage_->instants();
  return StorageSchema::Builder()
      .AddColumn<IdColumn>("id", TableId::kInstants)
      .AddOrderedNumericColumn("ts", &instants.timestamps())
      .AddStringColumn("name", &instants.name_ids(), &storage_->string_pool())
      .AddNumericColumn("value", &instants.values())
      .AddColumn<CountersTable::RefColumn>("ref", &instants.refs(),
                                           &instants.types(), storage_)
      .AddStringColumn("ref_type", &instants.types(), &ref_types_)
      .AddNumericColumn("arg_set_id", &instants.arg_set_ids())
      .Build({"name", "ts", "ref"});
}

uint32_t InstantsTable::RowCount() {
  return static_cast<uint32_t>(storage_->instants().instant_count());
}

int InstantsTable::BestIndex(const QueryConstraints& qc, BestIndexInfo* info) {
  info->estimated_cost =
      static_cast<uint32_t>(storage_->instants().instant_count());

  // Only the string columns are handled by SQLite
  info->order_by_consumed = true;
  size_t name_index = schema().ColumnIndexFromName("name");
  size_t ref_type_index = schema().ColumnIndexFromName("ref_type");
  for (size_t i = 0; i < qc.constraints().size(); i++) {
    info->omit[i] =
        qc.constraints()[i].iColumn != static_cast<int>(name_index) &&
        qc.constraints()[i].iColumn != static_cast<int>(ref_type_index);
  }

  return SQLITE_OK;
}
}  // namespace trace_processor
}  // namespace perfetto
<|endoftext|>


<commit_before>// -*- mode: c++; coding: utf-8 -*-
/*! @file simulation.cpp
    @brief Inplementation of Simulation class
*/
#include "simulation.h"

#include "cxxwtils/iostr.hpp"
#include "cxxwtils/getopt.hpp"
#include "cxxwtils/prandom.hpp"
#include "cxxwtils/os.hpp"
#include "cxxwtils/gz.hpp"
#include "cxxwtils/multiprocessing.hpp"

#include "individual.h"

/////////1/////////2/////////3/////////4/////////5/////////6/////////7/////////
// functions

//! Symbols for the program options can be different from those in equations
/*! @ingroup biol_param
    @return Program options description

    Command line option | Symbol   | Variable
    ------------------- | -------- | ------------------------------------------
    `--row,--col`       | -        | Simulation::NUM_COLS, Simulation::NUM_ROWS
    `-T,--time`         | -        | Simulation::ENTIRE_PERIOD
    `-I,--interval`     | -        | Simulation::OBSERVATION_CYCLE
*/
boost::program_options::options_description& Simulation::opt_description() {HERE;
    namespace po = boost::program_options;
    static po::options_description description("Simulation");
    description.add_options()
        ("help,h", po::value<bool>()->default_value(false)->implicit_value(true), "produce help")
        ("verbose,v", po::value<bool>(&VERBOSE)
            ->default_value(VERBOSE)->implicit_value(true), "verbose output")
        ("test", po::value<int>()->default_value(0)->implicit_value(1))
        ("mode", po::value<int>(&MODE)->default_value(MODE))
        ("ppn", po::value<size_t>(&PPN)->default_value(wtl::num_threads()))
        ("label", po::value<std::string>(&LABEL)->default_value("default"))
        ("top_dir", po::value<std::string>()->default_value(OUT_DIR.string()))
        ("row", po::value<size_t>(&NUM_ROWS)->default_value(NUM_ROWS))
        ("col", po::value<size_t>(&NUM_COLS)->default_value(NUM_COLS))
        ("dimensions,D", po::value<size_t>(&DIMENSIONS)->default_value(DIMENSIONS))
        ("time,T", po::value<size_t>(&ENTIRE_PERIOD)->default_value(ENTIRE_PERIOD))
        ("interval,I", po::value<size_t>(&OBSERVATION_CYCLE)->default_value(OBSERVATION_CYCLE))
        ("seed", po::value<unsigned int>(&SEED)->default_value(SEED))
    ;
    return description;
}

//! Unit test for each class
inline void test() {HERE;
    Individual::unit_test();
    Patch::unit_test();
}

Simulation::Simulation(int argc, char* argv[]) {HERE;
    std::vector<std::string> arguments(argv, argv + argc);
    std::cout << wtl::str_join(arguments, " ") << std::endl;
    std::cout << wtl::iso8601datetime() << std::endl;

    namespace po = boost::program_options;
    po::options_description description;
    description.add(opt_description());
    description.add(Individual::opt_description());
    po::variables_map vm;
    po::store(po::parse_command_line(argc, argv, description), vm);
    po::notify(vm);

    if (vm["help"].as<bool>()) {
        description.print(std::cout);
        exit(0);
    }
    OUT_DIR = fs::path(vm["top_dir"].as<std::string>());
    const std::string CONFIG_STRING = wtl::flags_into_string(description, vm);
    prandom().seed(SEED); // TODO: want to read seed?
    if (VERBOSE) {
        std::cout << CONFIG_STRING << std::endl;
    }
    if (ENTIRE_PERIOD % OBSERVATION_CYCLE > 0) {
        std::cerr << wtl::strprintf(
            "T=%d is not a multiple of I=%d",
            ENTIRE_PERIOD, OBSERVATION_CYCLE) << std::endl;
        exit(1);
    }
    if (DIMENSIONS == 1) {
        std::ostringstream ost;
        ost << "diameter_pref = 0\n"
            << "limb_select = 0\n"
            << "diameter_compe = 0\n"
            << "limb_compe = 0\n"
            << "mutation_mask = 10\n";
        std::istringstream ist(ost.str());
        po::store(po::parse_config_file(ist, description, false), vm);
    }
    switch (vm["test"].as<int>()) {
      case 0:
        break;
      case 1:
        test();
        exit(0);
      default:
        exit(1);
    }
    const std::string now(wtl::strftime("%Y%m%d_%H%M%S"));
    std::ostringstream pid_at_host;
    pid_at_host << ::getpid() << "@" << wtl::gethostname();
    WORK_DIR = TMP_DIR / (now + "_" + LABEL + "_" + pid_at_host.str());
    derr("mkdir && cd to " << WORK_DIR << std::endl);
    fs::create_directory(WORK_DIR);
    wtl::cd(WORK_DIR.string());
    fs::create_directory(OUT_DIR);
    OUT_DIR /= (LABEL + "_" + now + "_" + pid_at_host.str());
    wtl::Fout{"program_options.conf"} << CONFIG_STRING;
}

void Simulation::run() {HERE;
    switch (MODE) {
      case 0:
        evolve();
        break;
      case 1:
        Individual::write_resource_abundance();
        break;
      case 2:
        wtl::gzip{wtl::Fout{"possible_geographic.csv.gz"}} << Individual::possible_geographic();
        wtl::gzip{wtl::Fout{"possible_phenotypes.csv.gz"}} << Individual::possible_phenotypes();
        break;
      default:
        exit(1);
    }
    derr("mv results to " << OUT_DIR << std::endl);
    fs::rename(WORK_DIR, OUT_DIR);
    std::cout << wtl::iso8601datetime() << std::endl;
}

void Simulation::evolve() {HERE;
    assert(ENTIRE_PERIOD % OBSERVATION_CYCLE == 0);
    population.assign(NUM_ROWS, std::vector<Patch>(NUM_COLS));
    if (DIMENSIONS == 1) {
        population[0][0] = Patch(INITIAL_PATCH_SIZE, Individual{{15, 0, 15, 0}});
    } else {
        population[0][0] = Patch(INITIAL_PATCH_SIZE);
    }
    std::ostringstream ost;
    for (size_t t=0; t<=ENTIRE_PERIOD; ++t) {
        if (VERBOSE) {
            std::cout << "\nT = " << t << "\n"
                << str_population([](const Patch& p) {return p.size();});
        }
        if (t % OBSERVATION_CYCLE == 0) {
            write_snapshot(t, ost);
        }
        if (t < ENTIRE_PERIOD) {
            life_cycle();
        }
    }
    wtl::gzip{wtl::Fout{"evolution.csv.gz"}} << ost.str();
}

void Simulation::life_cycle() {
    std::vector<std::vector<Patch> > parents(population);
    wtl::Semaphore sem(PPN);
    std::mutex mtx;
    auto patch_task = [&](const size_t row, const size_t col) {
        auto offsprings = parents[row][col].mate_and_reproduce();
        std::lock_guard<std::mutex> lck(mtx);
        for (auto& child: offsprings) {
            size_t dest_row = row;
            size_t dest_col = col;
            choose_patch(&dest_row, &dest_col);
            population[dest_row][dest_col].append(std::move(child));
        }
        sem.unlock();
    };
    std::vector<std::thread> threads;
    for (size_t row=0; row<NUM_ROWS; ++row) {
        for (size_t col=0; col<NUM_COLS; ++col) {
            sem.lock();
            threads.emplace_back(patch_task, row, col);
        }
    }
    for (auto& th: threads) {th.join();}
    threads.clear();
    for (size_t row=0; row<NUM_ROWS; ++row) {
        for (size_t col=0; col<NUM_COLS; ++col) {
            sem.lock();
            threads.emplace_back([row, col, &sem, this] {
                population[row][col].viability_selection();
                sem.unlock();
            });
        }
    }
    for (auto& th: threads) {th.join();}
}

void Simulation::choose_patch(size_t* row, size_t* col) const {
    if (!prandom().bernoulli(Individual::MIGRATION_RATE())) {return;}
    size_t r = *row;
    size_t c = *col;
    switch (prandom().randrange(8)) {
      case 0:      ++c; break;
      case 1: ++r; ++c; break;
      case 2: ++r;      break;
      case 3: ++r; --c; break;
      case 4:      --c; break;
      case 5: --r; --c; break;
      case 6: --r;      break;
      case 7: --r; ++c; break;
    }
    // size_t(-1) also makes true
    if ((r >= NUM_ROWS) | (c >= NUM_COLS)) {return;}
    *row = r; *col = c;
}

void Simulation::write_snapshot(const size_t time, std::ostream& ost) const {
    const std::string sep{","};
    if (time == 0) {
        ost << "time" << sep << "row" << sep << "col" << sep
            << "n" << sep << Individual::header() << "\n";
    }
    std::size_t popsize = 0;
    for (size_t row=0; row<population.size(); ++row) {
        for (size_t col=0; col<population[row].size(); ++col) {
            for (const auto& item: population[row][col].summarize()) {
                ost << time << sep << row << sep << col << sep
                    << item.second << sep << item.first << "\n";
                popsize += item.second;
            }
        }
    }
    derr("N = " << popsize << std::endl);
}

<commit_msg>Add vm.notify() to let -D1 be effective. #1<commit_after>// -*- mode: c++; coding: utf-8 -*-
/*! @file simulation.cpp
    @brief Inplementation of Simulation class
*/
#include "simulation.h"

#include "cxxwtils/iostr.hpp"
#include "cxxwtils/getopt.hpp"
#include "cxxwtils/prandom.hpp"
#include "cxxwtils/os.hpp"
#include "cxxwtils/gz.hpp"
#include "cxxwtils/multiprocessing.hpp"

#include "individual.h"

/////////1/////////2/////////3/////////4/////////5/////////6/////////7/////////
// functions

//! Symbols for the program options can be different from those in equations
/*! @ingroup biol_param
    @return Program options description

    Command line option | Symbol   | Variable
    ------------------- | -------- | ------------------------------------------
    `--row,--col`       | -        | Simulation::NUM_COLS, Simulation::NUM_ROWS
    `-T,--time`         | -        | Simulation::ENTIRE_PERIOD
    `-I,--interval`     | -        | Simulation::OBSERVATION_CYCLE
*/
boost::program_options::options_description& Simulation::opt_description() {HERE;
    namespace po = boost::program_options;
    static po::options_description description("Simulation");
    description.add_options()
        ("help,h", po::value<bool>()->default_value(false)->implicit_value(true), "produce help")
        ("verbose,v", po::value<bool>(&VERBOSE)
            ->default_value(VERBOSE)->implicit_value(true), "verbose output")
        ("test", po::value<int>()->default_value(0)->implicit_value(1))
        ("mode", po::value<int>(&MODE)->default_value(MODE))
        ("ppn", po::value<size_t>(&PPN)->default_value(wtl::num_threads()))
        ("label", po::value<std::string>(&LABEL)->default_value("default"))
        ("top_dir", po::value<std::string>()->default_value(OUT_DIR.string()))
        ("row", po::value<size_t>(&NUM_ROWS)->default_value(NUM_ROWS))
        ("col", po::value<size_t>(&NUM_COLS)->default_value(NUM_COLS))
        ("dimensions,D", po::value<size_t>(&DIMENSIONS)->default_value(DIMENSIONS))
        ("time,T", po::value<size_t>(&ENTIRE_PERIOD)->default_value(ENTIRE_PERIOD))
        ("interval,I", po::value<size_t>(&OBSERVATION_CYCLE)->default_value(OBSERVATION_CYCLE))
        ("seed", po::value<unsigned int>(&SEED)->default_value(SEED))
    ;
    return description;
}

//! Unit test for each class
inline void test() {HERE;
    Individual::unit_test();
    Patch::unit_test();
}

Simulation::Simulation(int argc, char* argv[]) {HERE;
    std::vector<std::string> arguments(argv, argv + argc);
    std::cout << wtl::str_join(arguments, " ") << std::endl;
    std::cout << wtl::iso8601datetime() << std::endl;

    namespace po = boost::program_options;
    po::options_description description;
    description.add(opt_description());
    description.add(Individual::opt_description());
    po::variables_map vm;
    po::store(po::parse_command_line(argc, argv, description), vm);
    po::notify(vm);

    if (vm["help"].as<bool>()) {
        description.print(std::cout);
        exit(0);
    }
    OUT_DIR = fs::path(vm["top_dir"].as<std::string>());
    const std::string CONFIG_STRING = wtl::flags_into_string(description, vm);
    prandom().seed(SEED); // TODO: want to read seed?
    if (VERBOSE) {
        std::cout << CONFIG_STRING << std::endl;
    }
    if (ENTIRE_PERIOD % OBSERVATION_CYCLE > 0) {
        std::cerr << wtl::strprintf(
            "T=%d is not a multiple of I=%d",
            ENTIRE_PERIOD, OBSERVATION_CYCLE) << std::endl;
        exit(1);
    }
    if (DIMENSIONS == 1) {
        std::ostringstream ost;
        ost << "diameter_pref = 0\n"
            << "limb_select = 0\n"
            << "diameter_compe = 0\n"
            << "limb_compe = 0\n"
            << "mutation_mask = 10\n";
        std::istringstream ist(ost.str());
        po::store(po::parse_config_file(ist, description, false), vm);
        vm.notify();
    }
    switch (vm["test"].as<int>()) {
      case 0:
        break;
      case 1:
        test();
        exit(0);
      default:
        exit(1);
    }
    const std::string now(wtl::strftime("%Y%m%d_%H%M%S"));
    std::ostringstream pid_at_host;
    pid_at_host << ::getpid() << "@" << wtl::gethostname();
    WORK_DIR = TMP_DIR / (now + "_" + LABEL + "_" + pid_at_host.str());
    derr("mkdir && cd to " << WORK_DIR << std::endl);
    fs::create_directory(WORK_DIR);
    wtl::cd(WORK_DIR.string());
    fs::create_directory(OUT_DIR);
    OUT_DIR /= (LABEL + "_" + now + "_" + pid_at_host.str());
    wtl::Fout{"program_options.conf"} << CONFIG_STRING;
}

void Simulation::run() {HERE;
    switch (MODE) {
      case 0:
        evolve();
        break;
      case 1:
        Individual::write_resource_abundance();
        break;
      case 2:
        wtl::gzip{wtl::Fout{"possible_geographic.csv.gz"}} << Individual::possible_geographic();
        wtl::gzip{wtl::Fout{"possible_phenotypes.csv.gz"}} << Individual::possible_phenotypes();
        break;
      default:
        exit(1);
    }
    derr("mv results to " << OUT_DIR << std::endl);
    fs::rename(WORK_DIR, OUT_DIR);
    std::cout << wtl::iso8601datetime() << std::endl;
}

void Simulation::evolve() {HERE;
    assert(ENTIRE_PERIOD % OBSERVATION_CYCLE == 0);
    population.assign(NUM_ROWS, std::vector<Patch>(NUM_COLS));
    if (DIMENSIONS == 1) {
        population[0][0] = Patch(INITIAL_PATCH_SIZE, Individual{{15, 0, 15, 0}});
    } else {
        population[0][0] = Patch(INITIAL_PATCH_SIZE);
    }
    std::ostringstream ost;
    for (size_t t=0; t<=ENTIRE_PERIOD; ++t) {
        if (VERBOSE) {
            std::cout << "\nT = " << t << "\n"
                << str_population([](const Patch& p) {return p.size();});
        }
        if (t % OBSERVATION_CYCLE == 0) {
            write_snapshot(t, ost);
        }
        if (t < ENTIRE_PERIOD) {
            life_cycle();
        }
    }
    wtl::gzip{wtl::Fout{"evolution.csv.gz"}} << ost.str();
}

void Simulation::life_cycle() {
    std::vector<std::vector<Patch> > parents(population);
    wtl::Semaphore sem(PPN);
    std::mutex mtx;
    auto patch_task = [&](const size_t row, const size_t col) {
        auto offsprings = parents[row][col].mate_and_reproduce();
        std::lock_guard<std::mutex> lck(mtx);
        for (auto& child: offsprings) {
            size_t dest_row = row;
            size_t dest_col = col;
            choose_patch(&dest_row, &dest_col);
            population[dest_row][dest_col].append(std::move(child));
        }
        sem.unlock();
    };
    std::vector<std::thread> threads;
    for (size_t row=0; row<NUM_ROWS; ++row) {
        for (size_t col=0; col<NUM_COLS; ++col) {
            sem.lock();
            threads.emplace_back(patch_task, row, col);
        }
    }
    for (auto& th: threads) {th.join();}
    threads.clear();
    for (size_t row=0; row<NUM_ROWS; ++row) {
        for (size_t col=0; col<NUM_COLS; ++col) {
            sem.lock();
            threads.emplace_back([row, col, &sem, this] {
                population[row][col].viability_selection();
                sem.unlock();
            });
        }
    }
    for (auto& th: threads) {th.join();}
}

void Simulation::choose_patch(size_t* row, size_t* col) const {
    if (!prandom().bernoulli(Individual::MIGRATION_RATE())) {return;}
    size_t r = *row;
    size_t c = *col;
    switch (prandom().randrange(8)) {
      case 0:      ++c; break;
      case 1: ++r; ++c; break;
      case 2: ++r;      break;
      case 3: ++r; --c; break;
      case 4:      --c; break;
      case 5: --r; --c; break;
      case 6: --r;      break;
      case 7: --r; ++c; break;
    }
    // size_t(-1) also makes true
    if ((r >= NUM_ROWS) | (c >= NUM_COLS)) {return;}
    *row = r; *col = c;
}

void Simulation::write_snapshot(const size_t time, std::ostream& ost) const {
    const std::string sep{","};
    if (time == 0) {
        ost << "time" << sep << "row" << sep << "col" << sep
            << "n" << sep << Individual::header() << "\n";
    }
    std::size_t popsize = 0;
    for (size_t row=0; row<population.size(); ++row) {
        for (size_t col=0; col<population[row].size(); ++col) {
            for (const auto& item: population[row][col].summarize()) {
                ost << time << sep << row << sep << col << sep
                    << item.second << sep << item.first << "\n";
                popsize += item.second;
            }
        }
    }
    derr("N = " << popsize << std::endl);
}

<|endoftext|>


<commit_before>#include "cuda.h"
#include <cstdio>

struct checkers_point{
    int board[64];
    int how_much_children;
    checkers_point * children = NULL;
    checkers_point * next = NULL;
    checkers_point * prev = NULL;
    checkers_point * parent = NULL;
    bool min_max;
    int alpha = -1000000000;
    int beta = 1000000000;
    int value;
    int player;
};

#define default_n 8
#define EMPTY 0
#define WHITE 1
#define BLACK 2
#define queenW 11
#define queenB 22

int main(){
    //przekazane powinny zostac: int siize, default_row_with_pawn,     int * tab_with_board;
    int siize = 8;
    int * tab_with_board;
    int default_row_with_pawn = 3;
    tab_with_board = (int*) malloc(sizeof(int)*siize*siize);
    for (int i = 0; i < siize*siize; i++)
        tab_with_board[i] = EMPTY;
    for (int i = 0; i < default_row_with_pawn; ++i){
        for (int j = 0; j < siize/2; ++j){
            tab_with_board[i*siize+2*j+(i%2)] = BLACK;
            tab_with_board[(siize*siize-1)-(i*siize+2*j+(i%2))] = WHITE;
        }
    }
	for (int i = 0; i < 64; i++)
		printf("%d ", tab_with_board[i]);
    //^ do usuniecia
    cuInit(0);
    CUdevice cuDevice;
    CUresult res = cuDeviceGet(&cuDevice, 0);
    if (res != CUDA_SUCCESS){
        printf("cannot acquire device 0\n");
        exit(1);
    }

    CUcontext cuContext;
    res = cuCtxCreate(&cuContext, 0, cuDevice);
    if (res != CUDA_SUCCESS){
        printf("cannot create context\n");
        exit(1);
    }

    CUmodule cuModule = (CUmodule)0;
    res = cuModuleLoad(&cuModule, "checkers.ptx");
    if (res != CUDA_SUCCESS) {
        printf("cannot load module: %d\n", res);
        exit(1);
    }

    CUfunction create_tree, delete_tree, print_tree, set_root, copy_best_result;
    res = cuModuleGetFunction(&create_tree, cuModule, "create_tree");
    if (res != CUDA_SUCCESS){
        printf("cannot acquire kernel handle\n");
        exit(1);
    }
	res = cuModuleGetFunction(&delete_tree, cuModule, "delete_tree");
    if (res != CUDA_SUCCESS){
        printf("cannot acquire kernel handle\n");
        exit(1);
	}
    res = cuModuleGetFunction(&print_tree, cuModule, "print_tree");
    if (res != CUDA_SUCCESS){
        printf("cannot acquire kernel handle\n");
        exit(1);
    }
    res = cuModuleGetFunction(&set_root, cuModule, "set_root");
    if (res != CUDA_SUCCESS){
        printf("cannot acquire kernel handle\n");
        exit(1);
    }

    res = cuModuleGetFunction(&copy_best_result, cuModule, "copy_best_result");
    if (res != CUDA_SUCCESS){
        printf("cannot acquire kernel handle\n");
        exit(1);
    }

    int how_deep = 6;
    int max_children = 12 * 2;
    int n = max_children;
    for (int i = 0; i < 4; i++){
        n *= max_children;
    }
    printf("N: %d\n", n);
    size_t size = sizeof(checkers_point)*n;
    size_t size_tab = sizeof(int)*siize*siize;
    checkers_point * a = (checkers_point*) malloc(size);
    res = cuMemHostRegister(a, size, 0);
    if (res != CUDA_SUCCESS){
        printf("cuMemHostRegister\n");
        exit(1);
    }
    res = cuMemHostRegister(tab_with_board, size_tab, 0);
    if (res != CUDA_SUCCESS){
        printf("cuMemHostRegister\n");
        exit(1);
    }

    int blocks_per_grid = (n+1023)/1024;
    int threads_per_block = 1024;
	int num_threads = threads_per_block * blocks_per_grid;
    CUdeviceptr Adev, Atab, Vdev;
    res = cuMemAlloc(&Adev, size);
    if (res != CUDA_SUCCESS){
        printf("cuMemAlloc\n");
        exit(1);
    }
    res = cuMemAlloc(&Vdev, num_threads * sizeof(checkers_point*));
    if (res != CUDA_SUCCESS){
        printf("cuMemAlloc\n");
        exit(1);
    }
    res = cuMemAlloc(&Atab, size_tab);
    if (res != CUDA_SUCCESS){
        printf("cuMemAlloc\n");
        exit(1);
    }
    res = cuMemcpyHtoD(Atab, tab_with_board, size_tab);
    if (res != CUDA_SUCCESS){
        printf("cuMemcpy\n");
        exit(1);
    }
    int i = 1;
    void* args[] = {&n, &Adev, &i};
	void* args2[] = {&Adev, &num_threads, &Vdev};
    void* args_root[] = {&Adev, &Atab, &siize};
    res = cuLaunchKernel(set_root, blocks_per_grid, 1, 1, threads_per_block, 1, 1, 0, 0, args_root, 0);
    if (res != CUDA_SUCCESS){
        printf("cannot run kernel\n");
        exit(1);
    }
    for (i = 1; i < how_deep+1; i++){
        res = cuLaunchKernel(create_tree, blocks_per_grid, 1, 1, threads_per_block, 1, 1, 0, 0, args, 0);
	res = cuLaunchKernel(print_tree, blocks_per_grid, 1, 1, threads_per_block, 1, 1, 0, 0, args, 0);
    }
    if (res != CUDA_SUCCESS){
        printf("cannot run kernel\n");
        exit(1);
    }
    res = cuLaunchKernel(print_tree, blocks_per_grid, 1, 1, threads_per_block, 1, 1, 0, 0, args, 0);
    if (res != CUDA_SUCCESS){
        printf("cannot run kernel\n");
        exit(1);
    }
	res = cuLaunchKernel(delete_tree, blocks_per_grid, 1, 1, threads_per_block, 1, 1, 0, 0, args2, 0);
    if (res != CUDA_SUCCESS){
        printf("cannot run kernel\n");
        exit(1);
	}
	res = cuLaunchKernel(print_tree, blocks_per_grid, 1, 1, threads_per_block, 1, 1, 0, 0, args, 0);
    if (res != CUDA_SUCCESS){
        printf("cannot run kernel\n");
        exit(1);
	}
    res = cuLaunchKernel(copy_best_result, blocks_per_grid, 1, 1, threads_per_block, 1, 1, 0, 0, args_root, 0);
    if (res != CUDA_SUCCESS){
        printf("cannot run kernel\n");
        exit(1);
    }
    cuMemFree(Adev);
    cuMemFree(Atab);
    cuMemFree(Vdev);
    cuCtxDestroy(cuContext);
//    return tab_with_board;
    return 0;
}
<commit_msg>Changing main<commit_after>#include "cuda.h"
#include <cstdio>

struct checkers_point{
    int board[64];
    int how_much_children;
    checkers_point * children = NULL;
    checkers_point * next = NULL;
    checkers_point * prev = NULL;
    checkers_point * parent = NULL;
    bool min_max;
    int alpha = -1000000000;
    int beta = 1000000000;
    int value;
    int player;
};

#define default_n 8
#define EMPTY 0
#define WHITE 1
#define BLACK 2
#define queenW 11
#define queenB 22

int * computer_turn(int siize, int default_row_with_pawn, int * tab_with_board){

    cuInit(0);
    CUdevice cuDevice;
    CUresult res = cuDeviceGet(&cuDevice, 0);
    if (res != CUDA_SUCCESS){
        printf("cannot acquire device 0\n");
        exit(1);
    }

    CUcontext cuContext;
    res = cuCtxCreate(&cuContext, 0, cuDevice);
    if (res != CUDA_SUCCESS){
        printf("cannot create context\n");
        exit(1);
    }

    CUmodule cuModule = (CUmodule)0;
    res = cuModuleLoad(&cuModule, "checkers.ptx");
    if (res != CUDA_SUCCESS) {
        printf("cannot load module: %d\n", res);
        exit(1);
    }

    CUfunction alpha_beta, create_tree, delete_tree, print_tree, set_root, copy_best_result;

    res = cuModuleGetFunction(&alpha_beta, cuModule, "alpha_beta");
    if (res != CUDA_SUCCESS){
        printf("cannot acquire kernel handle\n");
        exit(1);
	}
    res = cuModuleGetFunction(&create_tree, cuModule, "create_tree");
    if (res != CUDA_SUCCESS){
        printf("cannot acquire kernel handle\n");
        exit(1);
    }
	res = cuModuleGetFunction(&delete_tree, cuModule, "delete_tree");
    if (res != CUDA_SUCCESS){
        printf("cannot acquire kernel handle\n");
        exit(1);
	}
    res = cuModuleGetFunction(&print_tree, cuModule, "print_tree");
    if (res != CUDA_SUCCESS){
        printf("cannot acquire kernel handle\n");
        exit(1);
    }
    res = cuModuleGetFunction(&set_root, cuModule, "set_root");
    if (res != CUDA_SUCCESS){
        printf("cannot acquire kernel handle\n");
        exit(1);
    }

    res = cuModuleGetFunction(&copy_best_result, cuModule, "copy_best_result");
    if (res != CUDA_SUCCESS){
        printf("cannot acquire kernel handle\n");
        exit(1);
    }

    int how_deep = 6;
    int max_children = 12 * 2;
    int n = max_children;
    for (int i = 0; i < 4; i++){
        n *= max_children;
    }
    //printf("N: %d\n", n);
    size_t size = sizeof(checkers_point)*n;
    size_t size_tab = sizeof(int)*siize*siize;
    checkers_point * a = (checkers_point*) malloc(size);
    res = cuMemHostRegister(a, size, 0);
    if (res != CUDA_SUCCESS){
        printf("cuMemHostRegister\n");
        exit(1);
    }
    res = cuMemHostRegister(tab_with_board, size_tab, 0);
    if (res != CUDA_SUCCESS){
        printf("cuMemHostRegister\n");
        exit(1);
    }

    int blocks_per_grid = (n+1023)/1024;
    int threads_per_block = 1024;
    int blocks_per_grid2 = 100;
    int threads_per_block2 = 100;
	int num_threads = threads_per_block2 * blocks_per_grid2;
    CUdeviceptr Adev, Atab, Vdev;
    res = cuMemAlloc(&Adev, size);
    if (res != CUDA_SUCCESS){
        printf("cuMemAlloc\n");
        exit(1);
    }
    res = cuMemAlloc(&Vdev, num_threads * sizeof(checkers_point*));
    if (res != CUDA_SUCCESS){
        printf("cuMemAlloc\n");
        exit(1);
    }
    res = cuMemAlloc(&Atab, size_tab);
    if (res != CUDA_SUCCESS){
        printf("cuMemAlloc\n");
        exit(1);
    }
    res = cuMemcpyHtoD(Atab, tab_with_board, size_tab);
    if (res != CUDA_SUCCESS){
        printf("cuMemcpy\n");
        exit(1);
    }
    int i = 1;
    void* args[] = {&n, &Adev, &i};
	void* args2[] = {&Adev, &num_threads, &Vdev};
	void* args3[] = {&Adev, &num_threads, &Vdev};
    void* args_root[] = {&Adev, &Atab, &siize};
    res = cuLaunchKernel(set_root, blocks_per_grid, 1, 1, threads_per_block, 1, 1, 0, 0, args_root, 0);
    if (res != CUDA_SUCCESS){
        printf("cannot run kernel\n");
        exit(1);
    }
    for (i = 1; i < how_deep+1; i++){
        res = cuLaunchKernel(create_tree, blocks_per_grid, 1, 1, threads_per_block, 1, 1, 0, 0, args, 0);
	res = cuLaunchKernel(print_tree, blocks_per_grid, 1, 1, threads_per_block, 1, 1, 0, 0, args, 0);
    }
    if (res != CUDA_SUCCESS){
        printf("cannot run kernel\n");
        exit(1);
    }
    res = cuLaunchKernel(alpha_beta, blocks_per_grid2, 1, 1, threads_per_block2, 1, 1, 0, 0, args3, 0);
    if (res != CUDA_SUCCESS){
        printf("cannot run kernel\n");
        exit(1);
    }
	res = cuLaunchKernel(delete_tree, blocks_per_grid2, 1, 1, threads_per_block2, 1, 1, 0, 0, args2, 0);
    if (res != CUDA_SUCCESS){
        printf("cannot run kernel\n");
        exit(1);
	}
    res = cuLaunchKernel(copy_best_result, blocks_per_grid, 1, 1, threads_per_block, 1, 1, 0, 0, args_root, 0);
    if (res != CUDA_SUCCESS){
        printf("cannot run kernel\n");
        exit(1);
    }

	res = cuMemcpyDtoH(tab_with_board, Atab, size_tab);
    if (res != CUDA_SUCCESS){
        printf("cuMemcpy\n");
        exit(1);
	}
    cuMemFree(Adev);
    cuMemFree(Atab);
    cuMemFree(Vdev);
    cuCtxDestroy(cuContext);

    return tab_with_board;
}
<|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 "chrome/common/common_param_traits.h"

#include "chrome/common/chrome_constants.h"
#include "gfx/rect.h"
#include "googleurl/src/gurl.h"
#ifndef EXCLUDE_SKIA_DEPENDENCIES
#include "third_party/skia/include/core/SkBitmap.h"
#endif
#include "webkit/glue/dom_operations.h"

namespace IPC {

#ifndef EXCLUDE_SKIA_DEPENDENCIES

namespace {

struct SkBitmap_Data {
  // The configuration for the bitmap (bits per pixel, etc).
  SkBitmap::Config fConfig;

  // The width of the bitmap in pixels.
  uint32 fWidth;

  // The height of the bitmap in pixels.
  uint32 fHeight;

  void InitSkBitmapDataForTransfer(const SkBitmap& bitmap) {
    fConfig = bitmap.config();
    fWidth = bitmap.width();
    fHeight = bitmap.height();
  }

  // Returns whether |bitmap| successfully initialized.
  bool InitSkBitmapFromData(SkBitmap* bitmap, const char* pixels,
                            size_t total_pixels) const {
    if (total_pixels) {
      bitmap->setConfig(fConfig, fWidth, fHeight, 0);
      if (!bitmap->allocPixels())
        return false;
      if (total_pixels != bitmap->getSize())
        return false;
      memcpy(bitmap->getPixels(), pixels, total_pixels);
    }
    return true;
  }
};

}  // namespace

void ParamTraits<SkBitmap>::Write(Message* m, const SkBitmap& p) {
  size_t fixed_size = sizeof(SkBitmap_Data);
  SkBitmap_Data bmp_data;
  bmp_data.InitSkBitmapDataForTransfer(p);
  m->WriteData(reinterpret_cast<const char*>(&bmp_data),
               static_cast<int>(fixed_size));
  size_t pixel_size = p.getSize();
  SkAutoLockPixels p_lock(p);
  m->WriteData(reinterpret_cast<const char*>(p.getPixels()),
               static_cast<int>(pixel_size));
}

bool ParamTraits<SkBitmap>::Read(const Message* m, void** iter, SkBitmap* r) {
  const char* fixed_data;
  int fixed_data_size = 0;
  if (!m->ReadData(iter, &fixed_data, &fixed_data_size) ||
     (fixed_data_size <= 0)) {
    NOTREACHED();
    return false;
  }
  if (fixed_data_size != sizeof(SkBitmap_Data))
    return false;  // Message is malformed.

  const char* variable_data;
  int variable_data_size = 0;
  if (!m->ReadData(iter, &variable_data, &variable_data_size) ||
     (variable_data_size < 0)) {
    NOTREACHED();
    return false;
  }
  const SkBitmap_Data* bmp_data =
      reinterpret_cast<const SkBitmap_Data*>(fixed_data);
  return bmp_data->InitSkBitmapFromData(r, variable_data, variable_data_size);
}

void ParamTraits<SkBitmap>::Log(const SkBitmap& p, std::wstring* l) {
  l->append(StringPrintf(L"<SkBitmap>"));
}

#endif  // EXCLUDE_SKIA_DEPENDENCIES

void ParamTraits<GURL>::Write(Message* m, const GURL& p) {
  m->WriteString(p.possibly_invalid_spec());
  // TODO(brettw) bug 684583: Add encoding for query params.
}

bool ParamTraits<GURL>::Read(const Message* m, void** iter, GURL* p) {
  std::string s;
  if (!m->ReadString(iter, &s) || s.length() > chrome::kMaxURLChars) {
    *p = GURL();
    return false;
  }
  *p = GURL(s);
  return true;
}

void ParamTraits<GURL>::Log(const GURL& p, std::wstring* l) {
  l->append(UTF8ToWide(p.spec()));
}

void ParamTraits<gfx::Point>::Write(Message* m, const gfx::Point& p) {
  m->WriteInt(p.x());
  m->WriteInt(p.y());
}

bool ParamTraits<gfx::Point>::Read(const Message* m, void** iter,
                                   gfx::Point* r) {
  int x, y;
  if (!m->ReadInt(iter, &x) ||
      !m->ReadInt(iter, &y))
    return false;
  r->set_x(x);
  r->set_y(y);
  return true;
}

void ParamTraits<gfx::Point>::Log(const gfx::Point& p, std::wstring* l) {
  l->append(StringPrintf(L"(%d, %d)", p.x(), p.y()));
}

void ParamTraits<gfx::Rect>::Write(Message* m, const gfx::Rect& p) {
  m->WriteInt(p.x());
  m->WriteInt(p.y());
  m->WriteInt(p.width());
  m->WriteInt(p.height());
}

bool ParamTraits<gfx::Rect>::Read(const Message* m, void** iter, gfx::Rect* r) {
  int x, y, w, h;
  if (!m->ReadInt(iter, &x) ||
      !m->ReadInt(iter, &y) ||
      !m->ReadInt(iter, &w) ||
      !m->ReadInt(iter, &h))
    return false;
  if (x < 0 || y < 0 || x >= (INT_MAX - w) || y >= (INT_MAX - h) ||
      w < 0 || h < 0 || h >= ((INT_MAX / 16) / (w ? w : 1)))
    return false;
  r->set_x(x);
  r->set_y(y);
  r->set_width(w);
  r->set_height(h);
  return true;
}

void ParamTraits<gfx::Rect>::Log(const gfx::Rect& p, std::wstring* l) {
  l->append(StringPrintf(L"(%d, %d, %d, %d)", p.x(), p.y(),
                         p.width(), p.height()));
}

void ParamTraits<gfx::Size>::Write(Message* m, const gfx::Size& p) {
  m->WriteInt(p.width());
  m->WriteInt(p.height());
}

bool ParamTraits<gfx::Size>::Read(const Message* m, void** iter, gfx::Size* r) {
  int w, h;
  if (!m->ReadInt(iter, &w) ||
      !m->ReadInt(iter, &h))
    return false;
  if (w < 0 || h < 0 || h >= ((INT_MAX / 16) / (w ? w : 1)))
    return false;
  r->set_width(w);
  r->set_height(h);
  return true;
}

void ParamTraits<gfx::Size>::Log(const gfx::Size& p, std::wstring* l) {
  l->append(StringPrintf(L"(%d, %d)", p.width(), p.height()));
}

void ParamTraits<ContentSettings>::Write(
    Message* m, const ContentSettings& settings) {
  for (size_t i = 0; i < arraysize(settings.settings); ++i)
    WriteParam(m, settings.settings[i]);
}

bool ParamTraits<ContentSettings>::Read(
    const Message* m, void** iter, ContentSettings* r) {
  for (size_t i = 0; i < arraysize(r->settings); ++i) {
    if (!ReadParam(m, iter, &r->settings[i]))
      return false;
  }
  return true;
}

void ParamTraits<ContentSettings>::Log(
    const ContentSettings& p, std::wstring* l) {
  l->append(StringPrintf(L"<ContentSettings>"));
}

void ParamTraits<webkit_glue::WebApplicationInfo>::Write(
    Message* m, const webkit_glue::WebApplicationInfo& p) {
  WriteParam(m, p.title);
  WriteParam(m, p.description);
  WriteParam(m, p.app_url);
  WriteParam(m, p.icons.size());
  for (size_t i = 0; i < p.icons.size(); ++i) {
    WriteParam(m, p.icons[i].url);
    WriteParam(m, p.icons[i].width);
    WriteParam(m, p.icons[i].height);
  }
}

bool ParamTraits<webkit_glue::WebApplicationInfo>::Read(
    const Message* m, void** iter, webkit_glue::WebApplicationInfo* r) {
  size_t icon_count;
  bool result =
    ReadParam(m, iter, &r->title) &&
    ReadParam(m, iter, &r->description) &&
    ReadParam(m, iter, &r->app_url) &&
    ReadParam(m, iter, &icon_count);
  if (!result)
    return false;
  for (size_t i = 0; i < icon_count; ++i) {
    param_type::IconInfo icon_info;
    result =
        ReadParam(m, iter, &icon_info.url) &&
        ReadParam(m, iter, &icon_info.width) &&
        ReadParam(m, iter, &icon_info.height);
    if (!result)
      return false;
    r->icons.push_back(icon_info);
  }
  return true;
}

void ParamTraits<webkit_glue::WebApplicationInfo>::Log(
    const webkit_glue::WebApplicationInfo& p, std::wstring* l) {
  l->append(L"<WebApplicationInfo>");
}

void ParamTraits<Geoposition::ErrorCode>::Write(
    Message* m, const Geoposition::ErrorCode& p) {
  int error_code = p;
  WriteParam(m, error_code);
}

bool ParamTraits<Geoposition::ErrorCode>::Read(
      const Message* m, void** iter, Geoposition::ErrorCode* p) {
  int error_code_param = 0;
  bool ret = ReadParam(m, iter, &error_code_param);
  *p = static_cast<Geoposition::ErrorCode>(error_code_param);
  return ret;
}

void ParamTraits<Geoposition::ErrorCode>::Log(
    const Geoposition::ErrorCode& p, std::wstring* l) {
  int error_code = p;
  l->append(StringPrintf(L"<Geoposition::ErrorCode>%d", error_code));
}

void ParamTraits<Geoposition>::Write(Message* m, const Geoposition& p) {
  WriteParam(m, p.latitude);
  WriteParam(m, p.longitude);
  WriteParam(m, p.accuracy);
  WriteParam(m, p.altitude);
  WriteParam(m, p.altitude_accuracy);
  WriteParam(m, p.speed);
  WriteParam(m, p.heading);
  WriteParam(m, p.timestamp);
  WriteParam(m, p.error_code);
  WriteParam(m, p.error_message);
}

bool ParamTraits<Geoposition>::Read(
      const Message* m, void** iter, Geoposition* p) {
  bool ret = ReadParam(m, iter, &p->latitude);
  ret = ret && ReadParam(m, iter, &p->longitude);
  ret = ret && ReadParam(m, iter, &p->accuracy);
  ret = ret && ReadParam(m, iter, &p->altitude);
  ret = ret && ReadParam(m, iter, &p->altitude_accuracy);
  ret = ret && ReadParam(m, iter, &p->speed);
  ret = ret && ReadParam(m, iter, &p->heading);
  ret = ret && ReadParam(m, iter, &p->timestamp);
  ret = ret && ReadParam(m, iter, &p->error_code);
  ret = ret && ReadParam(m, iter, &p->error_message);
  return ret;
}

void ParamTraits<Geoposition>::Log(const Geoposition& p, std::wstring* l) {
  l->append(
      StringPrintf(
          L"<Geoposition>"
          L"%.6f %.6f %.6f %.6f "
          L"%.6f %.6f %.6f ",
          p.latitude, p.longitude, p.accuracy, p.altitude,
          p.altitude_accuracy, p.speed, p.heading));
  LogParam(p.timestamp, l);
  l->append(L" ");
  l->append(p.error_message);
  LogParam(p.error_code, l);
}

}  // namespace IPC
<commit_msg>Revert 45797 - Apply a sanity limit to objects with width & height.<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 "chrome/common/common_param_traits.h"

#include "chrome/common/chrome_constants.h"
#include "gfx/rect.h"
#include "googleurl/src/gurl.h"
#ifndef EXCLUDE_SKIA_DEPENDENCIES
#include "third_party/skia/include/core/SkBitmap.h"
#endif
#include "webkit/glue/dom_operations.h"

namespace IPC {

#ifndef EXCLUDE_SKIA_DEPENDENCIES

namespace {

struct SkBitmap_Data {
  // The configuration for the bitmap (bits per pixel, etc).
  SkBitmap::Config fConfig;

  // The width of the bitmap in pixels.
  uint32 fWidth;

  // The height of the bitmap in pixels.
  uint32 fHeight;

  void InitSkBitmapDataForTransfer(const SkBitmap& bitmap) {
    fConfig = bitmap.config();
    fWidth = bitmap.width();
    fHeight = bitmap.height();
  }

  // Returns whether |bitmap| successfully initialized.
  bool InitSkBitmapFromData(SkBitmap* bitmap, const char* pixels,
                            size_t total_pixels) const {
    if (total_pixels) {
      bitmap->setConfig(fConfig, fWidth, fHeight, 0);
      if (!bitmap->allocPixels())
        return false;
      if (total_pixels != bitmap->getSize())
        return false;
      memcpy(bitmap->getPixels(), pixels, total_pixels);
    }
    return true;
  }
};

}  // namespace

void ParamTraits<SkBitmap>::Write(Message* m, const SkBitmap& p) {
  size_t fixed_size = sizeof(SkBitmap_Data);
  SkBitmap_Data bmp_data;
  bmp_data.InitSkBitmapDataForTransfer(p);
  m->WriteData(reinterpret_cast<const char*>(&bmp_data),
               static_cast<int>(fixed_size));
  size_t pixel_size = p.getSize();
  SkAutoLockPixels p_lock(p);
  m->WriteData(reinterpret_cast<const char*>(p.getPixels()),
               static_cast<int>(pixel_size));
}

bool ParamTraits<SkBitmap>::Read(const Message* m, void** iter, SkBitmap* r) {
  const char* fixed_data;
  int fixed_data_size = 0;
  if (!m->ReadData(iter, &fixed_data, &fixed_data_size) ||
     (fixed_data_size <= 0)) {
    NOTREACHED();
    return false;
  }
  if (fixed_data_size != sizeof(SkBitmap_Data))
    return false;  // Message is malformed.

  const char* variable_data;
  int variable_data_size = 0;
  if (!m->ReadData(iter, &variable_data, &variable_data_size) ||
     (variable_data_size < 0)) {
    NOTREACHED();
    return false;
  }
  const SkBitmap_Data* bmp_data =
      reinterpret_cast<const SkBitmap_Data*>(fixed_data);
  return bmp_data->InitSkBitmapFromData(r, variable_data, variable_data_size);
}

void ParamTraits<SkBitmap>::Log(const SkBitmap& p, std::wstring* l) {
  l->append(StringPrintf(L"<SkBitmap>"));
}

#endif  // EXCLUDE_SKIA_DEPENDENCIES

void ParamTraits<GURL>::Write(Message* m, const GURL& p) {
  m->WriteString(p.possibly_invalid_spec());
  // TODO(brettw) bug 684583: Add encoding for query params.
}

bool ParamTraits<GURL>::Read(const Message* m, void** iter, GURL* p) {
  std::string s;
  if (!m->ReadString(iter, &s) || s.length() > chrome::kMaxURLChars) {
    *p = GURL();
    return false;
  }
  *p = GURL(s);
  return true;
}

void ParamTraits<GURL>::Log(const GURL& p, std::wstring* l) {
  l->append(UTF8ToWide(p.spec()));
}

void ParamTraits<gfx::Point>::Write(Message* m, const gfx::Point& p) {
  m->WriteInt(p.x());
  m->WriteInt(p.y());
}

bool ParamTraits<gfx::Point>::Read(const Message* m, void** iter,
                                   gfx::Point* r) {
  int x, y;
  if (!m->ReadInt(iter, &x) ||
      !m->ReadInt(iter, &y))
    return false;
  r->set_x(x);
  r->set_y(y);
  return true;
}

void ParamTraits<gfx::Point>::Log(const gfx::Point& p, std::wstring* l) {
  l->append(StringPrintf(L"(%d, %d)", p.x(), p.y()));
}

void ParamTraits<gfx::Rect>::Write(Message* m, const gfx::Rect& p) {
  m->WriteInt(p.x());
  m->WriteInt(p.y());
  m->WriteInt(p.width());
  m->WriteInt(p.height());
}

bool ParamTraits<gfx::Rect>::Read(const Message* m, void** iter, gfx::Rect* r) {
  int x, y, w, h;
  if (!m->ReadInt(iter, &x) ||
      !m->ReadInt(iter, &y) ||
      !m->ReadInt(iter, &w) ||
      !m->ReadInt(iter, &h))
    return false;
  r->set_x(x);
  r->set_y(y);
  r->set_width(w);
  r->set_height(h);
  return true;
}

void ParamTraits<gfx::Rect>::Log(const gfx::Rect& p, std::wstring* l) {
  l->append(StringPrintf(L"(%d, %d, %d, %d)", p.x(), p.y(),
                         p.width(), p.height()));
}

void ParamTraits<gfx::Size>::Write(Message* m, const gfx::Size& p) {
  m->WriteInt(p.width());
  m->WriteInt(p.height());
}

bool ParamTraits<gfx::Size>::Read(const Message* m, void** iter, gfx::Size* r) {
  int w, h;
  if (!m->ReadInt(iter, &w) ||
      !m->ReadInt(iter, &h))
    return false;
  r->set_width(w);
  r->set_height(h);
  return true;
}

void ParamTraits<gfx::Size>::Log(const gfx::Size& p, std::wstring* l) {
  l->append(StringPrintf(L"(%d, %d)", p.width(), p.height()));
}

void ParamTraits<ContentSettings>::Write(
    Message* m, const ContentSettings& settings) {
  for (size_t i = 0; i < arraysize(settings.settings); ++i)
    WriteParam(m, settings.settings[i]);
}

bool ParamTraits<ContentSettings>::Read(
    const Message* m, void** iter, ContentSettings* r) {
  for (size_t i = 0; i < arraysize(r->settings); ++i) {
    if (!ReadParam(m, iter, &r->settings[i]))
      return false;
  }
  return true;
}

void ParamTraits<ContentSettings>::Log(
    const ContentSettings& p, std::wstring* l) {
  l->append(StringPrintf(L"<ContentSettings>"));
}

void ParamTraits<webkit_glue::WebApplicationInfo>::Write(
    Message* m, const webkit_glue::WebApplicationInfo& p) {
  WriteParam(m, p.title);
  WriteParam(m, p.description);
  WriteParam(m, p.app_url);
  WriteParam(m, p.icons.size());
  for (size_t i = 0; i < p.icons.size(); ++i) {
    WriteParam(m, p.icons[i].url);
    WriteParam(m, p.icons[i].width);
    WriteParam(m, p.icons[i].height);
  }
}

bool ParamTraits<webkit_glue::WebApplicationInfo>::Read(
    const Message* m, void** iter, webkit_glue::WebApplicationInfo* r) {
  size_t icon_count;
  bool result =
    ReadParam(m, iter, &r->title) &&
    ReadParam(m, iter, &r->description) &&
    ReadParam(m, iter, &r->app_url) &&
    ReadParam(m, iter, &icon_count);
  if (!result)
    return false;
  for (size_t i = 0; i < icon_count; ++i) {
    param_type::IconInfo icon_info;
    result =
        ReadParam(m, iter, &icon_info.url) &&
        ReadParam(m, iter, &icon_info.width) &&
        ReadParam(m, iter, &icon_info.height);
    if (!result)
      return false;
    r->icons.push_back(icon_info);
  }
  return true;
}

void ParamTraits<webkit_glue::WebApplicationInfo>::Log(
    const webkit_glue::WebApplicationInfo& p, std::wstring* l) {
  l->append(L"<WebApplicationInfo>");
}

void ParamTraits<Geoposition::ErrorCode>::Write(
    Message* m, const Geoposition::ErrorCode& p) {
  int error_code = p;
  WriteParam(m, error_code);
}

bool ParamTraits<Geoposition::ErrorCode>::Read(
      const Message* m, void** iter, Geoposition::ErrorCode* p) {
  int error_code_param = 0;
  bool ret = ReadParam(m, iter, &error_code_param);
  *p = static_cast<Geoposition::ErrorCode>(error_code_param);
  return ret;
}

void ParamTraits<Geoposition::ErrorCode>::Log(
    const Geoposition::ErrorCode& p, std::wstring* l) {
  int error_code = p;
  l->append(StringPrintf(L"<Geoposition::ErrorCode>%d", error_code));
}

void ParamTraits<Geoposition>::Write(Message* m, const Geoposition& p) {
  WriteParam(m, p.latitude);
  WriteParam(m, p.longitude);
  WriteParam(m, p.accuracy);
  WriteParam(m, p.altitude);
  WriteParam(m, p.altitude_accuracy);
  WriteParam(m, p.speed);
  WriteParam(m, p.heading);
  WriteParam(m, p.timestamp);
  WriteParam(m, p.error_code);
  WriteParam(m, p.error_message);
}

bool ParamTraits<Geoposition>::Read(
      const Message* m, void** iter, Geoposition* p) {
  bool ret = ReadParam(m, iter, &p->latitude);
  ret = ret && ReadParam(m, iter, &p->longitude);
  ret = ret && ReadParam(m, iter, &p->accuracy);
  ret = ret && ReadParam(m, iter, &p->altitude);
  ret = ret && ReadParam(m, iter, &p->altitude_accuracy);
  ret = ret && ReadParam(m, iter, &p->speed);
  ret = ret && ReadParam(m, iter, &p->heading);
  ret = ret && ReadParam(m, iter, &p->timestamp);
  ret = ret && ReadParam(m, iter, &p->error_code);
  ret = ret && ReadParam(m, iter, &p->error_message);
  return ret;
}

void ParamTraits<Geoposition>::Log(const Geoposition& p, std::wstring* l) {
  l->append(
      StringPrintf(
          L"<Geoposition>"
          L"%.6f %.6f %.6f %.6f "
          L"%.6f %.6f %.6f ",
          p.latitude, p.longitude, p.accuracy, p.altitude,
          p.altitude_accuracy, p.speed, p.heading));
  LogParam(p.timestamp, l);
  l->append(L" ");
  l->append(p.error_message);
  LogParam(p.error_code, l);
}

}  // namespace IPC
<|endoftext|>