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

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

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

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

#include "tensorflow/compiler/mlir/tfrt/translate/import_model.h"

#include "absl/strings/match.h"
#include "mlir/IR/Builders.h"  // from @llvm-project
#include "mlir/IR/MLIRContext.h"  // from @llvm-project
#include "tensorflow/compiler/mlir/tensorflow/transforms/bridge.h"
#include "tensorflow/compiler/mlir/tensorflow/translate/import_model.h"
#include "tensorflow/compiler/mlir/tensorflow/utils/dump_mlir_util.h"
#include "tensorflow/compiler/mlir/tensorflow/utils/error_util.h"
#include "tensorflow/compiler/mlir/tfrt/transforms/passes.h"
#include "tensorflow/compiler/mlir/tfrt/translate/tfrt_compile_options.h"
#include "tensorflow/core/common_runtime/function_body.h"
#include "tensorflow/core/common_runtime/function_def_utils.h"
#include "tfrt/bef_converter/mlir_to_bef.h"  // from @tf_runtime

namespace tensorflow {

Status ConvertFunctionToBef(
    mlir::StringRef function_name, const tensorflow::FunctionBody* fbody,
    const FunctionLibraryDefinition& flib_def,
    tfrt::ArrayRef<tfrt::string_view> devices,
    const tensorflow::TfrtFunctionCompileOptions& options,
    tfrt::BefBuffer* bef_buffer) {
  mlir::MLIRContext context;
  // FunctionDef -> TF Dialect
  auto expected_module =
      tensorflow::ConvertFunctionToMlir(fbody, flib_def, &context);

  if (!expected_module.ok())
    return tensorflow::errors::Internal(
        "Failed to convert function to mlir for function ", function_name.str(),
        ". Error: ", expected_module.status().error_message());

  auto module = expected_module.ConsumeValueOrDie();

  // Attach devices to the MLIR module.
  if (!devices.empty()) {
    mlir::Builder builder(module->getContext());
    module->getOperation()->setAttr("tf.devices",
                                    builder.getStrArrayAttr(devices));
  }

  // TF Dialect -> BEF
  return tensorflow::CompileTFMLIRToBEF(options, module.get(), bef_buffer);
}

Status ConvertTfMlirToBef(const TfrtCompileOptions& options,
                          mlir::ModuleOp module, tfrt::BefBuffer* bef_buffer) {
  mlir::StatusScopedDiagnosticHandler diag_handler(module.getContext());

  if (options.tpu_target == TfrtTpuInfraTarget::kTpurt) {
    VLOG(1) << "Running MLIR TPU bridge for tpurt";
    if (VLOG_IS_ON(1)) {
      tensorflow::DumpMlirOpToFile("tpu_bct_conversion_before", module);
    }

    TfrtTpuCompileOptions tpu_compile_options;
    tpu_compile_options.move_resource_gather_to_host =
        options.tpu_move_resource_gather_to_host;

    auto backward_compat_result =
        tensorflow::RunTPUBackwardCompatConversion(module, tpu_compile_options);
    if (mlir::failed(backward_compat_result)) {
      return diag_handler.Combine(
          tensorflow::errors::Internal("Failed to handle legacy TPU Ops"));
    }

    if (VLOG_IS_ON(1)) {
      tensorflow::DumpMlirOpToFile("tpu_bct_conversion_after", module);
    }

    TF_RETURN_IF_ERROR(
        mlir::TFTPU::TPUBridge(module, /*enable_logging=*/VLOG_IS_ON(1)));
  }

  if (VLOG_IS_ON(1)) {
    tensorflow::DumpMlirOpToFile("tf_dialect", module);
  }

  // Lower MLIR TF Dialect to MLIR TFRT CoreRT dialect.
  mlir::PassManager pm(module.getContext());

  tensorflow::TfrtPipelineOptions pass_options;
  if (!options.default_device.empty()) {
    pass_options.default_device = options.default_device;
  }
  if (!options.force_data_format.empty()) {
    pass_options.force_data_format = options.force_data_format;
  }

  // TODO(b/187991150): Consider only decomposing read-only resource variable
  // ops.
  pass_options.decompose_resource_ops = true;
  pass_options.enable_optimizer = options.enable_optimizer;
  pass_options.enable_native_ops = options.enable_native_ops;
  pass_options.target_tpurt =
      (options.tpu_target == TfrtTpuInfraTarget::kTpurt);
  pass_options.tpu_fuse_ops = options.tpu_fuse_ops;
  pass_options.use_tpu_host_allocator_for_inputs =
      options.use_tpu_host_allocator_for_inputs;
  pass_options.hoist_invariant_ops = options.hoist_invariant_ops;
  pass_options.func_use_fallback_tensor = true;
  pass_options.auto_fusion_oplist = options.auto_fusion_oplist;
  pass_options.auto_fusion_min_cluster_size =
      options.auto_fusion_min_cluster_size;
  pass_options.cost_threshold = options.cost_threshold;
  pass_options.upper_cost_threshold = options.upper_cost_threshold;
  pass_options.merge_inter_dependent_streams =
      options.merge_inter_dependent_streams;
  tensorflow::CreateTfExecutorToTfrtPipeline(pm, pass_options);

  if (mlir::failed(pm.run(module)))
    return diag_handler.Combine(tensorflow::errors::Internal(
        "failed to lower TF Dialect to CoreRT dialect."));

  if (VLOG_IS_ON(1)) {
    tensorflow::DumpMlirOpToFile("tfrt_dialect", module);
  }

  *bef_buffer =
      tfrt::ConvertMLIRToBEF(module, /*disable_optional_sections=*/true);
  if (bef_buffer->empty())
    return diag_handler.Combine(
        tensorflow::errors::Internal("failed to convert MLIR to BEF."));

  bef_buffer->shrink_to_fit();

  return Status::OK();
}

}  // namespace tensorflow
<commit_msg>Add 'tfrt-tpu-partitioned-call-fallback-compat' pipeline to support TFRT fallback execution of TPUPartitionedCallOp.<commit_after>/* Copyright 2021 The TensorFlow Authors. All Rights Reserved.

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

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

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

#include "tensorflow/compiler/mlir/tfrt/translate/import_model.h"

#include "absl/strings/match.h"
#include "mlir/IR/Builders.h"  // from @llvm-project
#include "mlir/IR/MLIRContext.h"  // from @llvm-project
#include "tensorflow/compiler/mlir/tensorflow/transforms/bridge.h"
#include "tensorflow/compiler/mlir/tensorflow/translate/import_model.h"
#include "tensorflow/compiler/mlir/tensorflow/utils/dump_mlir_util.h"
#include "tensorflow/compiler/mlir/tensorflow/utils/error_util.h"
#include "tensorflow/compiler/mlir/tfrt/transforms/passes.h"
#include "tensorflow/compiler/mlir/tfrt/translate/tfrt_compile_options.h"
#include "tensorflow/core/common_runtime/function_body.h"
#include "tensorflow/core/common_runtime/function_def_utils.h"
#include "tfrt/bef_converter/mlir_to_bef.h"  // from @tf_runtime

namespace tensorflow {

Status ConvertFunctionToBef(
    mlir::StringRef function_name, const tensorflow::FunctionBody* fbody,
    const FunctionLibraryDefinition& flib_def,
    tfrt::ArrayRef<tfrt::string_view> devices,
    const tensorflow::TfrtFunctionCompileOptions& options,
    tfrt::BefBuffer* bef_buffer) {
  mlir::MLIRContext context;
  // FunctionDef -> TF Dialect
  auto expected_module =
      tensorflow::ConvertFunctionToMlir(fbody, flib_def, &context);

  if (!expected_module.ok())
    return tensorflow::errors::Internal(
        "Failed to convert function to mlir for function ", function_name.str(),
        ". Error: ", expected_module.status().error_message());

  auto module = expected_module.ConsumeValueOrDie();

  // Attach devices to the MLIR module.
  if (!devices.empty()) {
    mlir::Builder builder(module->getContext());
    module->getOperation()->setAttr("tf.devices",
                                    builder.getStrArrayAttr(devices));
  }

  // TF Dialect -> BEF
  return tensorflow::CompileTFMLIRToBEF(options, module.get(), bef_buffer);
}

Status ConvertTfMlirToBef(const TfrtCompileOptions& options,
                          mlir::ModuleOp module, tfrt::BefBuffer* bef_buffer) {
  mlir::StatusScopedDiagnosticHandler diag_handler(module.getContext());

  if (options.tpu_target == TfrtTpuInfraTarget::kTpurt) {
    VLOG(1) << "Running MLIR TPU bridge for tpurt";
    if (VLOG_IS_ON(1)) {
      tensorflow::DumpMlirOpToFile("tpu_bct_conversion_before", module);
    }

    TfrtTpuCompileOptions tpu_compile_options;
    tpu_compile_options.move_resource_gather_to_host =
        options.tpu_move_resource_gather_to_host;

    auto backward_compat_result =
        tensorflow::RunTPUBackwardCompatConversion(module, tpu_compile_options);
    if (mlir::failed(backward_compat_result)) {
      return diag_handler.Combine(
          tensorflow::errors::Internal("Failed to handle legacy TPU Ops"));
    }

    if (VLOG_IS_ON(1)) {
      tensorflow::DumpMlirOpToFile("tpu_bct_conversion_after", module);
    }

    TF_RETURN_IF_ERROR(
        mlir::TFTPU::TPUBridge(module, /*enable_logging=*/VLOG_IS_ON(1)));
  } else if (options.tpu_target == TfrtTpuInfraTarget::kTfFallback) {
    auto tpu_partitioned_call_fallback_compat_result =
        tensorflow::RunTPUPartitionedCallFallbackCompatConversion(module);
    if (mlir::failed(tpu_partitioned_call_fallback_compat_result)) {
      return diag_handler.Combine(tensorflow::errors::Internal(
          "Failed to process TPUPartitionedCallOp for fallback execution"));
    }
  }

  if (VLOG_IS_ON(1)) {
    tensorflow::DumpMlirOpToFile("tf_dialect", module);
  }

  // Lower MLIR TF Dialect to MLIR TFRT CoreRT dialect.
  mlir::PassManager pm(module.getContext());

  tensorflow::TfrtPipelineOptions pass_options;
  if (!options.default_device.empty()) {
    pass_options.default_device = options.default_device;
  }
  if (!options.force_data_format.empty()) {
    pass_options.force_data_format = options.force_data_format;
  }

  // TODO(b/187991150): Consider only decomposing read-only resource variable
  // ops.
  pass_options.decompose_resource_ops = true;
  pass_options.enable_optimizer = options.enable_optimizer;
  pass_options.enable_native_ops = options.enable_native_ops;
  pass_options.target_tpurt =
      (options.tpu_target == TfrtTpuInfraTarget::kTpurt);
  pass_options.tpu_fuse_ops = options.tpu_fuse_ops;
  pass_options.use_tpu_host_allocator_for_inputs =
      options.use_tpu_host_allocator_for_inputs;
  pass_options.hoist_invariant_ops = options.hoist_invariant_ops;
  pass_options.func_use_fallback_tensor = true;
  pass_options.auto_fusion_oplist = options.auto_fusion_oplist;
  pass_options.auto_fusion_min_cluster_size =
      options.auto_fusion_min_cluster_size;
  pass_options.cost_threshold = options.cost_threshold;
  pass_options.upper_cost_threshold = options.upper_cost_threshold;
  pass_options.merge_inter_dependent_streams =
      options.merge_inter_dependent_streams;
  tensorflow::CreateTfExecutorToTfrtPipeline(pm, pass_options);

  if (mlir::failed(pm.run(module)))
    return diag_handler.Combine(tensorflow::errors::Internal(
        "failed to lower TF Dialect to CoreRT dialect."));

  if (VLOG_IS_ON(1)) {
    tensorflow::DumpMlirOpToFile("tfrt_dialect", module);
  }

  *bef_buffer =
      tfrt::ConvertMLIRToBEF(module, /*disable_optional_sections=*/true);
  if (bef_buffer->empty())
    return diag_handler.Combine(
        tensorflow::errors::Internal("failed to convert MLIR to BEF."));

  bef_buffer->shrink_to_fit();

  return Status::OK();
}

}  // namespace tensorflow
<|endoftext|>


