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

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

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

Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
==============================================================================*/
#include <algorithm>
#include <cmath>
#include <cstdlib>
#include <functional>
#include <iterator>
#include <limits>
#include <random>
#include <string>
#include <vector>

#include <gtest/gtest.h>
#include "tensorflow/lite/kernels/internal/optimized/integer_ops/pooling.h"
#include "tensorflow/lite/kernels/internal/reference/integer_ops/pooling.h"
#include "tensorflow/lite/kernels/internal/test_util.h"

namespace tflite {
namespace {

// Runs the reference and optimized AveragePool functions and asserts the values
// are the same.
void RunOneAveragePoolTest(const PoolParams& params,
                           const RuntimeShape& input_shape,
                           const int8* input_data,
                           const RuntimeShape& output_shape) {
  const int buffer_size = output_shape.FlatSize();
  std::vector<int8> optimized_averagePool_output(buffer_size);
  std::vector<int8> reference_averagePool_output(buffer_size);

  reference_integer_ops::AveragePool(params, input_shape, input_data,
                                     output_shape,
                                     reference_averagePool_output.data());
  optimized_integer_ops::AveragePool(params, input_shape, input_data,
                                     output_shape,
                                     optimized_averagePool_output.data());

  for (int i = 0; i < buffer_size; i++) {
    EXPECT_TRUE(reference_averagePool_output[i] ==
                optimized_averagePool_output[i]);
  }
}

// Creates random input shape (batch, height, width, depth), then computes
// output shape based on value of `padding_same`:
// `padding_same` == true, calculate output with padding == "SAME"
// `padding_same` == false, calculate output with padding == "VALID"
// With input/output shapes computed, fills the input data and calls the
// test function.
void CreateDataAndRunAveragePool(bool padding_same) {
  const int batch = UniformRandomInt(1, 2);
  const int input_depth = UniformRandomInt(1, 700);
  const int output_depth = input_depth;
  const int input_width_offset = UniformRandomInt(1, 30);
  const int input_height_offset = UniformRandomInt(1, 30);
  const int stride_width = UniformRandomInt(1, 10);
  const int stride_height = UniformRandomInt(1, 10);
  const int filter_width = UniformRandomInt(1, 10);
  const int filter_height = UniformRandomInt(1, 10);
  const int input_width = input_width_offset + filter_width;
  const int input_height = input_height_offset + filter_height;
  const int output_width =
      padding_same ? (input_width + stride_width - 1) / stride_width
                   : (input_width - filter_width + stride_width) / stride_width;
  const int output_height =
      padding_same
          ? (input_height + stride_height - 1) / stride_height
          : (input_height - filter_height + stride_height) / stride_height;

  auto input_shape =
      RuntimeShape({batch, input_height, input_width, input_depth});
  auto output_shape =
      RuntimeShape({batch, output_height, output_width, output_depth});
  const int buffer_size = input_shape.FlatSize();
  std::vector<int8> input_data(buffer_size);
  FillRandom(&input_data);

  PoolParams params;
  params.stride_height = stride_height;
  params.stride_width = stride_width;
  params.filter_height = filter_height;
  params.filter_width = filter_width;
  params.quantized_activation_min =
      static_cast<int8_t>(std::numeric_limits<int8_t>::lowest());
  params.quantized_activation_max =
      static_cast<int8_t>(std::numeric_limits<int8_t>::max());
  auto compute_padding = [](int stride, int in_size, int filter_size,
                            int out_size) {
    int padding = ((out_size - 1) * stride + filter_size - in_size) / 2;
    return padding > 0 ? padding : 0;
  };
  params.padding_values.width =
      compute_padding(stride_width, input_width, filter_width, output_width);
  params.padding_values.height = compute_padding(stride_height, input_height,
                                                 filter_height, output_height);
  RunOneAveragePoolTest(params, input_shape, input_data.data(), output_shape);
}

TEST(TestAveragePool, SymmetricQuantAveragePool) {
  const int kTestsToRun = 10;
  for (int i = 0; i < kTestsToRun; i++) {
    CreateDataAndRunAveragePool(/*padding_same=*/true);
    CreateDataAndRunAveragePool(/*padding_same=*/false);
  }
}

}  // namespace
}  // namespace tflite
<commit_msg>Added test for optimized average pooling that tests a tensor with values concentrated around the endpoints of the int8 numerical range.<commit_after>/* Copyright 2019 The TensorFlow Authors. All Rights Reserved.

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

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

Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
==============================================================================*/
#include <algorithm>
#include <cmath>
#include <cstdlib>
#include <functional>
#include <iterator>
#include <limits>
#include <random>
#include <string>
#include <vector>

#include <gtest/gtest.h>
#include "tensorflow/lite/kernels/internal/optimized/integer_ops/pooling.h"
#include "tensorflow/lite/kernels/internal/reference/integer_ops/pooling.h"
#include "tensorflow/lite/kernels/internal/test_util.h"

namespace tflite {
namespace {

// Runs the reference and optimized AveragePool functions and asserts the values
// are the same.
void RunOneAveragePoolTest(const PoolParams& params,
                           const RuntimeShape& input_shape,
                           const int8* input_data,
                           const RuntimeShape& output_shape) {
  const int buffer_size = output_shape.FlatSize();
  std::vector<int8> optimized_averagePool_output(buffer_size);
  std::vector<int8> reference_averagePool_output(buffer_size);

  reference_integer_ops::AveragePool(params, input_shape, input_data,
                                     output_shape,
                                     reference_averagePool_output.data());
  optimized_integer_ops::AveragePool(params, input_shape, input_data,
                                     output_shape,
                                     optimized_averagePool_output.data());

  for (int i = 0; i < buffer_size; i++) {
    EXPECT_TRUE(reference_averagePool_output[i] ==
                optimized_averagePool_output[i]);
  }
}

// Creates random input shape (batch, height, width, depth), then computes
// output shape based on value of `padding_same`:
// `padding_same` == true, calculate output with padding == "SAME"
// `padding_same` == false, calculate output with padding == "VALID"
// With input/output shapes computed, fills the input data and calls the
// test function.
void CreateDataAndRunAveragePool(bool padding_same) {
  const int batch = UniformRandomInt(1, 2);
  const int input_depth = UniformRandomInt(1, 700);
  const int output_depth = input_depth;
  const int input_width_offset = UniformRandomInt(1, 30);
  const int input_height_offset = UniformRandomInt(1, 30);
  const int stride_width = UniformRandomInt(1, 10);
  const int stride_height = UniformRandomInt(1, 10);
  const int filter_width = UniformRandomInt(1, 10);
  const int filter_height = UniformRandomInt(1, 10);
  const int input_width = input_width_offset + filter_width;
  const int input_height = input_height_offset + filter_height;
  const int output_width =
      padding_same ? (input_width + stride_width - 1) / stride_width
                   : (input_width - filter_width + stride_width) / stride_width;
  const int output_height =
      padding_same
          ? (input_height + stride_height - 1) / stride_height
          : (input_height - filter_height + stride_height) / stride_height;

  auto input_shape =
      RuntimeShape({batch, input_height, input_width, input_depth});
  auto output_shape =
      RuntimeShape({batch, output_height, output_width, output_depth});
  const int buffer_size = input_shape.FlatSize();
  std::vector<int8> input_data(buffer_size);
  FillRandom(&input_data);

  PoolParams params;
  params.stride_height = stride_height;
  params.stride_width = stride_width;
  params.filter_height = filter_height;
  params.filter_width = filter_width;
  params.quantized_activation_min =
      static_cast<int8_t>(std::numeric_limits<int8_t>::lowest());
  params.quantized_activation_max =
      static_cast<int8_t>(std::numeric_limits<int8_t>::max());
  auto compute_padding = [](int stride, int in_size, int filter_size,
                            int out_size) {
    int padding = ((out_size - 1) * stride + filter_size - in_size) / 2;
    return padding > 0 ? padding : 0;
  };
  params.padding_values.width =
      compute_padding(stride_width, input_width, filter_width, output_width);
  params.padding_values.height = compute_padding(stride_height, input_height,
                                                 filter_height, output_height);
  RunOneAveragePoolTest(params, input_shape, input_data.data(), output_shape);
}

TEST(TestAveragePool, SymmetricQuantAveragePool) {
  const int kTestsToRun = 10;
  for (int i = 0; i < kTestsToRun; i++) {
    CreateDataAndRunAveragePool(/*padding_same=*/true);
    CreateDataAndRunAveragePool(/*padding_same=*/false);
  }
}

// Creates random input shape (batch, height, width, depth), then computes
// output shape based on value of `padding_same`:
// `padding_same` == true, calculate output with padding == "SAME"
// `padding_same` == false, calculate output with padding == "VALID"
// With input/output shapes computed, fills the input data and calls the
// test function.
void CreateExtremalDataAndRunAveragePool(bool padding_same) {
  const int batch = UniformRandomInt(1, 2);
  const int input_depth = UniformRandomInt(1, 700);
  const int output_depth = input_depth;
  const int input_width_offset = UniformRandomInt(1, 30);
  const int input_height_offset = UniformRandomInt(1, 30);
  const int stride_width = UniformRandomInt(1, 128);
  const int stride_height = UniformRandomInt(1, 128);
  const int filter_width = UniformRandomInt(1, 28);
  const int filter_height = UniformRandomInt(1, 28);
  if (filter_width * filter_height > 64) {
    std::cout << "should test 32 version" << std::endl;
  }
  const int input_width = input_width_offset + filter_width;
  const int input_height = input_height_offset + filter_height;
  const int output_width =
      padding_same ? (input_width + stride_width - 1) / stride_width
                   : (input_width - filter_width + stride_width) / stride_width;
  const int output_height =
      padding_same
          ? (input_height + stride_height - 1) / stride_height
          : (input_height - filter_height + stride_height) / stride_height;

  auto input_shape =
      RuntimeShape({batch, input_height, input_width, input_depth});
  auto output_shape =
      RuntimeShape({batch, output_height, output_width, output_depth});

  PoolParams params;
  params.stride_height = stride_height;
  params.stride_width = stride_width;
  params.filter_height = filter_height;
  params.filter_width = filter_width;
  params.quantized_activation_min =
      static_cast<int8_t>(std::numeric_limits<int8_t>::lowest());
  params.quantized_activation_max =
      static_cast<int8_t>(std::numeric_limits<int8_t>::max());
  auto compute_padding = [](int stride, int in_size, int filter_size,
                            int out_size) {
    int padding = ((out_size - 1) * stride + filter_size - in_size) / 2;
    return padding > 0 ? padding : 0;
  };
  params.padding_values.width =
      compute_padding(stride_width, input_width, filter_width, output_width);
  params.padding_values.height = compute_padding(stride_height, input_height,
                                                 filter_height, output_height);

  const int buffer_size = input_shape.FlatSize();
  std::vector<int8> input_data(buffer_size);

  // Test small values
  int8 min = std::numeric_limits<int8>::min();
  int8 max = std::numeric_limits<int8>::min() + 10;
  FillRandom(&input_data, min, max);
  RunOneAveragePoolTest(params, input_shape, input_data.data(), output_shape);

  // Test large values
  min = std::numeric_limits<int8>::max() - 10;
  max = std::numeric_limits<int8>::max();
  FillRandom(&input_data, min, max);
  RunOneAveragePoolTest(params, input_shape, input_data.data(), output_shape);
}

TEST(TestAveragePool, SymmetricQuantExtremalAveragePool) {
  CreateExtremalDataAndRunAveragePool(/*padding_same=*/true);
  CreateExtremalDataAndRunAveragePool(/*padding_same=*/false);
}

}  // namespace
}  // namespace tflite
<|endoftext|>


<commit_before>// The libMesh Finite Element Library.
// Copyright (C) 2002-2021 Benjamin S. Kirk, John W. Peterson, Roy H. Stogner

// This library 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 2.1 of the License, or (at your option) any later version.

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

// You should have received a copy of the GNU Lesser General Public
// License along with this library; if not, write to the Free Software
// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA

