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

#include "xls/ir/function.h"

#include "absl/status/statusor.h"
#include "absl/strings/str_cat.h"
#include "absl/strings/str_format.h"
#include "absl/strings/str_join.h"
#include "xls/common/logging/logging.h"
#include "xls/common/status/ret_check.h"
#include "xls/common/status/status_macros.h"
#include "xls/ir/node_iterator.h"
#include "xls/ir/package.h"

namespace xls {

FunctionType* Function::GetType() {
  std::vector<Type*> arg_types;
  for (Param* param : params()) {
    arg_types.push_back(param->GetType());
  }
  XLS_CHECK(return_value() != nullptr);
  return package_->GetFunctionType(arg_types, return_value()->GetType());
}

std::string Function::DumpIr() const {
  std::string res = "fn " + name() + "(";
  std::vector<std::string> param_strings;
  for (Param* param : params_) {
    param_strings.push_back(
        absl::StrFormat("%s: %s", param->name(), param->GetType()->ToString()));
  }
  absl::StrAppend(&res, absl::StrJoin(param_strings, ", "));
  absl::StrAppend(&res, ") -> ");

  if (return_value() != nullptr) {
    absl::StrAppend(&res, return_value()->GetType()->ToString());
  }
  absl::StrAppend(&res, " {\n");

  for (Node* node : TopoSort(const_cast<Function*>(this))) {
    if (node->op() == Op::kParam && node == return_value()) {
      absl::StrAppendFormat(&res, "  ret %s: %s = param(name=%s)\n",
                            node->GetName(), node->GetType()->ToString(),
                            node->As<Param>()->name());
      continue;
    }
    if (node->op() == Op::kParam) {
      continue;  // Already accounted for in the signature.
    }
    absl::StrAppend(&res, "  ", node == return_value() ? "ret " : "",
                    node->ToString(), "\n");
  }

  absl::StrAppend(&res, "}\n");
  return res;
}

absl::StatusOr<Function*> Function::Clone(
    absl::string_view new_name, Package* target_package,
    const absl::flat_hash_map<const Function*, Function*>& call_remapping)
    const {
  absl::flat_hash_map<Node*, Node*> original_to_clone;
  if (target_package == nullptr) {
    target_package = package();
  }
  Function* cloned_function = target_package->AddFunction(
      std::make_unique<Function>(new_name, target_package));
  for (Node* node : TopoSort(const_cast<Function*>(this))) {
    std::vector<Node*> cloned_operands;
    for (Node* operand : node->operands()) {
      cloned_operands.push_back(original_to_clone.at(operand));
    }

    switch (node->op()) {
      // Remap CountedFor body.
      case Op::kCountedFor: {
        CountedFor* src = node->As<CountedFor>();
        Function* body = call_remapping.contains(src->body())
                             ? call_remapping.at(src->body())
                             : src->body();
        XLS_ASSIGN_OR_RETURN(
            original_to_clone[node],
            cloned_function->MakeNodeWithName<CountedFor>(
                src->loc(), cloned_operands[0],
                absl::Span<Node*>(cloned_operands).subspan(1),
                src->trip_count(), src->stride(), body, src->GetName()));
        break;
      }
      // Remap Map to_apply.
      case Op::kMap: {
        Map* src = node->As<Map>();
        Function* to_apply = call_remapping.contains(src->to_apply())
                                 ? call_remapping.at(src->to_apply())
                                 : src->to_apply();
        XLS_ASSIGN_OR_RETURN(
            original_to_clone[node],
            cloned_function->MakeNodeWithName<Map>(
                src->loc(), cloned_operands[0], to_apply, src->GetName()));
        break;
      }
      // Remap Invoke to_apply.
      case Op::kInvoke: {
        Invoke* src = node->As<Invoke>();
        Function* to_apply = call_remapping.contains(src->to_apply())
                                 ? call_remapping.at(src->to_apply())
                                 : src->to_apply();
        XLS_ASSIGN_OR_RETURN(
            original_to_clone[node],
            cloned_function->MakeNodeWithName<Invoke>(
                src->loc(), cloned_operands, to_apply, src->GetName()));
        break;
      }
      // Default clone.
      default: {
        XLS_ASSIGN_OR_RETURN(
            original_to_clone[node],
            node->CloneInNewFunction(cloned_operands, cloned_function));
        break;
      }
    }
  }
  XLS_RETURN_IF_ERROR(
      cloned_function->set_return_value(original_to_clone.at(return_value())));
  return cloned_function;
}

// Helper function for IsDefinitelyEqualTo. Recursively compares 'node' and
// 'other_node' and their operands using Node::IsDefinitelyEqualTo.
// 'matched_pairs' is used to memoize the result of the comparison.
static bool IsEqualRecurse(
    const Node* node, const Node* other_node,
    absl::flat_hash_map<const Node*, const Node*>* matched_pairs) {
  auto it = matched_pairs->find(node);
  if (it != matched_pairs->end()) {
    return it->second == other_node;
  }

  if (!node->IsDefinitelyEqualTo(other_node)) {
    XLS_VLOG(2) << absl::StrFormat("Function %s != %s: node %s != %s",
                                   node->function_base()->name(),
                                   other_node->function_base()->name(),
                                   node->GetName(), other_node->GetName());
    return false;
  }

  for (int64_t i = 0; i < node->operand_count(); ++i) {
    if (!IsEqualRecurse(node->operand(i), other_node->operand(i),
                        matched_pairs)) {
      return false;
    }
  }
  (*matched_pairs)[node] = other_node;
  return true;
}

bool Function::IsDefinitelyEqualTo(const Function* other) const {
  if (this == other) {
    XLS_VLOG(2) << absl::StrFormat("Function %s == %s: same pointer", name(),
                                   other->name());
    return true;
  }

  // Must have the types of parameters in the same order.
  if (params().size() != other->params().size()) {
    XLS_VLOG(2) << absl::StrFormat(
        "Function %s != %s: different number of parameters (%d vs %d)", name(),
        other->name(), params().size(), other->params().size());
    return false;
  }

  absl::flat_hash_map<const Node*, const Node*> matched_pairs;
  for (int64_t i = 0; i < params().size(); ++i) {
    // All we care about is the type (not the name) of the parameter so don't
    // use Param::IsDefinitelyEqualTo.
    if (!param(i)->GetType()->IsEqualTo(other->param(i)->GetType())) {
      XLS_VLOG(2) << absl::StrFormat(
          "Function %s != %s: type of parameter %d not the same (%s vs %s)",
          name(), other->name(), i, param(i)->GetType()->ToString(),
          other->param(i)->GetType()->ToString());
      return false;
    }
    matched_pairs[param(i)] = other->param(i);
  }

  bool result =
      IsEqualRecurse(return_value(), other->return_value(), &matched_pairs);
  XLS_VLOG_IF(2, result) << absl::StrFormat("Function %s is equal to %s",
                                            name(), other->name());
  return result;
}

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

#include "xls/ir/function.h"

#include "absl/status/statusor.h"
#include "absl/strings/str_cat.h"
#include "absl/strings/str_format.h"
#include "absl/strings/str_join.h"
#include "xls/common/logging/logging.h"
#include "xls/common/status/ret_check.h"
#include "xls/common/status/status_macros.h"
#include "xls/ir/node_iterator.h"
#include "xls/ir/package.h"

namespace xls {

FunctionType* Function::GetType() {
  std::vector<Type*> arg_types;
  for (Param* param : params()) {
    arg_types.push_back(param->GetType());
  }
  XLS_CHECK(return_value() != nullptr);
  return package_->GetFunctionType(arg_types, return_value()->GetType());
}

std::string Function::DumpIr() const {
  std::string res = "fn " + name() + "(";
  std::vector<std::string> param_strings;
  for (Param* param : params_) {
    param_strings.push_back(
        absl::StrFormat("%s: %s", param->name(), param->GetType()->ToString()));
  }
  absl::StrAppend(&res, absl::StrJoin(param_strings, ", "));
  absl::StrAppend(&res, ") -> ");

  if (return_value() != nullptr) {
    absl::StrAppend(&res, return_value()->GetType()->ToString());
  }
  absl::StrAppend(&res, " {\n");

  for (Node* node : TopoSort(const_cast<Function*>(this))) {
    if (node->op() == Op::kParam && node == return_value()) {
      absl::StrAppendFormat(&res, "  ret %s: %s = param(name=%s)\n",
                            node->GetName(), node->GetType()->ToString(),
                            node->As<Param>()->name());
      continue;
    }
    if (node->op() == Op::kParam) {
      continue;  // Already accounted for in the signature.
    }
    absl::StrAppend(&res, "  ", node == return_value() ? "ret " : "",
                    node->ToString(), "\n");
  }

  absl::StrAppend(&res, "}\n");
  return res;
}

absl::StatusOr<Function*> Function::Clone(
    absl::string_view new_name, Package* target_package,
    const absl::flat_hash_map<const Function*, Function*>& call_remapping)
    const {
  absl::flat_hash_map<Node*, Node*> original_to_clone;
  if (target_package == nullptr) {
    target_package = package();
  }
  Function* cloned_function = target_package->AddFunction(
      std::make_unique<Function>(new_name, target_package));
  // Clone parameters over first.
  for (Param* param : (const_cast<Function*>(this))->params()) {
    XLS_ASSIGN_OR_RETURN(
            original_to_clone[param],
            param->CloneInNewFunction({}, cloned_function));
  }
  for (Node* node : TopoSort(const_cast<Function*>(this))) {
    if (node->Is<Param>()) {  // Params were already copied.
      continue;
    }
    std::vector<Node*> cloned_operands;
    for (Node* operand : node->operands()) {
      cloned_operands.push_back(original_to_clone.at(operand));
    }

    switch (node->op()) {
      // Remap CountedFor body.
      case Op::kCountedFor: {
        CountedFor* src = node->As<CountedFor>();
        Function* body = call_remapping.contains(src->body())
                             ? call_remapping.at(src->body())
                             : src->body();
        XLS_ASSIGN_OR_RETURN(
            original_to_clone[node],
            cloned_function->MakeNodeWithName<CountedFor>(
                src->loc(), cloned_operands[0],
                absl::Span<Node*>(cloned_operands).subspan(1),
                src->trip_count(), src->stride(), body, src->GetName()));
        break;
      }
      // Remap Map to_apply.
      case Op::kMap: {
        Map* src = node->As<Map>();
        Function* to_apply = call_remapping.contains(src->to_apply())
                                 ? call_remapping.at(src->to_apply())
                                 : src->to_apply();
        XLS_ASSIGN_OR_RETURN(
            original_to_clone[node],
            cloned_function->MakeNodeWithName<Map>(
                src->loc(), cloned_operands[0], to_apply, src->GetName()));
        break;
      }
      // Remap Invoke to_apply.
      case Op::kInvoke: {
        Invoke* src = node->As<Invoke>();
        Function* to_apply = call_remapping.contains(src->to_apply())
                                 ? call_remapping.at(src->to_apply())
                                 : src->to_apply();
        XLS_ASSIGN_OR_RETURN(
            original_to_clone[node],
            cloned_function->MakeNodeWithName<Invoke>(
                src->loc(), cloned_operands, to_apply, src->GetName()));
        break;
      }
      // Default clone.
      default: {
        XLS_ASSIGN_OR_RETURN(
            original_to_clone[node],
            node->CloneInNewFunction(cloned_operands, cloned_function));
        break;
      }
    }
  }
  XLS_RETURN_IF_ERROR(
      cloned_function->set_return_value(original_to_clone.at(return_value())));
  return cloned_function;
}

// Helper function for IsDefinitelyEqualTo. Recursively compares 'node' and
// 'other_node' and their operands using Node::IsDefinitelyEqualTo.
// 'matched_pairs' is used to memoize the result of the comparison.
static bool IsEqualRecurse(
    const Node* node, const Node* other_node,
    absl::flat_hash_map<const Node*, const Node*>* matched_pairs) {
  auto it = matched_pairs->find(node);
  if (it != matched_pairs->end()) {
    return it->second == other_node;
  }

  if (!node->IsDefinitelyEqualTo(other_node)) {
    XLS_VLOG(2) << absl::StrFormat("Function %s != %s: node %s != %s",
                                   node->function_base()->name(),
                                   other_node->function_base()->name(),
                                   node->GetName(), other_node->GetName());
    return false;
  }

  for (int64_t i = 0; i < node->operand_count(); ++i) {
    if (!IsEqualRecurse(node->operand(i), other_node->operand(i),
                        matched_pairs)) {
      return false;
    }
  }
  (*matched_pairs)[node] = other_node;
  return true;
}

bool Function::IsDefinitelyEqualTo(const Function* other) const {
  if (this == other) {
    XLS_VLOG(2) << absl::StrFormat("Function %s == %s: same pointer", name(),
                                   other->name());
    return true;
  }

  // Must have the types of parameters in the same order.
  if (params().size() != other->params().size()) {
    XLS_VLOG(2) << absl::StrFormat(
        "Function %s != %s: different number of parameters (%d vs %d)", name(),
        other->name(), params().size(), other->params().size());
    return false;
  }

  absl::flat_hash_map<const Node*, const Node*> matched_pairs;
  for (int64_t i = 0; i < params().size(); ++i) {
    // All we care about is the type (not the name) of the parameter so don't
    // use Param::IsDefinitelyEqualTo.
    if (!param(i)->GetType()->IsEqualTo(other->param(i)->GetType())) {
      XLS_VLOG(2) << absl::StrFormat(
          "Function %s != %s: type of parameter %d not the same (%s vs %s)",
          name(), other->name(), i, param(i)->GetType()->ToString(),
          other->param(i)->GetType()->ToString());
      return false;
    }
    matched_pairs[param(i)] = other->param(i);
  }

  bool result =
      IsEqualRecurse(return_value(), other->return_value(), &matched_pairs);
  XLS_VLOG_IF(2, result) << absl::StrFormat("Function %s is equal to %s",
                                            name(), other->name());
  return result;
}

}  // namespace xls
<|endoftext|>


<commit_before>/*M///////////////////////////////////////////////////////////////////////////////////////
//
//  IMPORTANT: READ BEFORE DOWNLOADING, COPYING, INSTALLING OR USING.
//
//  By downloading, copying, installing or using the software you agree to this license.
//  If you do not agree to this license, do not download, install,
//  copy or use the software.
//
//
//                           License Agreement
//                For Open Source Computer Vision Library
//
// Copyright (C) 2010-2012, Multicoreware, Inc., all rights reserved.
// Copyright (C) 2010-2012, Advanced Micro Devices, Inc., all rights reserved.
// Third party copyrights are property of their respective owners.
//
// @Authors
//    Fangfang Bai, fangfang@multicorewareinc.com
//    Jin Ma,       jin@multicorewareinc.com
//
// Redistribution and use in source and binary forms, with or without modification,
// are permitted provided that the following conditions are met:
//
//   * Redistribution's of source code must retain the above copyright notice,
//     this list of conditions and the following disclaimer.
//
//   * Redistribution's 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.
//
//   * The name of the copyright holders may not 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 Intel Corporation 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.
//
//M*/
#include "perf_precomp.hpp"

using namespace perf;
using std::tr1::tuple;
using std::tr1::get;

///////////// WarpAffine ////////////////////////

typedef Size_MatType WarpAffineFixture;

PERF_TEST_P(WarpAffineFixture, WarpAffine,
            ::testing::Combine(OCL_TYPICAL_MAT_SIZES,
                               OCL_PERF_ENUM(CV_8UC1, CV_8UC4)))
{
    static const double coeffs[2][3] =
    {
        { cos(CV_PI / 6), -sin(CV_PI / 6), 100.0 },
        { sin(CV_PI / 6), cos(CV_PI / 6), -100.0 }
    };
    Mat M(2, 3, CV_64F, (void *)coeffs);
    const int interpolation = INTER_NEAREST;

    const Size_MatType_t params = GetParam();
    const Size srcSize = get<0>(params);
    const int type = get<1>(params);

    Mat src(srcSize, type), dst(srcSize, type);
    declare.in(src, WARMUP_RNG).out(dst);

    if (RUN_OCL_IMPL)
    {
        ocl::oclMat oclSrc(src), oclDst(srcSize, type);

        OCL_TEST_CYCLE() cv::ocl::warpAffine(oclSrc, oclDst, M, srcSize, interpolation);

        oclDst.download(dst);

        SANITY_CHECK(dst);
    }
    else if (RUN_PLAIN_IMPL)
    {
        TEST_CYCLE() cv::warpAffine(src, dst, M, srcSize, interpolation);

        SANITY_CHECK(dst);
    }
    else
        OCL_PERF_ELSE
}

///////////// WarpPerspective ////////////////////////

typedef Size_MatType WarpPerspectiveFixture;

PERF_TEST_P(WarpPerspectiveFixture, WarpPerspective,
            ::testing::Combine(OCL_TYPICAL_MAT_SIZES,
                               OCL_PERF_ENUM(CV_8UC1, CV_8UC4)))
{
    static const double coeffs[3][3] =
    {
        {cos(CV_PI / 6), -sin(CV_PI / 6), 100.0},
        {sin(CV_PI / 6), cos(CV_PI / 6), -100.0},
        {0.0, 0.0, 1.0}
    };
    Mat M(3, 3, CV_64F, (void *)coeffs);
    const int interpolation = INTER_LINEAR;

    const Size_MatType_t params = GetParam();
    const Size srcSize = get<0>(params);
    const int type = get<1>(params);

    Mat src(srcSize, type), dst(srcSize, type);
    declare.in(src, WARMUP_RNG).out(dst)
            .time(srcSize == OCL_SIZE_4000 ? 18 : srcSize == OCL_SIZE_2000 ? 5 : 2);

    if (RUN_OCL_IMPL)
    {
        ocl::oclMat oclSrc(src), oclDst(srcSize, type);

        OCL_TEST_CYCLE() cv::ocl::warpPerspective(oclSrc, oclDst, M, srcSize, interpolation);

        oclDst.download(dst);

        SANITY_CHECK(dst);
    }
    else if (RUN_PLAIN_IMPL)
    {
        TEST_CYCLE() cv::warpPerspective(src, dst, M, srcSize, interpolation);

        SANITY_CHECK(dst);
    }
    else
        OCL_PERF_ELSE
}

///////////// resize ////////////////////////

CV_ENUM(resizeInterType, INTER_NEAREST, INTER_LINEAR)

typedef tuple<Size, MatType, resizeInterType, double> resizeParams;
typedef TestBaseWithParam<resizeParams> resizeFixture;

PERF_TEST_P(resizeFixture, resize,
            ::testing::Combine(OCL_TYPICAL_MAT_SIZES,
                               OCL_PERF_ENUM(CV_8UC1, CV_8UC4),
                               resizeInterType::all(),
                               ::testing::Values(0.5, 2.0)))
{
    const resizeParams params = GetParam();
    const Size srcSize = get<0>(params);
    const int type = get<1>(params), interType = get<2>(params);
    double scale = get<3>(params);

    Mat src(srcSize, type), dst;
    const Size dstSize(cvRound(srcSize.width * scale), cvRound(srcSize.height * scale));
    dst.create(dstSize, type);
    declare.in(src, WARMUP_RNG).out(dst);
    if (interType == INTER_LINEAR && type == CV_8UC4 && OCL_SIZE_4000 == srcSize)
        declare.time(11);

    if (RUN_OCL_IMPL)
    {
        ocl::oclMat oclSrc(src), oclDst(dstSize, type);

        OCL_TEST_CYCLE() cv::ocl::resize(oclSrc, oclDst, Size(), scale, scale, interType);

        oclDst.download(dst);

        SANITY_CHECK(dst, 1 + DBL_EPSILON);
    }
    else if (RUN_PLAIN_IMPL)
    {
        TEST_CYCLE() cv::resize(src, dst, Size(), scale, scale, interType);

        SANITY_CHECK(dst, 1 + DBL_EPSILON);
    }
    else
        OCL_PERF_ELSE
}

///////////// remap////////////////////////

CV_ENUM(RemapInterType, INTER_NEAREST, INTER_LINEAR)

typedef tuple<Size, MatType, RemapInterType> remapParams;
typedef TestBaseWithParam<remapParams> remapFixture;

PERF_TEST_P(remapFixture, remap,
            ::testing::Combine(OCL_TYPICAL_MAT_SIZES,
                               OCL_PERF_ENUM(CV_8UC1, CV_8UC4),
                               RemapInterType::all()))
{
    const remapParams params = GetParam();
    const Size srcSize = get<0>(params);
    const int type = get<1>(params), interpolation = get<2>(params);

    Mat src(srcSize, type), dst(srcSize, type);
    declare.in(src, WARMUP_RNG).out(dst);

    if (srcSize == OCL_SIZE_4000 && interpolation == INTER_LINEAR)
        declare.time(9);

    Mat xmap, ymap;
    xmap.create(srcSize, CV_32FC1);
    ymap.create(srcSize, CV_32FC1);

    for (int i = 0; i < srcSize.height; ++i)
    {
        float * const xmap_row = xmap.ptr<float>(i);
        float * const ymap_row = ymap.ptr<float>(i);

        for (int j = 0; j < srcSize.width; ++j)
        {
            xmap_row[j] = (j - srcSize.width * 0.5f) * 0.75f + srcSize.width * 0.5f;
            ymap_row[j] = (i - srcSize.height * 0.5f) * 0.75f + srcSize.height * 0.5f;
        }
    }

    const int borderMode = BORDER_CONSTANT;

    if (RUN_OCL_IMPL)
    {
        ocl::oclMat oclSrc(src), oclDst(srcSize, type);
        ocl::oclMat oclXMap(xmap), oclYMap(ymap);

        OCL_TEST_CYCLE() cv::ocl::remap(oclSrc, oclDst, oclXMap, oclYMap, interpolation, borderMode);

        oclDst.download(dst);

        SANITY_CHECK(dst, 1 + DBL_EPSILON);
    }
    else if (RUN_PLAIN_IMPL)
    {
        TEST_CYCLE() cv::remap(src, dst, xmap, ymap, interpolation, borderMode);

        SANITY_CHECK(dst, 1 + DBL_EPSILON);
    }
    else
        OCL_PERF_ELSE
}

///////////// buildWarpPerspectiveMaps ////////////////////////

static void buildWarpPerspectiveMaps(const Mat &M, bool inverse, Size dsize, Mat &xmap, Mat &ymap)
{
    CV_Assert(M.rows == 3 && M.cols == 3);
    CV_Assert(dsize.area() > 0);

    xmap.create(dsize, CV_32FC1);
    ymap.create(dsize, CV_32FC1);

    float coeffs[3 * 3];
    Mat coeffsMat(3, 3, CV_32F, (void *)coeffs);

    if (inverse)
        M.convertTo(coeffsMat, coeffsMat.type());
    else
    {
        cv::Mat iM;
        invert(M, iM);
        iM.convertTo(coeffsMat, coeffsMat.type());
    }

    for (int y = 0; y < dsize.height; ++y)
    {
        float * const xmap_ptr = xmap.ptr<float>(y);
        float * const ymap_ptr = ymap.ptr<float>(y);

        for (int x = 0; x < dsize.width; ++x)
        {
            float coeff = 1.0f / (x * coeffs[6] + y * coeffs[7] + coeffs[8]);
            xmap_ptr[x] = (x * coeffs[0] + y * coeffs[1] + coeffs[2]) * coeff;
            ymap_ptr[x] = (x * coeffs[3] + y * coeffs[4] + coeffs[5]) * coeff;
        }
    }
}

typedef TestBaseWithParam<Size> buildWarpPerspectiveMapsFixture;

PERF_TEST_P(buildWarpPerspectiveMapsFixture, Inverse, OCL_TYPICAL_MAT_SIZES)
{
    static const double coeffs[3][3] =
    {
        {cos(CV_PI / 6), -sin(CV_PI / 6), 100.0},
        {sin(CV_PI / 6), cos(CV_PI / 6), -100.0},
        {0.0, 0.0, 1.0}
    };
    Mat M(3, 3, CV_64F, (void *)coeffs);
    const Size dsize = GetParam();

    Mat xmap(dsize, CV_32FC1), ymap(dsize, CV_32FC1);
    declare.in(M).out(xmap, ymap);

    if (RUN_OCL_IMPL)
    {
        ocl::oclMat oclXMap(dsize, CV_32FC1), oclYMap(dsize, CV_32FC1);

        OCL_TEST_CYCLE() cv::ocl::buildWarpPerspectiveMaps(M, true, dsize, oclXMap, oclYMap);

        oclXMap.download(xmap);
        oclYMap.download(ymap);

        SANITY_CHECK(xmap);
        SANITY_CHECK(ymap);
    }
    else if (RUN_PLAIN_IMPL)
    {
        TEST_CYCLE() buildWarpPerspectiveMaps(M, true, dsize, xmap, ymap);

        SANITY_CHECK(xmap);
        SANITY_CHECK(ymap);
    }
    else
        OCL_PERF_ELSE
}
<commit_msg>added eps to ocl::buildWarpPerspectiveMaps perf test<commit_after>/*M///////////////////////////////////////////////////////////////////////////////////////
//
//  IMPORTANT: READ BEFORE DOWNLOADING, COPYING, INSTALLING OR USING.
//
//  By downloading, copying, installing or using the software you agree to this license.
//  If you do not agree to this license, do not download, install,
//  copy or use the software.
//
//
//                           License Agreement
//                For Open Source Computer Vision Library
//
// Copyright (C) 2010-2012, Multicoreware, Inc., all rights reserved.
// Copyright (C) 2010-2012, Advanced Micro Devices, Inc., all rights reserved.
// Third party copyrights are property of their respective owners.
//
// @Authors
//    Fangfang Bai, fangfang@multicorewareinc.com
//    Jin Ma,       jin@multicorewareinc.com
//
// Redistribution and use in source and binary forms, with or without modification,
// are permitted provided that the following conditions are met:
//
//   * Redistribution's of source code must retain the above copyright notice,
//     this list of conditions and the following disclaimer.
//
//   * Redistribution's 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.
//
//   * The name of the copyright holders may not 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 Intel Corporation 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.
//
//M*/
#include "perf_precomp.hpp"

using namespace perf;
using std::tr1::tuple;
using std::tr1::get;

///////////// WarpAffine ////////////////////////

typedef Size_MatType WarpAffineFixture;

PERF_TEST_P(WarpAffineFixture, WarpAffine,
            ::testing::Combine(OCL_TYPICAL_MAT_SIZES,
                               OCL_PERF_ENUM(CV_8UC1, CV_8UC4)))
{
    static const double coeffs[2][3] =
    {
        { cos(CV_PI / 6), -sin(CV_PI / 6), 100.0 },
        { sin(CV_PI / 6), cos(CV_PI / 6), -100.0 }
    };
    Mat M(2, 3, CV_64F, (void *)coeffs);
    const int interpolation = INTER_NEAREST;

    const Size_MatType_t params = GetParam();
    const Size srcSize = get<0>(params);
    const int type = get<1>(params);

    Mat src(srcSize, type), dst(srcSize, type);
    declare.in(src, WARMUP_RNG).out(dst);

    if (RUN_OCL_IMPL)
    {
        ocl::oclMat oclSrc(src), oclDst(srcSize, type);

        OCL_TEST_CYCLE() cv::ocl::warpAffine(oclSrc, oclDst, M, srcSize, interpolation);

        oclDst.download(dst);

        SANITY_CHECK(dst);
    }
    else if (RUN_PLAIN_IMPL)
    {
        TEST_CYCLE() cv::warpAffine(src, dst, M, srcSize, interpolation);

        SANITY_CHECK(dst);
    }
    else
        OCL_PERF_ELSE
}

///////////// WarpPerspective ////////////////////////

typedef Size_MatType WarpPerspectiveFixture;

PERF_TEST_P(WarpPerspectiveFixture, WarpPerspective,
            ::testing::Combine(OCL_TYPICAL_MAT_SIZES,
                               OCL_PERF_ENUM(CV_8UC1, CV_8UC4)))
{
    static const double coeffs[3][3] =
    {
        {cos(CV_PI / 6), -sin(CV_PI / 6), 100.0},
        {sin(CV_PI / 6), cos(CV_PI / 6), -100.0},
        {0.0, 0.0, 1.0}
    };
    Mat M(3, 3, CV_64F, (void *)coeffs);
    const int interpolation = INTER_LINEAR;

    const Size_MatType_t params = GetParam();
    const Size srcSize = get<0>(params);
    const int type = get<1>(params);

    Mat src(srcSize, type), dst(srcSize, type);
    declare.in(src, WARMUP_RNG).out(dst)
            .time(srcSize == OCL_SIZE_4000 ? 18 : srcSize == OCL_SIZE_2000 ? 5 : 2);

    if (RUN_OCL_IMPL)
    {
        ocl::oclMat oclSrc(src), oclDst(srcSize, type);

        OCL_TEST_CYCLE() cv::ocl::warpPerspective(oclSrc, oclDst, M, srcSize, interpolation);

        oclDst.download(dst);

        SANITY_CHECK(dst);
    }
    else if (RUN_PLAIN_IMPL)
    {
        TEST_CYCLE() cv::warpPerspective(src, dst, M, srcSize, interpolation);

        SANITY_CHECK(dst);
    }
    else
        OCL_PERF_ELSE
}

///////////// resize ////////////////////////

CV_ENUM(resizeInterType, INTER_NEAREST, INTER_LINEAR)

typedef tuple<Size, MatType, resizeInterType, double> resizeParams;
typedef TestBaseWithParam<resizeParams> resizeFixture;

PERF_TEST_P(resizeFixture, resize,
            ::testing::Combine(OCL_TYPICAL_MAT_SIZES,
                               OCL_PERF_ENUM(CV_8UC1, CV_8UC4),
                               resizeInterType::all(),
                               ::testing::Values(0.5, 2.0)))
{
    const resizeParams params = GetParam();
    const Size srcSize = get<0>(params);
    const int type = get<1>(params), interType = get<2>(params);
    double scale = get<3>(params);

    Mat src(srcSize, type), dst;
    const Size dstSize(cvRound(srcSize.width * scale), cvRound(srcSize.height * scale));
    dst.create(dstSize, type);
    declare.in(src, WARMUP_RNG).out(dst);
    if (interType == INTER_LINEAR && type == CV_8UC4 && OCL_SIZE_4000 == srcSize)
        declare.time(11);

    if (RUN_OCL_IMPL)
    {
        ocl::oclMat oclSrc(src), oclDst(dstSize, type);

        OCL_TEST_CYCLE() cv::ocl::resize(oclSrc, oclDst, Size(), scale, scale, interType);

        oclDst.download(dst);

        SANITY_CHECK(dst, 1 + DBL_EPSILON);
    }
    else if (RUN_PLAIN_IMPL)
    {
        TEST_CYCLE() cv::resize(src, dst, Size(), scale, scale, interType);

        SANITY_CHECK(dst, 1 + DBL_EPSILON);
    }
    else
        OCL_PERF_ELSE
}

///////////// remap////////////////////////

CV_ENUM(RemapInterType, INTER_NEAREST, INTER_LINEAR)

typedef tuple<Size, MatType, RemapInterType> remapParams;
typedef TestBaseWithParam<remapParams> remapFixture;

PERF_TEST_P(remapFixture, remap,
            ::testing::Combine(OCL_TYPICAL_MAT_SIZES,
                               OCL_PERF_ENUM(CV_8UC1, CV_8UC4),
                               RemapInterType::all()))
{
    const remapParams params = GetParam();
    const Size srcSize = get<0>(params);
    const int type = get<1>(params), interpolation = get<2>(params);

    Mat src(srcSize, type), dst(srcSize, type);
    declare.in(src, WARMUP_RNG).out(dst);

    if (srcSize == OCL_SIZE_4000 && interpolation == INTER_LINEAR)
        declare.time(9);

    Mat xmap, ymap;
    xmap.create(srcSize, CV_32FC1);
    ymap.create(srcSize, CV_32FC1);

    for (int i = 0; i < srcSize.height; ++i)
    {
        float * const xmap_row = xmap.ptr<float>(i);
        float * const ymap_row = ymap.ptr<float>(i);

        for (int j = 0; j < srcSize.width; ++j)
        {
            xmap_row[j] = (j - srcSize.width * 0.5f) * 0.75f + srcSize.width * 0.5f;
            ymap_row[j] = (i - srcSize.height * 0.5f) * 0.75f + srcSize.height * 0.5f;
        }
    }

    const int borderMode = BORDER_CONSTANT;

    if (RUN_OCL_IMPL)
    {
        ocl::oclMat oclSrc(src), oclDst(srcSize, type);
        ocl::oclMat oclXMap(xmap), oclYMap(ymap);

        OCL_TEST_CYCLE() cv::ocl::remap(oclSrc, oclDst, oclXMap, oclYMap, interpolation, borderMode);

        oclDst.download(dst);

        SANITY_CHECK(dst, 1 + DBL_EPSILON);
    }
    else if (RUN_PLAIN_IMPL)
    {
        TEST_CYCLE() cv::remap(src, dst, xmap, ymap, interpolation, borderMode);

        SANITY_CHECK(dst, 1 + DBL_EPSILON);
    }
    else
        OCL_PERF_ELSE
}

///////////// buildWarpPerspectiveMaps ////////////////////////

static void buildWarpPerspectiveMaps(const Mat &M, bool inverse, Size dsize, Mat &xmap, Mat &ymap)
{
    CV_Assert(M.rows == 3 && M.cols == 3);
    CV_Assert(dsize.area() > 0);

    xmap.create(dsize, CV_32FC1);
    ymap.create(dsize, CV_32FC1);

    float coeffs[3 * 3];
    Mat coeffsMat(3, 3, CV_32F, (void *)coeffs);

    if (inverse)
        M.convertTo(coeffsMat, coeffsMat.type());
    else
    {
        cv::Mat iM;
        invert(M, iM);
        iM.convertTo(coeffsMat, coeffsMat.type());
    }

    for (int y = 0; y < dsize.height; ++y)
    {
        float * const xmap_ptr = xmap.ptr<float>(y);
        float * const ymap_ptr = ymap.ptr<float>(y);

        for (int x = 0; x < dsize.width; ++x)
        {
            float coeff = 1.0f / (x * coeffs[6] + y * coeffs[7] + coeffs[8]);
            xmap_ptr[x] = (x * coeffs[0] + y * coeffs[1] + coeffs[2]) * coeff;
            ymap_ptr[x] = (x * coeffs[3] + y * coeffs[4] + coeffs[5]) * coeff;
        }
    }
}

typedef TestBaseWithParam<Size> buildWarpPerspectiveMapsFixture;

PERF_TEST_P(buildWarpPerspectiveMapsFixture, Inverse, OCL_TYPICAL_MAT_SIZES)
{
    static const double coeffs[3][3] =
    {
        {cos(CV_PI / 6), -sin(CV_PI / 6), 100.0},
        {sin(CV_PI / 6), cos(CV_PI / 6), -100.0},
        {0.0, 0.0, 1.0}
    };
    Mat M(3, 3, CV_64F, (void *)coeffs);
    const Size dsize = GetParam();
    const double eps = 5e-4;

    Mat xmap(dsize, CV_32FC1), ymap(dsize, CV_32FC1);
    declare.in(M).out(xmap, ymap);

    if (RUN_OCL_IMPL)
    {
        ocl::oclMat oclXMap(dsize, CV_32FC1), oclYMap(dsize, CV_32FC1);

        OCL_TEST_CYCLE() cv::ocl::buildWarpPerspectiveMaps(M, true, dsize, oclXMap, oclYMap);

        oclXMap.download(xmap);
        oclYMap.download(ymap);

        SANITY_CHECK(xmap, eps);
        SANITY_CHECK(ymap, eps);
    }
    else if (RUN_PLAIN_IMPL)
    {
        TEST_CYCLE() buildWarpPerspectiveMaps(M, true, dsize, xmap, ymap);

        SANITY_CHECK(xmap, eps);
        SANITY_CHECK(ymap, eps);
    }
    else
        OCL_PERF_ELSE
}
<|endoftext|>


<commit_before>/* -*-  mode: c++; c-default-style: "google"; indent-tabs-mode: nil -*- */
/* -------------------------------------------------------------------------
ATS

License: see $ATS_DIR/COPYRIGHT
Author: Ethan Coon

Derived MPC for flow and energy.  This couples using a block-diagonal coupler.
------------------------------------------------------------------------- */

#include "wrm_richards_evaluator.hh"
#include "mpc_frozen_prec_coupled_flow_energy.hh"

namespace Amanzi {

#define DEBUG_FLAG 0

RegisteredPKFactory<MPCFrozenCoupledFlowEnergy> MPCFrozenCoupledFlowEnergy::reg_("frozen energy-flow preconditioner coupled");

bool MPCFrozenCoupledFlowEnergy::modify_predictor(double h, Teuchos::RCP<TreeVector> u) {
  Teuchos::RCP<CompositeVector> temp_guess = u->SubVector("energy")->data();
  Epetra_MultiVector& guess_cells = *temp_guess->ViewComponent("cell",false);
  Epetra_MultiVector& guess_faces = *temp_guess->ViewComponent("face",false);

  Teuchos::RCP<const CompositeVector> temp = S_next_->GetFieldData("temperature");
  const Epetra_MultiVector& temp_cells = *temp->ViewComponent("cell",false);

  bool update_faces(false);

#if DEBUG_FLAG
  std::cout << "--- Modifying Guess: ---" << std::cout;
#endif

  int ncells = temp->size("cell",false);
  std::vector<bool> changed(ncells, false);
  for (int c=0; c!=ncells; ++c) {
    if (temp_cells[0][c] >= 273.15 && guess_cells[0][c] < 273.15) {
      // freezing
      guess_cells[0][c] = 273.15 - 1.e-4;
      changed[c] = true;
      update_faces = true;
    } else if (temp_cells[0][c] <= 273.15 && guess_cells[0][c] > 273.15) {
      // thawing
      guess_cells[0][c] = 273.15 - 1.e-3;
      changed[c] = true;
      update_faces = true;
    } else if (273.15 > temp_cells[0][c] &&
               temp_cells[0][c] >= 273.1 &&
               (temp_cells[0][c] - guess_cells[0][c]) > 1.e-2) {
      // catch the 2nd step in freezing -- after the 2nd step the
      // extrapolation should be ok?
      guess_cells[0][c] = temp_cells[0][c];
      changed[c] = true;
      update_faces = true;
    }
  }

  // unclear... could do an AllReduce() on update_faces and not communicate if
  // not necessary, but AllReduces() suck... maybe more than extra Scatters?
  temp_guess->ScatterMasterToGhosted("cell");
  if (update_faces) {
    AmanziMesh::Entity_ID_List cells;

    int f_owned = temp_guess->size("face");
    for (int f=0; f!=f_owned; ++f) {
      cells.clear();
      temp_guess->mesh()->face_get_cells(f, AmanziMesh::USED, &cells);
      if (cells.size() == 2) {
        if (changed[cells[0]] || changed[cells[1]]) {
          guess_faces[0][f] = (guess_cells[0][cells[0]]
                  + guess_cells[0][cells[1]]) / 2.0;
        }
      }
    }
    return true;
  }
  return false;
}

bool MPCFrozenCoupledFlowEnergy::modify_predictor_temp(double h, Teuchos::RCP<TreeVector> u) {
  // modification of the initial guess occurs by updating T using this guess,
  // then calculating the p that would be required to keep the same water
  // mass.

  // Stuff temperature into state
  Teuchos::RCP<TreeVector> uT = u->SubVector("energy");
  sub_pks_[1]->changed_solution();

#if DEBUG_FLAG
  std::cout << std::endl;
  std::cout << "Modifying guess:" << std::endl;
  std::cout << "  T0: " << (*uT->data())("cell",0) << std::endl;
  std::cout << "  T1: " << (*uT->data())("cell",99) << std::endl;
#endif

  // update water content, which will get all the needed vals updated at the new temp.
  S_next_->GetFieldEvaluator("water_content")
      ->HasFieldChanged(S_next_.ptr(), "richards_pk");

  // get the needed vals
  Teuchos::RCP<const CompositeVector> wc0 = S_inter_->GetFieldData("water_content");
  Teuchos::RCP<const CompositeVector> cv = S_inter_->GetFieldData("cell_volume");
  Teuchos::RCP<const CompositeVector> phi = S_next_->GetFieldData("porosity");
  Teuchos::RCP<const CompositeVector> n_g = S_next_->GetFieldData("molar_density_gas");
  Teuchos::RCP<const CompositeVector> omega_g = S_next_->GetFieldData("mol_frac_gas");
  Teuchos::RCP<const CompositeVector> n_l = S_next_->GetFieldData("molar_density_liquid");
  Teuchos::RCP<const CompositeVector> n_i = S_next_->GetFieldData("molar_density_ice");
  Teuchos::RCP<const CompositeVector> one_on_A = S_next_->GetFieldData("wrm_permafrost_one_on_A");
  Teuchos::RCP<const double> p_atm = S_next_->GetScalarData("atmospheric_pressure");

  // get the WRMs
  Teuchos::RCP<FieldEvaluator> wrm_B_eval_base = S_next_->GetFieldEvaluator("wrm_permafrost_one_on_B");
  Teuchos::RCP<Flow::FlowRelations::WRMRichardsEvaluator> wrm_B_eval =
      Teuchos::rcp_dynamic_cast<Flow::FlowRelations::WRMRichardsEvaluator>(wrm_B_eval_base);
  Teuchos::RCP<Flow::FlowRelations::WRMRegionPairList> wrms = wrm_B_eval->get_WRMs();

  // get the result pressure
  Teuchos::RCP<CompositeVector> pres = u->SubVector("flow")->data();
  for (Flow::FlowRelations::WRMRegionPairList::iterator region=wrms->begin();
       region!=wrms->end(); ++region) {
    std::string name = region->first;
    int ncells = pres->mesh()->get_set_size(name, AmanziMesh::CELL, AmanziMesh::OWNED);
    AmanziMesh::Entity_ID_List cells(ncells);
    pres->mesh()->get_set_entities(name, AmanziMesh::CELL, AmanziMesh::OWNED, &cells);

    for (AmanziMesh::Entity_ID_List::iterator c=cells.begin(); c!=cells.end(); ++c) {
      double p = (*pres)("cell",*c);
      double A_minus_one = (1.0/(*one_on_A)("cell",*c) - 1.0);

      double wc = (*wc0)("cell",*c) / (*cv)("cell",*c);
      double sstar = (wc - (*n_g)("cell",*c)*(*omega_g)("cell",*c)*(*phi)("cell",*c)) /
          ((*phi)("cell",*c) * ((*n_l)("cell",*c) - (*n_g)("cell",*c)*(*omega_g)("cell",*c)
                  + (*n_i)("cell",*c)*A_minus_one) - A_minus_one*wc);

      if (sstar > 0.) {
        if (*c==0) std::cout << "   A-1(0) = " << A_minus_one << std::endl;
        if (*c==99) std::cout << "   A-1(99) = " << A_minus_one << std::endl;
        if (*c==0) std::cout << "   S*(0) = " << sstar << std::endl;
        if (*c==99) std::cout << "   S*(99) = " << sstar << std::endl;

        double pc = region->second->capillaryPressure(sstar);

        if (*c==0) std::cout << "   pc(0) = " << pc << std::endl;
        if (*c==99) std::cout << "   pc(99) = " << pc << std::endl;

        (*pres)("cell",*c) = *p_atm - pc;

        if (*c==0) std::cout << "   p(0) = " << (*pres)("cell",*c) << std::endl;
        if (*c==99) std::cout << "   p(99) = " <<  (*pres)("cell",*c) << std::endl;

      }
    }
  }

  AmanziMesh::Entity_ID_List cells;
  pres->ScatterMasterToGhosted("cell");

  int f_owned = pres->size("face");
  for (int f=0; f!=f_owned; ++f) {
    cells.clear();
    pres->mesh()->face_get_cells(f, AmanziMesh::USED, &cells);
    int ncells = cells.size();

    double face_value = 0.0;
    for (int n=0; n!=ncells; ++n) {
      face_value += (*pres)("cell",cells[n]);
    }
    (*pres)("face",f) = face_value / ncells;
  }

  return true;
};

} // namespace
<commit_msg>parallel issues in freezing projection -- needs thought and rework<commit_after>/* -*-  mode: c++; c-default-style: "google"; indent-tabs-mode: nil -*- */
/* -------------------------------------------------------------------------
ATS

License: see $ATS_DIR/COPYRIGHT
Author: Ethan Coon

Derived MPC for flow and energy.  This couples using a block-diagonal coupler.
------------------------------------------------------------------------- */

#include "wrm_richards_evaluator.hh"
#include "mpc_frozen_prec_coupled_flow_energy.hh"

namespace Amanzi {

#define DEBUG_FLAG 0

RegisteredPKFactory<MPCFrozenCoupledFlowEnergy> MPCFrozenCoupledFlowEnergy::reg_("frozen energy-flow preconditioner coupled");

bool MPCFrozenCoupledFlowEnergy::modify_predictor(double h, Teuchos::RCP<TreeVector> u) {
  Teuchos::RCP<CompositeVector> temp_guess = u->SubVector("energy")->data();
  Epetra_MultiVector& guess_cells = *temp_guess->ViewComponent("cell",false);
  Epetra_MultiVector& guess_faces = *temp_guess->ViewComponent("face",false);

  Teuchos::RCP<const CompositeVector> temp = S_next_->GetFieldData("temperature");
  const Epetra_MultiVector& temp_cells = *temp->ViewComponent("cell",false);

  bool update_faces(false);

#if DEBUG_FLAG
  std::cout << "--- Modifying Guess: ---" << std::cout;
#endif

  int ncells = temp->size("cell",false);
  std::vector<bool> changed(ncells, false);
  for (int c=0; c!=ncells; ++c) {
    if (temp_cells[0][c] >= 273.15 && guess_cells[0][c] < 273.15) {
      // freezing
      guess_cells[0][c] = 273.15 - 1.e-3;
      changed[c] = true;
      update_faces = true;
    } else if (temp_cells[0][c] <= 273.15 && guess_cells[0][c] > 273.15) {
      // thawing
      guess_cells[0][c] = 273.15 - 1.e-3;
      changed[c] = true;
      update_faces = true;
    } else if (273.15 > temp_cells[0][c] &&
               temp_cells[0][c] >= 273.1 &&
               (temp_cells[0][c] - guess_cells[0][c]) > 1.e-2) {
      // catch the 2nd step in freezing -- after the 2nd step the
      // extrapolation should be ok?
      guess_cells[0][c] = temp_cells[0][c];
      changed[c] = true;
      update_faces = true;
    }
  }

  // unclear... could do an AllReduce() on update_faces and not communicate if
  // not necessary, but AllReduces() suck... maybe more than extra Scatters?
  /*
  temp_guess->ScatterMasterToGhosted("cell");
  if (update_faces) {
    AmanziMesh::Entity_ID_List cells;

    int f_owned = temp_guess->size("face");
    for (int f=0; f!=f_owned; ++f) {
      cells.clear();
      temp_guess->mesh()->face_get_cells(f, AmanziMesh::USED, &cells);
      if (cells.size() == 2) {
        if (changed[cells[0]] || changed[cells[1]]) {
          guess_faces[0][f] = (guess_cells[0][cells[0]]
                  + guess_cells[0][cells[1]]) / 2.0;
        }
      }
    }
    return true;
  }
  */
  return true;
}

bool MPCFrozenCoupledFlowEnergy::modify_predictor_temp(double h, Teuchos::RCP<TreeVector> u) {
  // modification of the initial guess occurs by updating T using this guess,
  // then calculating the p that would be required to keep the same water
  // mass.

  // Stuff temperature into state
  Teuchos::RCP<TreeVector> uT = u->SubVector("energy");
  sub_pks_[1]->changed_solution();

#if DEBUG_FLAG
  std::cout << std::endl;
  std::cout << "Modifying guess:" << std::endl;
  std::cout << "  T0: " << (*uT->data())("cell",0) << std::endl;
  std::cout << "  T1: " << (*uT->data())("cell",99) << std::endl;
#endif

  // update water content, which will get all the needed vals updated at the new temp.
  S_next_->GetFieldEvaluator("water_content")
      ->HasFieldChanged(S_next_.ptr(), "richards_pk");

  // get the needed vals
  Teuchos::RCP<const CompositeVector> wc0 = S_inter_->GetFieldData("water_content");
  Teuchos::RCP<const CompositeVector> cv = S_inter_->GetFieldData("cell_volume");
  Teuchos::RCP<const CompositeVector> phi = S_next_->GetFieldData("porosity");
  Teuchos::RCP<const CompositeVector> n_g = S_next_->GetFieldData("molar_density_gas");
  Teuchos::RCP<const CompositeVector> omega_g = S_next_->GetFieldData("mol_frac_gas");
  Teuchos::RCP<const CompositeVector> n_l = S_next_->GetFieldData("molar_density_liquid");
  Teuchos::RCP<const CompositeVector> n_i = S_next_->GetFieldData("molar_density_ice");
  Teuchos::RCP<const CompositeVector> one_on_A = S_next_->GetFieldData("wrm_permafrost_one_on_A");
  Teuchos::RCP<const double> p_atm = S_next_->GetScalarData("atmospheric_pressure");

  // get the WRMs
  Teuchos::RCP<FieldEvaluator> wrm_B_eval_base = S_next_->GetFieldEvaluator("wrm_permafrost_one_on_B");
  Teuchos::RCP<Flow::FlowRelations::WRMRichardsEvaluator> wrm_B_eval =
      Teuchos::rcp_dynamic_cast<Flow::FlowRelations::WRMRichardsEvaluator>(wrm_B_eval_base);
  Teuchos::RCP<Flow::FlowRelations::WRMRegionPairList> wrms = wrm_B_eval->get_WRMs();

  // get the result pressure
  Teuchos::RCP<CompositeVector> pres = u->SubVector("flow")->data();
  for (Flow::FlowRelations::WRMRegionPairList::iterator region=wrms->begin();
       region!=wrms->end(); ++region) {
    std::string name = region->first;
    int ncells = pres->mesh()->get_set_size(name, AmanziMesh::CELL, AmanziMesh::OWNED);
    AmanziMesh::Entity_ID_List cells(ncells);
    pres->mesh()->get_set_entities(name, AmanziMesh::CELL, AmanziMesh::OWNED, &cells);

    for (AmanziMesh::Entity_ID_List::iterator c=cells.begin(); c!=cells.end(); ++c) {
      double p = (*pres)("cell",*c);
      double A_minus_one = (1.0/(*one_on_A)("cell",*c) - 1.0);

      double wc = (*wc0)("cell",*c) / (*cv)("cell",*c);
      double sstar = (wc - (*n_g)("cell",*c)*(*omega_g)("cell",*c)*(*phi)("cell",*c)) /
          ((*phi)("cell",*c) * ((*n_l)("cell",*c) - (*n_g)("cell",*c)*(*omega_g)("cell",*c)
                  + (*n_i)("cell",*c)*A_minus_one) - A_minus_one*wc);

      if (sstar > 0.) {
        if (*c==0) std::cout << "   A-1(0) = " << A_minus_one << std::endl;
        if (*c==99) std::cout << "   A-1(99) = " << A_minus_one << std::endl;
        if (*c==0) std::cout << "   S*(0) = " << sstar << std::endl;
        if (*c==99) std::cout << "   S*(99) = " << sstar << std::endl;

        double pc = region->second->capillaryPressure(sstar);

        if (*c==0) std::cout << "   pc(0) = " << pc << std::endl;
        if (*c==99) std::cout << "   pc(99) = " << pc << std::endl;

        (*pres)("cell",*c) = *p_atm - pc;

        if (*c==0) std::cout << "   p(0) = " << (*pres)("cell",*c) << std::endl;
        if (*c==99) std::cout << "   p(99) = " <<  (*pres)("cell",*c) << std::endl;

      }
    }
  }

  AmanziMesh::Entity_ID_List cells;
  pres->ScatterMasterToGhosted("cell");

  int f_owned = pres->size("face");
  for (int f=0; f!=f_owned; ++f) {
    cells.clear();
    pres->mesh()->face_get_cells(f, AmanziMesh::USED, &cells);
    int ncells = cells.size();

    double face_value = 0.0;
    for (int n=0; n!=ncells; ++n) {
      face_value += (*pres)("cell",cells[n]);
    }
    (*pres)("face",f) = face_value / ncells;
  }

  return true;
};

} // namespace
<|endoftext|>


<commit_before>// Copyright (c) 2021 ASMlover. All rights reserved.
//
//  ______             __                  ___
// /\__  _\           /\ \                /\_ \
// \/_/\ \/    __     \_\ \  _____     ___\//\ \      __
//    \ \ \  /'__`\   /'_` \/\ '__`\  / __`\\ \ \   /'__`\
//     \ \ \/\ \L\.\_/\ \L\ \ \ \L\ \/\ \L\ \\_\ \_/\  __/
//      \ \_\ \__/.\_\ \___,_\ \ ,__/\ \____//\____\ \____\
//       \/_/\/__/\/_/\/__,_ /\ \ \/  \/___/ \/____/\/____/
//                             \ \_\
//                              \/_/
//
// 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 ofconditions 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 materialsprovided with the
//    distribution.
//
// 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 HOLDER 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.
#pragma once

#include <string>
#include <string_view>
#include <Common/Macros.hh>

namespace Tadpole {

class _Safe {};
class _Unsafe {};

using nil_t     = std::nullptr_t;
using byte_t    = std::uint8_t;
using i8_t      = std::int8_t;
using u8_t      = std::uint8_t;
using i16_t     = std::int16_t;
using u16_t     = std::uint16_t;
using i32_t     = std::int32_t;
using u32_t     = std::uint32_t;
using i64_t     = std::int64_t;
using u64_t     = std::uint64_t;
using sz_t      = std::size_t;
#if defined(TADPOLE_GNUC)
  using ssz_t   = std::ssize_t;
#else
  using ssz_t   = std::int64_t;
#endif
using str_t     = std::string;
using strv_t    = std::string_view;
using ss_t      = std::stringstream;
using safe_t    = _Safe;
using unsafe_t  = _Unsafe;

}
<commit_msg>:construction: chore(types): updated the types<commit_after>// Copyright (c) 2021 ASMlover. All rights reserved.
//
//  ______             __                  ___
// /\__  _\           /\ \                /\_ \
// \/_/\ \/    __     \_\ \  _____     ___\//\ \      __
//    \ \ \  /'__`\   /'_` \/\ '__`\  / __`\\ \ \   /'__`\
//     \ \ \/\ \L\.\_/\ \L\ \ \ \L\ \/\ \L\ \\_\ \_/\  __/
//      \ \_\ \__/.\_\ \___,_\ \ ,__/\ \____//\____\ \____\
//       \/_/\/__/\/_/\/__,_ /\ \ \/  \/___/ \/____/\/____/
//                             \ \_\
//                              \/_/
//
// 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 ofconditions 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 materialsprovided with the
//    distribution.
//
// 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 HOLDER 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.
#pragma once

#include <string>
#include <string_view>
#include <sstream>
#include <Common/Macros.hh>

namespace Tadpole {

class _Safe {};
class _Unsafe {};

using nil_t     = std::nullptr_t;
using byte_t    = std::uint8_t;
using i8_t      = std::int8_t;
using u8_t      = std::uint8_t;
using i16_t     = std::int16_t;
using u16_t     = std::uint16_t;
using i32_t     = std::int32_t;
using u32_t     = std::uint32_t;
using i64_t     = std::int64_t;
using u64_t     = std::uint64_t;
using sz_t      = std::size_t;
#if defined(TADPOLE_GNUC)
  using ssz_t   = std::ssize_t;
#else
  using ssz_t   = std::int64_t;
#endif
using str_t     = std::string;
using strv_t    = std::string_view;
using ss_t      = std::stringstream;
using safe_t    = _Safe;
using unsafe_t  = _Unsafe;

}
<|endoftext|>


<commit_before>// Copyright (c) 2019 ASMlover. All rights reserved.
//
// 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 ofconditions 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 materialsprovided with the
//    distribution.
//
// 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 HOLDER 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.
#include <sstream>
#include "../common/errors.hh"
#include "environment.hh"
#include "interpret_helper.hh"
#include "interpreter.hh"
#include "callable.hh"

namespace sage {

Function::Function(
    const FunctionStmtPtr& decl, const EnvironmentPtr& closure, bool is_ctor)
  : decl_(decl)
  , closure_(closure)
  , is_ctor_(is_ctor) {
}

std::string Function::name(void) const {
  return decl_->name().get_literal();
}

Value Function::call(
    const InterpreterPtr& interp, const std::vector<Value>& arguments) {
  auto envp = std::make_shared<Environment>(closure_);
  auto& params = decl_->params();
  std::size_t n{params.size()};
  for (std::size_t i = 0; i < n; ++i)
    envp->define(params[i].get_literal(), arguments[i]);

  try {
    interp->invoke_evaluate_block(decl_->body(), envp);
  }
  catch (const Return& r) {
    if (is_ctor_)
      return closure_->get_at(0, "self");
    return r.value();
  }
  if (is_ctor_)
    return closure_->get_at(0, "self");
  return nullptr;
}

std::size_t Function::arity(void) const {
  return decl_->params().size();
}

std::string Function::to_string(void) const {
  return "<script fn `" + decl_->name().get_literal() + "`>";
}

FunctionPtr Function::bind(const InstancePtr& inst) {
  auto envp = std::make_shared<Environment>(closure_);
  envp->define("self", Value(inst));
  return std::make_shared<Function>(decl_, envp, is_ctor_);
}

Class::Class(const std::string& name,
    const ClassPtr& superclass,
    const std::unordered_map<std::string, FunctionPtr>& methods)
  : name_(name)
  , superclass_(superclass)
  , methods_(methods) {
}

std::string Class::name(void) const {
  return name_;
}

Value Class::call(
    const InterpreterPtr& interp, const std::vector<Value>& arguments) {
  auto inst = std::make_shared<Instance>(shared_from_this());
  auto ctor = get_method(inst, "ctor");
  if (ctor)
    ctor->call(interp, arguments);
  return inst;
}

std::size_t Class::arity(void) const {
  auto method_iter = methods_.find("ctor");
  if (method_iter != methods_.end())
    return method_iter->second->arity();
  return 0;
}

std::string Class::to_string(void) const {
  return "<script class `" + name_ + "`>";
}

FunctionPtr Class::get_method(
    const InstancePtr& inst, const std::string& name) {
  auto method_iter = methods_.find(name);
  if (method_iter != methods_.end())
    return method_iter->second->bind(inst);
  return nullptr;
}

Instance::Instance(const ClassPtr& cls)
  : class_(cls) {
}

bool Instance::is_truthy(void) const {
  // TODO: default is true
  return true;
}

std::string Instance::to_string(void) const {
  std::stringstream ss;
  ss << "<`" << class_->name() << "` instance at " << this << ">";
  return ss.str();
}

void Instance::set_attribute(const Token& name, const Value& value) {
  attributes_[name.get_literal()] = value;
}

Value Instance::get_attribute(const Token& name) {
  auto attr_iter = attributes_.find(name.get_literal());
  if (attr_iter != attributes_.end())
    return attr_iter->second;

  auto method = class_->get_method(shared_from_this(), name.get_literal());
  if (method)
    return method;

  throw RuntimeError(name, "undefined attribute `" + name.get_literal() + "`");
}

}
<commit_msg>:construction: chore(inherit): add calling inheritance methods support<commit_after>// Copyright (c) 2019 ASMlover. All rights reserved.
//
// 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 ofconditions 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 materialsprovided with the
//    distribution.
//
// 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 HOLDER 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.
#include <sstream>
#include "../common/errors.hh"
#include "environment.hh"
#include "interpret_helper.hh"
#include "interpreter.hh"
#include "callable.hh"

namespace sage {

Function::Function(
    const FunctionStmtPtr& decl, const EnvironmentPtr& closure, bool is_ctor)
  : decl_(decl)
  , closure_(closure)
  , is_ctor_(is_ctor) {
}

std::string Function::name(void) const {
  return decl_->name().get_literal();
}

Value Function::call(
    const InterpreterPtr& interp, const std::vector<Value>& arguments) {
  auto envp = std::make_shared<Environment>(closure_);
  auto& params = decl_->params();
  std::size_t n{params.size()};
  for (std::size_t i = 0; i < n; ++i)
    envp->define(params[i].get_literal(), arguments[i]);

  try {
    interp->invoke_evaluate_block(decl_->body(), envp);
  }
  catch (const Return& r) {
    if (is_ctor_)
      return closure_->get_at(0, "self");
    return r.value();
  }
  if (is_ctor_)
    return closure_->get_at(0, "self");
  return nullptr;
}

std::size_t Function::arity(void) const {
  return decl_->params().size();
}

std::string Function::to_string(void) const {
  return "<script fn `" + decl_->name().get_literal() + "`>";
}

FunctionPtr Function::bind(const InstancePtr& inst) {
  auto envp = std::make_shared<Environment>(closure_);
  envp->define("self", Value(inst));
  return std::make_shared<Function>(decl_, envp, is_ctor_);
}

Class::Class(const std::string& name,
    const ClassPtr& superclass,
    const std::unordered_map<std::string, FunctionPtr>& methods)
  : name_(name)
  , superclass_(superclass)
  , methods_(methods) {
}

std::string Class::name(void) const {
  return name_;
}

Value Class::call(
    const InterpreterPtr& interp, const std::vector<Value>& arguments) {
  auto inst = std::make_shared<Instance>(shared_from_this());
  auto ctor = get_method(inst, "ctor");
  if (ctor)
    ctor->call(interp, arguments);
  return inst;
}

std::size_t Class::arity(void) const {
  auto method_iter = methods_.find("ctor");
  if (method_iter != methods_.end())
    return method_iter->second->arity();
  return 0;
}

std::string Class::to_string(void) const {
  return "<script class `" + name_ + "`>";
}

FunctionPtr Class::get_method(
    const InstancePtr& inst, const std::string& name) {
  auto method_iter = methods_.find(name);
  if (method_iter != methods_.end())
    return method_iter->second->bind(inst);
  if (superclass_)
    return superclass_->get_method(inst, name);
  return nullptr;
}

Instance::Instance(const ClassPtr& cls)
  : class_(cls) {
}

bool Instance::is_truthy(void) const {
  // TODO: default is true
  return true;
}

std::string Instance::to_string(void) const {
  std::stringstream ss;
  ss << "<`" << class_->name() << "` instance at " << this << ">";
  return ss.str();
}

void Instance::set_attribute(const Token& name, const Value& value) {
  attributes_[name.get_literal()] = value;
}

Value Instance::get_attribute(const Token& name) {
  auto attr_iter = attributes_.find(name.get_literal());
  if (attr_iter != attributes_.end())
    return attr_iter->second;

  auto method = class_->get_method(shared_from_this(), name.get_literal());
  if (method)
    return method;

  throw RuntimeError(name, "undefined attribute `" + name.get_literal() + "`");
}

}
<|endoftext|>


<commit_before>#include <iostream>
#include <sstream>
#include <vector>

#include <queue>
#include <map>
#include <boost/program_options.hpp>
#include <boost/shared_ptr.hpp>

#include "filelib.h"
#include "alignment_io.h"

namespace po = boost::program_options;
using namespace std;

struct Command {
  virtual ~Command() {}
  virtual string Name() const = 0;