<commit_before>/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
/*
 * This file is part of the LibreOffice project.
 *
 * This Source Code Form is subject to the terms of the Mozilla Public
 * License, v. 2.0. If a copy of the MPL was not distributed with this
 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
 *
 * This file incorporates work covered by the following license notice:
 *
 *   Licensed to the Apache Software Foundation (ASF) under one or more
 *   contributor license agreements. See the NOTICE file distributed
 *   with this work for additional information regarding copyright
 *   ownership. The ASF licenses this file to you 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 .
 */

#ifndef _VCL_GTKINST_HXX
#define _VCL_GTKINST_HXX

#include <boost/shared_ptr.hpp>

#include <unx/salinst.h>
#include <generic/gensys.h>
#include <headless/svpinst.hxx>
#include <gtk/gtk.h>

namespace vcl
{
namespace unx
{
class GtkPrintWrapper;
}
}

class GenPspGraphics;
class GtkYieldMutex : public SalYieldMutex
{
    std::list<sal_uLong> aYieldStack;

public:
                        GtkYieldMutex();
    virtual void        acquire();
    virtual void        release();
    virtual bool        tryToAcquire()  { return SalYieldMutex::tryToAcquire(); }

    void ThreadsEnter();
    void ThreadsLeave();
};

class GtkSalTimer;
#if GTK_CHECK_VERSION(3,0,0)
class GtkInstance : public SvpSalInstance
#else
class GtkInstance : public X11SalInstance
#endif
{
#if GTK_CHECK_VERSION(3,0,0)
    typedef SvpSalInstance Superclass_t;
#else
    typedef X11SalInstance Superclass_t;
#endif
public:
            GtkInstance( SalYieldMutex* pMutex );
    virtual ~GtkInstance();
    void    Init();

    virtual SalFrame*           CreateFrame( SalFrame* pParent, sal_uLong nStyle );
    virtual SalFrame*           CreateChildFrame( SystemParentData* pParent, sal_uLong nStyle );
    virtual SalObject*          CreateObject( SalFrame* pParent, SystemWindowData* pWindowData, sal_Bool bShow = sal_True );
    virtual SalSystem*          CreateSalSystem();
    virtual SalInfoPrinter*     CreateInfoPrinter(SalPrinterQueueInfo* pPrinterQueueInfo, ImplJobSetup* pJobSetup);
    virtual SalPrinter*         CreatePrinter( SalInfoPrinter* pInfoPrinter );
    virtual SalMenu*            CreateMenu( sal_Bool, Menu* );
    virtual void                DestroyMenu( SalMenu* pMenu );
    virtual SalMenuItem*        CreateMenuItem( const SalItemParams* );
    virtual void                DestroyMenuItem( SalMenuItem* pItem );
    virtual SalTimer*           CreateSalTimer();
    virtual void                AddToRecentDocumentList(const OUString& rFileUrl, const OUString& rMimeType);
    virtual SalVirtualDevice*   CreateVirtualDevice( SalGraphics*,
                                                     long nDX, long nDY,
                                                     sal_uInt16 nBitCount,
                                                     const SystemGraphicsData* );
    virtual SalBitmap*          CreateSalBitmap();

    virtual void                Yield( bool bWait, bool bHandleAllCurrentEvents );
    virtual bool                AnyInput( sal_uInt16 nType );

    virtual GenPspGraphics     *CreatePrintGraphics();

    virtual bool hasNativeFileSelection() const { return true; }

    virtual com::sun::star::uno::Reference< com::sun::star::ui::dialogs::XFilePicker2 >
        createFilePicker( const com::sun::star::uno::Reference<
                              com::sun::star::uno::XComponentContext >& );
    virtual com::sun::star::uno::Reference< com::sun::star::ui::dialogs::XFolderPicker2 >
        createFolderPicker( const com::sun::star::uno::Reference<
                                com::sun::star::uno::XComponentContext >& );

    void                        RemoveTimer (SalTimer *pTimer);

    // for managing a mirror of the in-flight un-dispatched gdk event queue
    void                        addEvent( sal_uInt16 nMask );
    void                        subtractEvent( sal_uInt16 nMask );

    boost::shared_ptr<vcl::unx::GtkPrintWrapper> getPrintWrapper() const;
  private:
    std::vector<GtkSalTimer *>  m_aTimers;
    bool                        IsTimerExpired();

    mutable boost::shared_ptr<vcl::unx::GtkPrintWrapper> m_pPrintWrapper;
};

#endif // _VCL_GTKINST_HXX

/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
<commit_msg>Remove redundant override<commit_after>/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
/*
 * This file is part of the LibreOffice project.
 *
 * This Source Code Form is subject to the terms of the Mozilla Public
 * License, v. 2.0. If a copy of the MPL was not distributed with this
 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
 *
 * This file incorporates work covered by the following license notice:
 *
 *   Licensed to the Apache Software Foundation (ASF) under one or more
 *   contributor license agreements. See the NOTICE file distributed
 *   with this work for additional information regarding copyright
 *   ownership. The ASF licenses this file to you 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 .
 */

#ifndef _VCL_GTKINST_HXX
#define _VCL_GTKINST_HXX

#include <boost/shared_ptr.hpp>

#include <unx/salinst.h>
#include <generic/gensys.h>
#include <headless/svpinst.hxx>
#include <gtk/gtk.h>

namespace vcl
{
namespace unx
{
class GtkPrintWrapper;
}
}

class GenPspGraphics;
class GtkYieldMutex : public SalYieldMutex
{
    std::list<sal_uLong> aYieldStack;

public:
                        GtkYieldMutex();
    virtual void        acquire();
    virtual void        release();

    void ThreadsEnter();
    void ThreadsLeave();
};

class GtkSalTimer;
#if GTK_CHECK_VERSION(3,0,0)
class GtkInstance : public SvpSalInstance
#else
class GtkInstance : public X11SalInstance
#endif
{
#if GTK_CHECK_VERSION(3,0,0)
    typedef SvpSalInstance Superclass_t;
#else
    typedef X11SalInstance Superclass_t;
#endif
public:
            GtkInstance( SalYieldMutex* pMutex );
    virtual ~GtkInstance();
    void    Init();

    virtual SalFrame*           CreateFrame( SalFrame* pParent, sal_uLong nStyle );
    virtual SalFrame*           CreateChildFrame( SystemParentData* pParent, sal_uLong nStyle );
    virtual SalObject*          CreateObject( SalFrame* pParent, SystemWindowData* pWindowData, sal_Bool bShow = sal_True );
    virtual SalSystem*          CreateSalSystem();
    virtual SalInfoPrinter*     CreateInfoPrinter(SalPrinterQueueInfo* pPrinterQueueInfo, ImplJobSetup* pJobSetup);
    virtual SalPrinter*         CreatePrinter( SalInfoPrinter* pInfoPrinter );
    virtual SalMenu*            CreateMenu( sal_Bool, Menu* );
    virtual void                DestroyMenu( SalMenu* pMenu );
    virtual SalMenuItem*        CreateMenuItem( const SalItemParams* );
    virtual void                DestroyMenuItem( SalMenuItem* pItem );
    virtual SalTimer*           CreateSalTimer();
    virtual void                AddToRecentDocumentList(const OUString& rFileUrl, const OUString& rMimeType);
    virtual SalVirtualDevice*   CreateVirtualDevice( SalGraphics*,
                                                     long nDX, long nDY,
                                                     sal_uInt16 nBitCount,
                                                     const SystemGraphicsData* );
    virtual SalBitmap*          CreateSalBitmap();

    virtual void                Yield( bool bWait, bool bHandleAllCurrentEvents );
    virtual bool                AnyInput( sal_uInt16 nType );

    virtual GenPspGraphics     *CreatePrintGraphics();

    virtual bool hasNativeFileSelection() const { return true; }

    virtual com::sun::star::uno::Reference< com::sun::star::ui::dialogs::XFilePicker2 >
        createFilePicker( const com::sun::star::uno::Reference<
                              com::sun::star::uno::XComponentContext >& );
    virtual com::sun::star::uno::Reference< com::sun::star::ui::dialogs::XFolderPicker2 >
        createFolderPicker( const com::sun::star::uno::Reference<
                                com::sun::star::uno::XComponentContext >& );

    void                        RemoveTimer (SalTimer *pTimer);

    // for managing a mirror of the in-flight un-dispatched gdk event queue
    void                        addEvent( sal_uInt16 nMask );
    void                        subtractEvent( sal_uInt16 nMask );

    boost::shared_ptr<vcl::unx::GtkPrintWrapper> getPrintWrapper() const;
  private:
    std::vector<GtkSalTimer *>  m_aTimers;
    bool                        IsTimerExpired();

    mutable boost::shared_ptr<vcl::unx::GtkPrintWrapper> m_pPrintWrapper;
};

#endif // _VCL_GTKINST_HXX

/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
<|endoftext|>


<commit_before>// Copyright (c) 2006-2009 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
//
// The PasswordManagerAutocompleteTests in this file test only the
// PasswordAutocompleteListener class implementation (and not any of the
// higher level dom autocomplete framework).

#include <string>

#include "base/string_util.h"
#include "testing/gtest/include/gtest/gtest.h"
#include "webkit/glue/form_field.h"
#include "webkit/glue/webpasswordautocompletelistener_impl.h"

using WebKit::WebString;
using webkit_glue::FormField;
using webkit_glue::PasswordFormDomManager;
using webkit_glue::WebInputElementDelegate;
using webkit_glue::WebPasswordAutocompleteListenerImpl;

class TestWebInputElementDelegate : public WebInputElementDelegate {
 public:
  TestWebInputElementDelegate() : WebInputElementDelegate(),
                                  did_call_on_finish_(false),
                                  did_set_value_(false),
                                  did_set_selection_(false),
                                  selection_start_(0),
                                  selection_end_(0),
                                  is_editable_(true) {
  }

  // Override those methods we implicitly invoke in the tests.
  virtual bool IsEditable() {
    return is_editable_;
  }

  virtual void SetValue(const string16& value) {
    value_ = value;
    did_set_value_ = true;
  }

  virtual void OnFinishedAutocompleting() {
    did_call_on_finish_ = true;
  }

  virtual void SetSelectionRange(size_t start, size_t end) {
    selection_start_ = start;
    selection_end_ = end;
    did_set_selection_ = true;
  }

  // Testing-only methods.
  void ResetTestState() {
    did_call_on_finish_ = false;
    did_set_value_ = false;
    did_set_selection_ = false;
  }

  void set_is_editable(bool editable) {
    is_editable_ = editable;
  }

  string16 value() const {
    return value_;
  }

  bool did_call_on_finish() const {
    return did_call_on_finish_;
  }

  bool did_set_value() const {
    return did_set_value_;
  }

  bool did_set_selection() const {
    return did_set_selection_;
  }

  size_t selection_start() const {
    return selection_start_;
  }

  size_t selection_end() const {
    return selection_end_;
  }

 private:
  bool did_call_on_finish_;
  bool did_set_value_;
  bool did_set_selection_;
  string16 value_;
  size_t selection_start_;
  size_t selection_end_;
  bool is_editable_;
};

namespace {
class PasswordManagerAutocompleteTests : public testing::Test {
 public:
  virtual void SetUp() {
    // Add a preferred login and an additional login to the FillData.
    username1_ = ASCIIToUTF16("alice");
    password1_ = ASCIIToUTF16("password");
    username2_ = ASCIIToUTF16("bob");
    password2_ = ASCIIToUTF16("bobsyouruncle");
    data_.basic_data.fields.push_back(FormField(string16(),
                                                string16(),
                                                username1_,
                                                string16()));
    data_.basic_data.fields.push_back(FormField(string16(),
                                                string16(),
                                                password1_,
                                                string16()));
    data_.additional_logins[username2_] = password2_;
    testing::Test::SetUp();
  }