// Local includes
#include "libmesh/node.h"
#include "libmesh/elem.h"
#include "libmesh/reference_elem.h"
#include "libmesh/libmesh_singleton.h"
#include "libmesh/threads.h"
#include "libmesh/enum_to_string.h"
#include "libmesh/enum_elem_type.h"

// C++ includes
#include <map>
#include <sstream>

//-----------------------------------------------
// anonymous namespace for implementation details
namespace
{
using namespace libMesh;

namespace ElemDataStrings
{
// GCC 5.2.0 warns about overlength strings in the auto-generated
// reference_elem.data file.
#pragma GCC diagnostic ignored "-Woverlength-strings"
#include "reference_elem.data"
#pragma GCC diagnostic warning "-Woverlength-strings"
}

typedef Threads::spin_mutex InitMutex;

// Mutex for thread safety.
InitMutex init_mtx;

// map from ElemType to reference element file system object name
typedef std::map<ElemType, const char *> FileMapType;
FileMapType ref_elem_file;
Elem * ref_elem_map[INVALID_ELEM];

class SingletonCache : public libMesh::Singleton
{
public:
  ~SingletonCache()
  {
    for (auto & elem : elem_list)
      {
        delete elem;
        elem = nullptr;
      }

    elem_list.clear();

    for (auto & node : node_list)
      {
        delete node;
        node = nullptr;
      }

    node_list.clear();
  }

  std::vector<Node *> node_list;
  std::vector<Elem *> elem_list;
};

// singleton object, dynamically created and then
// removed at program exit
SingletonCache * singleton_cache = nullptr;

void read_ref_elem (const ElemType type_in,
                    std::istream & in)
{
  libmesh_assert (singleton_cache != nullptr);

  std::string dummy;
  unsigned int n_elem, n_nodes, elem_type_read, nn;
  double x, y, z;

  in >> dummy;
  in >> n_elem;  /**/ std::getline (in, dummy); libmesh_assert_equal_to (n_elem, 1);
  in >> n_nodes; /**/ std::getline (in, dummy);
  in >> dummy;   /**/ std::getline (in, dummy);
  in >> dummy;   /**/ std::getline (in, dummy);
  in >> dummy;   /**/ std::getline (in, dummy);
  in >> dummy;   /**/ std::getline (in, dummy);
  in >> n_elem;  /**/ std::getline (in, dummy); libmesh_assert_equal_to (n_elem, 1);

  in >> elem_type_read;

  libmesh_assert_less (elem_type_read, INVALID_ELEM);
  libmesh_assert_equal_to (elem_type_read, static_cast<unsigned int>(type_in));
  libmesh_assert_equal_to (n_nodes, Elem::type_to_n_nodes_map[elem_type_read]);

  // Construct elem of appropriate type
  std::unique_ptr<Elem> uelem = Elem::build(type_in);

  // We are expecting an identity map, so assert it!
  for (unsigned int n=0; n<n_nodes; n++)
    {
      in >> nn;
      libmesh_assert_equal_to (n,nn);
    }

  for (unsigned int n=0; n<n_nodes; n++)
    {
      in >> x >> y >> z;

      Node * node = new Node(x,y,z,n);
      singleton_cache->node_list.push_back(node);

      uelem->set_node(n) = node;
    }

  // it is entirely possible we ran out of file or encountered
  // another error.  If so, throw an error.
  libmesh_error_msg_if(!in, "ERROR while creating element singleton!");

  // Release the pointer into the care of the singleton_cache
  singleton_cache->elem_list.push_back (uelem.release());

  // Also store it in the array.
  ref_elem_map[type_in] = singleton_cache->elem_list.back();
}

void init_ref_elem_table()
{
  // outside mutex - if this pointer is set, we can trust it.
  if (singleton_cache != nullptr)
    return;

  // playing with fire here - lock before touching shared
  // data structures
  InitMutex::scoped_lock lock(init_mtx);

  // inside mutex - pointer may have changed while waiting
  // for the lock to acquire, check it again.
  if (singleton_cache != nullptr)
    return;

  // OK, if we get here we have the lock and we are not
  // initialized.  populate singleton.
  singleton_cache = new SingletonCache;

  // initialize the reference file table
  {
    ref_elem_file.clear();

    // 1D elements
    ref_elem_file[EDGE2]    = ElemDataStrings::one_edge;
    ref_elem_file[EDGE3]    = ElemDataStrings::one_edge3;
    ref_elem_file[EDGE4]    = ElemDataStrings::one_edge4;

    // 2D elements
    ref_elem_file[TRI3]     = ElemDataStrings::one_tri;
    ref_elem_file[TRI6]     = ElemDataStrings::one_tri6;

    ref_elem_file[QUAD4]    = ElemDataStrings::one_quad;
    ref_elem_file[QUAD8]    = ElemDataStrings::one_quad8;
    ref_elem_file[QUAD9]    = ElemDataStrings::one_quad9;

    // 3D elements
    ref_elem_file[HEX8]     = ElemDataStrings::one_hex;
    ref_elem_file[HEX20]    = ElemDataStrings::one_hex20;
    ref_elem_file[HEX27]    = ElemDataStrings::one_hex27;

    ref_elem_file[TET4]     = ElemDataStrings::one_tet;
    ref_elem_file[TET10]    = ElemDataStrings::one_tet10;

    ref_elem_file[PRISM6]   = ElemDataStrings::one_prism;
    ref_elem_file[PRISM15]  = ElemDataStrings::one_prism15;
    ref_elem_file[PRISM18]  = ElemDataStrings::one_prism18;

    ref_elem_file[PYRAMID5] = ElemDataStrings::one_pyramid;
    ref_elem_file[PYRAMID13] = ElemDataStrings::one_pyramid13;
    ref_elem_file[PYRAMID14] = ElemDataStrings::one_pyramid14;
  }

  // Read'em
  for (const auto & pr : ref_elem_file)
    {
      std::istringstream stream(pr.second);
      read_ref_elem(pr.first, stream);
    }
}

// no reason to do this at startup -
// data structures will get initialized *if*
// ReferenceElem::get() is ever called.
// // Class to setup singleton data
// class ReferenceElemSetup : public Singleton::Setup
// {
//   void setup ()
//   {
//     init_ref_elem_table();
//   }
// } reference_elem_setup;

} // anonymous namespace

//----------------------------------------------------------------------------
// external API Implementation
namespace libMesh
{
namespace ReferenceElem
{
const Elem & get (const ElemType type_in)
{
  ElemType base_type = type_in;

  // For shell elements, use non shell type as the base type
  if (type_in == TRISHELL3)
    base_type = TRI3;

  if (type_in == QUADSHELL4)
    base_type = QUAD4;

  if (type_in == QUADSHELL8)
    base_type = QUAD8;

  init_ref_elem_table();

  // Throw an error if the user asked for an ElemType that we don't
  // have a reference element for.
  libmesh_error_msg_if(ref_elem_map[base_type] == nullptr || type_in == INVALID_ELEM,
                       "No reference elem data available for ElemType " << type_in
                       << " = " << Utility::enum_to_string(type_in) << ".");

  return *ref_elem_map[base_type];
}
} // namespace ReferenceElem
} // namespace libMesh
<commit_msg>Add TRI7 reference element entry<commit_after>// The libMesh Finite Element Library.
// Copyright (C) 2002-2021 Benjamin S. Kirk, John W. Peterson, Roy H. Stogner

// This library 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 2.1 of the License, or (at your option) any later version.

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

// You should have received a copy of the GNU Lesser General Public
// License along with this library; if not, write to the Free Software
// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA

// Local includes
#include "libmesh/node.h"
#include "libmesh/elem.h"
#include "libmesh/reference_elem.h"
#include "libmesh/libmesh_singleton.h"
#include "libmesh/threads.h"
#include "libmesh/enum_to_string.h"
#include "libmesh/enum_elem_type.h"

// C++ includes
#include <map>
#include <sstream>

//-----------------------------------------------
// anonymous namespace for implementation details
namespace
{
using namespace libMesh;

namespace ElemDataStrings
{
// GCC 5.2.0 warns about overlength strings in the auto-generated
// reference_elem.data file.
#pragma GCC diagnostic ignored "-Woverlength-strings"
#include "reference_elem.data"
#pragma GCC diagnostic warning "-Woverlength-strings"
}

typedef Threads::spin_mutex InitMutex;

// Mutex for thread safety.
InitMutex init_mtx;

// map from ElemType to reference element file system object name
typedef std::map<ElemType, const char *> FileMapType;
FileMapType ref_elem_file;
Elem * ref_elem_map[INVALID_ELEM];

class SingletonCache : public libMesh::Singleton
{
public:
  ~SingletonCache()
  {
    for (auto & elem : elem_list)
      {
        delete elem;
        elem = nullptr;
      }

    elem_list.clear();

    for (auto & node : node_list)
      {
        delete node;
        node = nullptr;
      }

    node_list.clear();
  }

  std::vector<Node *> node_list;
  std::vector<Elem *> elem_list;
};

// singleton object, dynamically created and then
// removed at program exit
SingletonCache * singleton_cache = nullptr;

void read_ref_elem (const ElemType type_in,
                    std::istream & in)
{
  libmesh_assert (singleton_cache != nullptr);

  std::string dummy;
  unsigned int n_elem, n_nodes, elem_type_read, nn;
  double x, y, z;

  in >> dummy;
  in >> n_elem;  /**/ std::getline (in, dummy); libmesh_assert_equal_to (n_elem, 1);
  in >> n_nodes; /**/ std::getline (in, dummy);
  in >> dummy;   /**/ std::getline (in, dummy);
  in >> dummy;   /**/ std::getline (in, dummy);
  in >> dummy;   /**/ std::getline (in, dummy);
  in >> dummy;   /**/ std::getline (in, dummy);
  in >> n_elem;  /**/ std::getline (in, dummy); libmesh_assert_equal_to (n_elem, 1);

  in >> elem_type_read;

  libmesh_assert_less (elem_type_read, INVALID_ELEM);
  libmesh_assert_equal_to (elem_type_read, static_cast<unsigned int>(type_in));
  libmesh_assert_equal_to (n_nodes, Elem::type_to_n_nodes_map[elem_type_read]);

  // Construct elem of appropriate type
  std::unique_ptr<Elem> uelem = Elem::build(type_in);

  // We are expecting an identity map, so assert it!
  for (unsigned int n=0; n<n_nodes; n++)
    {
      in >> nn;
      libmesh_assert_equal_to (n,nn);
    }

  for (unsigned int n=0; n<n_nodes; n++)
    {
      in >> x >> y >> z;

      Node * node = new Node(x,y,z,n);
      singleton_cache->node_list.push_back(node);

      uelem->set_node(n) = node;
    }

  // it is entirely possible we ran out of file or encountered
  // another error.  If so, throw an error.
  libmesh_error_msg_if(!in, "ERROR while creating element singleton!");

  // Release the pointer into the care of the singleton_cache
  singleton_cache->elem_list.push_back (uelem.release());

  // Also store it in the array.
  ref_elem_map[type_in] = singleton_cache->elem_list.back();
}

void init_ref_elem_table()
{
  // outside mutex - if this pointer is set, we can trust it.
  if (singleton_cache != nullptr)
    return;

  // playing with fire here - lock before touching shared
  // data structures
  InitMutex::scoped_lock lock(init_mtx);

  // inside mutex - pointer may have changed while waiting
  // for the lock to acquire, check it again.
  if (singleton_cache != nullptr)
    return;

  // OK, if we get here we have the lock and we are not
  // initialized.  populate singleton.
  singleton_cache = new SingletonCache;

  // initialize the reference file table
  {
    ref_elem_file.clear();

    // 1D elements
    ref_elem_file[EDGE2]    = ElemDataStrings::one_edge;
    ref_elem_file[EDGE3]    = ElemDataStrings::one_edge3;
    ref_elem_file[EDGE4]    = ElemDataStrings::one_edge4;

    // 2D elements
    ref_elem_file[TRI3]     = ElemDataStrings::one_tri;
    ref_elem_file[TRI6]     = ElemDataStrings::one_tri6;
    ref_elem_file[TRI7]     = ElemDataStrings::one_tri7;

    ref_elem_file[QUAD4]    = ElemDataStrings::one_quad;
    ref_elem_file[QUAD8]    = ElemDataStrings::one_quad8;
    ref_elem_file[QUAD9]    = ElemDataStrings::one_quad9;

    // 3D elements
    ref_elem_file[HEX8]     = ElemDataStrings::one_hex;
    ref_elem_file[HEX20]    = ElemDataStrings::one_hex20;
    ref_elem_file[HEX27]    = ElemDataStrings::one_hex27;

    ref_elem_file[TET4]     = ElemDataStrings::one_tet;
    ref_elem_file[TET10]    = ElemDataStrings::one_tet10;

    ref_elem_file[PRISM6]   = ElemDataStrings::one_prism;
    ref_elem_file[PRISM15]  = ElemDataStrings::one_prism15;
    ref_elem_file[PRISM18]  = ElemDataStrings::one_prism18;

    ref_elem_file[PYRAMID5] = ElemDataStrings::one_pyramid;
    ref_elem_file[PYRAMID13] = ElemDataStrings::one_pyramid13;
    ref_elem_file[PYRAMID14] = ElemDataStrings::one_pyramid14;
  }

  // Read'em
  for (const auto & pr : ref_elem_file)
    {
      std::istringstream stream(pr.second);
      read_ref_elem(pr.first, stream);
    }
}

// no reason to do this at startup -
// data structures will get initialized *if*
// ReferenceElem::get() is ever called.
// // Class to setup singleton data
// class ReferenceElemSetup : public Singleton::Setup
// {
//   void setup ()
//   {
//     init_ref_elem_table();
//   }
// } reference_elem_setup;

} // anonymous namespace