  // returns 1 for alignment grid output [default]
  // returns 2 if Summary() should be called [for AER, etc]
  virtual int Result() const { return 1; }

  virtual bool RequiresTwoOperands() const { return true; }
  virtual void Apply(const Array2D<bool>& a, const Array2D<bool>& b, Array2D<bool>* x) = 0;
  void EnsureSize(const Array2D<bool>& a, const Array2D<bool>& b, Array2D<bool>* x) {
    x->resize(max(a.width(), b.width()), max(a.height(), b.height()));
  }
  static bool Safe(const Array2D<bool>& a, int i, int j) {
    if (i >= 0 && j >= 0 && i < static_cast<int>(a.width()) && j < static_cast<int>(a.height()))
      return a(i,j);
    else
      return false;
  }
  virtual void Summary() { assert(!"Summary should have been overridden"); }
};

// compute fmeasure, second alignment is reference, first is hyp
struct FMeasureCommand : public Command {
  FMeasureCommand() : matches(), num_predicted(), num_in_ref() {}
  int Result() const { return 2; }
  string Name() const { return "fmeasure"; }
  bool RequiresTwoOperands() const { return true; }
  void Apply(const Array2D<bool>& hyp, const Array2D<bool>& ref, Array2D<bool>* x) {
    (void) x;   // AER just computes statistics, not an alignment
    unsigned i_len = ref.width();
    unsigned j_len = ref.height();
    for (unsigned i = 0; i < i_len; ++i) {
      for (unsigned j = 0; j < j_len; ++j) {
        if (ref(i,j)) {
          ++num_in_ref;
          if (Safe(hyp, i, j)) ++matches;
        }
      }
    }
    for (unsigned i = 0; i < hyp.width(); ++i)
      for (unsigned j = 0; j < hyp.height(); ++j)
        if (hyp(i,j)) ++num_predicted;
  }
  void Summary() {
    if (num_predicted == 0 || num_in_ref == 0) {
      cerr << "Insufficient statistics to compute f-measure!\n";
      abort();
    }
    const double prec = static_cast<double>(matches) / num_predicted;
    const double rec = static_cast<double>(matches) / num_in_ref;
    cout << "P: " << prec << endl;
    cout << "R: " << rec << endl;
    const double f = (2.0 * prec * rec) / (rec + prec);
    cout << "F: " << f << endl;
  }
  int matches;
  int num_predicted;
  int num_in_ref;
};

struct DisplayCommand : public Command {
  string Name() const { return "display"; }
  bool RequiresTwoOperands() const { return false; }
  void Apply(const Array2D<bool>& in, const Array2D<bool>&, Array2D<bool>* x) {
    *x = in;
    cout << *x << endl;
  }
};

struct ConvertCommand : public Command {
  string Name() const { return "convert"; }
  bool RequiresTwoOperands() const { return false; }
  void Apply(const Array2D<bool>& in, const Array2D<bool>&, Array2D<bool>* x) {
    *x = in;
  }
};

struct InvertCommand : public Command {
  string Name() const { return "invert"; }
  bool RequiresTwoOperands() const { return false; }
  void Apply(const Array2D<bool>& in, const Array2D<bool>&, Array2D<bool>* x) {
    Array2D<bool>& res = *x;
    res.resize(in.height(), in.width());
    for (unsigned i = 0; i < in.height(); ++i)
      for (unsigned j = 0; j < in.width(); ++j)
        res(i, j) = in(j, i);
  }
};

struct IntersectCommand : public Command {
  string Name() const { return "intersect"; }
  bool RequiresTwoOperands() const { return true; }
  void Apply(const Array2D<bool>& a, const Array2D<bool>& b, Array2D<bool>* x) {
    EnsureSize(a, b, x);
    Array2D<bool>& res = *x;
    for (unsigned i = 0; i < a.width(); ++i)
      for (unsigned j = 0; j < a.height(); ++j)
        res(i, j) = Safe(a, i, j) && Safe(b, i, j);
  }
};

struct UnionCommand : public Command {
  string Name() const { return "union"; }
  bool RequiresTwoOperands() const { return true; }
  void Apply(const Array2D<bool>& a, const Array2D<bool>& b, Array2D<bool>* x) {
    EnsureSize(a, b, x);
    Array2D<bool>& res = *x;
    for (unsigned i = 0; i < res.width(); ++i)
      for (unsigned j = 0; j < res.height(); ++j)
        res(i, j) = Safe(a, i, j) || Safe(b, i, j);
  }
};

struct RefineCommand : public Command {
  RefineCommand() {
    neighbors_.push_back(make_pair(1,0));
    neighbors_.push_back(make_pair(-1,0));
    neighbors_.push_back(make_pair(0,1));
    neighbors_.push_back(make_pair(0,-1));
  }
  bool RequiresTwoOperands() const { return true; }