  string16 username1_;
  string16 password1_;
  string16 username2_;
  string16 password2_;
  PasswordFormDomManager::FillData data_;
};

TEST_F(PasswordManagerAutocompleteTests, OnBlur) {
  TestWebInputElementDelegate* username_delegate =
      new TestWebInputElementDelegate();
  TestWebInputElementDelegate* password_delegate =
      new TestWebInputElementDelegate();

  scoped_ptr<WebPasswordAutocompleteListenerImpl> listener(
      new WebPasswordAutocompleteListenerImpl(username_delegate,
                                              password_delegate,
                                              data_));

  // Clear the password field.
  password_delegate->SetValue(string16());

  // Make the password field read-only.
  password_delegate->set_is_editable(false);
  // Simulate a blur event on the username field, but r/o password won't fill.
  listener->didBlurInputElement(username1_);
  EXPECT_EQ(string16(), password_delegate->value());
  password_delegate->set_is_editable(true);

  // Simulate a blur event on the username field and expect a password autofill.
  listener->didBlurInputElement(username1_);
  EXPECT_EQ(password1_, password_delegate->value());

  // Now the user goes back and changes the username to something we don't
  // have saved. The password should remain unchanged.
  listener->didBlurInputElement(ASCIIToUTF16("blahblahblah"));
  EXPECT_EQ(password1_, password_delegate->value());

  // Now they type in the additional login username.
  listener->didBlurInputElement(username2_);
  EXPECT_EQ(password2_, password_delegate->value());
}

TEST_F(PasswordManagerAutocompleteTests, OnInlineAutocompleteNeeded) {
  TestWebInputElementDelegate* username_delegate =
      new TestWebInputElementDelegate();
  TestWebInputElementDelegate* password_delegate =
      new TestWebInputElementDelegate();

  scoped_ptr<WebPasswordAutocompleteListenerImpl> listener(
      new WebPasswordAutocompleteListenerImpl(username_delegate,
                                              password_delegate,
                                              data_));

  password_delegate->SetValue(string16());
  // Simulate the user typing in the first letter of 'alice', a stored username.
  listener->performInlineAutocomplete(ASCIIToUTF16("a"), false, false);
  // Both the username and password delegates should reflect selection
  // of the stored login.
  EXPECT_EQ(username1_, username_delegate->value());
  EXPECT_EQ(password1_, password_delegate->value());
  // And the selection should have been set to 'lice', the last 4 letters.
  EXPECT_EQ(1U, username_delegate->selection_start());
  EXPECT_EQ(username1_.length(), username_delegate->selection_end());
  // And both fields should have observed OnFinishedAutocompleting.
  EXPECT_TRUE(username_delegate->did_call_on_finish());
  EXPECT_TRUE(password_delegate->did_call_on_finish());

  // Now the user types the next letter of the same username, 'l'.
  listener->performInlineAutocomplete(ASCIIToUTF16("al"), false, false);
  // Now the fields should have the same value, but the selection should have a
  // different start value.
  EXPECT_EQ(username1_, username_delegate->value());
  EXPECT_EQ(password1_, password_delegate->value());
  EXPECT_EQ(2U, username_delegate->selection_start());
  EXPECT_EQ(username1_.length(), username_delegate->selection_end());

  // Now lets say the user goes astray from the stored username and types
  // the letter 'f', spelling 'alf'.  We don't know alf (that's just sad),
  // so in practice the username should no longer be 'alice' and the selected
  // range should be empty. In our case, when the autocomplete code doesn't
  // know the text, it won't set the value or the selection and hence our
  // delegate methods won't get called. The WebCore::HTMLInputElement's value
  // and selection would be set directly by WebCore in practice.

  // Reset the delegate's test state so we can determine what, if anything,
  // was invoked during performInlineAutocomplete.
  username_delegate->ResetTestState();
  password_delegate->ResetTestState();
  listener->performInlineAutocomplete(ASCIIToUTF16("alf"), false, false);
  EXPECT_FALSE(username_delegate->did_set_selection());
  EXPECT_FALSE(username_delegate->did_set_value());
  EXPECT_FALSE(username_delegate->did_call_on_finish());
  EXPECT_FALSE(password_delegate->did_set_value());
  EXPECT_FALSE(password_delegate->did_call_on_finish());

  // Ok, so now the user removes all the text and enters the letter 'b'.
  listener->performInlineAutocomplete(ASCIIToUTF16("b"), false, false);
  // The username and password fields should match the 'bob' entry.
  EXPECT_EQ(username2_, username_delegate->value());
  EXPECT_EQ(password2_, password_delegate->value());
  EXPECT_EQ(1U, username_delegate->selection_start());
  EXPECT_EQ(username2_.length(), username_delegate->selection_end());
}

TEST_F(PasswordManagerAutocompleteTests, TestWaitUsername) {
  TestWebInputElementDelegate* username_delegate =
      new TestWebInputElementDelegate();
  TestWebInputElementDelegate* password_delegate =
      new TestWebInputElementDelegate();

  // If we had an action authority mismatch (for example), we don't want to
  // automatically autofill anything without some user interaction first.
  // We require an explicit blur on the username field, and that a valid
  // matching username is in the field, before we autofill passwords.
  data_.wait_for_username = true;
  scoped_ptr<WebPasswordAutocompleteListenerImpl> listener(
      new WebPasswordAutocompleteListenerImpl(username_delegate,
                                              password_delegate,
                                              data_));

  string16 empty;
  // In all cases, username_delegate should remain empty because we should
  // never modify it when wait_for_username is true; only the user can by
  // typing into (in real life) the HTMLInputElement.
  password_delegate->SetValue(string16());
  listener->performInlineAutocomplete(ASCIIToUTF16("a"), false, false);
  EXPECT_EQ(empty, username_delegate->value());
  EXPECT_EQ(empty, password_delegate->value());
  listener->performInlineAutocomplete(ASCIIToUTF16("al"), false, false);
  EXPECT_EQ(empty, username_delegate->value());
  EXPECT_EQ(empty, password_delegate->value());
  listener->performInlineAutocomplete(ASCIIToUTF16("alice"), false, false);
  EXPECT_EQ(empty, username_delegate->value());
  EXPECT_EQ(empty, password_delegate->value());

  listener->didBlurInputElement(ASCIIToUTF16("a"));
  EXPECT_EQ(empty, username_delegate->value());
  EXPECT_EQ(empty, password_delegate->value());
  listener->didBlurInputElement(ASCIIToUTF16("ali"));
  EXPECT_EQ(empty, username_delegate->value());
  EXPECT_EQ(empty, password_delegate->value());

  // Blur with 'alice' should allow password autofill.
  listener->didBlurInputElement(ASCIIToUTF16("alice"));
  EXPECT_EQ(empty, username_delegate->value());
  EXPECT_EQ(password1_, password_delegate->value());
}

}  // namespace
<commit_msg>Compile fix for CL: Form AutoFill Phone number should be displayed as xxx-xxx-xxxx<commit_after>// Copyright (c) 2006-2009 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
//
// The PasswordManagerAutocompleteTests in this file test only the
// PasswordAutocompleteListener class implementation (and not any of the
// higher level dom autocomplete framework).

#include <string>

#include "base/string_util.h"
#include "testing/gtest/include/gtest/gtest.h"
#include "webkit/glue/form_field.h"
#include "webkit/glue/webpasswordautocompletelistener_impl.h"

using WebKit::WebString;
using webkit_glue::FormField;
using webkit_glue::PasswordFormDomManager;
using webkit_glue::WebInputElementDelegate;
using webkit_glue::WebPasswordAutocompleteListenerImpl;

class TestWebInputElementDelegate : public WebInputElementDelegate {
 public:
  TestWebInputElementDelegate() : WebInputElementDelegate(),
                                  did_call_on_finish_(false),
                                  did_set_value_(false),
                                  did_set_selection_(false),
                                  selection_start_(0),
                                  selection_end_(0),
                                  is_editable_(true) {
  }

  // Override those methods we implicitly invoke in the tests.
  virtual bool IsEditable() {
    return is_editable_;
  }

  virtual void SetValue(const string16& value) {
    value_ = value;
    did_set_value_ = true;
  }

  virtual void OnFinishedAutocompleting() {
    did_call_on_finish_ = true;
  }

  virtual void SetSelectionRange(size_t start, size_t end) {
    selection_start_ = start;
    selection_end_ = end;
    did_set_selection_ = true;
  }

  // Testing-only methods.
  void ResetTestState() {
    did_call_on_finish_ = false;
    did_set_value_ = false;
    did_set_selection_ = false;
  }

  void set_is_editable(bool editable) {
    is_editable_ = editable;
  }

  string16 value() const {
    return value_;
  }

  bool did_call_on_finish() const {
    return did_call_on_finish_;
  }

  bool did_set_value() const {
    return did_set_value_;
  }

  bool did_set_selection() const {
    return did_set_selection_;
  }

  size_t selection_start() const {
    return selection_start_;
  }

  size_t selection_end() const {
    return selection_end_;
  }

 private:
  bool did_call_on_finish_;
  bool did_set_value_;
  bool did_set_selection_;
  string16 value_;
  size_t selection_start_;
  size_t selection_end_;
  bool is_editable_;
};

namespace {
class PasswordManagerAutocompleteTests : public testing::Test {
 public:
  virtual void SetUp() {
    // Add a preferred login and an additional login to the FillData.
    username1_ = ASCIIToUTF16("alice");
    password1_ = ASCIIToUTF16("password");
    username2_ = ASCIIToUTF16("bob");
    password2_ = ASCIIToUTF16("bobsyouruncle");
    data_.basic_data.fields.push_back(FormField(string16(),
                                                string16(),
                                                username1_,
                                                string16(),
                                                0));
    data_.basic_data.fields.push_back(FormField(string16(),
                                                string16(),
                                                password1_,
                                                string16(),
                                                0));
    data_.additional_logins[username2_] = password2_;
    testing::Test::SetUp();
  }