//----------------------------------------------------------------------------
// external API Implementation
namespace libMesh
{
namespace ReferenceElem
{
const Elem & get (const ElemType type_in)
{
  ElemType base_type = type_in;

  // For shell elements, use non shell type as the base type
  if (type_in == TRISHELL3)
    base_type = TRI3;

  if (type_in == QUADSHELL4)
    base_type = QUAD4;

  if (type_in == QUADSHELL8)
    base_type = QUAD8;

  init_ref_elem_table();

  // Throw an error if the user asked for an ElemType that we don't
  // have a reference element for.
  libmesh_error_msg_if(ref_elem_map[base_type] == nullptr || type_in == INVALID_ELEM,
                       "No reference elem data available for ElemType " << type_in
                       << " = " << Utility::enum_to_string(type_in) << ".");

  return *ref_elem_map[base_type];
}
} // namespace ReferenceElem
} // namespace libMesh
<|endoftext|>


<commit_before>//******************************************************************************
// FILE : function_matrix_determinant.cpp
//
// LAST MODIFIED : 6 October 2004
//
// DESCRIPTION :
//==============================================================================

#if defined (ONE_TEMPLATE_DEFINITION_IMPLEMENTED)
#include "computed_variable/function_matrix_determinant_implementation.cpp"
#else // defined (ONE_TEMPLATE_DEFINITION_IMPLEMENTED)
#include "computed_variable/function_matrix_determinant.hpp"
#endif // defined (ONE_TEMPLATE_DEFINITION_IMPLEMENTED)

#if !defined (AIX)
#include "computed_variable/function_derivative_matrix.hpp"

template<>
Function_handle Function_variable_matrix_determinant<Scalar>::
	evaluate_derivative(
	std::list<Function_variable_handle>& independent_variables)
//******************************************************************************
// LAST MODIFIED : 6 October 2004
//
// DESCRIPTION :
//==============================================================================
{
	boost::intrusive_ptr< Function_matrix_determinant<Scalar> >
		function_matrix_determinant;
	Function_handle result(0);
	Function_size_type order;

	if ((function_matrix_determinant=boost::dynamic_pointer_cast<
		Function_matrix_determinant<Scalar>,Function>(function()))&&
		(0<(order=independent_variables.size())))
	{
		Function_size_type number_of_dependent_values,number_of_independent_values,
			number_of_rows;
		boost::intrusive_ptr< Function_matrix<Scalar> > derivative,matrix;

		if ((matrix=boost::dynamic_pointer_cast<Function_matrix<Scalar>,
			Function>(function_matrix_determinant->matrix_private->evaluate()))&&
			(matrix->number_of_columns()==(number_of_rows=matrix->number_of_rows()))&&
			(derivative=boost::dynamic_pointer_cast<Function_matrix<Scalar>,
			Function>(function_matrix_determinant->matrix_private->
			evaluate_derivative(independent_variables)))&&
			(number_of_rows*number_of_rows==
			(number_of_dependent_values=derivative->number_of_rows()))&&
			(0<(number_of_independent_values=derivative->number_of_columns())))
		{
			bool valid;
			Function_size_type i,j,k,l,number_of_columns;
			std::vector<Function_size_type> entries(2*order);
			std::vector<Matrix> Df(order);

			number_of_columns=number_of_dependent_values;
			i=0;
			valid=true;
			while (valid&&(i<order))
			{
				Matrix& Df_i=Df[i];

				Df_i.resize(1,number_of_columns);
				if (i<number_of_rows)
				{
					bool zero_derivative;

					for (j=0;j<=2*i+1;j++)
					{
						entries[j]=1;
					}
					j=0;
					while (valid&&(j<number_of_columns))
					{
						// check for repeated rows/columns in derivative
						zero_derivative=false;
						k=0;
						while (!zero_derivative&&(k<=i))
						{
							l=0;
							while (!zero_derivative&&(l<k))
							{
								zero_derivative=((entries[2*l]==entries[2*k])||
									(entries[2*l+1]==entries[2*k+1]));
								l++;
							}
							k++;
						}
						if (zero_derivative)
						{
							Df_i(0,j)=0;
						}
						else
						{
							// doing a copy
							boost::intrusive_ptr< Function_matrix<Scalar> >
								matrix_temp(boost::dynamic_pointer_cast<Function_matrix<Scalar>,
								Function>((matrix->output())->get_value()));
							Function_size_type column,row;

							if (matrix_temp)
							{
								for (k=0;k<=i;k++)
								{
									row=entries[2*k];
									column=entries[2*k+1];
									for (l=1;l<=number_of_rows;l++)
									{
										(*matrix_temp)(row,l)=0;
									}
									for (l=1;l<=number_of_rows;l++)
									{
										(*matrix_temp)(l,column)=0;
									}
									(*matrix_temp)(row,column)=1;
								}
								valid=matrix_temp->determinant(Df_i(0,j));
							}
							else
							{
								valid=false;
							}
						}
						// move to next
						k=2*i+1;
						entries[k]++;
						while ((0!=k)&&(number_of_rows<entries[k]))
						{
							entries[k]=1;
							k--;
							entries[k]++;
						}
						if ((0==k)&&(number_of_rows<entries[k]))
						{
							entries[k]=1;
						}
						j++;
					}
				}
				else
				{
					Df_i.clear();
				}
				number_of_columns *= number_of_dependent_values;
				i++;
			}
			if (valid)
			{
				Function_derivative_matrix_handle derivative_f(0),derivative_g(0);
				std::list<Function_variable_handle> intermediate_independent_variables(
					order,function_matrix_determinant->matrix_private);
				std::list<Matrix> matrices(0);
				std::list<Matrix>::iterator matrix_iterator,matrix_iterator_end;

				for (i=0;i<order;i++)
				{
					matrices.push_back(Df[0]);
					matrix_iterator_end=matrices.end();
					matrix_iterator_end--;
					matrix_iterator=matrices.begin();
					number_of_columns=number_of_dependent_values;
					j=1;
					while (matrix_iterator!=matrix_iterator_end)
					{
						if (number_of_columns!=(k=matrix_iterator->size2()))
						{
							if (number_of_dependent_values==k)
							{
								j=1;
							}
							else
							{
								if (number_of_columns*number_of_dependent_values==k)
								{
									j++;
									number_of_columns=k;
								}
							}
						}
						matrices.push_back(Df[j]);
						matrix_iterator++;
					}
				}
				derivative_f=new Function_derivative_matrix(this,
					intermediate_independent_variables,matrices);
				derivative_g=new Function_derivative_matrix(
					function_matrix_determinant->matrix_private,independent_variables);
				if (derivative_f&&derivative_g)
				{
					Function_derivative_matrix_handle derivative_matrix=
						Function_derivative_matrix_compose(this,derivative_f,derivative_g);

					if (derivative_matrix)
					{
						result=derivative_matrix->matrix(independent_variables);
					}
				}
			}
		}
	}

	return (result);
}

template<>
bool Function_matrix_determinant<Scalar>::evaluate_derivative(
	Scalar& derivative,Function_variable_handle atomic_variable,
	std::list<Function_variable_handle>& atomic_independent_variables)
//******************************************************************************
// LAST MODIFIED : 6 October 2004
//
// DESCRIPTION :
//==============================================================================
{
	bool result;
	boost::intrusive_ptr< Function_variable_matrix_determinant<Scalar> >
		atomic_variable_matrix_determinant;

	result=false;
	if ((atomic_variable_matrix_determinant=boost::dynamic_pointer_cast<
		Function_variable_matrix_determinant<Scalar>,Function_variable>(
		atomic_variable))&&equivalent(Function_handle(this),
		atomic_variable_matrix_determinant->function())&&
		(1==atomic_variable_matrix_determinant->row())&&
		(1==atomic_variable_matrix_determinant->column())&&
		(0<atomic_independent_variables.size()))
	{
		boost::intrusive_ptr< Function_matrix<Scalar> > derivative_matrix=
			boost::dynamic_pointer_cast<Function_matrix<Scalar>,Function>(
			atomic_variable_matrix_determinant->evaluate_derivative(
			atomic_independent_variables));

		if (derivative_matrix)
		{
			result=true;
			derivative=(*derivative_matrix)(1,1);
		}
	}

	return (result);
}

#if defined (OLD_CODE)
template<>
bool Function_matrix_determinant<Scalar>::evaluate_derivative(
	Scalar& derivative,Function_variable_handle atomic_variable,
	std::list<Function_variable_handle>& atomic_independent_variables)