  void Align(unsigned i, unsigned j) {
    res_(i, j) = true;
    is_i_aligned_[i] = true;
    is_j_aligned_[j] = true;
  }

  bool IsNeighborAligned(int i, int j) const {
    for (unsigned k = 0; k < neighbors_.size(); ++k) {
      const int di = neighbors_[k].first;
      const int dj = neighbors_[k].second;
      if (Safe(res_, i + di, j + dj))
        return true;
    }
    return false;
  }

  bool IsNeitherAligned(int i, int j) const {
    return !(is_i_aligned_[i] || is_j_aligned_[j]);
  }

  bool IsOneOrBothUnaligned(int i, int j) const {
    return !(is_i_aligned_[i] && is_j_aligned_[j]);
  }

  bool KoehnAligned(int i, int j) const {
    return IsOneOrBothUnaligned(i, j) && IsNeighborAligned(i, j);
  }

  typedef bool (RefineCommand::*Predicate)(int i, int j) const;

 protected:
  void InitRefine(
      const Array2D<bool>& a,
      const Array2D<bool>& b) {
    res_.clear();
    EnsureSize(a, b, &res_);
    in_.clear(); un_.clear(); is_i_aligned_.clear(); is_j_aligned_.clear();
    EnsureSize(a, b, &in_);
    EnsureSize(a, b, &un_);
    is_i_aligned_.resize(res_.width(), false);
    is_j_aligned_.resize(res_.height(), false);
    for (unsigned i = 0; i < in_.width(); ++i)
      for (unsigned j = 0; j < in_.height(); ++j) {
        un_(i, j) = Safe(a, i, j) || Safe(b, i, j);
        in_(i, j) = Safe(a, i, j) && Safe(b, i, j);
        if (in_(i, j)) Align(i, j);
    }
  }
  // "grow" the resulting alignment using the points in adds
  // if they match the constraints determined by pred
  void Grow(Predicate pred, bool idempotent, const Array2D<bool>& adds) {
    if (idempotent) {
      for (unsigned i = 0; i < adds.width(); ++i)
        for (unsigned j = 0; j < adds.height(); ++j) {
          if (adds(i, j) && !res_(i, j) &&
              (this->*pred)(i, j)) Align(i, j);
        }
      return;
    }
    set<pair<int, int> > p;
    for (unsigned i = 0; i < adds.width(); ++i)
      for (unsigned j = 0; j < adds.height(); ++j)
        if (adds(i, j) && !res_(i, j))
          p.insert(make_pair(i, j));
    bool keep_going = !p.empty();
    while (keep_going) {
      keep_going = false;
      for (set<pair<int, int> >::iterator pi = p.begin();
           pi != p.end(); ++pi) {
        if ((this->*pred)(pi->first, pi->second)) {
          Align(pi->first, pi->second);
          p.erase(pi);
          keep_going = true;
        }
      }
    }
  }
  Array2D<bool> res_;  // refined alignment
  Array2D<bool> in_;   // intersection alignment
  Array2D<bool> un_;   // union alignment
  vector<bool> is_i_aligned_;
  vector<bool> is_j_aligned_;
  vector<pair<int,int> > neighbors_;
};

struct DiagCommand : public RefineCommand {
  DiagCommand() {
    neighbors_.push_back(make_pair(1,1));
    neighbors_.push_back(make_pair(-1,1));
    neighbors_.push_back(make_pair(1,-1));
    neighbors_.push_back(make_pair(-1,-1));
  }
};

struct GDCommand : public DiagCommand {
  string Name() const { return "grow-diag"; }
  void Apply(const Array2D<bool>& a, const Array2D<bool>& b, Array2D<bool>* x) {
    InitRefine(a, b);
    Grow(&RefineCommand::KoehnAligned, false, un_);
    *x = res_;
  }
};

struct GDFCommand : public DiagCommand {
  string Name() const { return "grow-diag-final"; }
  void Apply(const Array2D<bool>& a, const Array2D<bool>& b, Array2D<bool>* x) {
    InitRefine(a, b);
    Grow(&RefineCommand::KoehnAligned, false, un_);
    Grow(&RefineCommand::IsOneOrBothUnaligned, true, a);
    Grow(&RefineCommand::IsOneOrBothUnaligned, true, b);
    *x = res_;
  }
};

struct GDFACommand : public DiagCommand {
  string Name() const { return "grow-diag-final-and"; }
  void Apply(const Array2D<bool>& a, const Array2D<bool>& b, Array2D<bool>* x) {
    InitRefine(a, b);
    Grow(&RefineCommand::KoehnAligned, false, un_);
    Grow(&RefineCommand::IsNeitherAligned, true, a);
    Grow(&RefineCommand::IsNeitherAligned, true, b);
    *x = res_;
  }
};

map<string, boost::shared_ptr<Command> > commands;

void InitCommandLine(unsigned argc, char** argv, po::variables_map* conf) {
  po::options_description opts("Configuration options");
  ostringstream os;
  os << "Operation to perform:";
  for (map<string, boost::shared_ptr<Command> >::iterator it = commands.begin();
       it != commands.end(); ++it) {
    os << ' ' << it->first;
  }
  string cstr = os.str();
  opts.add_options()
        ("input_1,i", po::value<string>(), "[REQUIRED] Alignment 1 file, - for STDIN")
        ("input_2,j", po::value<string>(), "Alignment 2 file, - for STDIN")
	("command,c", po::value<string>()->default_value("convert"), cstr.c_str())
        ("help,h", "Print this help message and exit");
  po::options_description clo("Command line options");
  po::options_description dcmdline_options;
  dcmdline_options.add(opts);

  po::store(parse_command_line(argc, argv, dcmdline_options), *conf);
  po::notify(*conf);

  if (conf->count("help") || conf->count("input_1") == 0 || conf->count("command") == 0) {
    cerr << dcmdline_options << endl;
    exit(1);
  }
  const string cmd = (*conf)["command"].as<string>();
  if (commands.count(cmd) == 0) {
    cerr << "Don't understand command: " << cmd << endl;
    exit(1);
  }
  if (commands[cmd]->RequiresTwoOperands()) {
    if (conf->count("input_2") == 0) {
      cerr << "Command '" << cmd << "' requires two alignment files\n";
      exit(1);
    }
    if ((*conf)["input_1"].as<string>() == "-" && (*conf)["input_2"].as<string>() == "-") {
      cerr << "Both inputs STDIN, reading PAIRS of lines\n";
    }
  } else {
    if (conf->count("input_2") != 0) {
      cerr << "Command '" << cmd << "' requires only one alignment file\n";
      exit(1);
    }
  }
}

template<class C> static void AddCommand() {
  C* c = new C;
  commands[c->Name()].reset(c);
}

int main(int argc, char **argv) {
  AddCommand<ConvertCommand>();
  AddCommand<DisplayCommand>();
  AddCommand<InvertCommand>();
  AddCommand<IntersectCommand>();
  AddCommand<UnionCommand>();
  AddCommand<GDCommand>();
  AddCommand<GDFCommand>();
  AddCommand<GDFACommand>();
  AddCommand<FMeasureCommand>();
  po::variables_map conf;
  InitCommandLine(argc, argv, &conf);
  Command& cmd = *commands[conf["command"].as<string>()];
  boost::shared_ptr<ReadFile> rf1(new ReadFile(conf["input_1"].as<string>()));
  boost::shared_ptr<ReadFile> rf2;
  if (cmd.RequiresTwoOperands())
    rf2.reset(new ReadFile(conf["input_2"].as<string>()));
  istream* in1 = rf1->stream();
  istream* in2 = NULL;
  if (rf2) in2 = rf2->stream();
  while(*in1) {
    string line1;
    string line2;
    getline(*in1, line1);
    if (in2) {
      getline(*in2, line2);
      if ((*in1 && !*in2) || (*in2 && !*in1)) {
        cerr << "Mismatched number of lines!\n";
        exit(1);
      }
    }
    if (line1.empty() && !*in1) break;
    boost::shared_ptr<Array2D<bool> > out(new Array2D<bool>);
    boost::shared_ptr<Array2D<bool> > a1 = AlignmentIO::ReadPharaohAlignmentGrid(line1);
    if (in2) {
      boost::shared_ptr<Array2D<bool> > a2 = AlignmentIO::ReadPharaohAlignmentGrid(line2);
      cmd.Apply(*a1, *a2, out.get());
    } else {
      Array2D<bool> dummy;
      cmd.Apply(*a1, dummy, out.get());
    }

    if (cmd.Result() == 1) {
      AlignmentIO::SerializePharaohFormat(*out, &cout);
    }
  }
  if (cmd.Result() == 2)
    cmd.Summary();
  return 0;
}

<commit_msg>fix iterator misuse<commit_after>#include <iostream>
#include <sstream>
#include <vector>

#include <queue>
#include <map>
#include <boost/program_options.hpp>
#include <boost/shared_ptr.hpp>

#include "filelib.h"
#include "alignment_io.h"

namespace po = boost::program_options;
using namespace std;

struct Command {
  virtual ~Command() {}
  virtual string Name() const = 0;