  string16 username1_;
  string16 password1_;
  string16 username2_;
  string16 password2_;
  PasswordFormDomManager::FillData data_;
};

TEST_F(PasswordManagerAutocompleteTests, OnBlur) {
  TestWebInputElementDelegate* username_delegate =
      new TestWebInputElementDelegate();
  TestWebInputElementDelegate* password_delegate =
      new TestWebInputElementDelegate();

  scoped_ptr<WebPasswordAutocompleteListenerImpl> listener(
      new WebPasswordAutocompleteListenerImpl(username_delegate,
                                              password_delegate,
                                              data_));

  // Clear the password field.
  password_delegate->SetValue(string16());

  // Make the password field read-only.
  password_delegate->set_is_editable(false);
  // Simulate a blur event on the username field, but r/o password won't fill.
  listener->didBlurInputElement(username1_);
  EXPECT_EQ(string16(), password_delegate->value());
  password_delegate->set_is_editable(true);

  // Simulate a blur event on the username field and expect a password autofill.
  listener->didBlurInputElement(username1_);
  EXPECT_EQ(password1_, password_delegate->value());

  // Now the user goes back and changes the username to something we don't
  // have saved. The password should remain unchanged.
  listener->didBlurInputElement(ASCIIToUTF16("blahblahblah"));
  EXPECT_EQ(password1_, password_delegate->value());

  // Now they type in the additional login username.
  listener->didBlurInputElement(username2_);
  EXPECT_EQ(password2_, password_delegate->value());
}

TEST_F(PasswordManagerAutocompleteTests, OnInlineAutocompleteNeeded) {
  TestWebInputElementDelegate* username_delegate =
      new TestWebInputElementDelegate();
  TestWebInputElementDelegate* password_delegate =
      new TestWebInputElementDelegate();

  scoped_ptr<WebPasswordAutocompleteListenerImpl> listener(
      new WebPasswordAutocompleteListenerImpl(username_delegate,
                                              password_delegate,
                                              data_));

  password_delegate->SetValue(string16());
  // Simulate the user typing in the first letter of 'alice', a stored username.
  listener->performInlineAutocomplete(ASCIIToUTF16("a"), false, false);
  // Both the username and password delegates should reflect selection
  // of the stored login.
  EXPECT_EQ(username1_, username_delegate->value());
  EXPECT_EQ(password1_, password_delegate->value());
  // And the selection should have been set to 'lice', the last 4 letters.
  EXPECT_EQ(1U, username_delegate->selection_start());
  EXPECT_EQ(username1_.length(), username_delegate->selection_end());
  // And both fields should have observed OnFinishedAutocompleting.
  EXPECT_TRUE(username_delegate->did_call_on_finish());
  EXPECT_TRUE(password_delegate->did_call_on_finish());

  // Now the user types the next letter of the same username, 'l'.
  listener->performInlineAutocomplete(ASCIIToUTF16("al"), false, false);
  // Now the fields should have the same value, but the selection should have a
  // different start value.
  EXPECT_EQ(username1_, username_delegate->value());
  EXPECT_EQ(password1_, password_delegate->value());
  EXPECT_EQ(2U, username_delegate->selection_start());
  EXPECT_EQ(username1_.length(), username_delegate->selection_end());

  // Now lets say the user goes astray from the stored username and types
  // the letter 'f', spelling 'alf'.  We don't know alf (that's just sad),
  // so in practice the username should no longer be 'alice' and the selected
  // range should be empty. In our case, when the autocomplete code doesn't
  // know the text, it won't set the value or the selection and hence our
  // delegate methods won't get called. The WebCore::HTMLInputElement's value
  // and selection would be set directly by WebCore in practice.

  // Reset the delegate's test state so we can determine what, if anything,
  // was invoked during performInlineAutocomplete.
  username_delegate->ResetTestState();
  password_delegate->ResetTestState();
  listener->performInlineAutocomplete(ASCIIToUTF16("alf"), false, false);
  EXPECT_FALSE(username_delegate->did_set_selection());
  EXPECT_FALSE(username_delegate->did_set_value());
  EXPECT_FALSE(username_delegate->did_call_on_finish());
  EXPECT_FALSE(password_delegate->did_set_value());
  EXPECT_FALSE(password_delegate->did_call_on_finish());

  // Ok, so now the user removes all the text and enters the letter 'b'.
  listener->performInlineAutocomplete(ASCIIToUTF16("b"), false, false);
  // The username and password fields should match the 'bob' entry.
  EXPECT_EQ(username2_, username_delegate->value());
  EXPECT_EQ(password2_, password_delegate->value());
  EXPECT_EQ(1U, username_delegate->selection_start());
  EXPECT_EQ(username2_.length(), username_delegate->selection_end());
}

TEST_F(PasswordManagerAutocompleteTests, TestWaitUsername) {
  TestWebInputElementDelegate* username_delegate =
      new TestWebInputElementDelegate();
  TestWebInputElementDelegate* password_delegate =
      new TestWebInputElementDelegate();

  // If we had an action authority mismatch (for example), we don't want to
  // automatically autofill anything without some user interaction first.
  // We require an explicit blur on the username field, and that a valid
  // matching username is in the field, before we autofill passwords.
  data_.wait_for_username = true;
  scoped_ptr<WebPasswordAutocompleteListenerImpl> listener(
      new WebPasswordAutocompleteListenerImpl(username_delegate,
                                              password_delegate,
                                              data_));

  string16 empty;
  // In all cases, username_delegate should remain empty because we should
  // never modify it when wait_for_username is true; only the user can by
  // typing into (in real life) the HTMLInputElement.
  password_delegate->SetValue(string16());
  listener->performInlineAutocomplete(ASCIIToUTF16("a"), false, false);
  EXPECT_EQ(empty, username_delegate->value());
  EXPECT_EQ(empty, password_delegate->value());
  listener->performInlineAutocomplete(ASCIIToUTF16("al"), false, false);
  EXPECT_EQ(empty, username_delegate->value());
  EXPECT_EQ(empty, password_delegate->value());
  listener->performInlineAutocomplete(ASCIIToUTF16("alice"), false, false);
  EXPECT_EQ(empty, username_delegate->value());
  EXPECT_EQ(empty, password_delegate->value());

  listener->didBlurInputElement(ASCIIToUTF16("a"));
  EXPECT_EQ(empty, username_delegate->value());
  EXPECT_EQ(empty, password_delegate->value());
  listener->didBlurInputElement(ASCIIToUTF16("ali"));
  EXPECT_EQ(empty, username_delegate->value());
  EXPECT_EQ(empty, password_delegate->value());

  // Blur with 'alice' should allow password autofill.
  listener->didBlurInputElement(ASCIIToUTF16("alice"));
  EXPECT_EQ(empty, username_delegate->value());
  EXPECT_EQ(password1_, password_delegate->value());
}

}  // namespace
<|endoftext|>


<commit_before>#ifndef INTERACTABLE_GL_KINEMATIC_BODY_HPP
#define INTERACTABLE_GL_KINEMATIC_BODY_HPP

#include "GlKinematicBody.hpp"
#include <collision/collision_detector.h>
#include <collision/collision_object_sphere.h>
#include <collision/collision_object_cylinder.h>
#include <collision/collision_object_box.h>
#include <collision/collision_object_torus.h>
namespace visualization_utils {

class InteractableGlKinematicBody: public GlKinematicBody
{

  public:
    std::string _unique_name;
    std::map<std::string,   boost::shared_ptr<collision::Collision_Object> > _collision_object_map;

    // create a collision detector class
    // collision::Collision_Detector _collision_detector;
    boost::shared_ptr<collision::Collision_Detector> _collision_detector;

    //separate collision detector for interactable markers
    std::map<std::string,   boost::shared_ptr<collision::Collision_Object> > _markers_collision_object_map;
    std::map<std::string,   boost::shared_ptr<collision::Collision_Object> > _dofmarkers_collision_object_map;
    boost::shared_ptr<collision::Collision_Detector> _collision_detector_floatingbase_markers;
    boost::shared_ptr<collision::Collision_Detector> _collision_detector_jointdof_markers;

  private:
   std::string selected_link;
   bool link_selection_enabled;
   bool whole_body_selection_enabled;

   std::string selected_marker;
   bool bodypose_adjustment_enabled;
   bool jointdof_adjustment_enabled;
   bool jointdof_markers_initialized;

   void init_vars(void);
  public:
   enum _bodyadjust_type
   {
     THREE_D=0, TWO_D, THREE_D_TRANS, THREE_D_ROT, TWO_D_TRANS, TWO_D_ROT
   } bodypose_adjustment_type;

  private:
   Eigen::Vector3f _floatingbase_offset; // visual offset of the root link, if any
   float _floatingbase_markers_boxsize;
   Eigen::Vector2f _floatingbase_markers_torusdims;

  public:
  //copy Constructors
  InteractableGlKinematicBody( const InteractableGlKinematicBody& other, std::string unique_name);
  InteractableGlKinematicBody( const GlKinematicBody& other,
                              boost::shared_ptr<collision::Collision_Detector> col_detector,
                              bool enable_selection,
                              std::string unique_name);
  // create
  InteractableGlKinematicBody( const GlKinematicBody& other,
                              bool enable_selection,
                              std::string unique_name);
 // Constructors (Reuses code from GLKinematicBody Constructor)
  InteractableGlKinematicBody(std::string urdf_xml_string,
                              boost::shared_ptr<collision::Collision_Detector> col_detector,
                              bool enable_selection, std::string unique_name);
  InteractableGlKinematicBody (boost::shared_ptr<otdf::ModelInterface> otdf_instance,
                              boost::shared_ptr<collision::Collision_Detector> col_detector,
                              bool enable_selection, std::string unique_name);
  ~InteractableGlKinematicBody();
   void init_urdf_collision_objects();
   void init_otdf_collision_objects();
   void set_state(const drc::robot_state_t &msg);
   void set_state(const KDL::Frame &T_world_body, const drc::joint_angles_t &msg);
   void set_state(const KDL::Frame &T_world_body, std::map<std::string, double> &jointpos_in);
   void set_state(boost::shared_ptr<otdf::ModelInterface> _otdf_instance);
   void update_urdf_collision_objects(void);
   void update_otdf_collision_objects(void);

   // overloaded from GLKinematicBody They call update functions for marker collision objects
   void set_future_state(const KDL::Frame &T_world_body, std::map<std::string, double> &jointpos_in);

   // double c[3] = {0.3,0.3,0.3};
   // double alpha = self->alpha;
   void draw_body (float (&c)[3], float alpha)
   {

      glColor4f(c[0],c[1],c[2],alpha);
      for(uint i = 0; i < _link_geometry_tfs.size(); i++)
      {
        LinkFrameStruct nextTf=_link_geometry_tfs[i];
        std::stringstream oss;
        oss << _unique_name << "_"<< _link_geometry_tfs[i].name;
        if((link_selection_enabled)&&(selected_link == oss.str())) {
//          if((bodypose_adjustment_enabled)&&(is_otdf_instance))
//            draw_interactable_markers(_otdf_link_shapes[i],_link_geometry_tfs[i]); // draws shapes and adds them to _collision_detector
//          else if((bodypose_adjustment_enabled)&&(!is_otdf_instance))
//            draw_interactable_markers(_link_shapes[i],_link_geometry_tfs[i]);

          glColor4f(0.7,0.1,0.1,alpha);
        }
        else
           glColor4f(c[0],c[1],c[2],alpha);

        if((whole_body_selection_enabled)&&(selected_link == _unique_name)){
          glColor4f(0.7,0.1,0.1,alpha); // whole body is selected instead of an individual link
        }
        //int64_t tic = bot_timestamp_now();
        GlKinematicBody::draw_link_current_and_future(c,alpha,i,nextTf);
        //int64_t toc = bot_timestamp_now();
        //std::cout << _link_geometry_tfs[i].name << " usec: " << bot_timestamp_useconds(toc-tic) << std::endl;

      }

      //draw_whole_body_bbox();
       if((_root_name!="world")&&(bodypose_adjustment_enabled)){
        if(_floatingbase_markers_boxsize!=0){
          draw_floatingbase_markers();
        }
       }
       if(jointdof_adjustment_enabled){
         draw_jointdof_markers();
       }

   };

   void draw_body_in_frame (float (&c)[3], float alpha,const KDL::Frame &T_drawFrame_currentWorldFrame)
   {

      glColor4f(c[0],c[1],c[2],alpha);
      for(uint i = 0; i < _link_geometry_tfs.size(); i++)
      {
        KDL::Frame T_currentWorldFrame_link,T_drawFrame_link;
        LinkFrameStruct nextTf=_link_geometry_tfs[i];

        T_currentWorldFrame_link = nextTf.frame;
        T_drawFrame_link = T_drawFrame_currentWorldFrame*T_currentWorldFrame_link;
        nextTf.frame = T_drawFrame_link;

        std::stringstream oss;
        oss << _unique_name << "_"<< nextTf.name;
        if((link_selection_enabled)&&(selected_link == oss.str())) {
//          if((bodypose_adjustment_enabled)&&(is_otdf_instance))
//            draw_interactable_markers(_otdf_link_shapes[i],nextTf);
//          else if((bodypose_adjustment_enabled)&&(!is_otdf_instance))
//            draw_interactable_markers(_link_shapes[i],nextTf);

          glColor4f(0.7,0.1,0.1,alpha);
        }
        else
           glColor4f(c[0],c[1],c[2],alpha);

        if((whole_body_selection_enabled)&&(selected_link == _unique_name)) {
          glColor4f(0.7,0.1,0.1,alpha); // whole body is selected instead of an individual link
        }

        GlKinematicBody::draw_link_current_and_future(c,alpha,i,nextTf);

      }

   };

  // Interactive markers
   void init_floatingbase_marker_collision_objects(); // requires  as FK needs to be solved atleast once to derive. Called inside setstate.
   void update_floatingbase_marker_collision_objects();
   void draw_floatingbase_markers();

   void init_jointdof_marker_collision_objects(); // requires  as FK needs to be solved atleast once to derive. Called inside setstate.
   void update_jointdof_marker_collision_objects();
   void draw_jointdof_markers();

   void draw_interactable_markers(boost::shared_ptr<otdf::Geometry> &_link_shape, const LinkFrameStruct &link_tf);
   void draw_interactable_markers(boost::shared_ptr<urdf::Geometry> &_link_shape,const LinkFrameStruct &link_tf);
   void draw_markers(float (&pos)[3], float markersize, float inner_radius, float outer_radius);

   void enable_link_selection(bool value)   {
       link_selection_enabled = value;
   };
   void highlight_link(std::string &link_name)   {
       selected_link = link_name;
   };

   void highlight_body(std::string &body_name)   {
       selected_link = body_name;
   };

   void highlight_marker(std::string &marker_name)   {
       selected_marker = marker_name;
   };
   void enable_bodypose_adjustment(bool value)   {
    bodypose_adjustment_enabled = value;
    if(value)
    {
      jointdof_adjustment_enabled = false; // mutually exclusive
      if(_root_name=="world"){
        std::cerr << "ERROR: root link pose cannot be adjusted as it is fixed to the world. Enabling jointdof adjusment instead" << std::endl;
        enable_jointdof_adjustment(true);
       }
    }
   };
   void enable_jointdof_adjustment(bool value)   {
    jointdof_adjustment_enabled = value;
    if(value){
      bodypose_adjustment_enabled = false; // mutually exclusive
//      if(_collision_detector_jointdof_markers==NULL)
//        _collision_detector_jointdof_markers = boost::shared_ptr<collision::Collision_Detector>(new collision::Collision_Detector());
    }
   };
   void set_bodypose_adjustment_type(int type){
    bodypose_adjustment_type= (_bodyadjust_type)type;
   }