//******************************************************************************
// LAST MODIFIED : 4 October 2004
//
// DESCRIPTION :
//==============================================================================
{
	bool result;
	boost::intrusive_ptr< Function_variable_matrix_determinant<Scalar> >
		atomic_variable_matrix_determinant;
	Function_derivative_matrix_handle derivative_g(0);
	Function_handle matrix_current(0);
	boost::intrusive_ptr< Function_matrix<Scalar> > matrix(0);
	Function_size_type number_of_rows,order;

	result=false;
	if ((atomic_variable_matrix_determinant=boost::dynamic_pointer_cast<
		Function_variable_matrix_determinant<Scalar>,Function_variable>(
		atomic_variable))&&equivalent(Function_handle(this),
		atomic_variable_matrix_determinant->function())&&
		(1==atomic_variable_matrix_determinant->row())&&
		(1==atomic_variable_matrix_determinant->column())&&
		(0<(order=atomic_independent_variables.size()))&&matrix_private&&
		(matrix_current=matrix_private->get_value())&&
		(matrix=boost::dynamic_pointer_cast<Function_matrix<Scalar>,Function>(
		matrix_private->evaluate()))&&
		(0<(number_of_rows=matrix->number_of_rows()))&&
		(derivative_g=new Function_derivative_matrix(matrix_private,
		atomic_independent_variables)))
	{
		bool valid;
		Function_size_type i,j,k,l,number_of_columns,size;
		std::vector<Function_size_type> entries(2*order);
		std::vector<Matrix> Df(order);

		size=number_of_rows*number_of_rows;
		number_of_columns=size;
		i=0;
		valid=true;
		while (valid&&(i<order))
		{
			Matrix& Df_i=Df[i];

			Df_i.resize(1,number_of_columns);
			if (i<number_of_rows)
			{
				bool zero_derivative;

				for (j=0;j<=2*i+1;j++)
				{
					entries[j]=1;
				}
				j=0;
				while (valid&&(j<number_of_columns))
				{
					// check for repeated rows/columns in derivative
					zero_derivative=false;
					k=0;
					while (!zero_derivative&&(k<=i))
					{
						l=0;
						while (!zero_derivative&&(l<k))
						{
							zero_derivative=((entries[2*l]==entries[2*k])||
								(entries[2*l+1]==entries[2*k+1]));
							l++;
						}
						k++;
					}
					if (zero_derivative)
					{
						Df_i(0,j)=0;
					}
					else
					{
						// doing a copy
						boost::intrusive_ptr< Function_matrix<Scalar> >
							matrix_temp(boost::dynamic_pointer_cast<Function_matrix<Scalar>,
							Function>((matrix->output())->get_value()));
						Function_size_type column,row;

						if (matrix_temp)
						{
							for (k=0;k<=i;k++)
							{
								row=entries[2*k];
								column=entries[2*k+1];
								for (l=1;l<=number_of_rows;l++)
								{
									(*matrix_temp)(row,l)=0;
								}
								for (l=1;l<=number_of_rows;l++)
								{
									(*matrix_temp)(l,column)=0;
								}
								(*matrix_temp)(row,column)=1;
							}
							valid=matrix_temp->determinant(Df_i(0,j));
						}
						else
						{
							valid=false;
						}
					}
					// move to next
					k=2*i+1;
					entries[k]++;
					while ((0!=k)&&(number_of_rows<entries[k]))
					{
						entries[k]=1;
						k--;
						entries[k]++;
					}
					if ((0==k)&&(number_of_rows<entries[k]))
					{
						entries[k]=1;
					}
					j++;
				}
			}
			else
			{
				Df_i.clear();
			}
			number_of_columns *= size;
			i++;
		}
		if (valid)
		{
			Function_derivative_matrix_handle derivative_f(0);
			std::list<Function_variable_handle> intermediate_independent_variables(
				order,matrix_private);
			std::list<Matrix> matrices(0);
			std::list<Matrix>::iterator matrix_iterator,matrix_iterator_end;

			for (i=0;i<order;i++)
			{
				matrices.push_back(Df[0]);
				matrix_iterator_end=matrices.end();
				matrix_iterator_end--;
				matrix_iterator=matrices.begin();
				number_of_columns=size;
				j=1;
				while (matrix_iterator!=matrix_iterator_end)
				{
					if (number_of_columns!=(k=matrix_iterator->size2()))
					{
						if (size==k)
						{
							j=1;
						}
						else
						{
							if (number_of_columns*size==k)
							{
								j++;
								number_of_columns=k;
							}
						}
					}
					matrices.push_back(Df[j]);
					matrix_iterator++;
				}
			}
			derivative_f=new Function_derivative_matrix(atomic_variable,
				intermediate_independent_variables,matrices);
			if (derivative_f)
			{
				Function_derivative_matrix_handle derivative_matrix=
					Function_derivative_matrix_compose(atomic_variable,derivative_f,
					derivative_g);
				boost::intrusive_ptr< Function_matrix<Scalar> > function_matrix;

				if (derivative_matrix&&(function_matrix=boost::dynamic_pointer_cast<
					Function_matrix<Scalar>,Function>(derivative_matrix->matrix(
					atomic_independent_variables))))
				{
					derivative=(*function_matrix)(1,1);
					result=true;
				}
			}
		}
	}
	if (matrix_current)
	{
		matrix_private->rset_value(matrix_current);
	}

	return (result);
}
#endif // defined (OLD_CODE)
#endif // !defined (AIX)
<commit_msg>Removed unused variable<commit_after>//******************************************************************************
// FILE : function_matrix_determinant.cpp
//
// LAST MODIFIED : 18 October 2004
//
// DESCRIPTION :
//==============================================================================

#if defined (ONE_TEMPLATE_DEFINITION_IMPLEMENTED)
#include "computed_variable/function_matrix_determinant_implementation.cpp"
#else // defined (ONE_TEMPLATE_DEFINITION_IMPLEMENTED)
#include "computed_variable/function_matrix_determinant.hpp"
#endif // defined (ONE_TEMPLATE_DEFINITION_IMPLEMENTED)

#if !defined (AIX)
#include "computed_variable/function_derivative_matrix.hpp"

template<>
Function_handle Function_variable_matrix_determinant<Scalar>::
	evaluate_derivative(
	std::list<Function_variable_handle>& independent_variables)
//******************************************************************************
// LAST MODIFIED : 18 October 2004
//
// DESCRIPTION :
//==============================================================================
{
	boost::intrusive_ptr< Function_matrix_determinant<Scalar> >
		function_matrix_determinant;
	Function_handle result(0);
	Function_size_type order;

	if ((function_matrix_determinant=boost::dynamic_pointer_cast<
		Function_matrix_determinant<Scalar>,Function>(function()))&&
		(0<(order=independent_variables.size())))
	{
		Function_size_type number_of_dependent_values,number_of_rows;
		boost::intrusive_ptr< Function_matrix<Scalar> > derivative,matrix;

		if ((matrix=boost::dynamic_pointer_cast<Function_matrix<Scalar>,
			Function>(function_matrix_determinant->matrix_private->evaluate()))&&
			(matrix->number_of_columns()==(number_of_rows=matrix->number_of_rows()))&&
			(derivative=boost::dynamic_pointer_cast<Function_matrix<Scalar>,
			Function>(function_matrix_determinant->matrix_private->
			evaluate_derivative(independent_variables)))&&
			(number_of_rows*number_of_rows==
			(number_of_dependent_values=derivative->number_of_rows()))&&
			(0<derivative->number_of_columns()))
		{
			bool valid;
			Function_size_type i,j,k,l,number_of_columns;
			std::vector<Function_size_type> entries(2*order);
			std::vector<Matrix> Df(order);

			number_of_columns=number_of_dependent_values;
			i=0;
			valid=true;
			while (valid&&(i<order))
			{
				Matrix& Df_i=Df[i];

				Df_i.resize(1,number_of_columns);
				if (i<number_of_rows)
				{
					bool zero_derivative;

					for (j=0;j<=2*i+1;j++)
					{
						entries[j]=1;
					}
					j=0;
					while (valid&&(j<number_of_columns))
					{
						// check for repeated rows/columns in derivative
						zero_derivative=false;
						k=0;
						while (!zero_derivative&&(k<=i))
						{
							l=0;
							while (!zero_derivative&&(l<k))
							{
								zero_derivative=((entries[2*l]==entries[2*k])||
									(entries[2*l+1]==entries[2*k+1]));
								l++;
							}
							k++;
						}
						if (zero_derivative)
						{
							Df_i(0,j)=0;
						}
						else
						{
							// doing a copy
							boost::intrusive_ptr< Function_matrix<Scalar> >
								matrix_temp(boost::dynamic_pointer_cast<Function_matrix<Scalar>,
								Function>((matrix->output())->get_value()));
							Function_size_type column,row;

							if (matrix_temp)
							{
								for (k=0;k<=i;k++)
								{
									row=entries[2*k];
									column=entries[2*k+1];
									for (l=1;l<=number_of_rows;l++)
									{
										(*matrix_temp)(row,l)=0;
									}
									for (l=1;l<=number_of_rows;l++)
									{
										(*matrix_temp)(l,column)=0;
									}
									(*matrix_temp)(row,column)=1;
								}
								valid=matrix_temp->determinant(Df_i(0,j));
							}
							else
							{
								valid=false;
							}
						}
						// move to next
						k=2*i+1;
						entries[k]++;
						while ((0!=k)&&(number_of_rows<entries[k]))
						{
							entries[k]=1;
							k--;
							entries[k]++;
						}
						if ((0==k)&&(number_of_rows<entries[k]))
						{
							entries[k]=1;
						}
						j++;
					}
				}
				else
				{
					Df_i.clear();
				}
				number_of_columns *= number_of_dependent_values;
				i++;
			}
			if (valid)
			{
				Function_derivative_matrix_handle derivative_f(0),derivative_g(0);
				std::list<Function_variable_handle> intermediate_independent_variables(
					order,function_matrix_determinant->matrix_private);
				std::list<Matrix> matrices(0);
				std::list<Matrix>::iterator matrix_iterator,matrix_iterator_end;

				for (i=0;i<order;i++)
				{
					matrices.push_back(Df[0]);
					matrix_iterator_end=matrices.end();
					matrix_iterator_end--;
					matrix_iterator=matrices.begin();
					number_of_columns=number_of_dependent_values;
					j=1;
					while (matrix_iterator!=matrix_iterator_end)
					{
						if (number_of_columns!=(k=matrix_iterator->size2()))
						{
							if (number_of_dependent_values==k)
							{
								j=1;
							}
							else
							{
								if (number_of_columns*number_of_dependent_values==k)
								{
									j++;
									number_of_columns=k;
								}
							}
						}
						matrices.push_back(Df[j]);
						matrix_iterator++;
					}
				}
				derivative_f=new Function_derivative_matrix(this,
					intermediate_independent_variables,matrices);
				derivative_g=new Function_derivative_matrix(
					function_matrix_determinant->matrix_private,independent_variables);
				if (derivative_f&&derivative_g)
				{
					Function_derivative_matrix_handle derivative_matrix=
						Function_derivative_matrix_compose(this,derivative_f,derivative_g);

					if (derivative_matrix)
					{
						result=derivative_matrix->matrix(independent_variables);
					}
				}
			}
		}
	}

	return (result);
}

template<>
bool Function_matrix_determinant<Scalar>::evaluate_derivative(
	Scalar& derivative,Function_variable_handle atomic_variable,
	std::list<Function_variable_handle>& atomic_independent_variables)
//******************************************************************************
// LAST MODIFIED : 6 October 2004
//
// DESCRIPTION :
//==============================================================================
{
	bool result;
	boost::intrusive_ptr< Function_variable_matrix_determinant<Scalar> >
		atomic_variable_matrix_determinant;

	result=false;
	if ((atomic_variable_matrix_determinant=boost::dynamic_pointer_cast<
		Function_variable_matrix_determinant<Scalar>,Function_variable>(
		atomic_variable))&&equivalent(Function_handle(this),
		atomic_variable_matrix_determinant->function())&&
		(1==atomic_variable_matrix_determinant->row())&&
		(1==atomic_variable_matrix_determinant->column())&&
		(0<atomic_independent_variables.size()))
	{
		boost::intrusive_ptr< Function_matrix<Scalar> > derivative_matrix=
			boost::dynamic_pointer_cast<Function_matrix<Scalar>,Function>(
			atomic_variable_matrix_determinant->evaluate_derivative(
			atomic_independent_variables));

		if (derivative_matrix)
		{
			result=true;
			derivative=(*derivative_matrix)(1,1);
		}
	}

	return (result);
}

#if defined (OLD_CODE)
template<>
bool Function_matrix_determinant<Scalar>::evaluate_derivative(
	Scalar& derivative,Function_variable_handle atomic_variable,
	std::list<Function_variable_handle>& atomic_independent_variables)