  // returns 1 for alignment grid output [default]
  // returns 2 if Summary() should be called [for AER, etc]
  virtual int Result() const { return 1; }

  virtual bool RequiresTwoOperands() const { return true; }
  virtual void Apply(const Array2D<bool>& a, const Array2D<bool>& b, Array2D<bool>* x) = 0;
  void EnsureSize(const Array2D<bool>& a, const Array2D<bool>& b, Array2D<bool>* x) {
    x->resize(max(a.width(), b.width()), max(a.height(), b.height()));
  }
  static bool Safe(const Array2D<bool>& a, int i, int j) {
    if (i >= 0 && j >= 0 && i < static_cast<int>(a.width()) && j < static_cast<int>(a.height()))
      return a(i,j);
    else
      return false;
  }
  virtual void Summary() { assert(!"Summary should have been overridden"); }
};

// compute fmeasure, second alignment is reference, first is hyp
struct FMeasureCommand : public Command {
  FMeasureCommand() : matches(), num_predicted(), num_in_ref() {}
  int Result() const { return 2; }
  string Name() const { return "fmeasure"; }
  bool RequiresTwoOperands() const { return true; }
  void Apply(const Array2D<bool>& hyp, const Array2D<bool>& ref, Array2D<bool>* x) {
    (void) x;   // AER just computes statistics, not an alignment
    unsigned i_len = ref.width();
    unsigned j_len = ref.height();
    for (unsigned i = 0; i < i_len; ++i) {
      for (unsigned j = 0; j < j_len; ++j) {
        if (ref(i,j)) {
          ++num_in_ref;
          if (Safe(hyp, i, j)) ++matches;
        }
      }
    }
    for (unsigned i = 0; i < hyp.width(); ++i)
      for (unsigned j = 0; j < hyp.height(); ++j)
        if (hyp(i,j)) ++num_predicted;
  }
  void Summary() {
    if (num_predicted == 0 || num_in_ref == 0) {
      cerr << "Insufficient statistics to compute f-measure!\n";
      abort();
    }
    const double prec = static_cast<double>(matches) / num_predicted;
    const double rec = static_cast<double>(matches) / num_in_ref;
    cout << "P: " << prec << endl;
    cout << "R: " << rec << endl;
    const double f = (2.0 * prec * rec) / (rec + prec);
    cout << "F: " << f << endl;
  }
  int matches;
  int num_predicted;
  int num_in_ref;
};

struct DisplayCommand : public Command {
  string Name() const { return "display"; }
  bool RequiresTwoOperands() const { return false; }
  void Apply(const Array2D<bool>& in, const Array2D<bool>&, Array2D<bool>* x) {
    *x = in;
    cout << *x << endl;
  }
};

struct ConvertCommand : public Command {
  string Name() const { return "convert"; }
  bool RequiresTwoOperands() const { return false; }
  void Apply(const Array2D<bool>& in, const Array2D<bool>&, Array2D<bool>* x) {
    *x = in;
  }
};

struct InvertCommand : public Command {
  string Name() const { return "invert"; }
  bool RequiresTwoOperands() const { return false; }
  void Apply(const Array2D<bool>& in, const Array2D<bool>&, Array2D<bool>* x) {
    Array2D<bool>& res = *x;
    res.resize(in.height(), in.width());
    for (unsigned i = 0; i < in.height(); ++i)
      for (unsigned j = 0; j < in.width(); ++j)
        res(i, j) = in(j, i);
  }
};

struct IntersectCommand : public Command {
  string Name() const { return "intersect"; }
  bool RequiresTwoOperands() const { return true; }
  void Apply(const Array2D<bool>& a, const Array2D<bool>& b, Array2D<bool>* x) {
    EnsureSize(a, b, x);
    Array2D<bool>& res = *x;
    for (unsigned i = 0; i < a.width(); ++i)
      for (unsigned j = 0; j < a.height(); ++j)
        res(i, j) = Safe(a, i, j) && Safe(b, i, j);
  }
};

struct UnionCommand : public Command {
  string Name() const { return "union"; }
  bool RequiresTwoOperands() const { return true; }
  void Apply(const Array2D<bool>& a, const Array2D<bool>& b, Array2D<bool>* x) {
    EnsureSize(a, b, x);
    Array2D<bool>& res = *x;
    for (unsigned i = 0; i < res.width(); ++i)
      for (unsigned j = 0; j < res.height(); ++j)
        res(i, j) = Safe(a, i, j) || Safe(b, i, j);
  }
};

struct RefineCommand : public Command {
  RefineCommand() {
    neighbors_.push_back(make_pair(1,0));
    neighbors_.push_back(make_pair(-1,0));
    neighbors_.push_back(make_pair(0,1));
    neighbors_.push_back(make_pair(0,-1));
  }
  bool RequiresTwoOperands() const { return true; }