   bool is_bodypose_adjustment_enabled()   {
    return bodypose_adjustment_enabled;
   };
   bool is_jointdof_adjustment_enabled()   {
    return jointdof_adjustment_enabled;
   };
   void enable_whole_body_selection(bool value)   {
    whole_body_selection_enabled = value;
   };

};

} // end namespace

#endif //INTERACTABLE_GL_KINEMATIC_BODY_HPP
<commit_msg> bug fix where ppitch and roll collision elements were stick existing even though markers were selected to be 2D <commit_after>#ifndef INTERACTABLE_GL_KINEMATIC_BODY_HPP
#define INTERACTABLE_GL_KINEMATIC_BODY_HPP

#include "GlKinematicBody.hpp"
#include <collision/collision_detector.h>
#include <collision/collision_object_sphere.h>
#include <collision/collision_object_cylinder.h>
#include <collision/collision_object_box.h>
#include <collision/collision_object_torus.h>
namespace visualization_utils {

class InteractableGlKinematicBody: public GlKinematicBody
{

  public:
    std::string _unique_name;
    std::map<std::string,   boost::shared_ptr<collision::Collision_Object> > _collision_object_map;

    // create a collision detector class
    // collision::Collision_Detector _collision_detector;
    boost::shared_ptr<collision::Collision_Detector> _collision_detector;

    //separate collision detector for interactable markers
    std::map<std::string,   boost::shared_ptr<collision::Collision_Object> > _markers_collision_object_map;
    std::map<std::string,   boost::shared_ptr<collision::Collision_Object> > _dofmarkers_collision_object_map;
    boost::shared_ptr<collision::Collision_Detector> _collision_detector_floatingbase_markers;
    boost::shared_ptr<collision::Collision_Detector> _collision_detector_jointdof_markers;

  private:
   std::string selected_link;
   bool link_selection_enabled;
   bool whole_body_selection_enabled;

   std::string selected_marker;
   bool bodypose_adjustment_enabled;
   bool jointdof_adjustment_enabled;
   bool jointdof_markers_initialized;

   void init_vars(void);
  public:
   enum _bodyadjust_type
   {
     THREE_D=0, TWO_D, THREE_D_TRANS, THREE_D_ROT, TWO_D_TRANS, TWO_D_ROT
   } bodypose_adjustment_type;

  private:
   Eigen::Vector3f _floatingbase_offset; // visual offset of the root link, if any
   float _floatingbase_markers_boxsize;
   Eigen::Vector2f _floatingbase_markers_torusdims;

  public:
  //copy Constructors
  InteractableGlKinematicBody( const InteractableGlKinematicBody& other, std::string unique_name);
  InteractableGlKinematicBody( const GlKinematicBody& other,
                              boost::shared_ptr<collision::Collision_Detector> col_detector,
                              bool enable_selection,
                              std::string unique_name);
  // create
  InteractableGlKinematicBody( const GlKinematicBody& other,
                              bool enable_selection,
                              std::string unique_name);
 // Constructors (Reuses code from GLKinematicBody Constructor)
  InteractableGlKinematicBody(std::string urdf_xml_string,
                              boost::shared_ptr<collision::Collision_Detector> col_detector,
                              bool enable_selection, std::string unique_name);
  InteractableGlKinematicBody (boost::shared_ptr<otdf::ModelInterface> otdf_instance,
                              boost::shared_ptr<collision::Collision_Detector> col_detector,
                              bool enable_selection, std::string unique_name);
  ~InteractableGlKinematicBody();
   void init_urdf_collision_objects();
   void init_otdf_collision_objects();
   void set_state(const drc::robot_state_t &msg);
   void set_state(const KDL::Frame &T_world_body, const drc::joint_angles_t &msg);
   void set_state(const KDL::Frame &T_world_body, std::map<std::string, double> &jointpos_in);
   void set_state(boost::shared_ptr<otdf::ModelInterface> _otdf_instance);
   void update_urdf_collision_objects(void);
   void update_otdf_collision_objects(void);

   // overloaded from GLKinematicBody They call update functions for marker collision objects
   void set_future_state(const KDL::Frame &T_world_body, std::map<std::string, double> &jointpos_in);

   // double c[3] = {0.3,0.3,0.3};
   // double alpha = self->alpha;
   void draw_body (float (&c)[3], float alpha)
   {

      glColor4f(c[0],c[1],c[2],alpha);
      for(uint i = 0; i < _link_geometry_tfs.size(); i++)
      {
        LinkFrameStruct nextTf=_link_geometry_tfs[i];
        std::stringstream oss;
        oss << _unique_name << "_"<< _link_geometry_tfs[i].name;
        if((link_selection_enabled)&&(selected_link == oss.str())) {
//          if((bodypose_adjustment_enabled)&&(is_otdf_instance))
//            draw_interactable_markers(_otdf_link_shapes[i],_link_geometry_tfs[i]); // draws shapes and adds them to _collision_detector
//          else if((bodypose_adjustment_enabled)&&(!is_otdf_instance))
//            draw_interactable_markers(_link_shapes[i],_link_geometry_tfs[i]);

          glColor4f(0.7,0.1,0.1,alpha);
        }
        else
           glColor4f(c[0],c[1],c[2],alpha);

        if((whole_body_selection_enabled)&&(selected_link == _unique_name)){
          glColor4f(0.7,0.1,0.1,alpha); // whole body is selected instead of an individual link
        }
        //int64_t tic = bot_timestamp_now();
        GlKinematicBody::draw_link_current_and_future(c,alpha,i,nextTf);
        //int64_t toc = bot_timestamp_now();
        //std::cout << _link_geometry_tfs[i].name << " usec: " << bot_timestamp_useconds(toc-tic) << std::endl;

      }

      //draw_whole_body_bbox();
       if((_root_name!="world")&&(bodypose_adjustment_enabled)){
        if(_floatingbase_markers_boxsize!=0){
          draw_floatingbase_markers();
        }
       }
       if(jointdof_adjustment_enabled){
         draw_jointdof_markers();
       }

   };

   void draw_body_in_frame (float (&c)[3], float alpha,const KDL::Frame &T_drawFrame_currentWorldFrame)
   {

      glColor4f(c[0],c[1],c[2],alpha);
      for(uint i = 0; i < _link_geometry_tfs.size(); i++)
      {
        KDL::Frame T_currentWorldFrame_link,T_drawFrame_link;
        LinkFrameStruct nextTf=_link_geometry_tfs[i];

        T_currentWorldFrame_link = nextTf.frame;
        T_drawFrame_link = T_drawFrame_currentWorldFrame*T_currentWorldFrame_link;
        nextTf.frame = T_drawFrame_link;

        std::stringstream oss;
        oss << _unique_name << "_"<< nextTf.name;
        if((link_selection_enabled)&&(selected_link == oss.str())) {
//          if((bodypose_adjustment_enabled)&&(is_otdf_instance))
//            draw_interactable_markers(_otdf_link_shapes[i],nextTf);
//          else if((bodypose_adjustment_enabled)&&(!is_otdf_instance))
//            draw_interactable_markers(_link_shapes[i],nextTf);

          glColor4f(0.7,0.1,0.1,alpha);
        }
        else
           glColor4f(c[0],c[1],c[2],alpha);

        if((whole_body_selection_enabled)&&(selected_link == _unique_name)) {
          glColor4f(0.7,0.1,0.1,alpha); // whole body is selected instead of an individual link
        }

        GlKinematicBody::draw_link_current_and_future(c,alpha,i,nextTf);

      }

   };

  // Interactive markers
   void init_floatingbase_marker_collision_objects(); // requires  as FK needs to be solved atleast once to derive. Called inside setstate.
   void update_floatingbase_marker_collision_objects();
   void draw_floatingbase_markers();

   void init_jointdof_marker_collision_objects(); // requires  as FK needs to be solved atleast once to derive. Called inside setstate.
   void update_jointdof_marker_collision_objects();
   void draw_jointdof_markers();

   void draw_interactable_markers(boost::shared_ptr<otdf::Geometry> &_link_shape, const LinkFrameStruct &link_tf);
   void draw_interactable_markers(boost::shared_ptr<urdf::Geometry> &_link_shape,const LinkFrameStruct &link_tf);
   void draw_markers(float (&pos)[3], float markersize, float inner_radius, float outer_radius);

   void enable_link_selection(bool value)   {
       link_selection_enabled = value;
   };
   void highlight_link(std::string &link_name)   {
       selected_link = link_name;
   };

   void highlight_body(std::string &body_name)   {
       selected_link = body_name;
   };

   void highlight_marker(std::string &marker_name)   {
       selected_marker = marker_name;
   };
   void enable_bodypose_adjustment(bool value)   {
    bodypose_adjustment_enabled = value;
    if(value)
    {
      jointdof_adjustment_enabled = false; // mutually exclusive
      if(_root_name=="world"){
        std::cerr << "ERROR: root link pose cannot be adjusted as it is fixed to the world. Enabling jointdof adjusment instead" << std::endl;
        enable_jointdof_adjustment(true);
       }
    }
   };
   void enable_jointdof_adjustment(bool value)   {
    jointdof_adjustment_enabled = value;
    if(value){
      bodypose_adjustment_enabled = false; // mutually exclusive
//      if(_collision_detector_jointdof_markers==NULL)
//        _collision_detector_jointdof_markers = boost::shared_ptr<collision::Collision_Detector>(new collision::Collision_Detector());
    }
   };
   void set_bodypose_adjustment_type(int type){
    bodypose_adjustment_type= (_bodyadjust_type)type;
    _collision_detector_floatingbase_markers->clear_collision_objects(); // reset markers
    _markers_collision_object_map.clear();
    init_floatingbase_marker_collision_objects();
    update_floatingbase_marker_collision_objects();
   }

   bool is_bodypose_adjustment_enabled()   {
    return bodypose_adjustment_enabled;
   };
   bool is_jointdof_adjustment_enabled()   {
    return jointdof_adjustment_enabled;
   };
   void enable_whole_body_selection(bool value)   {
    whole_body_selection_enabled = value;
   };

};

} // end namespace

#endif //INTERACTABLE_GL_KINEMATIC_BODY_HPP
<|endoftext|>


<commit_before>/*
This file is part of Bohrium and copyright (c) 2012 the Bohrium
team <http://www.bh107.org>.

Bohrium is free software: you can redistribute it and/or modify
it under the terms of the GNU Lesser General Public License as
published by the Free Software Foundation, either version 3
of the License, or (at your option) any later version.

Bohrium is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
GNU General Public License for more details.

You should have received a copy of the
GNU Lesser General Public License along with Bohrium.

If not, see <http://www.gnu.org/licenses/>.
*/
#include <iostream>
#include <functional>
#include <algorithm>
#include <sstream>
#include <cassert>
#include <stdexcept>
#include <bh.h>
#include "InstructionBatch.hpp"
#include "GenerateSourceCode.hpp"

InstructionBatch::KernelMap InstructionBatch::kernelMap = InstructionBatch::KernelMap();

InstructionBatch::InstructionBatch(bh_instruction* inst, const std::vector<KernelParameter*>& operands)
    : arraynum(0)
    , scalarnum(0)
    , float16(false)
    , float64(false)
    , complex(false)
{
#ifdef STATS
    gettimeofday(&createTime,NULL);
#endif
    if (inst->operand[0].ndim > 3)
        throw std::runtime_error("More than 3 dimensions not supported.");
    shape = std::vector<bh_index>(inst->operand[0].shape, inst->operand[0].shape + inst->operand[0].ndim);
    add(inst, operands);
}

bool InstructionBatch::shapeMatch(bh_intp ndim,const bh_index dims[])
{
    int size = shape.size();
    if (ndim == size)
    {
        for (int i = 0; i < ndim; ++i)
        {
            if (dims[i] != shape[i])
                return false;
        }
        return true;
    }
    return false;
}

bool InstructionBatch::sameView(const bh_view& a, const bh_view& b)
{
    //assumes the the views shape are the same and they have the same base
    if (a.start != b.start)
        return false;
    for (size_t i = 0; i < shape.size(); ++i)
    {
        if (a.stride[i] != b.stride[i])
            return false;
    }
    return true;
}

inline int gcd(int a, int b)
{
    int c = a % b;
    while(c != 0)
    {
        a = b;
        b = c;
        c = a % b;
    }
    return b;
}