//******************************************************************************
// LAST MODIFIED : 4 October 2004
//
// DESCRIPTION :
//==============================================================================
{
	bool result;
	boost::intrusive_ptr< Function_variable_matrix_determinant<Scalar> >
		atomic_variable_matrix_determinant;
	Function_derivative_matrix_handle derivative_g(0);
	Function_handle matrix_current(0);
	boost::intrusive_ptr< Function_matrix<Scalar> > matrix(0);
	Function_size_type number_of_rows,order;

	result=false;
	if ((atomic_variable_matrix_determinant=boost::dynamic_pointer_cast<
		Function_variable_matrix_determinant<Scalar>,Function_variable>(
		atomic_variable))&&equivalent(Function_handle(this),
		atomic_variable_matrix_determinant->function())&&
		(1==atomic_variable_matrix_determinant->row())&&
		(1==atomic_variable_matrix_determinant->column())&&
		(0<(order=atomic_independent_variables.size()))&&matrix_private&&
		(matrix_current=matrix_private->get_value())&&
		(matrix=boost::dynamic_pointer_cast<Function_matrix<Scalar>,Function>(
		matrix_private->evaluate()))&&
		(0<(number_of_rows=matrix->number_of_rows()))&&
		(derivative_g=new Function_derivative_matrix(matrix_private,
		atomic_independent_variables)))
	{
		bool valid;
		Function_size_type i,j,k,l,number_of_columns,size;
		std::vector<Function_size_type> entries(2*order);
		std::vector<Matrix> Df(order);

		size=number_of_rows*number_of_rows;
		number_of_columns=size;
		i=0;
		valid=true;
		while (valid&&(i<order))
		{
			Matrix& Df_i=Df[i];

			Df_i.resize(1,number_of_columns);
			if (i<number_of_rows)
			{
				bool zero_derivative;

				for (j=0;j<=2*i+1;j++)
				{
					entries[j]=1;
				}
				j=0;
				while (valid&&(j<number_of_columns))
				{
					// check for repeated rows/columns in derivative
					zero_derivative=false;
					k=0;
					while (!zero_derivative&&(k<=i))
					{
						l=0;
						while (!zero_derivative&&(l<k))
						{
							zero_derivative=((entries[2*l]==entries[2*k])||
								(entries[2*l+1]==entries[2*k+1]));
							l++;
						}
						k++;
					}
					if (zero_derivative)
					{
						Df_i(0,j)=0;
					}
					else
					{
						// doing a copy
						boost::intrusive_ptr< Function_matrix<Scalar> >
							matrix_temp(boost::dynamic_pointer_cast<Function_matrix<Scalar>,
							Function>((matrix->output())->get_value()));
						Function_size_type column,row;

						if (matrix_temp)
						{
							for (k=0;k<=i;k++)
							{
								row=entries[2*k];
								column=entries[2*k+1];
								for (l=1;l<=number_of_rows;l++)
								{
									(*matrix_temp)(row,l)=0;
								}
								for (l=1;l<=number_of_rows;l++)
								{
									(*matrix_temp)(l,column)=0;
								}
								(*matrix_temp)(row,column)=1;
							}
							valid=matrix_temp->determinant(Df_i(0,j));
						}
						else
						{
							valid=false;
						}
					}
					// move to next
					k=2*i+1;
					entries[k]++;
					while ((0!=k)&&(number_of_rows<entries[k]))
					{
						entries[k]=1;
						k--;
						entries[k]++;
					}
					if ((0==k)&&(number_of_rows<entries[k]))
					{
						entries[k]=1;
					}
					j++;
				}
			}
			else
			{
				Df_i.clear();
			}
			number_of_columns *= size;
			i++;
		}
		if (valid)
		{
			Function_derivative_matrix_handle derivative_f(0);
			std::list<Function_variable_handle> intermediate_independent_variables(
				order,matrix_private);
			std::list<Matrix> matrices(0);
			std::list<Matrix>::iterator matrix_iterator,matrix_iterator_end;

			for (i=0;i<order;i++)
			{
				matrices.push_back(Df[0]);
				matrix_iterator_end=matrices.end();
				matrix_iterator_end--;
				matrix_iterator=matrices.begin();
				number_of_columns=size;
				j=1;
				while (matrix_iterator!=matrix_iterator_end)
				{
					if (number_of_columns!=(k=matrix_iterator->size2()))
					{
						if (size==k)
						{
							j=1;
						}
						else
						{
							if (number_of_columns*size==k)
							{
								j++;
								number_of_columns=k;
							}
						}
					}
					matrices.push_back(Df[j]);
					matrix_iterator++;
				}
			}
			derivative_f=new Function_derivative_matrix(atomic_variable,
				intermediate_independent_variables,matrices);
			if (derivative_f)
			{
				Function_derivative_matrix_handle derivative_matrix=
					Function_derivative_matrix_compose(atomic_variable,derivative_f,
					derivative_g);
				boost::intrusive_ptr< Function_matrix<Scalar> > function_matrix;

				if (derivative_matrix&&(function_matrix=boost::dynamic_pointer_cast<
					Function_matrix<Scalar>,Function>(derivative_matrix->matrix(
					atomic_independent_variables))))
				{
					derivative=(*function_matrix)(1,1);
					result=true;
				}
			}
		}
	}
	if (matrix_current)
	{
		matrix_private->rset_value(matrix_current);
	}

	return (result);
}
#endif // defined (OLD_CODE)
#endif // !defined (AIX)
<|endoftext|>


<commit_before>#include <map>
#include <cppformat/format.h>

#include "command.hpp"
#include "server.hpp"
#include "client.hpp"
#include "proxy.hpp"
#include "response.hpp"
#include "except/exceptions.hpp"
#include "utils/alg.hpp"
#include "utils/logging.hpp"
#include "syscalls/poll.h"
#include "syscalls/fctl.h"

using namespace cerb;

void Server::on_events(int events)
{
    if (this->closed()) {
        return;
    }
    if (poll::event_is_hup(events)) {
        return this->close_conn();
    }
    if (poll::event_is_read(events)) {
        try {
            this->_recv_from();
        } catch (BadRedisMessage& e) {
            LOG(ERROR) << "Receive bad message from server " << this->str()
                       << " because: " << e.what()
                       << " dump buffer (before close): "
                       << this->_buffer.to_string();
            return this->close_conn();
        }
    }
    this->_push_to_buffer_set();
    if (poll::event_is_write(events)) {
        this->_output_buffer_set.writev(this->fd);
    }
    if (this->_output_buffer_set.empty()) {
        this->_proxy->set_conn_poll_ro(this);
    } else {
        this->_proxy->set_conn_poll_rw(this);
    }
}

void Server::_push_to_buffer_set()
{
    auto now = Clock::now();
    for (util::sref<DataCommand> c: this->_commands) {
        this->_sent_commands.push_back(c);
        this->_output_buffer_set.append(c->buffer);
        c->sent_time = now;
    }
    this->_commands.clear();
}

void Server::_recv_from()
{
    int n = this->_buffer.read(this->fd);
    if (n == 0) {
        throw ConnectionHungUp();
    }
    LOG(DEBUG) << "Read " << this->str() << " buffer size " << this->_buffer.size();
    auto responses(split_server_response(this->_buffer));
    if (responses.size() > this->_sent_commands.size()) {
        LOG(ERROR) << "+Error on split, expected size: " << this->_sent_commands.size()
                   << " actual: " << responses.size() << " dump buffer:";
        for (util::sptr<Response> const& rsp: responses) {
            LOG(ERROR) << "::: " << rsp->get_buffer().to_string();
        }
        LOG(ERROR) << "Rest buffer: " << this->_buffer.to_string();
        return this->close_conn();
    }
    LOG(DEBUG) << "+responses size: " << responses.size();
    LOG(DEBUG) << "+rest buffer: " << this->_buffer.size();
    auto cmd_it = this->_sent_commands.begin();
    auto now = Clock::now();
    for (util::sptr<Response>& rsp: responses) {
        util::sref<DataCommand> c = *cmd_it++;
        if (c.not_nul()) {
            rsp->rsp_to(c, util::mkref(*this->_proxy));
            c->resp_time = now;
        }
    }
    this->_sent_commands.erase(this->_sent_commands.begin(), cmd_it);
}

void Server::push_client_command(util::sref<DataCommand> cmd)
{
    _commands.push_back(cmd);
    cmd->group->client->add_peer(this);
}

void Server::pop_client(Client* cli)
{
    util::erase_if(
        this->_commands,
        [&](util::sref<DataCommand> cmd)
        {
            return cmd->group->client.is(cli);
        });
    for (util::sref<DataCommand>& cmd: this->_sent_commands) {
        if (cmd.not_nul() && cmd->group->client.is(cli)) {
            cmd.reset();
        }
    }
}

std::vector<util::sref<DataCommand>> Server::deliver_commands()
{
    util::erase_if(
        this->_sent_commands,
        [](util::sref<DataCommand> cmd)
        {
            return cmd.nul();
        });
    _commands.insert(_commands.end(), _sent_commands.begin(),
                     _sent_commands.end());
    return std::move(_commands);
}

static thread_local std::map<util::Address, Server*> servers_map;
static thread_local std::vector<Server*> servers_pool;

static void remove_entry(Server* server)
{
    ::servers_map.erase(server->addr);
    ::servers_pool.push_back(server);
}

void Server::after_events(std::set<Connection*>&)
{
    if (this->closed()) {
        this->_proxy->update_slot_map();
    }
}

std::string Server::str() const
{
    return fmt::format("Server({}@{})[{}]", this->fd,
                       static_cast<void const*>(this), this->addr.str());
}

void Server::close_conn()
{
    if (!this->closed()) {
        LOG(INFO) << "Close " << this->str();
        this->close();
        this->_buffer.clear();
        this->_output_buffer_set.clear();

        for (util::sref<DataCommand> c: this->_commands) {
            this->_proxy->retry_move_ask_command_later(c);
        }
        this->_commands.clear();

        for (util::sref<DataCommand> c: this->_sent_commands) {
            if (c.nul()) {
                continue;
            }
            this->_proxy->retry_move_ask_command_later(c);
        }
        this->_sent_commands.clear();

        for (ProxyConnection* conn: this->attached_long_connections) {
            this->_proxy->inactivate_long_conn(conn);
        }
        this->attached_long_connections.clear();

        ::remove_entry(this);
    }
}

std::map<util::Address, Server*>::iterator Server::addr_begin()
{
    return ::servers_map.begin();
}

std::map<util::Address, Server*>::iterator Server::addr_end()
{
    return ::servers_map.end();
}

static std::function<void(int, std::vector<util::sref<DataCommand>>&)> on_server_connected(
    [](int, std::vector<util::sref<DataCommand>>&) {});

void Server::_reconnect(util::Address const& addr, Proxy* p)
{
    this->fd = fctl::new_stream_socket();
    this->_proxy = p;
    this->addr = addr;

    fctl::set_nonblocking(this->fd);
    fctl::connect_fd(addr.host, addr.port, this->fd);
    LOG(INFO) << "Open " << this->str();
    p->poll_add_rw(this);
    ::on_server_connected(this->fd, this->_sent_commands);
}

Server* Server::_alloc_server(util::Address const& addr, Proxy* p)
{
    if (servers_pool.empty()) {
        for (int i = 0; i < 8; ++i) {
            servers_pool.push_back(new Server);
            LOG(DEBUG) << "Allocate Server: " << servers_pool.back();
        }
    }
    Server* s = servers_pool.back();
    try {
        s->_reconnect(addr, p);
    } catch (IOErrorBase& e) {
        LOG(ERROR) << "Fail to open server " << s->str() << " because " << e.what();
        s->close_conn();
    }
    servers_pool.pop_back();
    return s;
}

Server* Server::get_server(util::Address addr, Proxy* p)
{
    auto i = servers_map.find(addr);
    if (i == servers_map.end() || i->second->closed()) {
        Server* s = Server::_alloc_server(addr, p);
        servers_map.insert(std::make_pair(std::move(addr), s));
        return s;
    }
    return i->second;
}

static std::string const READONLY_CMD("READONLY\r\n");

void Server::send_readonly_for_each_conn()
{
    ::on_server_connected =
        [](int fd, std::vector<util::sref<DataCommand>>& cmds)
        {
            flush_string(fd, READONLY_CMD);
            cmds.push_back(util::sref<DataCommand>(nullptr));
        };
}
<commit_msg>fix segment fault when pop_cient<commit_after>#include <map>
#include <cppformat/format.h>

#include "command.hpp"
#include "server.hpp"
#include "client.hpp"
#include "proxy.hpp"
#include "response.hpp"
#include "except/exceptions.hpp"
#include "utils/alg.hpp"
#include "utils/logging.hpp"
#include "syscalls/poll.h"
#include "syscalls/fctl.h"