  void Align(unsigned i, unsigned j) {
    res_(i, j) = true;
    is_i_aligned_[i] = true;
    is_j_aligned_[j] = true;
  }

  bool IsNeighborAligned(int i, int j) const {
    for (unsigned k = 0; k < neighbors_.size(); ++k) {
      const int di = neighbors_[k].first;
      const int dj = neighbors_[k].second;
      if (Safe(res_, i + di, j + dj))
        return true;
    }
    return false;
  }

  bool IsNeitherAligned(int i, int j) const {
    return !(is_i_aligned_[i] || is_j_aligned_[j]);
  }

  bool IsOneOrBothUnaligned(int i, int j) const {
    return !(is_i_aligned_[i] && is_j_aligned_[j]);
  }

  bool KoehnAligned(int i, int j) const {
    return IsOneOrBothUnaligned(i, j) && IsNeighborAligned(i, j);
  }

  typedef bool (RefineCommand::*Predicate)(int i, int j) const;

 protected:
  void InitRefine(
      const Array2D<bool>& a,
      const Array2D<bool>& b) {
    res_.clear();
    EnsureSize(a, b, &res_);
    in_.clear(); un_.clear(); is_i_aligned_.clear(); is_j_aligned_.clear();
    EnsureSize(a, b, &in_);
    EnsureSize(a, b, &un_);
    is_i_aligned_.resize(res_.width(), false);
    is_j_aligned_.resize(res_.height(), false);
    for (unsigned i = 0; i < in_.width(); ++i)
      for (unsigned j = 0; j < in_.height(); ++j) {
        un_(i, j) = Safe(a, i, j) || Safe(b, i, j);
        in_(i, j) = Safe(a, i, j) && Safe(b, i, j);
        if (in_(i, j)) Align(i, j);
    }
  }
  // "grow" the resulting alignment using the points in adds
  // if they match the constraints determined by pred
  void Grow(Predicate pred, bool idempotent, const Array2D<bool>& adds) {
    if (idempotent) {
      for (unsigned i = 0; i < adds.width(); ++i)
        for (unsigned j = 0; j < adds.height(); ++j) {
          if (adds(i, j) && !res_(i, j) &&
              (this->*pred)(i, j)) Align(i, j);
        }
      return;
    }
    set<pair<int, int> > p;
    for (unsigned i = 0; i < adds.width(); ++i)
      for (unsigned j = 0; j < adds.height(); ++j)
        if (adds(i, j) && !res_(i, j))
          p.insert(make_pair(i, j));
    bool keep_going = !p.empty();
    while (keep_going) {
      keep_going = false;
      set<pair<int, int> > added;
      for (set<pair<int, int> >::iterator pi = p.begin(); pi != p.end(); ++pi) {
        if ((this->*pred)(pi->first, pi->second)) {
          Align(pi->first, pi->second);
          added.insert(make_pair(pi->first, pi->second));
          keep_going = true;
        }
      }
      for (set<pair<int, int> >::iterator ai = added.begin(); ai != added.end(); ++ai)
        p.erase(*ai);
    }
  }
  Array2D<bool> res_;  // refined alignment
  Array2D<bool> in_;   // intersection alignment
  Array2D<bool> un_;   // union alignment
  vector<bool> is_i_aligned_;
  vector<bool> is_j_aligned_;
  vector<pair<int,int> > neighbors_;
};

struct DiagCommand : public RefineCommand {
  DiagCommand() {
    neighbors_.push_back(make_pair(1,1));
    neighbors_.push_back(make_pair(-1,1));
    neighbors_.push_back(make_pair(1,-1));
    neighbors_.push_back(make_pair(-1,-1));
  }
};

struct GDCommand : public DiagCommand {
  string Name() const { return "grow-diag"; }
  void Apply(const Array2D<bool>& a, const Array2D<bool>& b, Array2D<bool>* x) {
    InitRefine(a, b);
    Grow(&RefineCommand::KoehnAligned, false, un_);
    *x = res_;
  }
};

struct GDFCommand : public DiagCommand {
  string Name() const { return "grow-diag-final"; }
  void Apply(const Array2D<bool>& a, const Array2D<bool>& b, Array2D<bool>* x) {
    InitRefine(a, b);
    Grow(&RefineCommand::KoehnAligned, false, un_);
    Grow(&RefineCommand::IsOneOrBothUnaligned, true, a);
    Grow(&RefineCommand::IsOneOrBothUnaligned, true, b);
    *x = res_;
  }
};

struct GDFACommand : public DiagCommand {
  string Name() const { return "grow-diag-final-and"; }
  void Apply(const Array2D<bool>& a, const Array2D<bool>& b, Array2D<bool>* x) {
    InitRefine(a, b);
    Grow(&RefineCommand::KoehnAligned, false, un_);
    Grow(&RefineCommand::IsNeitherAligned, true, a);
    Grow(&RefineCommand::IsNeitherAligned, true, b);
    *x = res_;
  }
};

map<string, boost::shared_ptr<Command> > commands;

void InitCommandLine(unsigned argc, char** argv, po::variables_map* conf) {
  po::options_description opts("Configuration options");
  ostringstream os;
  os << "Operation to perform:";
  for (map<string, boost::shared_ptr<Command> >::iterator it = commands.begin();
       it != commands.end(); ++it) {
    os << ' ' << it->first;
  }
  string cstr = os.str();
  opts.add_options()
        ("input_1,i", po::value<string>(), "[REQUIRED] Alignment 1 file, - for STDIN")
        ("input_2,j", po::value<string>(), "Alignment 2 file, - for STDIN")
	("command,c", po::value<string>()->default_value("convert"), cstr.c_str())
        ("help,h", "Print this help message and exit");
  po::options_description clo("Command line options");
  po::options_description dcmdline_options;
  dcmdline_options.add(opts);

  po::store(parse_command_line(argc, argv, dcmdline_options), *conf);
  po::notify(*conf);

  if (conf->count("help") || conf->count("input_1") == 0 || conf->count("command") == 0) {
    cerr << dcmdline_options << endl;
    exit(1);
  }
  const string cmd = (*conf)["command"].as<string>();
  if (commands.count(cmd) == 0) {
    cerr << "Don't understand command: " << cmd << endl;
    exit(1);
  }
  if (commands[cmd]->RequiresTwoOperands()) {
    if (conf->count("input_2") == 0) {
      cerr << "Command '" << cmd << "' requires two alignment files\n";
      exit(1);
    }
    if ((*conf)["input_1"].as<string>() == "-" && (*conf)["input_2"].as<string>() == "-") {
      cerr << "Both inputs STDIN, reading PAIRS of lines\n";
    }
  } else {
    if (conf->count("input_2") != 0) {
      cerr << "Command '" << cmd << "' requires only one alignment file\n";
      exit(1);
    }
  }
}

template<class C> static void AddCommand() {
  C* c = new C;
  commands[c->Name()].reset(c);
}

int main(int argc, char **argv) {
  AddCommand<ConvertCommand>();
  AddCommand<DisplayCommand>();
  AddCommand<InvertCommand>();
  AddCommand<IntersectCommand>();
  AddCommand<UnionCommand>();
  AddCommand<GDCommand>();
  AddCommand<GDFCommand>();
  AddCommand<GDFACommand>();
  AddCommand<FMeasureCommand>();
  po::variables_map conf;
  InitCommandLine(argc, argv, &conf);
  Command& cmd = *commands[conf["command"].as<string>()];
  boost::shared_ptr<ReadFile> rf1(new ReadFile(conf["input_1"].as<string>()));
  boost::shared_ptr<ReadFile> rf2;
  if (cmd.RequiresTwoOperands())
    rf2.reset(new ReadFile(conf["input_2"].as<string>()));
  istream* in1 = rf1->stream();
  istream* in2 = NULL;
  if (rf2) in2 = rf2->stream();
  while(*in1) {
    string line1;
    string line2;
    getline(*in1, line1);
    if (in2) {
      getline(*in2, line2);
      if ((*in1 && !*in2) || (*in2 && !*in1)) {
        cerr << "Mismatched number of lines!\n";
        exit(1);
      }
    }
    if (line1.empty() && !*in1) break;
    boost::shared_ptr<Array2D<bool> > out(new Array2D<bool>);
    boost::shared_ptr<Array2D<bool> > a1 = AlignmentIO::ReadPharaohAlignmentGrid(line1);
    if (in2) {
      boost::shared_ptr<Array2D<bool> > a2 = AlignmentIO::ReadPharaohAlignmentGrid(line2);
      cmd.Apply(*a1, *a2, out.get());
    } else {
      Array2D<bool> dummy;
      cmd.Apply(*a1, dummy, out.get());
    }

    if (cmd.Result() == 1) {
      AlignmentIO::SerializePharaohFormat(*out, &cout);
    }
  }
  if (cmd.Result() == 2)
    cmd.Summary();
  return 0;
}

<|endoftext|>


<commit_before><commit_msg>INTEGRATION: CWS sdk02 (1.1.32); FILE MERGED 2003/05/28 12:48:37 np 1.1.32.1: #108925#<commit_after><|endoftext|>


<commit_before>/****************************************************************************
**
** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
** All rights reserved.
** Contact: Nokia Corporation (qt-info@nokia.com)
**
** This file is part of the QtDeclarative module of the Qt Toolkit.
**
** $QT_BEGIN_LICENSE:LGPL$
** No Commercial Usage
** This file contains pre-release code and may not be distributed.
** You may use this file in accordance with the terms and conditions
** contained in the Technology Preview License Agreement accompanying
** this package.
**
** GNU Lesser General Public License Usage
** Alternatively, this file may be used under the terms of the GNU Lesser
** General Public License version 2.1 as published by the Free Software
** Foundation and appearing in the file LICENSE.LGPL included in the
** packaging of this file.  Please review the following information to
** ensure the GNU Lesser General Public License version 2.1 requirements
** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
**
** In addition, as a special exception, Nokia gives you certain additional
** rights.  These rights are described in the Nokia Qt LGPL Exception
** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
**
** If you have questions regarding the use of this file, please contact
** Nokia at qt-info@nokia.com.
**
**
**
**
**
**
**
**
** $QT_END_LICENSE$
**
****************************************************************************/

#include "qmlostplugin.h"
#include "qostdevice.h"

#include <private/qdeclarativedebugserver_p.h>
#include <private/qpacketprotocol_p.h>

QT_BEGIN_NAMESPACE

static const TInt KQmlOstProtocolId = 0x94;

class QmlOstPluginPrivate {
public:
    QmlOstPluginPrivate();