bool InstructionBatch::disjointView(const bh_view& a, const bh_view& b)
{
    //assumes the the views shape are the same and they have the same base
    int astart = a.start;
    int bstart = b.start;
    int stride = 1;
    for (int i = 0; i < a.ndim; ++i)
    {
        stride = gcd(a.stride[i], b.stride[i]);
        int as = astart / stride;
        int bs = bstart / stride;
        int ae = as + a.shape[i] * (a.stride[i]/stride);
        int be = bs + b.shape[i] * (b.stride[i]/stride);
        if (ae <= bs || be <= as)
            return true;
        astart %= stride;
        bstart %= stride;
    }
    if (stride > 1 && a.start % stride != b.start % stride)
        return true;
    return false;
}

void InstructionBatch::add(bh_instruction* inst, const std::vector<KernelParameter*>& operands)
{
    assert(!isScalar(operands[0]));

    // Check that the shape matches
    if (!shapeMatch(inst->operand[0].ndim, inst->operand[0].shape))
        throw BatchException(0);

    std::vector<int> opids(operands.size(),-1);
    std::vector<bool> load_store(operands.size(),true); //do we need to load/store variables
    for (size_t op = 0; op < operands.size(); ++op)
    {
        BaseArray* ba = dynamic_cast<BaseArray*>(operands[op]);
        if (ba) // not a scalar
        {
            // If any operand's base is already used as output, it has to be alligned or disjoint
            ArrayRange orange = output.equal_range(ba);
            for (ArrayMap::iterator oit = orange.first ; oit != orange.second; ++oit)
            {
                if (sameView(views[oit->second], inst->operand[op]))
                {
                    // Same view so we use the ID for it
                    opids[op] = oit->second;
                    if (op == 0) // also output
                        load_store[op] = false;
                }
                else if (!disjointView(views[oit->second], inst->operand[op]))
                {
                    throw BatchException(0);
                }
            }
            // If the output operand is allready used as input it has to be alligned or disjoint
            ArrayRange irange = input.equal_range(ba);
            for (ArrayMap::iterator iit = irange.first ; iit != irange.second; ++iit)
            {
                if (sameView(views[iit->second], inst->operand[op]))
                {
                    // Same view so we use the same ID for it
                    opids[op] =  iit->second;
                    if (op > 0) // also input
                        load_store[op] = false;
                }
                else if (op == 0 && !disjointView(views[iit->second], inst->operand[0]))
                {
                    throw BatchException(0);
                }
            }
        }
    }

    // OK so we can accept the instruction
    // Register unknow parameters
    for (size_t op = 0; op < operands.size(); ++op)
    {
        if (opids[op]<0 || load_store[op])
        {
            KernelParameter* kp = operands[op];
            BaseArray* ba = dynamic_cast<BaseArray*>(kp);
            if (ba)
            {
                int i = op-1;
                for (; i >= 0; --i)
                {   //catch when same view is used twice within oparation and doesn't allready have an id
                    if (inst->operand[op].base == inst->operand[i].base &&
                        sameView(inst->operand[op], inst->operand[i]))
                    {
                        opids[op] = opids[i];
                        if (op > 0 && i > 0) // both input
                            load_store[op] = false;
                        break;
                    }
                }
                if (opids[op] < 0)
                {   // Unkwown view
                    opids[op] = views.size();
                    views.push_back(inst->operand[op]);
                }
                if (op == 0 && load_store[op])
                {
                    output.insert(std::make_pair(ba, opids[op]));
                }
                else if (load_store[op])
                {
                    input.insert(std::make_pair(ba, opids[op]));
                }
                if (parameters.find(kp) == parameters.end())
                {
                    std::stringstream ss;
                    ss << "a" << arraynum++;
                    parameters[kp] = ss.str();
                }
            }
            else //scalar
            {
                std::stringstream ss;
                ss << "s" << scalarnum++;
                opids[op] = SCALAR_OFFSET+scalarnum;
                kernelVariables[opids[op]] = ss.str();
                parameters[kp] = ss.str();
            }
            switch (kp->type())
            {
            case OCL_FLOAT16:
                float16 = true;
                break;
            case OCL_FLOAT64:
                float64 = true;
                break;
            case OCL_COMPLEX64:
                complex = true;
                break;
            case OCL_COMPLEX128:
                float64 = true;
                complex = true;
                break;
            default:
                break;
            }
        }
    }
    instructions.push_back(make_pair(inst, opids));

}

Kernel InstructionBatch::generateKernel(ResourceManager* resourceManager)
{
#ifdef STATS
    timeval start, end;
    gettimeofday(&start,NULL);
#endif
    std::string code = generateCode();
#ifdef STATS
    gettimeofday(&end,NULL);
    resourceManager->batchSource += (end.tv_sec - start.tv_sec)*1000000.0 + (end.tv_usec - start.tv_usec);
#endif
    size_t codeHash = string_hasher(code);

    KernelMap::iterator kit = kernelMap.find(codeHash);
    if (kit == kernelMap.end())
    {
        std::stringstream source, kname;
        kname << "kernel" << std::hex << codeHash;
        if (float16)
        {
            source << "#pragma OPENCL EXTENSION cl_khr_fp16 : enable\n";
        }
        if (float64)
        {
            source << "#pragma OPENCL EXTENSION cl_khr_fp64 : enable\n";
        }
        if (complex)
        {
            source << "#include <complex.h>\n";
        }
        source << "__kernel void " << kname.str() << code;
        Kernel kernel(resourceManager, shape.size(), source.str(), kname.str());
        kernelMap.insert(std::make_pair(codeHash, kernel));
        return kernel;
    } else {
        return kit->second;
    }
}

void InstructionBatch::run(ResourceManager* resourceManager)
{
#ifdef STATS
    timeval now;
    gettimeofday(&now,NULL);
    resourceManager->batchBuild += (now.tv_sec - createTime.tv_sec)*1000000.0 + (now.tv_usec - createTime.tv_usec);
#endif

    if (output.begin() != output.end())
    {
        for (ParameterMap::iterator pit = parameters.begin(); pit != parameters.end(); ++pit)
            parameterList.insert(std::make_pair(pit->second, pit->first));
        for (ArrayMap::iterator iit = input.begin(); iit != input.end(); ++iit)
            inputList.insert(std::make_pair(iit->second, iit->first));
        for (ArrayMap::iterator oit = output.begin(); oit != output.end(); ++oit)
            outputList.insert(std::make_pair(oit->second, oit->first));
        Kernel kernel = generateKernel(resourceManager);
        Kernel::Parameters kernelParameters;
        for (ParameterList::iterator pit = parameterList.begin(); pit != parameterList.end(); ++pit)
        {
            if (output.find(static_cast<BaseArray*>(pit->second)) == output.end())
                kernelParameters.push_back(std::make_pair(pit->second, false));
            else
                kernelParameters.push_back(std::make_pair(pit->second, true));
        }
        std::vector<size_t> globalShape;
        for (int i = shape.size()-1; i>=0; --i)
            globalShape.push_back(shape[i]);
        kernel.call(kernelParameters, globalShape);
    }
}

std::string InstructionBatch::generateCode()
{
    std::stringstream source;
    source << "( ";
    // Add Array kernel parameters
    ParameterList::iterator pit = parameterList.begin();
    source << *(pit->second) << " " << pit->first;
    for (++pit; pit != parameterList.end(); ++pit)
    {
        source << "\n                     , " << *(pit->second) << " " << pit->first;
    }

    source << ")\n{\n";

    generateGIDSource(shape, source);

    // Load input parameters
    for (ArrayList::iterator iit = inputList.begin(); iit != inputList.end(); ++iit)
    {
        std::stringstream ss;
        ss << "v" << iit->first;
        kernelVariables[iit->first] = ss.str();
        source << "\t" << oclTypeStr(iit->second->type()) << " " << ss.str() << " = " <<
            parameters[iit->second] << "[";
        generateOffsetSource(views[iit->first], source);
        source << "];\n";
    }

    // Generate code for instructions
    for (InstructionList::iterator iit = instructions.begin(); iit != instructions.end(); ++iit)
    {
        std::vector<std::string> operands;
        // Has the output operand been assigned a variable name?
        VariableMap::iterator kvit = kernelVariables.find(iit->second[0]);
        if (kvit == kernelVariables.end())
        {
            std::stringstream ss;
            ss << "v" << iit->second[0];
            kernelVariables[(iit->second)[0]] = ss.str();
            operands.push_back(ss.str());
            source << "\t" << oclTypeStr(oclType(iit->first->operand[0].base->type)) << " " << ss.str() << ";\n";
        }
        else
        {
            operands.push_back(kvit->second);
        }
        // find variable names for input operands
        for (int op = 1; op < bh_operands(iit->first->opcode); ++op)
        {
            operands.push_back(kernelVariables[iit->second[op]]);
        }
        // generate source code for the instruction
        generateInstructionSource(iit->first->opcode,
                                  std::make_pair(oclType(iit->first->operand[0].base->type),
                                                 oclType(iit->first->operand[1].base ?
                                                         iit->first->operand[1].base->type :
                                                         iit->first->constant.type)),
                                  operands, source);
    }

    // Save output parameters
    for (ArrayList::iterator oit = outputList.begin(); oit != outputList.end(); ++oit)
    {
        source << "\t" << parameters[oit->second] << "[";
        generateOffsetSource(views[oit->first], source);
        source << "] = " <<  kernelVariables[oit->first] << ";\n";
    }

    source << "}\n";
    return source.str();
}

bool InstructionBatch::read(BaseArray* array)
{
    if (input.find(array) == input.end())
        return false;
    return true;
}

bool InstructionBatch::write(BaseArray* array)
{
    if (output.find(array) == output.end())
        return false;
    return true;
}

bool InstructionBatch::access(BaseArray* array)
{
    return (read(array) || write(array));
}

bool InstructionBatch::discard(BaseArray* array)
{
    output.erase(array);
    bool r =  read(array);
    if (!r)
    {
        parameters.erase(static_cast<KernelParameter*>(array));
    }
    return !r;
}
<commit_msg>Code cleanup<commit_after>/*
This file is part of Bohrium and copyright (c) 2012 the Bohrium
team <http://www.bh107.org>.

Bohrium is free software: you can redistribute it and/or modify
it under the terms of the GNU Lesser General Public License as
published by the Free Software Foundation, either version 3
of the License, or (at your option) any later version.

Bohrium is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
GNU General Public License for more details.

You should have received a copy of the
GNU Lesser General Public License along with Bohrium.

If not, see <http://www.gnu.org/licenses/>.
*/
#include <iostream>
#include <functional>
#include <algorithm>
#include <sstream>
#include <cassert>
#include <stdexcept>
#include <bh.h>
#include "InstructionBatch.hpp"
#include "GenerateSourceCode.hpp"

InstructionBatch::KernelMap InstructionBatch::kernelMap = InstructionBatch::KernelMap();

InstructionBatch::InstructionBatch(bh_instruction* inst, const std::vector<KernelParameter*>& operands)
    : arraynum(0)
    , scalarnum(0)
    , float16(false)
    , float64(false)
    , complex(false)
{
#ifdef STATS
    gettimeofday(&createTime,NULL);
#endif
    if (inst->operand[0].ndim > 3)
        throw std::runtime_error("More than 3 dimensions not supported.");
    shape = std::vector<bh_index>(inst->operand[0].shape, inst->operand[0].shape + inst->operand[0].ndim);
    add(inst, operands);
}

bool InstructionBatch::shapeMatch(bh_intp ndim,const bh_index dims[])
{
    int size = shape.size();
    if (ndim == size)
    {
        for (int i = 0; i < ndim; ++i)
        {
            if (dims[i] != shape[i])
                return false;
        }
        return true;
    }
    return false;
}

bool InstructionBatch::sameView(const bh_view& a, const bh_view& b)
{
    //assumes the the views shape are the same and they have the same base
    if (a.start != b.start)
        return false;
    for (size_t i = 0; i < shape.size(); ++i)
    {
        if (a.stride[i] != b.stride[i])
            return false;
    }
    return true;
}

inline int gcd(int a, int b)
{
    int c = a % b;
    while(c != 0)
    {
        a = b;
        b = c;
        c = a % b;
    }
    return b;
}