using namespace cerb;

void Server::on_events(int events)
{
    if (this->closed()) {
        return;
    }
    if (poll::event_is_hup(events)) {
        return this->close_conn();
    }
    if (poll::event_is_read(events)) {
        try {
            this->_recv_from();
        } catch (BadRedisMessage& e) {
            LOG(ERROR) << "Receive bad message from server " << this->str()
                       << " because: " << e.what()
                       << " dump buffer (before close): "
                       << this->_buffer.to_string();
            return this->close_conn();
        }
    }
    this->_push_to_buffer_set();
    if (poll::event_is_write(events)) {
        this->_output_buffer_set.writev(this->fd);
    }
    if (this->_output_buffer_set.empty()) {
        this->_proxy->set_conn_poll_ro(this);
    } else {
        this->_proxy->set_conn_poll_rw(this);
    }
}

void Server::_push_to_buffer_set()
{
    auto now = Clock::now();
    for (util::sref<DataCommand> c: this->_commands) {
        this->_sent_commands.push_back(c);
        this->_output_buffer_set.append(c->buffer);
        c->sent_time = now;
    }
    this->_commands.clear();
}

void Server::_recv_from()
{
    int n = this->_buffer.read(this->fd);
    if (n == 0) {
        throw ConnectionHungUp();
    }
    LOG(DEBUG) << "Read " << this->str() << " buffer size " << this->_buffer.size();
    auto responses(split_server_response(this->_buffer));
    if (responses.size() > this->_sent_commands.size()) {
        LOG(ERROR) << "+Error on split, expected size: " << this->_sent_commands.size()
                   << " actual: " << responses.size() << " dump buffer:";
        for (util::sptr<Response> const& rsp: responses) {
            LOG(ERROR) << "::: " << rsp->get_buffer().to_string();
        }
        LOG(ERROR) << "Rest buffer: " << this->_buffer.to_string();
        return this->close_conn();
    }
    LOG(DEBUG) << "+responses size: " << responses.size();
    LOG(DEBUG) << "+rest buffer: " << this->_buffer.size();
    auto cmd_it = this->_sent_commands.begin();
    auto now = Clock::now();
    for (util::sptr<Response>& rsp: responses) {
        util::sref<DataCommand> c = *cmd_it++;
        if (c.not_nul()) {
            rsp->rsp_to(c, util::mkref(*this->_proxy));
            c->resp_time = now;
        }
    }
    this->_sent_commands.erase(this->_sent_commands.begin(), cmd_it);
}

void Server::push_client_command(util::sref<DataCommand> cmd)
{
    _commands.push_back(cmd);
    cmd->group->client->add_peer(this);
}

void Server::pop_client(Client* cli)
{
    util::erase_if(
        this->_commands,
        [&](util::sref<DataCommand> cmd)
        {
            return cmd->group->client.is(cli);
        });
    for (util::sref<DataCommand>& cmd: this->_sent_commands) {
        if (cmd.not_nul() &&
            cmd->group.not_nul() &&
            cmd->group->client.not_nul() &&
            cmd->group->client.is(cli)) {
            cmd.reset();
        }
    }
}

std::vector<util::sref<DataCommand>> Server::deliver_commands()
{
    util::erase_if(
        this->_sent_commands,
        [](util::sref<DataCommand> cmd)
        {
            return cmd.nul();
        });
    _commands.insert(_commands.end(), _sent_commands.begin(),
                     _sent_commands.end());
    return std::move(_commands);
}

static thread_local std::map<util::Address, Server*> servers_map;
static thread_local std::vector<Server*> servers_pool;

static void remove_entry(Server* server)
{
    ::servers_map.erase(server->addr);
    ::servers_pool.push_back(server);
}

void Server::after_events(std::set<Connection*>&)
{
    if (this->closed()) {
        this->_proxy->update_slot_map();
    }
}

std::string Server::str() const
{
    return fmt::format("Server({}@{})[{}]", this->fd,
                       static_cast<void const*>(this), this->addr.str());
}

void Server::close_conn()
{
    if (!this->closed()) {
        LOG(INFO) << "Close " << this->str();
        this->close();
        this->_buffer.clear();
        this->_output_buffer_set.clear();

        for (util::sref<DataCommand> c: this->_commands) {
            this->_proxy->retry_move_ask_command_later(c);
        }
        this->_commands.clear();

        for (util::sref<DataCommand> c: this->_sent_commands) {
            if (c.nul()) {
                continue;
            }
            this->_proxy->retry_move_ask_command_later(c);
        }
        this->_sent_commands.clear();

        for (ProxyConnection* conn: this->attached_long_connections) {
            this->_proxy->inactivate_long_conn(conn);
        }
        this->attached_long_connections.clear();

        ::remove_entry(this);
    }
}

std::map<util::Address, Server*>::iterator Server::addr_begin()
{
    return ::servers_map.begin();
}

std::map<util::Address, Server*>::iterator Server::addr_end()
{
    return ::servers_map.end();
}

static std::function<void(int, std::vector<util::sref<DataCommand>>&)> on_server_connected(
    [](int, std::vector<util::sref<DataCommand>>&) {});

void Server::_reconnect(util::Address const& addr, Proxy* p)
{
    this->fd = fctl::new_stream_socket();
    this->_proxy = p;
    this->addr = addr;

    fctl::set_nonblocking(this->fd);
    fctl::connect_fd(addr.host, addr.port, this->fd);
    LOG(INFO) << "Open " << this->str();
    p->poll_add_rw(this);
    ::on_server_connected(this->fd, this->_sent_commands);
}

Server* Server::_alloc_server(util::Address const& addr, Proxy* p)
{
    if (servers_pool.empty()) {
        for (int i = 0; i < 8; ++i) {
            servers_pool.push_back(new Server);
            LOG(DEBUG) << "Allocate Server: " << servers_pool.back();
        }
    }
    Server* s = servers_pool.back();
    try {
        s->_reconnect(addr, p);
    } catch (IOErrorBase& e) {
        LOG(ERROR) << "Fail to open server " << s->str() << " because " << e.what();
        s->close_conn();
    }
    servers_pool.pop_back();
    return s;
}

Server* Server::get_server(util::Address addr, Proxy* p)
{
    auto i = servers_map.find(addr);
    if (i == servers_map.end() || i->second->closed()) {
        Server* s = Server::_alloc_server(addr, p);
        servers_map.insert(std::make_pair(std::move(addr), s));
        return s;
    }
    return i->second;
}

static std::string const READONLY_CMD("READONLY\r\n");

void Server::send_readonly_for_each_conn()
{
    ::on_server_connected =
        [](int fd, std::vector<util::sref<DataCommand>>& cmds)
        {
            flush_string(fd, READONLY_CMD);
            cmds.push_back(util::sref<DataCommand>(nullptr));
        };
}
<|endoftext|>


<commit_before>#include "graphics/renderer.h"
#include "core/array.h"
#include "core/crc32.h"
#include "core/fs/file_system.h"
#include "core/json_serializer.h"
#include "core/math_utils.h"
#include "core/array.h"
#include "core/vec4.h"
#include "core/resource_manager.h"
#include "core/resource_manager_base.h"
#include "engine/engine.h"
#include "graphics/geometry.h"
#include "graphics/gl_ext.h"
#include "graphics/irender_device.h"
#include "graphics/material.h"
#include "graphics/model.h"
#include "graphics/model_instance.h"
#include "graphics/pipeline.h"
#include "graphics/render_scene.h"
#include "graphics/shader.h"
#include "graphics/texture.h"
#include "universe/component_event.h"
#include "universe/entity_moved_event.h"
#include "universe/universe.h"

namespace Lux
{

static const uint32_t light_hash = crc32("light");
static const uint32_t renderable_hash = crc32("renderable");
static const uint32_t camera_hash = crc32("camera");

struct RendererImpl : public Renderer
{

	RendererImpl()
	{
	}

	virtual void setProjection(float width, float height, float fov, float near_plane, float far_plane, const Matrix& mtx) override
	{
		glViewport(0, 0, (GLsizei)width, (GLsizei)height);
		glMatrixMode(GL_PROJECTION);
		glLoadIdentity();
		gluPerspective(fov, width / height, near_plane, far_plane);
		glMatrixMode(GL_MODELVIEW);
		glLoadIdentity();
		Vec3 pos = mtx.getTranslation();
		Vec3 center = pos - mtx.getZVector();
		Vec3 up = mtx.getYVector();
		gluLookAt(pos.x, pos.y, pos.z, center.x, center.y, center.z, up.x, up.y, up.z);
	}

	virtual void setRenderDevice(IRenderDevice& device) override
	{
		m_render_device = &device;
	}

	virtual void renderGame() override
	{
		if (m_render_device)
		{
			m_render_device->beginFrame();
			render(*m_render_device);
			m_render_device->endFrame();
		}
	}

	virtual void render(IRenderDevice& device) override
	{
		// init
		glEnable(GL_DEPTH_TEST);
		glDisable(GL_BLEND);

		// render
		device.getPipeline().render();

		// cleanup
		glBindBuffer(GL_ARRAY_BUFFER, 0);
		glUseProgram(0);
		for(int i = 0; i < 16; ++i)
		{
			glActiveTexture(GL_TEXTURE0 + i);
			glDisable(GL_TEXTURE_2D);
		}
		glActiveTexture(GL_TEXTURE0);
	}

	virtual bool create(Engine& engine) override
	{
		m_engine = &engine;
		glewExperimental = GL_TRUE;
		GLenum err = glewInit();
		return err == GLEW_OK
			&& GLEW_EXT_framebuffer_object
			&& GLEW_ARB_framebuffer_object
			&& GLEW_ARB_shader_objects
			&& GLEW_ARB_fragment_shader
			&& GLEW_ARB_vertex_shader
			&& GLEW_ARB_vertex_buffer_object;
	}

	virtual void destroy() override
	{
	}

	virtual const char* getName() const override
	{
		return "renderer";
	}

	virtual Component createComponent(uint32_t, const Entity&) override
	{
		return Component::INVALID;
	}

	virtual void enableZTest(bool enable) override
	{
		if (enable)
		{
			glEnable(GL_DEPTH_TEST);
		}
		else
		{
			glDisable(GL_DEPTH_TEST);
		}
	}

	virtual Engine& getEngine() override
	{
		return *m_engine;
	}

	virtual void renderModel(const Model& model, const Matrix& transform, PipelineInstance& pipeline) override
	{
		glPushMatrix();
		glMultMatrixf(&transform.m11);
		for (int i = 0, c = model.getMeshCount(); i < c;  ++i)
		{
			const Mesh& mesh = model.getMesh(i);
			mesh.getMaterial()->apply(*this, pipeline);
			model.getGeometry()->draw(mesh.getStart(), mesh.getCount(), *mesh.getMaterial()->getShader());
		}
		glPopMatrix();
	}

	virtual Model* getModel(const char* path) override
	{
		return static_cast<Model*>(m_engine->getResourceManager().get(ResourceManager::MODEL)->load(path));
	}

	virtual void serialize(ISerializer&) override
	{
	}

	virtual void deserialize(ISerializer&) override
	{
	}

	Engine* m_engine;
	Array<Model*> m_models;
	IRenderDevice* m_render_device;
};

Renderer* Renderer::createInstance()
{
	return LUX_NEW(RendererImpl);
}

void Renderer::destroyInstance(Renderer& renderer)
{
	LUX_DELETE(&renderer);
}

} // ~namespace Lux<commit_msg>opengl extensions check updated<commit_after>#include "graphics/renderer.h"
#include "core/array.h"
#include "core/crc32.h"
#include "core/fs/file_system.h"
#include "core/json_serializer.h"
#include "core/math_utils.h"
#include "core/array.h"
#include "core/vec4.h"
#include "core/resource_manager.h"
#include "core/resource_manager_base.h"
#include "engine/engine.h"
#include "graphics/geometry.h"
#include "graphics/gl_ext.h"
#include "graphics/irender_device.h"
#include "graphics/material.h"
#include "graphics/model.h"
#include "graphics/model_instance.h"
#include "graphics/pipeline.h"
#include "graphics/render_scene.h"
#include "graphics/shader.h"
#include "graphics/texture.h"
#include "universe/component_event.h"
#include "universe/entity_moved_event.h"
#include "universe/universe.h"