    QOstDevice *ost;
    QPacketProtocol *protocol;
    QDeclarativeDebugServer *debugServer;
};

QmlOstPluginPrivate::QmlOstPluginPrivate() :
    ost(0),
    protocol(0),
    debugServer(0)
{
}

QmlOstPlugin::QmlOstPlugin() :
    d_ptr(new QmlOstPluginPrivate)
{
}

QmlOstPlugin::~QmlOstPlugin()
{
    delete d_ptr;
}

void QmlOstPlugin::setServer(QDeclarativeDebugServer *server)
{
    Q_D(QmlOstPlugin);
    d->debugServer = server;
}

bool QmlOstPlugin::isConnected() const
{
    Q_D(const QmlOstPlugin);
    return d->ost && d->ost->isOpen();
}

void QmlOstPlugin::send(const QByteArray &message)
{
    Q_D(QmlOstPlugin);

    if (!isConnected())
        return;

    QPacket pack;
    pack.writeRawData(message.data(), message.length());

    d->protocol->send(pack);
    //d->socket->flush();
}

void QmlOstPlugin::disconnect()
{
    Q_D(QmlOstPlugin);

    delete d->protocol;
    d->protocol = 0;
}

void QmlOstPlugin::waitForMessage()
{
    Q_D(QmlOstPlugin);
    d->protocol->waitForReadyRead(-1);
}

void QmlOstPlugin::setPort(int port, bool block)
{
    Q_UNUSED(port);
    Q_UNUSED(block);

    Q_D(QmlOstPlugin);

    d->ost = new QOstDevice(this);
    bool ok = d->ost->open(KQmlOstProtocolId);
    if (!ok) {
        if (d->ost->errorString().length())
            qDebug("Error from QOstDevice: %s", qPrintable(d->ost->errorString()));
        qWarning("QDeclarativeDebugServer: Unable to listen on OST"); // This message is part of the signalling - do not change the format!
        return;
    }
    d->protocol = new QPacketProtocol(d->ost, this);
    QObject::connect(d->protocol, SIGNAL(readyRead()), this, SLOT(readyRead()));
    qWarning("QDeclarativeDebugServer: Waiting for connection via OST"); // This message is part of the signalling - do not change the format!
}

void QmlOstPlugin::readyRead()
{
    Q_D(QmlOstPlugin);
    QPacket packet = d->protocol->read();

    QByteArray content = packet.data();
    d->debugServer->receiveMessage(content);
}

Q_EXPORT_PLUGIN2(qmlostplugin, QmlOstPlugin)

QT_END_NAMESPACE
<commit_msg>QmlDebug: Fix QmlOstPlugin compilation failure<commit_after>/****************************************************************************
**
** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
** All rights reserved.
** Contact: Nokia Corporation (qt-info@nokia.com)
**
** This file is part of the QtDeclarative module of the Qt Toolkit.
**
** $QT_BEGIN_LICENSE:LGPL$
** No Commercial Usage
** This file contains pre-release code and may not be distributed.
** You may use this file in accordance with the terms and conditions
** contained in the Technology Preview License Agreement accompanying
** this package.
**
** GNU Lesser General Public License Usage
** Alternatively, this file may be used under the terms of the GNU Lesser
** General Public License version 2.1 as published by the Free Software
** Foundation and appearing in the file LICENSE.LGPL included in the
** packaging of this file.  Please review the following information to
** ensure the GNU Lesser General Public License version 2.1 requirements
** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
**
** In addition, as a special exception, Nokia gives you certain additional
** rights.  These rights are described in the Nokia Qt LGPL Exception
** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
**
** If you have questions regarding the use of this file, please contact
** Nokia at qt-info@nokia.com.
**
**
**
**
**
**
**
**
** $QT_END_LICENSE$
**
****************************************************************************/

#include "qmlostplugin.h"
#include "qostdevice.h"

#include <private/qdeclarativedebugserver_p.h>
#include <private/qpacketprotocol_p.h>

QT_BEGIN_NAMESPACE

static const TInt KQmlOstProtocolId = 0x94;

class QmlOstPluginPrivate {
public:
    QmlOstPluginPrivate();