bool InstructionBatch::disjointView(const bh_view& a, const bh_view& b)
{
    //assumes the the views shape are the same and they have the same base
    int astart = a.start;
    int bstart = b.start;
    int stride = 1;
    for (int i = 0; i < a.ndim; ++i)
    {
        stride = gcd(a.stride[i], b.stride[i]);
        int as = astart / stride;
        int bs = bstart / stride;
        int ae = as + a.shape[i] * (a.stride[i]/stride);
        int be = bs + b.shape[i] * (b.stride[i]/stride);
        if (ae <= bs || be <= as)
            return true;
        astart %= stride;
        bstart %= stride;
    }
    if (stride > 1 && a.start % stride != b.start % stride)
        return true;
    return false;
}

void InstructionBatch::add(bh_instruction* inst, const std::vector<KernelParameter*>& operands)
{
    assert(!isScalar(operands[0]));

    // Check that the shape matches
    if (!shapeMatch(inst->operand[0].ndim, inst->operand[0].shape))
        throw BatchException(0);

    std::vector<int> opids(operands.size(),-1);
    std::vector<bool> load_store(operands.size(),true); //do we need to load/store variables
    for (size_t op = 0; op < operands.size(); ++op)
    {
        BaseArray* ba = dynamic_cast<BaseArray*>(operands[op]);
        if (ba) // not a scalar
        {
            // If any operand's base is already used as output, it has to be alligned or disjoint
            ArrayRange orange = output.equal_range(ba);
            for (ArrayMap::iterator oit = orange.first ; oit != orange.second; ++oit)
            {
                if (sameView(views[oit->second], inst->operand[op]))
                {
                    // Same view so we use the ID for it
                    opids[op] = oit->second;
                    if (op == 0) // also output
                        load_store[op] = false;
                }
                else if (!disjointView(views[oit->second], inst->operand[op]))
                {
                    throw BatchException(0);
                }
            }
            // If the output operand is allready used as input it has to be alligned or disjoint
            ArrayRange irange = input.equal_range(ba);
            for (ArrayMap::iterator iit = irange.first ; iit != irange.second; ++iit)
            {
                if (sameView(views[iit->second], inst->operand[op]))
                {
                    // Same view so we use the same ID for it
                    opids[op] =  iit->second;
                    if (op > 0) // also input
                        load_store[op] = false;
                }
                else if (op == 0 && !disjointView(views[iit->second], inst->operand[0]))
                {
                    throw BatchException(0);
                }
            }
        }
    }

    // OK so we can accept the instruction
    for (size_t op = 0; op < operands.size(); ++op)
    {
        // Assign new view id's
        if (opids[op]<0 && inst->operand[op].base)
        {
            int i = op-1;
            for (; i >= 0; --i)
            {   //catch when same view is used twice within oparation and doesn't allready have an id
                if (inst->operand[op].base == inst->operand[i].base &&
                    sameView(inst->operand[op], inst->operand[i]))
                {
                    opids[op] = opids[i];
                    if (op > 0 && i > 0) // both input
                        load_store[op] = false;
                    break;
                }
            }
            if (opids[op] < 0)
            {   // Unkwown view
                opids[op] = views.size();
                views.push_back(inst->operand[op]);
            }
        }

        // Register new parameters and input / output variables
        if (load_store[op])
        {
            KernelParameter* kp = operands[op];
            BaseArray* ba = dynamic_cast<BaseArray*>(kp);
            if (ba)
            {
                if (op == 0)
                {
                    output.insert(std::make_pair(ba, opids[op]));
                }
                else
                {
                    input.insert(std::make_pair(ba, opids[op]));
                }
                if (parameters.find(kp) == parameters.end())
                {
                    std::stringstream ss;
                    ss << "a" << arraynum++;
                    parameters[kp] = ss.str();
                }
            }
            else //scalar
            {
                std::stringstream ss;
                ss << "s" << scalarnum++;
                opids[op] = SCALAR_OFFSET+scalarnum;
                kernelVariables[opids[op]] = ss.str();
                parameters[kp] = ss.str();
            }
            switch (kp->type())
            {
            case OCL_FLOAT16:
                float16 = true;
                break;
            case OCL_FLOAT64:
                float64 = true;
                break;
            case OCL_COMPLEX64:
                complex = true;
                break;
            case OCL_COMPLEX128:
                float64 = true;
                complex = true;
                break;
            default:
                break;
            }
        }
    }
    instructions.push_back(make_pair(inst, opids));
}

Kernel InstructionBatch::generateKernel(ResourceManager* resourceManager)
{
#ifdef STATS
    timeval start, end;
    gettimeofday(&start,NULL);
#endif
    std::string code = generateCode();
#ifdef STATS
    gettimeofday(&end,NULL);
    resourceManager->batchSource += (end.tv_sec - start.tv_sec)*1000000.0 + (end.tv_usec - start.tv_usec);
#endif
    size_t codeHash = string_hasher(code);

    KernelMap::iterator kit = kernelMap.find(codeHash);
    if (kit == kernelMap.end())
    {
        std::stringstream source, kname;
        kname << "kernel" << std::hex << codeHash;
        if (float16)
        {
            source << "#pragma OPENCL EXTENSION cl_khr_fp16 : enable\n";
        }
        if (float64)
        {
            source << "#pragma OPENCL EXTENSION cl_khr_fp64 : enable\n";
        }
        if (complex)
        {
            source << "#include <complex.h>\n";
        }
        source << "__kernel void " << kname.str() << code;
        Kernel kernel(resourceManager, shape.size(), source.str(), kname.str());
        kernelMap.insert(std::make_pair(codeHash, kernel));
        return kernel;
    } else {
        return kit->second;
    }
}

void InstructionBatch::run(ResourceManager* resourceManager)
{
#ifdef STATS
    timeval now;
    gettimeofday(&now,NULL);
    resourceManager->batchBuild += (now.tv_sec - createTime.tv_sec)*1000000.0 + (now.tv_usec - createTime.tv_usec);
#endif

    if (output.begin() != output.end())
    {
        for (ParameterMap::iterator pit = parameters.begin(); pit != parameters.end(); ++pit)
            parameterList.insert(std::make_pair(pit->second, pit->first));
        for (ArrayMap::iterator iit = input.begin(); iit != input.end(); ++iit)
            inputList.insert(std::make_pair(iit->second, iit->first));
        for (ArrayMap::iterator oit = output.begin(); oit != output.end(); ++oit)
            outputList.insert(std::make_pair(oit->second, oit->first));
        Kernel kernel = generateKernel(resourceManager);
        Kernel::Parameters kernelParameters;
        for (ParameterList::iterator pit = parameterList.begin(); pit != parameterList.end(); ++pit)
        {
            if (output.find(static_cast<BaseArray*>(pit->second)) == output.end())
                kernelParameters.push_back(std::make_pair(pit->second, false));
            else
                kernelParameters.push_back(std::make_pair(pit->second, true));
        }
        std::vector<size_t> globalShape;
        for (int i = shape.size()-1; i>=0; --i)
            globalShape.push_back(shape[i]);
        kernel.call(kernelParameters, globalShape);
    }
}

std::string InstructionBatch::generateCode()
{
    std::stringstream source;
    source << "( ";
    // Add Array kernel parameters
    ParameterList::iterator pit = parameterList.begin();
    source << *(pit->second) << " " << pit->first;
    for (++pit; pit != parameterList.end(); ++pit)
    {
        source << "\n                     , " << *(pit->second) << " " << pit->first;
    }

    source << ")\n{\n";

    generateGIDSource(shape, source);

    // Load input parameters
    for (ArrayList::iterator iit = inputList.begin(); iit != inputList.end(); ++iit)
    {
        std::stringstream ss;
        ss << "v" << iit->first;
        kernelVariables[iit->first] = ss.str();
        source << "\t" << oclTypeStr(iit->second->type()) << " " << ss.str() << " = " <<
            parameters[iit->second] << "[";
        generateOffsetSource(views[iit->first], source);
        source << "];\n";
    }

    // Generate code for instructions
    for (InstructionList::iterator iit = instructions.begin(); iit != instructions.end(); ++iit)
    {
        std::vector<std::string> operands;
        // Has the output operand been assigned a variable name?
        VariableMap::iterator kvit = kernelVariables.find(iit->second[0]);
        if (kvit == kernelVariables.end())
        {
            std::stringstream ss;
            ss << "v" << iit->second[0];
            kernelVariables[(iit->second)[0]] = ss.str();
            operands.push_back(ss.str());
            source << "\t" << oclTypeStr(oclType(iit->first->operand[0].base->type)) << " " << ss.str() << ";\n";
        }
        else
        {
            operands.push_back(kvit->second);
        }
        // find variable names for input operands
        for (int op = 1; op < bh_operands(iit->first->opcode); ++op)
        {
            operands.push_back(kernelVariables[iit->second[op]]);
        }
        // generate source code for the instruction
        generateInstructionSource(iit->first->opcode,
                                  std::make_pair(oclType(iit->first->operand[0].base->type),
                                                 oclType(iit->first->operand[1].base ?
                                                         iit->first->operand[1].base->type :
                                                         iit->first->constant.type)),
                                  operands, source);
    }

    // Save output parameters
    for (ArrayList::iterator oit = outputList.begin(); oit != outputList.end(); ++oit)
    {
        source << "\t" << parameters[oit->second] << "[";
        generateOffsetSource(views[oit->first], source);
        source << "] = " <<  kernelVariables[oit->first] << ";\n";
    }

    source << "}\n";
    return source.str();
}

bool InstructionBatch::read(BaseArray* array)
{
    if (input.find(array) == input.end())
        return false;
    return true;
}

bool InstructionBatch::write(BaseArray* array)
{
    if (output.find(array) == output.end())
        return false;
    return true;
}

bool InstructionBatch::access(BaseArray* array)
{
    return (read(array) || write(array));
}

bool InstructionBatch::discard(BaseArray* array)
{
    output.erase(array);
    bool r =  read(array);
    if (!r)
    {
        parameters.erase(static_cast<KernelParameter*>(array));
    }
    return !r;
}
<|endoftext|>


<commit_before>#include "viewer/primitives/camera.hh"

#include <GL/glew.h>

#include "viewer/gl_aliases.hh"

namespace viewer {

cv::Mat Camera::capture_framebuffer() const {
  constexpr int ORIGIN_X = 0;
  constexpr int ORIGIN_Y = 0;
  constexpr int FORMAT = GL_BGR;

  constexpr int WIDTH = 640;
  constexpr int HEIGHT = 640;

  constexpr int TYPE = GL_UNSIGNED_BYTE;

  uint8_t* out_data = new uint8_t[WIDTH * HEIGHT * 3];
  glReadPixels(ORIGIN_X, ORIGIN_Y, WIDTH, HEIGHT, FORMAT, TYPE, out_data);
  constexpr int IM_CV_TYPE = CV_8UC3;
  const cv::Mat image(HEIGHT, WIDTH, IM_CV_TYPE, out_data);
  cv::Mat flipped;
  cv::flip(image, flipped, 0);
  return flipped;
}

void Camera::prepare_view() const {
  glViewport(0, 0, size_.width, size_.height);
  glMatrixMode(GL_PROJECTION);
  glLoadIdentity();
  const double aspect_ratio =
      (static_cast<double>(size_.width) / static_cast<double>(size_.height));
  constexpr double NEAR_CLIP = 0.001;
  constexpr double FAR_CLIP = 1000.0;
  constexpr double FOV = 90.0;
  gluPerspective(FOV, aspect_ratio, NEAR_CLIP, FAR_CLIP);

  glMatrixMode(GL_MODELVIEW);
  glLoadIdentity();
  glTransform(world_from_camera_.inverse());
}

void Camera::draw() {
  const std::lock_guard<std::mutex> lk(draw_mutex_);
  image_ = capture_framebuffer();

  proj_ = Projection::get_from_current();
  have_image_ = true;
}

}  // namespace viewer<commit_msg>Remove memory leak from camera<commit_after>#include "viewer/primitives/camera.hh"

#include <GL/glew.h>

#include "viewer/gl_aliases.hh"