namespace Lux
{

static const uint32_t light_hash = crc32("light");
static const uint32_t renderable_hash = crc32("renderable");
static const uint32_t camera_hash = crc32("camera");

struct RendererImpl : public Renderer
{

	RendererImpl()
	{
	}

	virtual void setProjection(float width, float height, float fov, float near_plane, float far_plane, const Matrix& mtx) override
	{
		glViewport(0, 0, (GLsizei)width, (GLsizei)height);
		glMatrixMode(GL_PROJECTION);
		glLoadIdentity();
		gluPerspective(fov, width / height, near_plane, far_plane);
		glMatrixMode(GL_MODELVIEW);
		glLoadIdentity();
		Vec3 pos = mtx.getTranslation();
		Vec3 center = pos - mtx.getZVector();
		Vec3 up = mtx.getYVector();
		gluLookAt(pos.x, pos.y, pos.z, center.x, center.y, center.z, up.x, up.y, up.z);
	}

	virtual void setRenderDevice(IRenderDevice& device) override
	{
		m_render_device = &device;
	}

	virtual void renderGame() override
	{
		if (m_render_device)
		{
			m_render_device->beginFrame();
			render(*m_render_device);
			m_render_device->endFrame();
		}
	}

	virtual void render(IRenderDevice& device) override
	{
		// init
		glEnable(GL_DEPTH_TEST);
		glDisable(GL_BLEND);

		// render
		device.getPipeline().render();

		// cleanup
		glBindBuffer(GL_ARRAY_BUFFER, 0);
		glUseProgram(0);
		for(int i = 0; i < 16; ++i)
		{
			glActiveTexture(GL_TEXTURE0 + i);
			glDisable(GL_TEXTURE_2D);
		}
		glActiveTexture(GL_TEXTURE0);
	}

	virtual bool create(Engine& engine) override
	{
		m_engine = &engine;
		glewExperimental = GL_TRUE;
		GLenum err = glewInit();
		return err == GLEW_OK
			&& (GLEW_EXT_framebuffer_object || GLEW_ARB_framebuffer_object)
			&& GLEW_ARB_shader_objects
			&& GLEW_ARB_fragment_shader
			&& GLEW_ARB_vertex_shader
			&& GLEW_ARB_vertex_buffer_object;
	}

	virtual void destroy() override
	{
	}

	virtual const char* getName() const override
	{
		return "renderer";
	}

	virtual Component createComponent(uint32_t, const Entity&) override
	{
		return Component::INVALID;
	}

	virtual void enableZTest(bool enable) override
	{
		if (enable)
		{
			glEnable(GL_DEPTH_TEST);
		}
		else
		{
			glDisable(GL_DEPTH_TEST);
		}
	}

	virtual Engine& getEngine() override
	{
		return *m_engine;
	}

	virtual void renderModel(const Model& model, const Matrix& transform, PipelineInstance& pipeline) override
	{
		glPushMatrix();
		glMultMatrixf(&transform.m11);
		for (int i = 0, c = model.getMeshCount(); i < c;  ++i)
		{
			const Mesh& mesh = model.getMesh(i);
			mesh.getMaterial()->apply(*this, pipeline);
			model.getGeometry()->draw(mesh.getStart(), mesh.getCount(), *mesh.getMaterial()->getShader());
		}
		glPopMatrix();
	}

	virtual Model* getModel(const char* path) override
	{
		return static_cast<Model*>(m_engine->getResourceManager().get(ResourceManager::MODEL)->load(path));
	}

	virtual void serialize(ISerializer&) override
	{
	}

	virtual void deserialize(ISerializer&) override
	{
	}

	Engine* m_engine;
	Array<Model*> m_models;
	IRenderDevice* m_render_device;
};

Renderer* Renderer::createInstance()
{
	return LUX_NEW(RendererImpl);
}

void Renderer::destroyInstance(Renderer& renderer)
{
	LUX_DELETE(&renderer);
}

} // ~namespace Lux<|endoftext|>


<commit_before>/*
 * Author: Zion Orent <zorent@ics.com>
 * Copyright (c) 2015 Intel Corporation.
 *
 * Permission is hereby granted, free of charge, to any person obtaining
 * a copy of this software and associated documentation files (the
 * "Software"), to deal in the Software without restriction, including
 * without limitation the rights to use, copy, modify, merge, publish,
 * distribute, sublicense, and/or sell copies of the Software, and to
 * permit persons to whom the Software is furnished to do so, subject to
 * the following conditions:
 *
 * The above copyright notice and this permission notice shall be
 * included in all copies or substantial portions of the Software.
 *
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
 * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
 * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
 * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
 * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
 * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
 */

#include <iostream>

#include "groveemg.h"

using namespace upm;
using namespace std;

GroveEMG::GroveEMG(int pin)
{
    if ( !(m_aio = mraa_aio_init(pin)) )
    {
      cerr << __FUNCTION__ << ": mraa_aio_init() failed" << endl;
      return;
    }
}

GroveEMG::~GroveEMG()
{
  mraa_aio_close(m_aio);
}

void GroveEMG::calibrate()
{
	int val, sum = 0;

	for (int i=0; i<1100; i++)
	{
		val = mraa_aio_read(m_aio);
		sum += val;
		usleep(1000);
	}
	sum /= 1100;
	cout << "Static analog data = " << sum << endl;
}

int GroveEMG::value()
{
	int val = mraa_aio_read(m_aio);
	return val;
}
<commit_msg>groveemg: throw exception(s) on fatal errors<commit_after>/*
 * Author: Zion Orent <zorent@ics.com>
 * Copyright (c) 2015 Intel Corporation.
 *
 * Permission is hereby granted, free of charge, to any person obtaining
 * a copy of this software and associated documentation files (the
 * "Software"), to deal in the Software without restriction, including
 * without limitation the rights to use, copy, modify, merge, publish,
 * distribute, sublicense, and/or sell copies of the Software, and to
 * permit persons to whom the Software is furnished to do so, subject to
 * the following conditions:
 *
 * The above copyright notice and this permission notice shall be
 * included in all copies or substantial portions of the Software.
 *
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
 * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
 * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
 * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
 * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
 * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
 */

#include <iostream>
#include <string>
#include <stdexcept>

#include "groveemg.h"

using namespace upm;
using namespace std;

GroveEMG::GroveEMG(int pin)
{
    if ( !(m_aio = mraa_aio_init(pin)) )
    {
      throw std::invalid_argument(std::string(__FUNCTION__) +
                                  ": mraa_aio_init() failed, invalid pin?");
      return;
    }
}

GroveEMG::~GroveEMG()
{
  mraa_aio_close(m_aio);
}

void GroveEMG::calibrate()
{
	int val, sum = 0;

	for (int i=0; i<1100; i++)
	{
		val = mraa_aio_read(m_aio);
		sum += val;
		usleep(1000);
	}
	sum /= 1100;
	cout << "Static analog data = " << sum << endl;
}

int GroveEMG::value()
{
	int val = mraa_aio_read(m_aio);
	return val;
}
<|endoftext|>


<commit_before>// https://oj.leetcode.com/problems/sort-list/
namespace SortList {
    class Solution {
    public:

        ListNode * splitInMid(ListNode * head) {
            if (head == NULL || head->next == NULL) {
                return NULL;
            }

            ListNode * slow = head;
            ListNode * fast = head;
            while (fast->next != NULL && fast->next->next != NULL) {
                slow = slow->next;
                fast = fast->next->next;
            }

            ListNode * mid = slow->next;
            slow->next = NULL;
            return mid;
        }

        ListNode * merge(ListNode * h1, ListNode * h2) {
            if (h1 == NULL && h2 == NULL) {
                return NULL;
            }

            if (h1 == NULL) {
                return h2;
            }

            if (h2 == NULL) {
                return h1;
            }

            ListNode * c1 = h1;
            ListNode * c2 = h2;
            ListNode dummy(-1);
            ListNode * cur = &dummy;

            while (c1 != NULL && c2 != NULL) {
                if (c1->val < c2->val) {
                    cur->next = c1;
                    c1 = c1->next;
                } else {
                    cur->next = c2;
                    c2 = c2->next;
                }

                cur = cur->next;
            }

            if (c1 == NULL) {
                cur->next = c2;
            } else {
                cur->next = c1;
            }

            return dummy.next;
        }

        ListNode *sortList(ListNode *head) {
            if (head == NULL || head->next == NULL) {
                return head;
            }
            ListNode * mid = splitInMid(head);
            ListNode * sortedList1 = sortList(head);
            ListNode * sortedList2 = sortList(mid);
            return merge(sortedList1, sortedList2);
        }
    };
}
<commit_msg>Update SortList.cc<commit_after>// https://oj.leetcode.com/problems/sort-list/
namespace SortList {
    class Solution {
    public:

        ListNode * splitInMid(ListNode * head) {
            if (head == NULL || head->next == NULL) {
                return NULL;
            }

            ListNode * slow = head;
            ListNode * fast = head;
            while (fast->next != NULL && fast->next->next != NULL) {
                slow = slow->next;
                fast = fast->next->next;
            }

            ListNode * mid = slow->next;
            slow->next = NULL;
            return mid;
        }

        ListNode * merge(ListNode * h1, ListNode * h2) {
            if (h1 == NULL && h2 == NULL) {
                return NULL;
            }

            if (h1 == NULL) {
                return h2;
            }

            if (h2 == NULL) {
                return h1;
            }

            ListNode * c1 = h1;
            ListNode * c2 = h2;
            ListNode dummy(-1);
            ListNode * cur = &dummy;

            while (c1 != NULL && c2 != NULL) {
                if (c1->val < c2->val) {
                    cur->next = c1;
                    c1 = c1->next;
                } else {
                    cur->next = c2;
                    c2 = c2->next;
                }

                cur = cur->next;
            }

            if (c1 == NULL) {
                cur->next = c2;
            } else {
                cur->next = c1;
            }

            return dummy.next;
        }

        ListNode *sortList(ListNode *head) {
            if (head == NULL || head->next == NULL) {
                return head;
            }
            ListNode * mid = splitInMid(head);
            ListNode * sortedList1 = sortList(head);
            ListNode * sortedList2 = sortList(mid);
            return merge(sortedList1, sortedList2);
        }
    };

    // This solution make use of the movement of "head" in recursion. No "split" is needed here
    class Solution2 {
    public:
        ListNode * merge(ListNode * head1, ListNode * head2) {
            ListNode dummy(-1);
            ListNode * prev = &dummy;

            while (head1 != NULL && head2 != NULL) {
                if (head1->val < head2->val) {
                    prev->next = head1;
                    head1 = head1->next;
                } else {
                    prev->next = head2;
                    head2 = head2->next;
                }
                prev = prev->next;
            }

            if (head1 == NULL) {
                prev->next = head2;
            }

            if (head2 == NULL) {
                prev->next = head1;
            }

            return dummy.next;
        }
        ListNode * doSortList(ListNode * &head, int len) {
            if (len == 0 ) {
                return head;
            }

            if (len == 1) {
                ListNode * tmp = head;
                head = head->next;
                tmp->next = NULL;
                return tmp;
            }

            ListNode * part1 = doSortList(head, len / 2);
            ListNode * part2 = doSortList(head, len - len / 2);
            return merge(part1, part2);
        }

        ListNode *sortList(ListNode *head) {
            int len = 0;
            ListNode * cur = head;
            while (cur != NULL) {
                len++;
                cur = cur->next;
            }

            return doSortList(head, len);
        }
    };
}

<|endoftext|>