    QOstDevice *ost;
    QPacketProtocol *protocol;
    QDeclarativeDebugServer *debugServer;
};

QmlOstPluginPrivate::QmlOstPluginPrivate() :
    ost(0),
    protocol(0),
    debugServer(0)
{
}

QmlOstPlugin::QmlOstPlugin() :
    d_ptr(new QmlOstPluginPrivate)
{
}

QmlOstPlugin::~QmlOstPlugin()
{
    delete d_ptr;
}

void QmlOstPlugin::setServer(QDeclarativeDebugServer *server)
{
    Q_D(QmlOstPlugin);
    d->debugServer = server;
}

bool QmlOstPlugin::isConnected() const
{
    Q_D(const QmlOstPlugin);
    return d->ost && d->ost->isOpen();
}

void QmlOstPlugin::send(const QByteArray &message)
{
    Q_D(QmlOstPlugin);

    if (!isConnected())
        return;

    QPacket pack;
    pack.writeRawData(message.data(), message.length());

    d->protocol->send(pack);
    //d->socket->flush();
}

void QmlOstPlugin::disconnect()
{
    Q_D(QmlOstPlugin);

    delete d->protocol;
    d->protocol = 0;
}

bool QmlOstPlugin::waitForMessage()
{
    Q_D(QmlOstPlugin);
    return d->protocol->waitForReadyRead(-1);
}

void QmlOstPlugin::setPort(int port, bool block)
{
    Q_UNUSED(port);
    Q_UNUSED(block);

    Q_D(QmlOstPlugin);

    d->ost = new QOstDevice(this);
    bool ok = d->ost->open(KQmlOstProtocolId);
    if (!ok) {
        if (d->ost->errorString().length())
            qDebug("Error from QOstDevice: %s", qPrintable(d->ost->errorString()));
        qWarning("QDeclarativeDebugServer: Unable to listen on OST"); // This message is part of the signalling - do not change the format!
        return;
    }
    d->protocol = new QPacketProtocol(d->ost, this);
    QObject::connect(d->protocol, SIGNAL(readyRead()), this, SLOT(readyRead()));
    qWarning("QDeclarativeDebugServer: Waiting for connection via OST"); // This message is part of the signalling - do not change the format!
}

void QmlOstPlugin::readyRead()
{
    Q_D(QmlOstPlugin);
    QPacket packet = d->protocol->read();

    QByteArray content = packet.data();
    d->debugServer->receiveMessage(content);
}

Q_EXPORT_PLUGIN2(qmlostplugin, QmlOstPlugin)

QT_END_NAMESPACE
<|endoftext|>