namespace viewer {

cv::Mat Camera::capture_framebuffer() const {
  constexpr int ORIGIN_X = 0;
  constexpr int ORIGIN_Y = 0;
  constexpr int FORMAT = GL_BGR;

  constexpr int WIDTH = 640;
  constexpr int HEIGHT = 640;

  constexpr int TYPE = GL_UNSIGNED_BYTE;

  uint8_t* out_data = new uint8_t[WIDTH * HEIGHT * 3];
  glReadPixels(ORIGIN_X, ORIGIN_Y, WIDTH, HEIGHT, FORMAT, TYPE, out_data);
  constexpr int IM_CV_TYPE = CV_8UC3;
  const cv::Mat image(HEIGHT, WIDTH, IM_CV_TYPE, out_data);
  cv::Mat flipped;
  cv::flip(image, flipped, 0);
  delete out_data;
  return flipped;
}

void Camera::prepare_view() const {
  glViewport(0, 0, size_.width, size_.height);
  glMatrixMode(GL_PROJECTION);
  glLoadIdentity();
  const double aspect_ratio =
      (static_cast<double>(size_.width) / static_cast<double>(size_.height));
  constexpr double NEAR_CLIP = 0.001;
  constexpr double FAR_CLIP = 1000.0;
  constexpr double FOV = 90.0;
  gluPerspective(FOV, aspect_ratio, NEAR_CLIP, FAR_CLIP);

  glMatrixMode(GL_MODELVIEW);
  glLoadIdentity();
  glTransform(world_from_camera_.inverse());
}

void Camera::draw() {
  const std::lock_guard<std::mutex> lk(draw_mutex_);
  image_ = capture_framebuffer();

  proj_ = Projection::get_from_current();
  have_image_ = true;
}

}  // namespace viewer<|endoftext|>


<commit_before>#include "mha_error.hh"
#include <gtest/gtest.h>

TEST(mha_error, helper_function_digits_computes_correct_number_of_decimal_digits)
{
  using mha_error_helpers::digits;
  EXPECT_EQ(1U, digits(0U));
  EXPECT_EQ(1U, digits(1U));
  EXPECT_EQ(1U, digits(9U));
  EXPECT_EQ(2U, digits(10U));
  EXPECT_EQ(2U, digits(99U));
  EXPECT_EQ(3U, digits(100U));
  EXPECT_EQ(10U, digits(4294967295U));
}
<commit_msg>More MHA_Error unit tests.<commit_after>#include "mha_error.hh"
#include <gtest/gtest.h>

TEST(MHA_Error, helper_function_digits_computes_correct_number_of_decimal_digits)
{
  using mha_error_helpers::digits;
  EXPECT_EQ(1U, digits(0U));
  EXPECT_EQ(1U, digits(1U));
  EXPECT_EQ(1U, digits(9U));
  EXPECT_EQ(2U, digits(10U));
  EXPECT_EQ(2U, digits(99U));
  EXPECT_EQ(3U, digits(100U));
  EXPECT_EQ(10U, digits(4294967295U));
}

TEST(MHA_Error, MHA_Error_is_a_subclass_of_std_exception) {
  MHA_Error error_instance("",0,"");
  std::exception * std_exception_pointer = &error_instance;
  EXPECT_NE(nullptr, std_exception_pointer);
}
<|endoftext|>


<commit_before>
#include <log4cplus/consoleappender.h>
#include <log4cplus/layout.h>
#include <log4cplus/logger.h>
#include <log4cplus/ndc.h>
#include <log4cplus/helpers/loglog.h>
#include <log4cplus/thread/threads.h>
#include <log4cplus/helpers/sleep.h>
#include <log4cplus/streams.h>
#include <log4cplus/loggingmacros.h>
#include <log4cplus/tracelogger.h>
#include <exception>
#include <iostream>
#include <string>

using namespace std;
using namespace log4cplus;
using namespace log4cplus::helpers;
using namespace log4cplus::thread;

#define MILLIS_TO_NANOS 1000
#define NUM_THREADS 4
#define NUM_LOOPS 10

class SlowObject {
public:
    SlowObject()
        : logger(Logger::getInstance(LOG4CPLUS_TEXT("SlowObject")))
    {
        logger.setLogLevel(TRACE_LOG_LEVEL);
    }

    void doSomething()
    {
        LOG4CPLUS_TRACE_METHOD(logger, LOG4CPLUS_TEXT("SlowObject::doSomething()"));
        {
            log4cplus::thread::MutexGuard guard (mutex);
            LOG4CPLUS_INFO(logger, LOG4CPLUS_TEXT("Actually doing something..."));
            sleep(0, 75 * MILLIS_TO_NANOS);
            LOG4CPLUS_INFO_FMT(logger,
                LOG4CPLUS_TEXT (
                    "Actually doing something...%d, %d, %d...DONE"),
                1, 2, 3);
        }
        log4cplus::thread::yield();
    }

    ~SlowObject ()
    { }

private:
    log4cplus::thread::Mutex mutex;
    Logger logger;
};

SlowObject *global;

class TestThread : public AbstractThread {
public:
    TestThread(tstring n)
        : name(n), logger(Logger::getInstance(LOG4CPLUS_TEXT("test.TestThread")))
     {
     }

    virtual void run();

private:
    tstring name;
    Logger logger;
};

int
main()
{
    auto_ptr<SlowObject> globalContainer(new SlowObject());
    global = globalContainer.get();

    try {
        log4cplus::helpers::LogLog::getLogLog()->setInternalDebugging(true);
        Logger logger = Logger::getInstance(LOG4CPLUS_TEXT("main"));
        Logger::getRoot().setLogLevel(INFO_LOG_LEVEL);
        LogLevel ll = logger.getLogLevel();
        tcout << "main Priority: " << getLogLevelManager().toString(ll) << endl;

        helpers::SharedObjectPtr<Appender> append_1(new ConsoleAppender());
        append_1->setLayout( std::auto_ptr<Layout>(new log4cplus::TTCCLayout()) );
        Logger::getRoot().addAppender(append_1);
        append_1->setName(LOG4CPLUS_TEXT("cout"));

	    append_1 = 0;

        log4cplus::helpers::SharedObjectPtr<TestThread> threads[NUM_THREADS];
        int i = 0;
        for(i=0; i<NUM_THREADS; ++i) {
            tostringstream s;
            s << "Thread-" << i;
            threads[i] = new TestThread(s.str());
        }

        for(i=0; i<NUM_THREADS; ++i) {
            threads[i]->start();
        }
        LOG4CPLUS_DEBUG(logger, "All Threads started...");

        for(i=0; i<NUM_THREADS; ++i) {
            while(threads[i]->isRunning()) {
                sleep(0, 200 * MILLIS_TO_NANOS);
            }
        }
        LOG4CPLUS_INFO(logger, "Exiting main()...");
    }
    catch(std::exception &e) {
        LOG4CPLUS_FATAL(Logger::getRoot(), "main()- Exception occured: " << e.what());
    }
    catch(...) {
        LOG4CPLUS_FATAL(Logger::getRoot(), "main()- Exception occured");
    }

    log4cplus::Logger::shutdown();
    return 0;
}

void
TestThread::run()
{
    try {
        LOG4CPLUS_WARN(logger, name + LOG4CPLUS_TEXT(" TestThread.run()- Starting..."));
        NDC& ndc = getNDC();
        NDCContextCreator _first_ndc(name);
        LOG4CPLUS_DEBUG(logger, "Entering Run()...");
        for(int i=0; i<NUM_LOOPS; ++i) {
            NDCContextCreator _ndc(LOG4CPLUS_TEXT("loop"));
            global->doSomething();
        }
        LOG4CPLUS_DEBUG(logger, "Exiting run()...");

        ndc.remove();
    }
    catch(exception& e) {
        LOG4CPLUS_FATAL(logger, "TestThread.run()- Exception occurred: " << e.what());
    }
    catch(...) {
        LOG4CPLUS_FATAL(logger, "TestThread.run()- Exception occurred!!");
    }
    LOG4CPLUS_WARN(logger, name << " TestThread.run()- Finished");
} // end "run"

<commit_msg>thread_test/main.cxx: Use %ls and wchar_t string literal.<commit_after>
#include <log4cplus/consoleappender.h>
#include <log4cplus/layout.h>
#include <log4cplus/logger.h>
#include <log4cplus/ndc.h>
#include <log4cplus/helpers/loglog.h>
#include <log4cplus/thread/threads.h>
#include <log4cplus/helpers/sleep.h>
#include <log4cplus/streams.h>
#include <log4cplus/loggingmacros.h>
#include <log4cplus/tracelogger.h>
#include <exception>
#include <iostream>
#include <string>

using namespace std;
using namespace log4cplus;
using namespace log4cplus::helpers;
using namespace log4cplus::thread;

#define MILLIS_TO_NANOS 1000
#define NUM_THREADS 4
#define NUM_LOOPS 10

class SlowObject {
public:
    SlowObject()
        : logger(Logger::getInstance(LOG4CPLUS_TEXT("SlowObject")))
    {
        logger.setLogLevel(TRACE_LOG_LEVEL);
    }

    void doSomething()
    {
        LOG4CPLUS_TRACE_METHOD(logger, LOG4CPLUS_TEXT("SlowObject::doSomething()"));
        {
            log4cplus::thread::MutexGuard guard (mutex);
            LOG4CPLUS_INFO(logger, LOG4CPLUS_TEXT("Actually doing something..."));
            sleep(0, 75 * MILLIS_TO_NANOS);
            LOG4CPLUS_INFO_FMT(logger,
                LOG4CPLUS_TEXT (
                    "Actually doing something...%d, %d, %d, %ls...DONE"),
                1, 2, 3, L"testing");
        }
        log4cplus::thread::yield();
    }

    ~SlowObject ()
    { }

private:
    log4cplus::thread::Mutex mutex;
    Logger logger;
};

SlowObject *global;

class TestThread : public AbstractThread {
public:
    TestThread(tstring n)
        : name(n), logger(Logger::getInstance(LOG4CPLUS_TEXT("test.TestThread")))
     {
     }

    virtual void run();

private:
    tstring name;
    Logger logger;
};

int
main()
{
    auto_ptr<SlowObject> globalContainer(new SlowObject());
    global = globalContainer.get();

    try {
        log4cplus::helpers::LogLog::getLogLog()->setInternalDebugging(true);
        Logger logger = Logger::getInstance(LOG4CPLUS_TEXT("main"));
        Logger::getRoot().setLogLevel(INFO_LOG_LEVEL);
        LogLevel ll = logger.getLogLevel();
        tcout << "main Priority: " << getLogLevelManager().toString(ll) << endl;

        helpers::SharedObjectPtr<Appender> append_1(new ConsoleAppender());
        append_1->setLayout( std::auto_ptr<Layout>(new log4cplus::TTCCLayout()) );
        Logger::getRoot().addAppender(append_1);
        append_1->setName(LOG4CPLUS_TEXT("cout"));

	    append_1 = 0;

        log4cplus::helpers::SharedObjectPtr<TestThread> threads[NUM_THREADS];
        int i = 0;
        for(i=0; i<NUM_THREADS; ++i) {
            tostringstream s;
            s << "Thread-" << i;
            threads[i] = new TestThread(s.str());
        }

        for(i=0; i<NUM_THREADS; ++i) {
            threads[i]->start();
        }
        LOG4CPLUS_DEBUG(logger, "All Threads started...");

        for(i=0; i<NUM_THREADS; ++i) {
            while(threads[i]->isRunning()) {
                sleep(0, 200 * MILLIS_TO_NANOS);
            }
        }
        LOG4CPLUS_INFO(logger, "Exiting main()...");
    }
    catch(std::exception &e) {
        LOG4CPLUS_FATAL(Logger::getRoot(), "main()- Exception occured: " << e.what());
    }
    catch(...) {
        LOG4CPLUS_FATAL(Logger::getRoot(), "main()- Exception occured");
    }

    log4cplus::Logger::shutdown();
    return 0;
}

void
TestThread::run()
{
    try {
        LOG4CPLUS_WARN(logger, name + LOG4CPLUS_TEXT(" TestThread.run()- Starting..."));
        NDC& ndc = getNDC();
        NDCContextCreator _first_ndc(name);
        LOG4CPLUS_DEBUG(logger, "Entering Run()...");
        for(int i=0; i<NUM_LOOPS; ++i) {
            NDCContextCreator _ndc(LOG4CPLUS_TEXT("loop"));
            global->doSomething();
        }
        LOG4CPLUS_DEBUG(logger, "Exiting run()...");

        ndc.remove();
    }
    catch(exception& e) {
        LOG4CPLUS_FATAL(logger, "TestThread.run()- Exception occurred: " << e.what());
    }
    catch(...) {
        LOG4CPLUS_FATAL(logger, "TestThread.run()- Exception occurred!!");
    }
    LOG4CPLUS_WARN(logger, name << " TestThread.run()- Finished");
} // end "run"

<|endoftext|>