<commit_before>#ifdef EXAFMM_TAPAS_MPI
# include <mpi.h>
#endif

#include "args.h"
#include "bound_box.h"
#ifdef CILK
#include "build_tree3.h"
#else
#include "build_tree.h"
#endif
#include "dataset.h"
#include "logger.h"
#include "traversal.h"
#include "up_down_pass.h"
#include "verify.h"

#define TAPAS

#ifdef TAPAS
#include "tapas_exafmm.h"
#include "serial_tapas_helper.cxx"
#endif

int main(int argc, char ** argv) {
  Args args(argc, argv);
  Bodies bodies, bodies2, bodies3, jbodies;
  BoundBox boundBox(args.nspawn);
  Bounds bounds;
  BuildTree buildTree(args.ncrit, args.nspawn);
  Cells cells, jcells;
  Dataset data;
  Traversal traversal(args.nspawn, args.images);

#ifdef EXAFMM_TAPAS_MPI
    MPI_Init(&argc, &argv);
    MPI_Comm_rank(MPI_COMM_WORLD, &args.mpi_rank);
    MPI_Comm_size(MPI_COMM_WORLD, &args.mpi_size);
#endif

  if (args.useRmax) {
    std::cerr << "Rmax not supported." << std::endl;
    std::cerr << "Use --useRmax 0 option." << std::endl;
    exit(1);
  }
  if (args.useRopt) {
    std::cerr << "Ropt not supported." << std::endl;
    std::cerr << "Use --useRopt 0 option." << std::endl;
    exit(1);
  }
  UpDownPass upDownPass(args.theta, args.useRmax, args.useRopt);
  Verify verify;

  Region tr;

  num_threads(args.threads);

  const real_t cycle = 2 * M_PI;
  logger::verbose = args.verbose && (args.mpi_rank == 0);
  logger::printTitle("FMM Parameters");
  args.print(logger::stringLength, P);
  bodies = data.initBodies(args.numBodies, args.distribution, 0);

  for (int t=0; t<args.repeat; t++) {
    logger::printTitle("FMM Profiling");
    logger::startTimer("Total FMM");
    logger::startPAPI();
    logger::startDAG();
    bounds = boundBox.getBounds(bodies);
#ifdef TAPAS
    asn(tr, bounds);
    std::cerr << "#1" << std::endl;
    TAPAS_LOG_DEBUG() << "Bounding box: " << tr << std::endl;
#endif

    Tapas::Cell *root = Tapas::Partition(
        bodies.data(), args.numBodies, tr, args.ncrit);
#if 0
    {
      std::ofstream tapas_out("tapas_0.txt");
      for (int i = 0; i < args.numBodies; ++i) {
        tapas_out << root->body_attrs()[i] << std::endl;
      }
    }
#endif

    logger::startTimer("Upward pass");                          // Start timer
    tapas::Map(FMM_P2M, *root, args.theta);
    logger::stopTimer("Upward pass");                          // Start timer
    TAPAS_LOG_DEBUG() << "P2M done\n";
#if 0
    {
      std::ofstream tapas_out("tapas_P2M.txt");
      for (int i = 0; i < args.numBodies; ++i) {
        tapas_out << root->body_attrs()[i] << std::endl;
      }
    }
#endif

    logger::startTimer("Traverse");
    numM2L = 0; numP2P = 0;
    tapas::Map(FMM_M2L, tapas::Product(*root, *root), args.mutual, args.nspawn);
    logger::stopTimer("Traverse");

    TAPAS_LOG_DEBUG() << "M2L done\n";
    jbodies = bodies;
#if 0
    {
      std::ofstream tapas_out("tapas_M2L.txt");
      for (int i = 0; i < args.numBodies; ++i) {
        tapas_out << root->body_attrs()[i] << std::endl;
      }
    }
#endif

    logger::startTimer("Downward pass");
    tapas::Map(FMM_L2P, *root);
    logger::stopTimer("Downward pass");

    TAPAS_LOG_DEBUG() << "L2P done\n";
#if 0
    {
      std::ofstream tapas_out("tapas_L2P.txt");
      for (int i = 0; i < args.numBodies; ++i) {
        tapas_out << root->body_attrs()[i] << std::endl;
      }
    }
#endif

    CopyBackResult(bodies, root->body_attrs(), args.numBodies);
#if 0
    {
      std::ofstream tapas_out("tapas_final.txt");
      for (int i = 0; i < args.numBodies; ++i) {
        tapas_out << bodies[i].TRG << std::endl;
        //tapas_out << root->body_attrs()[i] << std::endl;
      }
    }
#endif

    logger::printTitle("Total runtime");
    logger::stopPAPI();
    logger::stopTimer("Total FMM");
    logger::resetTimer("Total FMM");
#if WRITE_TIME
    logger::writeTime();
#endif
    const int numTargets = 100;
    bodies3 = bodies;
    data.sampleBodies(bodies, numTargets);
    bodies2 = bodies;
    data.initTarget(bodies);
    logger::startTimer("Total Direct");
    traversal.direct(bodies, jbodies, cycle);
    traversal.normalize(bodies);
    logger::stopTimer("Total Direct");
    double potDif = verify.getDifScalar(bodies, bodies2);
    double potNrm = verify.getNrmScalar(bodies);
    double accDif = verify.getDifVector(bodies, bodies2);
    double accNrm = verify.getNrmVector(bodies);
    logger::printTitle("FMM vs. direct");
    verify.print("Rel. L2 Error (pot)",std::sqrt(potDif/potNrm));
    verify.print("Rel. L2 Error (acc)",std::sqrt(accDif/accNrm));
    std::cerr << "M2L calls: " << numM2L << std::endl;
    std::cerr << "P2P calls: " << numP2P << std::endl;
    buildTree.printTreeData(cells);
    traversal.printTraversalData();
    logger::printPAPI();
    logger::stopDAG();
    bodies = bodies3;
    data.initTarget(bodies);
  }
  logger::writeDAG();
#ifdef EXAFMM_TAPAS_MPI
  MPI_Finalize();
#endif
  return 0;
}
<commit_msg>minor fix: removed unnecessary debug info<commit_after>#ifdef EXAFMM_TAPAS_MPI
# include <mpi.h>
#endif

#include "args.h"
#include "bound_box.h"
#ifdef CILK
#include "build_tree3.h"
#else
#include "build_tree.h"
#endif
#include "dataset.h"
#include "logger.h"
#include "traversal.h"
#include "up_down_pass.h"
#include "verify.h"

#define TAPAS

#ifdef TAPAS
#include "tapas_exafmm.h"
#include "serial_tapas_helper.cxx"
#endif

int main(int argc, char ** argv) {
  Args args(argc, argv);
  Bodies bodies, bodies2, bodies3, jbodies;
  BoundBox boundBox(args.nspawn);
  Bounds bounds;
  BuildTree buildTree(args.ncrit, args.nspawn);
  Cells cells, jcells;
  Dataset data;
  Traversal traversal(args.nspawn, args.images);

#ifdef EXAFMM_TAPAS_MPI
    MPI_Init(&argc, &argv);
    MPI_Comm_rank(MPI_COMM_WORLD, &args.mpi_rank);
    MPI_Comm_size(MPI_COMM_WORLD, &args.mpi_size);
#endif

  if (args.useRmax) {
    std::cerr << "Rmax not supported." << std::endl;
    std::cerr << "Use --useRmax 0 option." << std::endl;
    exit(1);
  }
  if (args.useRopt) {
    std::cerr << "Ropt not supported." << std::endl;
    std::cerr << "Use --useRopt 0 option." << std::endl;
    exit(1);
  }
  UpDownPass upDownPass(args.theta, args.useRmax, args.useRopt);
  Verify verify;

  Region tr;

  num_threads(args.threads);

  const real_t cycle = 2 * M_PI;
  logger::verbose = args.verbose && (args.mpi_rank == 0);
  logger::printTitle("FMM Parameters");
  args.print(logger::stringLength, P);
  bodies = data.initBodies(args.numBodies, args.distribution, 0);

  for (int t=0; t<args.repeat; t++) {
    logger::printTitle("FMM Profiling");
    logger::startTimer("Total FMM");
    logger::startPAPI();
    logger::startDAG();
    bounds = boundBox.getBounds(bodies);
#ifdef TAPAS
    asn(tr, bounds);
    TAPAS_LOG_DEBUG() << "Bounding box: " << tr << std::endl;
#endif

    Tapas::Cell *root = Tapas::Partition(
        bodies.data(), args.numBodies, tr, args.ncrit);
#if 0
    {
      std::ofstream tapas_out("tapas_0.txt");
      for (int i = 0; i < args.numBodies; ++i) {
        tapas_out << root->body_attrs()[i] << std::endl;
      }
    }
#endif

    logger::startTimer("Upward pass");                          // Start timer
    tapas::Map(FMM_P2M, *root, args.theta);
    logger::stopTimer("Upward pass");                          // Start timer
    TAPAS_LOG_DEBUG() << "P2M done\n";
#if 0
    {
      std::ofstream tapas_out("tapas_P2M.txt");
      for (int i = 0; i < args.numBodies; ++i) {
        tapas_out << root->body_attrs()[i] << std::endl;
      }
    }
#endif

    logger::startTimer("Traverse");
    numM2L = 0; numP2P = 0;
    tapas::Map(FMM_M2L, tapas::Product(*root, *root), args.mutual, args.nspawn);
    logger::stopTimer("Traverse");

    TAPAS_LOG_DEBUG() << "M2L done\n";
    jbodies = bodies;
#if 0
    {
      std::ofstream tapas_out("tapas_M2L.txt");
      for (int i = 0; i < args.numBodies; ++i) {
        tapas_out << root->body_attrs()[i] << std::endl;
      }
    }
#endif

    logger::startTimer("Downward pass");
    tapas::Map(FMM_L2P, *root);
    logger::stopTimer("Downward pass");

    TAPAS_LOG_DEBUG() << "L2P done\n";
#if 0
    {
      std::ofstream tapas_out("tapas_L2P.txt");
      for (int i = 0; i < args.numBodies; ++i) {
        tapas_out << root->body_attrs()[i] << std::endl;
      }
    }
#endif

    CopyBackResult(bodies, root->body_attrs(), args.numBodies);
#if 0
    {
      std::ofstream tapas_out("tapas_final.txt");
      for (int i = 0; i < args.numBodies; ++i) {
        tapas_out << bodies[i].TRG << std::endl;
        //tapas_out << root->body_attrs()[i] << std::endl;
      }
    }
#endif

    logger::printTitle("Total runtime");
    logger::stopPAPI();
    logger::stopTimer("Total FMM");
    logger::resetTimer("Total FMM");
#if WRITE_TIME
    logger::writeTime();
#endif
    const int numTargets = 100;
    bodies3 = bodies;
    data.sampleBodies(bodies, numTargets);
    bodies2 = bodies;
    data.initTarget(bodies);
    logger::startTimer("Total Direct");
    traversal.direct(bodies, jbodies, cycle);
    traversal.normalize(bodies);
    logger::stopTimer("Total Direct");
    double potDif = verify.getDifScalar(bodies, bodies2);
    double potNrm = verify.getNrmScalar(bodies);
    double accDif = verify.getDifVector(bodies, bodies2);
    double accNrm = verify.getNrmVector(bodies);
    logger::printTitle("FMM vs. direct");
    verify.print("Rel. L2 Error (pot)",std::sqrt(potDif/potNrm));
    verify.print("Rel. L2 Error (acc)",std::sqrt(accDif/accNrm));
    std::cerr << "M2L calls: " << numM2L << std::endl;
    std::cerr << "P2P calls: " << numP2P << std::endl;
    buildTree.printTreeData(cells);
    traversal.printTraversalData();
    logger::printPAPI();
    logger::stopDAG();
    bodies = bodies3;
    data.initTarget(bodies);
  }
  logger::writeDAG();
#ifdef EXAFMM_TAPAS_MPI
  MPI_Finalize();
#endif
  return 0;
}
<|endoftext|>