<commit_before>#pragma once

#include <cilantro/principal_component_analysis.hpp>
#include <cilantro/kd_tree.hpp>

namespace cilantro {
    template <typename ScalarT, ptrdiff_t EigenDim>
    class NormalEstimation {
    public:
        EIGEN_MAKE_ALIGNED_OPERATOR_NEW

        NormalEstimation(const ConstVectorSetMatrixMap<ScalarT,EigenDim> &points, size_t max_leaf_size = 10)
                : points_(points),
                  kd_tree_ptr_(new KDTree<ScalarT,EigenDim,KDTreeDistanceAdaptors::L2>(points, max_leaf_size)),
                  kd_tree_owned_(true),
                  view_point_(Vector<ScalarT,EigenDim>::Zero())
        {}

        NormalEstimation(const KDTree<ScalarT,EigenDim,KDTreeDistanceAdaptors::L2> &kd_tree)
                : points_(kd_tree.getPointsMatrixMap()),
                  kd_tree_ptr_(&kd_tree),
                  kd_tree_owned_(false),
                  view_point_(Vector<ScalarT,EigenDim>::Zero())
        {}

        ~NormalEstimation() {
            if (kd_tree_owned_) delete kd_tree_ptr_;
        }

        inline const Vector<ScalarT,EigenDim>& getViewPoint() const { return view_point_; }

        inline NormalEstimation& setViewPoint(const Eigen::Ref<const Vector<ScalarT,EigenDim>> &vp) { view_point_ = vp; return *this; }

        inline const NormalEstimation& estimateNormalsAndCurvatureKNN(VectorSet<ScalarT,EigenDim> &normals, VectorSet<ScalarT,1> &curvatures, size_t k) const {
            compute_<NeighborhoodType::KNN>(normals, curvatures, NeighborhoodSpecification<ScalarT>(NeighborhoodType::KNN, k, 0.0));
            return *this;
        }

        inline VectorSet<ScalarT,EigenDim> estimateNormalsKNN(size_t k) const {
            VectorSet<ScalarT,EigenDim> normals;
            VectorSet<ScalarT,1> curvatures;
            compute_<NeighborhoodType::KNN>(normals, curvatures, NeighborhoodSpecification<ScalarT>(NeighborhoodType::KNN, k, 0.0));
            return normals;
        }

        inline VectorSet<ScalarT,1> estimateCurvatureKNN(size_t k) const {
            VectorSet<ScalarT,EigenDim> normals;
            VectorSet<ScalarT,1> curvatures;
            compute_<NeighborhoodType::KNN>(normals, curvatures, NeighborhoodSpecification<ScalarT>(NeighborhoodType::KNN, k, 0.0));
            return curvatures;
        }

        inline const NormalEstimation& estimateNormalsAndCurvatureRadius(VectorSet<ScalarT,EigenDim> &normals, VectorSet<ScalarT,1> &curvatures, ScalarT radius) const {
            compute_radius_(normals, curvatures, radius);
            return *this;
        }

        inline VectorSet<ScalarT,EigenDim> estimateNormalsRadius(ScalarT radius) const {
            VectorSet<ScalarT,EigenDim> normals;
            VectorSet<ScalarT,1> curvatures;
            compute_<NeighborhoodType::RADIUS>(normals, curvatures, NeighborhoodSpecification<ScalarT>(NeighborhoodType::RADIUS, 0, radius*radius));
            return normals;
        }

        inline VectorSet<ScalarT,1> estimateCurvatureRadius(ScalarT radius) const {
            VectorSet<ScalarT,EigenDim> normals;
            VectorSet<ScalarT,1> curvatures;
            compute_<NeighborhoodType::RADIUS>(normals, curvatures, NeighborhoodSpecification<ScalarT>(NeighborhoodType::RADIUS, 0, radius*radius));
            return curvatures;
        }

        inline const NormalEstimation& estimateNormalsAndCurvatureKNNInRadius(VectorSet<ScalarT,EigenDim> &normals, VectorSet<ScalarT,1> &curvatures, size_t k, ScalarT radius) const {
            compute_<NeighborhoodType::KNN_IN_RADIUS>(normals, curvatures, NeighborhoodSpecification<ScalarT>(NeighborhoodType::KNN_IN_RADIUS, k, radius*radius));
            return *this;
        }

        inline VectorSet<ScalarT,EigenDim> estimateNormalsKNNInRadius(size_t k, ScalarT radius) const {
            VectorSet<ScalarT,EigenDim> normals;
            VectorSet<ScalarT,1> curvatures;
            compute_<NeighborhoodType::KNN_IN_RADIUS>(normals, curvatures, NeighborhoodSpecification<ScalarT>(NeighborhoodType::KNN_IN_RADIUS, k, radius*radius));
            return normals;
        }

        inline VectorSet<ScalarT,1> estimateCurvatureKNNInRadius(size_t k, ScalarT radius) const {
            VectorSet<ScalarT,EigenDim> normals;
            VectorSet<ScalarT,1> curvatures;
            compute_<NeighborhoodType::KNN_IN_RADIUS>(normals, curvatures, NeighborhoodSpecification<ScalarT>(NeighborhoodType::KNN_IN_RADIUS, k, radius*radius));
            return curvatures;
        }

        template <NeighborhoodType NT>
        inline const NormalEstimation& estimateNormalsAndCurvature(VectorSet<ScalarT,EigenDim> &normals, VectorSet<ScalarT,1> &curvatures, const NeighborhoodSpecification<ScalarT> &nh) const {
            compute_<NT>(normals, curvatures, nh);
            return *this;
        }

        template <NeighborhoodType NT>
        inline VectorSet<ScalarT,EigenDim> estimateNormals(const NeighborhoodSpecification<ScalarT> &nh) const {
            VectorSet<ScalarT,EigenDim> normals;
            VectorSet<ScalarT,1> curvatures;
            compute_<NT>(normals, curvatures, nh);
            return normals;
        }

        template <NeighborhoodType NT>
        inline VectorSet<ScalarT,1> estimateCurvature(const NeighborhoodSpecification<ScalarT> &nh) const {
            VectorSet<ScalarT,EigenDim> normals;
            VectorSet<ScalarT,1> curvatures;
            compute_<NT>(normals, curvatures, nh);
            return curvatures;
        }

        inline const NormalEstimation& estimateNormalsAndCurvature(VectorSet<ScalarT,EigenDim> &normals, VectorSet<ScalarT,1> &curvatures, const NeighborhoodSpecification<ScalarT> &nh) const {
            compute_nh_(normals, curvatures, nh);
            return *this;
        }

        inline VectorSet<ScalarT,EigenDim> estimateNormals(const NeighborhoodSpecification<ScalarT> &nh) const {
            VectorSet<ScalarT,EigenDim> normals;
            VectorSet<ScalarT,1> curvatures;
            compute_nh_(normals, curvatures, nh);
            return normals;
        }

        inline VectorSet<ScalarT,1> estimateCurvature(const NeighborhoodSpecification<ScalarT> &nh) const {
            VectorSet<ScalarT,EigenDim> normals;
            VectorSet<ScalarT,1> curvatures;
            compute_nh_(normals, curvatures, nh);
            return curvatures;
        }

    private:
        ConstVectorSetMatrixMap<ScalarT,EigenDim> points_;
        const KDTree<ScalarT,EigenDim,KDTreeDistanceAdaptors::L2> *kd_tree_ptr_;
        bool kd_tree_owned_;
        Vector<ScalarT,EigenDim> view_point_;

        void compute_nh_(VectorSet<ScalarT,EigenDim> &normals, VectorSet<ScalarT,1> &curvatures, const NeighborhoodSpecification<ScalarT> &nh) const {
            switch (nh.type) {
                case NeighborhoodType::KNN:
                    compute_<NeighborhoodType::KNN>(normals, curvatures, nh);
                    break;
                case NeighborhoodType::RADIUS:
                    compute_<NeighborhoodType::RADIUS>(normals, curvatures, nh);
                    break;
                case NeighborhoodType::KNN_IN_RADIUS:
                    compute_<NeighborhoodType::KNN_IN_RADIUS>(normals, curvatures, nh);
                    break;
            }
        }

        template <NeighborhoodType NT>
        void compute_(VectorSet<ScalarT,EigenDim> &normals, VectorSet<ScalarT,1> &curvatures, const NeighborhoodSpecification<ScalarT> &nh) const {
            size_t dim = points_.rows();
            size_t num_points = points_.cols();

            normals.resize(dim, num_points);
            curvatures.resize(1, num_points);

            std::vector<size_t> neighbors;
            std::vector<ScalarT> distances;
#pragma omp parallel for shared (normals) private (neighbors, distances)
            for (size_t i = 0; i < num_points; i++) {
                kd_tree_ptr_->template search<NT>(points_.col(i), nh, neighbors, distances);
                if (neighbors.size() < dim) {
                    normals.col(i).setConstant(std::numeric_limits<ScalarT>::quiet_NaN());
                    curvatures[i] = std::numeric_limits<ScalarT>::quiet_NaN();
                    continue;
                }
                VectorSet<ScalarT,EigenDim> neighborhood(dim, neighbors.size());
                for (size_t j = 0; j < neighbors.size(); j++) {
                    neighborhood.col(j) = points_.col(neighbors[j]);
                }
                PrincipalComponentAnalysis<ScalarT,EigenDim> pca(neighborhood);
                normals.col(i) = pca.getEigenVectors().col(dim-1);
                if (normals.col(i).dot(view_point_ - points_.col(i)) < 0.0) {
                    normals.col(i) *= -1.0;
                }
                curvatures[i] = pca.getEigenValues()[dim-1]/pca.getEigenValues().sum();
            }
        }

    };

    typedef NormalEstimation<float,2> NormalEstimation2D;
    typedef NormalEstimation<float,3> NormalEstimation3D;
}
<commit_msg>NormalEstimation fixes<commit_after>#pragma once

#include <cilantro/principal_component_analysis.hpp>
#include <cilantro/kd_tree.hpp>

namespace cilantro {
    template <typename ScalarT, ptrdiff_t EigenDim>
    class NormalEstimation {
    public:
        EIGEN_MAKE_ALIGNED_OPERATOR_NEW

        NormalEstimation(const ConstVectorSetMatrixMap<ScalarT,EigenDim> &points, size_t max_leaf_size = 10)
                : points_(points),
                  kd_tree_ptr_(new KDTree<ScalarT,EigenDim,KDTreeDistanceAdaptors::L2>(points, max_leaf_size)),
                  kd_tree_owned_(true),
                  view_point_(Vector<ScalarT,EigenDim>::Zero())
        {}

        NormalEstimation(const KDTree<ScalarT,EigenDim,KDTreeDistanceAdaptors::L2> &kd_tree)
                : points_(kd_tree.getPointsMatrixMap()),
                  kd_tree_ptr_(&kd_tree),
                  kd_tree_owned_(false),
                  view_point_(Vector<ScalarT,EigenDim>::Zero())
        {}

        ~NormalEstimation() {
            if (kd_tree_owned_) delete kd_tree_ptr_;
        }

        inline const Vector<ScalarT,EigenDim>& getViewPoint() const { return view_point_; }

        inline NormalEstimation& setViewPoint(const Eigen::Ref<const Vector<ScalarT,EigenDim>> &vp) { view_point_ = vp; return *this; }

        inline const NormalEstimation& estimateNormalsAndCurvatureKNN(VectorSet<ScalarT,EigenDim> &normals, VectorSet<ScalarT,1> &curvatures, size_t k) const {
            compute_<NeighborhoodType::KNN>(normals, curvatures, NeighborhoodSpecification<ScalarT>(NeighborhoodType::KNN, k, 0.0));
            return *this;
        }

        inline VectorSet<ScalarT,EigenDim> estimateNormalsKNN(size_t k) const {
            VectorSet<ScalarT,EigenDim> normals;
            VectorSet<ScalarT,1> curvatures;
            compute_<NeighborhoodType::KNN>(normals, curvatures, NeighborhoodSpecification<ScalarT>(NeighborhoodType::KNN, k, 0.0));
            return normals;
        }

        inline VectorSet<ScalarT,1> estimateCurvatureKNN(size_t k) const {
            VectorSet<ScalarT,EigenDim> normals;
            VectorSet<ScalarT,1> curvatures;
            compute_<NeighborhoodType::KNN>(normals, curvatures, NeighborhoodSpecification<ScalarT>(NeighborhoodType::KNN, k, 0.0));
            return curvatures;
        }

        inline const NormalEstimation& estimateNormalsAndCurvatureRadius(VectorSet<ScalarT,EigenDim> &normals, VectorSet<ScalarT,1> &curvatures, ScalarT radius) const {
            compute_<NeighborhoodType::RADIUS>(normals, curvatures, NeighborhoodSpecification<ScalarT>(NeighborhoodType::RADIUS, 0, radius));
            return *this;
        }

        inline VectorSet<ScalarT,EigenDim> estimateNormalsRadius(ScalarT radius) const {
            VectorSet<ScalarT,EigenDim> normals;
            VectorSet<ScalarT,1> curvatures;
            compute_<NeighborhoodType::RADIUS>(normals, curvatures, NeighborhoodSpecification<ScalarT>(NeighborhoodType::RADIUS, 0, radius));
            return normals;
        }

        inline VectorSet<ScalarT,1> estimateCurvatureRadius(ScalarT radius) const {
            VectorSet<ScalarT,EigenDim> normals;
            VectorSet<ScalarT,1> curvatures;
            compute_<NeighborhoodType::RADIUS>(normals, curvatures, NeighborhoodSpecification<ScalarT>(NeighborhoodType::RADIUS, 0, radius));
            return curvatures;
        }

        inline const NormalEstimation& estimateNormalsAndCurvatureKNNInRadius(VectorSet<ScalarT,EigenDim> &normals, VectorSet<ScalarT,1> &curvatures, size_t k, ScalarT radius) const {
            compute_<NeighborhoodType::KNN_IN_RADIUS>(normals, curvatures, NeighborhoodSpecification<ScalarT>(NeighborhoodType::KNN_IN_RADIUS, k, radius));
            return *this;
        }

        inline VectorSet<ScalarT,EigenDim> estimateNormalsKNNInRadius(size_t k, ScalarT radius) const {
            VectorSet<ScalarT,EigenDim> normals;
            VectorSet<ScalarT,1> curvatures;
            compute_<NeighborhoodType::KNN_IN_RADIUS>(normals, curvatures, NeighborhoodSpecification<ScalarT>(NeighborhoodType::KNN_IN_RADIUS, k, radius));
            return normals;
        }

        inline VectorSet<ScalarT,1> estimateCurvatureKNNInRadius(size_t k, ScalarT radius) const {
            VectorSet<ScalarT,EigenDim> normals;
            VectorSet<ScalarT,1> curvatures;
            compute_<NeighborhoodType::KNN_IN_RADIUS>(normals, curvatures, NeighborhoodSpecification<ScalarT>(NeighborhoodType::KNN_IN_RADIUS, k, radius));
            return curvatures;
        }

        template <NeighborhoodType NT>
        inline const NormalEstimation& estimateNormalsAndCurvature(VectorSet<ScalarT,EigenDim> &normals, VectorSet<ScalarT,1> &curvatures, const NeighborhoodSpecification<ScalarT> &nh) const {
            compute_<NT>(normals, curvatures, nh);
            return *this;
        }

        template <NeighborhoodType NT>
        inline VectorSet<ScalarT,EigenDim> estimateNormals(const NeighborhoodSpecification<ScalarT> &nh) const {
            VectorSet<ScalarT,EigenDim> normals;
            VectorSet<ScalarT,1> curvatures;
            compute_<NT>(normals, curvatures, nh);
            return normals;
        }

        template <NeighborhoodType NT>
        inline VectorSet<ScalarT,1> estimateCurvature(const NeighborhoodSpecification<ScalarT> &nh) const {
            VectorSet<ScalarT,EigenDim> normals;
            VectorSet<ScalarT,1> curvatures;
            compute_<NT>(normals, curvatures, nh);
            return curvatures;
        }

        inline const NormalEstimation& estimateNormalsAndCurvature(VectorSet<ScalarT,EigenDim> &normals, VectorSet<ScalarT,1> &curvatures, const NeighborhoodSpecification<ScalarT> &nh) const {
            compute_nh_(normals, curvatures, nh);
            return *this;
        }

        inline VectorSet<ScalarT,EigenDim> estimateNormals(const NeighborhoodSpecification<ScalarT> &nh) const {
            VectorSet<ScalarT,EigenDim> normals;
            VectorSet<ScalarT,1> curvatures;
            compute_nh_(normals, curvatures, nh);
            return normals;
        }

        inline VectorSet<ScalarT,1> estimateCurvature(const NeighborhoodSpecification<ScalarT> &nh) const {
            VectorSet<ScalarT,EigenDim> normals;
            VectorSet<ScalarT,1> curvatures;
            compute_nh_(normals, curvatures, nh);
            return curvatures;
        }

    private:
        ConstVectorSetMatrixMap<ScalarT,EigenDim> points_;
        const KDTree<ScalarT,EigenDim,KDTreeDistanceAdaptors::L2> *kd_tree_ptr_;
        bool kd_tree_owned_;
        Vector<ScalarT,EigenDim> view_point_;

        void compute_nh_(VectorSet<ScalarT,EigenDim> &normals, VectorSet<ScalarT,1> &curvatures, const NeighborhoodSpecification<ScalarT> &nh) const {
            switch (nh.type) {
                case NeighborhoodType::KNN:
                    compute_<NeighborhoodType::KNN>(normals, curvatures, nh);
                    break;
                case NeighborhoodType::RADIUS:
                    compute_<NeighborhoodType::RADIUS>(normals, curvatures, nh);
                    break;
                case NeighborhoodType::KNN_IN_RADIUS:
                    compute_<NeighborhoodType::KNN_IN_RADIUS>(normals, curvatures, nh);
                    break;
            }
        }

        template <NeighborhoodType NT>
        void compute_(VectorSet<ScalarT,EigenDim> &normals, VectorSet<ScalarT,1> &curvatures, const NeighborhoodSpecification<ScalarT> &nh) const {
            NeighborhoodSpecification<ScalarT> nh_sq(nh);
            nh_sq.radius = nh_sq.radius*nh_sq.radius;

            size_t dim = points_.rows();
            size_t num_points = points_.cols();

            normals.resize(dim, num_points);
            curvatures.resize(1, num_points);

            std::vector<size_t> neighbors;
            std::vector<ScalarT> distances;
#pragma omp parallel for shared (normals) private (neighbors, distances)
            for (size_t i = 0; i < num_points; i++) {
                kd_tree_ptr_->template search<NT>(points_.col(i), nh_sq, neighbors, distances);
                if (neighbors.size() < dim) {
                    normals.col(i).setConstant(std::numeric_limits<ScalarT>::quiet_NaN());
                    curvatures[i] = std::numeric_limits<ScalarT>::quiet_NaN();
                    continue;
                }
                VectorSet<ScalarT,EigenDim> neighborhood(dim, neighbors.size());
                for (size_t j = 0; j < neighbors.size(); j++) {
                    neighborhood.col(j) = points_.col(neighbors[j]);
                }
                PrincipalComponentAnalysis<ScalarT,EigenDim> pca(neighborhood);
                normals.col(i) = pca.getEigenVectors().col(dim-1);
                if (normals.col(i).dot(view_point_ - points_.col(i)) < 0.0) {
                    normals.col(i) *= -1.0;
                }
                curvatures[i] = pca.getEigenValues()[dim-1]/pca.getEigenValues().sum();
            }
        }

    };

    typedef NormalEstimation<float,2> NormalEstimation2D;
    typedef NormalEstimation<float,3> NormalEstimation3D;
}
<|endoftext|>


<commit_before>/**
 *  @file
 *  @copyright defined in eosio/LICENSE.txt
 */
#include <appbase/application.hpp>

#include <eosio/chain_plugin/chain_plugin.hpp>
#include <eosio/http_plugin/http_plugin.hpp>
#include <eosio/history_plugin/history_plugin.hpp>
#include <eosio/net_plugin/net_plugin.hpp>
#include <eosio/producer_plugin/producer_plugin.hpp>
#include <eosio/utilities/common.hpp>

#include <fc/log/logger_config.hpp>
#include <fc/log/appender.hpp>
#include <fc/exception/exception.hpp>

#include <boost/dll/runtime_symbol_info.hpp>
#include <boost/exception/diagnostic_information.hpp>

#include "config.hpp"

using namespace appbase;
using namespace eosio;

namespace fc {
   std::unordered_map<std::string,appender::ptr>& get_appender_map();
}

namespace detail {

void configure_logging(const bfs::path& config_path)
{
   try {
      try {
         fc::configure_logging(config_path);
      } catch (...) {
         elog("Error reloading logging.json");
         throw;
      }
   } catch (const fc::exception& e) {
      elog("${e}", ("e",e.to_detail_string()));
   } catch (const boost::exception& e) {
      elog("${e}", ("e",boost::diagnostic_information(e)));
   } catch (const std::exception& e) {
      elog("${e}", ("e",e.what()));
   } catch (...) {
      // empty
   }
}

} // namespace detail

void logging_conf_loop()
{
   std::shared_ptr<boost::asio::signal_set> sighup_set(new boost::asio::signal_set(app().get_io_service(), SIGHUP));
   sighup_set->async_wait([sighup_set](const boost::system::error_code& err, int /*num*/) {
      if(!err)
      {
         ilog("Received HUP.  Reloading logging configuration.");
         auto config_path = app().get_logging_conf();
         if(fc::exists(config_path))
            ::detail::configure_logging(config_path);
         for(auto iter : fc::get_appender_map())
            iter.second->initialize(app().get_io_service());
         logging_conf_loop();
      }
   });
}

void initialize_logging()
{
   auto config_path = app().get_logging_conf();
   if(fc::exists(config_path))
     fc::configure_logging(config_path); // intentionally allowing exceptions to escape
   for(auto iter : fc::get_appender_map())
     iter.second->initialize(app().get_io_service());

   logging_conf_loop();
}

enum return_codes {
   OTHER_FAIL        = -2,
   INITIALIZE_FAIL   = -1,
   SUCCESS           = 0,
   BAD_ALLOC         = 1,
   DATABASE_DIRTY    = 2,
   FIXED_REVERSIBLE  = 3,
   EXTRACTED_GENESIS = 4,
   NODE_MANAGEMENT_SUCCESS = 5
};

int main(int argc, char** argv)
{
   try {
      app().set_version(eosio::nodeos::config::version);

      auto root = fc::app_path();
      app().set_default_data_dir(root / "eosio/nodeos/data" );
      app().set_default_config_dir(root / "eosio/nodeos/config" );
      http_plugin::set_defaults({
         .address_config_prefix = "",
         .default_unix_socket_path = "",
         .default_http_port = 8888
      });
      if(!app().initialize<chain_plugin, http_plugin, net_plugin, producer_plugin>(argc, argv))
         return INITIALIZE_FAIL;
      initialize_logging();
      ilog("nodeos version ${ver}", ("ver", app().version_string()));
      ilog("eosio root is ${root}", ("root", root.string()));
      ilog("nodeos using configuration file ${c}", ("c", app().full_config_file_path().string()));
      ilog("nodeos data directory is ${d}", ("d", app().data_dir().string()));
      app().startup();
      app().exec();
   } catch( const extract_genesis_state_exception& e ) {
      return EXTRACTED_GENESIS;
   } catch( const fixed_reversible_db_exception& e ) {
      return FIXED_REVERSIBLE;
   } catch( const node_management_success& e ) {
      return NODE_MANAGEMENT_SUCCESS;
   } catch( const fc::exception& e ) {
      if( e.code() == fc::std_exception_code ) {
         if( e.top_message().find( "database dirty flag set" ) != std::string::npos ) {
            elog( "database dirty flag set (likely due to unclean shutdown): replay required" );
            return DATABASE_DIRTY;
         } else if( e.top_message().find( "database metadata dirty flag set" ) != std::string::npos ) {
            elog( "database metadata dirty flag set (likely due to unclean shutdown): replay required" );
            return DATABASE_DIRTY;
         }
      }
      elog( "${e}", ("e", e.to_detail_string()));
      return OTHER_FAIL;
   } catch( const boost::interprocess::bad_alloc& e ) {
      elog("bad alloc");
      return BAD_ALLOC;
   } catch( const boost::exception& e ) {
      elog("${e}", ("e",boost::diagnostic_information(e)));
      return OTHER_FAIL;
   } catch( const std::runtime_error& e ) {
      if( std::string(e.what()) == "database dirty flag set" ) {
         elog( "database dirty flag set (likely due to unclean shutdown): replay required" );
         return DATABASE_DIRTY;
      } else if( std::string(e.what()) == "database metadata dirty flag set" ) {
         elog( "database metadata dirty flag set (likely due to unclean shutdown): replay required" );
         return DATABASE_DIRTY;
      } else {
         elog( "${e}", ("e",e.what()));
      }
      return OTHER_FAIL;
   } catch( const std::exception& e ) {
      elog("${e}", ("e",e.what()));
      return OTHER_FAIL;
   } catch( ... ) {
      elog("unknown exception");
      return OTHER_FAIL;
   }

   return SUCCESS;
}
<commit_msg>Remove unneeded include.<commit_after>/**
 *  @file
 *  @copyright defined in eosio/LICENSE.txt
 */
#include <appbase/application.hpp>

#include <eosio/chain_plugin/chain_plugin.hpp>
#include <eosio/http_plugin/http_plugin.hpp>
#include <eosio/net_plugin/net_plugin.hpp>
#include <eosio/producer_plugin/producer_plugin.hpp>
#include <eosio/utilities/common.hpp>

#include <fc/log/logger_config.hpp>
#include <fc/log/appender.hpp>
#include <fc/exception/exception.hpp>

#include <boost/dll/runtime_symbol_info.hpp>
#include <boost/exception/diagnostic_information.hpp>

#include "config.hpp"

using namespace appbase;
using namespace eosio;

namespace fc {
   std::unordered_map<std::string,appender::ptr>& get_appender_map();
}

namespace detail {

void configure_logging(const bfs::path& config_path)
{
   try {
      try {
         fc::configure_logging(config_path);
      } catch (...) {
         elog("Error reloading logging.json");
         throw;
      }
   } catch (const fc::exception& e) {
      elog("${e}", ("e",e.to_detail_string()));
   } catch (const boost::exception& e) {
      elog("${e}", ("e",boost::diagnostic_information(e)));
   } catch (const std::exception& e) {
      elog("${e}", ("e",e.what()));
   } catch (...) {
      // empty
   }
}

} // namespace detail

void logging_conf_loop()
{
   std::shared_ptr<boost::asio::signal_set> sighup_set(new boost::asio::signal_set(app().get_io_service(), SIGHUP));
   sighup_set->async_wait([sighup_set](const boost::system::error_code& err, int /*num*/) {
      if(!err)
      {
         ilog("Received HUP.  Reloading logging configuration.");
         auto config_path = app().get_logging_conf();
         if(fc::exists(config_path))
            ::detail::configure_logging(config_path);
         for(auto iter : fc::get_appender_map())
            iter.second->initialize(app().get_io_service());
         logging_conf_loop();
      }
   });
}

void initialize_logging()
{
   auto config_path = app().get_logging_conf();
   if(fc::exists(config_path))
     fc::configure_logging(config_path); // intentionally allowing exceptions to escape
   for(auto iter : fc::get_appender_map())
     iter.second->initialize(app().get_io_service());

   logging_conf_loop();
}

enum return_codes {
   OTHER_FAIL        = -2,
   INITIALIZE_FAIL   = -1,
   SUCCESS           = 0,
   BAD_ALLOC         = 1,
   DATABASE_DIRTY    = 2,
   FIXED_REVERSIBLE  = 3,
   EXTRACTED_GENESIS = 4,
   NODE_MANAGEMENT_SUCCESS = 5
};

int main(int argc, char** argv)
{
   try {
      app().set_version(eosio::nodeos::config::version);

      auto root = fc::app_path();
      app().set_default_data_dir(root / "eosio/nodeos/data" );
      app().set_default_config_dir(root / "eosio/nodeos/config" );
      http_plugin::set_defaults({
         .address_config_prefix = "",
         .default_unix_socket_path = "",
         .default_http_port = 8888
      });
      if(!app().initialize<chain_plugin, http_plugin, net_plugin, producer_plugin>(argc, argv))
         return INITIALIZE_FAIL;
      initialize_logging();
      ilog("nodeos version ${ver}", ("ver", app().version_string()));
      ilog("eosio root is ${root}", ("root", root.string()));
      ilog("nodeos using configuration file ${c}", ("c", app().full_config_file_path().string()));
      ilog("nodeos data directory is ${d}", ("d", app().data_dir().string()));
      app().startup();
      app().exec();
   } catch( const extract_genesis_state_exception& e ) {
      return EXTRACTED_GENESIS;
   } catch( const fixed_reversible_db_exception& e ) {
      return FIXED_REVERSIBLE;
   } catch( const node_management_success& e ) {
      return NODE_MANAGEMENT_SUCCESS;
   } catch( const fc::exception& e ) {
      if( e.code() == fc::std_exception_code ) {
         if( e.top_message().find( "database dirty flag set" ) != std::string::npos ) {
            elog( "database dirty flag set (likely due to unclean shutdown): replay required" );
            return DATABASE_DIRTY;
         } else if( e.top_message().find( "database metadata dirty flag set" ) != std::string::npos ) {
            elog( "database metadata dirty flag set (likely due to unclean shutdown): replay required" );
            return DATABASE_DIRTY;
         }
      }
      elog( "${e}", ("e", e.to_detail_string()));
      return OTHER_FAIL;
   } catch( const boost::interprocess::bad_alloc& e ) {
      elog("bad alloc");
      return BAD_ALLOC;
   } catch( const boost::exception& e ) {
      elog("${e}", ("e",boost::diagnostic_information(e)));
      return OTHER_FAIL;
   } catch( const std::runtime_error& e ) {
      if( std::string(e.what()) == "database dirty flag set" ) {
         elog( "database dirty flag set (likely due to unclean shutdown): replay required" );
         return DATABASE_DIRTY;
      } else if( std::string(e.what()) == "database metadata dirty flag set" ) {
         elog( "database metadata dirty flag set (likely due to unclean shutdown): replay required" );
         return DATABASE_DIRTY;
      } else {
         elog( "${e}", ("e",e.what()));
      }
      return OTHER_FAIL;
   } catch( const std::exception& e ) {
      elog("${e}", ("e",e.what()));
      return OTHER_FAIL;
   } catch( ... ) {
      elog("unknown exception");
      return OTHER_FAIL;
   }

   return SUCCESS;
}
<|endoftext|>


<commit_before>// Copyright (c) 2017 Sony Corporation. 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.

/** RandomShift
 */
#ifndef __NBLA_FUNCTION_RANDOM_SHIFT_HPP__
#define __NBLA_FUNCTION_RANDOM_SHIFT_HPP__

#include <nbla/cpu.hpp>
#include <nbla/function.hpp>
#include <nbla/function_registry.hpp>

#include <random>

namespace nbla {

NBLA_REGISTER_FUNCTION_HEADER(RandomShift, const vector<int> &, const string &,
                              float, int, int);

/** RandomShift randomly shifts the array elements within the specified range.

Inputs:
- N-D array.

Outputs:
- N-D array.

@tparam T Data type for computation.
@param shift Max absolute amount to shift elements. For example, to shift image
data horizontally by +-2 pixels and vertically by +-3 pixels, specify (3,2).
@param border_mode Specify how to process the ends of arrays whose values will
be undetermined as a result of shifting. nearest: The data at the ends of the
original array is copied and used. reflect: Original data reflected at the ends
of the original array is used.
\ingroup FunctionImplGrp
*/

template <typename T>
class RandomShift : public BaseFunction<const vector<int> &, const string &,
                                        float, int, int> {
protected:
  vector<int> shifts_;
  string border_mode_;
  int base_axis_;

  int size_;

  const T constant_value_;
  const int CVAL_INDEX = -1;

  // This variable is an array to realize different shift amount for each data.
  vector<vector<vector<int>>> addr_table_;

  int seed_;
  std::mt19937 rgen_;

public:
  RandomShift(const Context &ctx, const vector<int> &shifts,
              const string &border_mode, float constant_value, int base_axis,
              int seed)
      : BaseFunction(ctx, shifts, border_mode, constant_value, base_axis, seed),
        shifts_(shifts), border_mode_(border_mode), base_axis_(base_axis),
        constant_value_(constant_value),  seed_(seed) {}
  virtual ~RandomShift() {}
  virtual shared_ptr<Function> copy() const {
    return create_RandomShift(ctx_, shifts_, border_mode_, constant_value_,
                              base_axis_, seed_);
  }
  virtual vector<dtypes> in_types() { return vector<dtypes>{get_dtype<T>()}; }
  virtual vector<dtypes> out_types() { return vector<dtypes>{get_dtype<T>()}; }
  virtual int min_inputs() { return 1; }
  virtual int min_outputs() { return 1; }
  virtual string name() { return "RandomShift"; }
  virtual vector<string> allowed_array_classes() {
    return SingletonManager::get<Cpu>()->array_classes();
  }

protected:
  NBLA_API virtual void setup_impl(const Variables &inputs,
                                   const Variables &outputs);
  NBLA_API virtual void forward_impl(const Variables &inputs,
                                     const Variables &outputs);
  NBLA_API virtual void backward_impl(const Variables &inputs,
                                      const Variables &outputs,
                                      const vector<bool> &propagate_down,
                                      const vector<bool> &accum);

  vector<vector<int>> prepare_addr_table(const Variables &inputs,
                                         const vector<int> &shifts);

private:
  void shift_recursive(const Variable *inp, const T *x, T *y, int x_offset,
                       int y_offset, int dim, int &shift_index);
  void shift_backward_recursive(const Variable *inp, const T *dy, T *dx,
                                int x_offset, int y_offset, int dim,
                                int &shift_index);
};
}
#endif
<commit_msg>fix format for random_shift.<commit_after>// Copyright (c) 2017 Sony Corporation. 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.

/** RandomShift
 */
#ifndef __NBLA_FUNCTION_RANDOM_SHIFT_HPP__
#define __NBLA_FUNCTION_RANDOM_SHIFT_HPP__

#include <nbla/cpu.hpp>
#include <nbla/function.hpp>
#include <nbla/function_registry.hpp>

#include <random>

namespace nbla {

NBLA_REGISTER_FUNCTION_HEADER(RandomShift, const vector<int> &, const string &,
                              float, int, int);

/** RandomShift randomly shifts the array elements within the specified range.

Inputs:
- N-D array.

Outputs:
- N-D array.

@tparam T Data type for computation.
@param shift Max absolute amount to shift elements. For example, to shift image
data horizontally by +-2 pixels and vertically by +-3 pixels, specify (3,2).
@param border_mode Specify how to process the ends of arrays whose values will
be undetermined as a result of shifting. nearest: The data at the ends of the
original array is copied and used. reflect: Original data reflected at the ends
of the original array is used.
\ingroup FunctionImplGrp
*/

template <typename T>
class RandomShift : public BaseFunction<const vector<int> &, const string &,
                                        float, int, int> {
protected:
  vector<int> shifts_;
  string border_mode_;
  int base_axis_;

  int size_;

  const T constant_value_;
  const int CVAL_INDEX = -1;

  // This variable is an array to realize different shift amount for each data.
  vector<vector<vector<int>>> addr_table_;

  int seed_;
  std::mt19937 rgen_;

public:
  RandomShift(const Context &ctx, const vector<int> &shifts,
              const string &border_mode, float constant_value, int base_axis,
              int seed)
      : BaseFunction(ctx, shifts, border_mode, constant_value, base_axis, seed),
        shifts_(shifts), border_mode_(border_mode), base_axis_(base_axis),
        constant_value_(constant_value), seed_(seed) {}
  virtual ~RandomShift() {}
  virtual shared_ptr<Function> copy() const {
    return create_RandomShift(ctx_, shifts_, border_mode_, constant_value_,
                              base_axis_, seed_);
  }
  virtual vector<dtypes> in_types() { return vector<dtypes>{get_dtype<T>()}; }
  virtual vector<dtypes> out_types() { return vector<dtypes>{get_dtype<T>()}; }
  virtual int min_inputs() { return 1; }
  virtual int min_outputs() { return 1; }
  virtual string name() { return "RandomShift"; }
  virtual vector<string> allowed_array_classes() {
    return SingletonManager::get<Cpu>()->array_classes();
  }

protected:
  NBLA_API virtual void setup_impl(const Variables &inputs,
                                   const Variables &outputs);
  NBLA_API virtual void forward_impl(const Variables &inputs,
                                     const Variables &outputs);
  NBLA_API virtual void backward_impl(const Variables &inputs,
                                      const Variables &outputs,
                                      const vector<bool> &propagate_down,
                                      const vector<bool> &accum);

  vector<vector<int>> prepare_addr_table(const Variables &inputs,
                                         const vector<int> &shifts);

private:
  void shift_recursive(const Variable *inp, const T *x, T *y, int x_offset,
                       int y_offset, int dim, int &shift_index);
  void shift_backward_recursive(const Variable *inp, const T *dy, T *dx,
                                int x_offset, int y_offset, int dim,
                                int &shift_index);
};
}
#endif
<|endoftext|>


<commit_before>/*
 * This file is part of otf2xx (https://github.com/tud-zih-energy/otf2xx)
 * otf2xx - A wrapper for the Open Trace Format 2 library
 *
 * Copyright (c) 2013-2016, Technische Universität Dresden, Germany
 * All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions are met:
 *
 * * Redistributions of source code must retain the above copyright notice, this
 *   list of conditions and the following disclaimer.
 *
 * * Redistributions in binary form must reproduce the above copyright notice,
 *   this list of conditions and the following disclaimer in the documentation
 *   and/or other materials provided with the distribution.
 *
 * * Neither the name of the copyright holder nor the names of its
 *   contributors may be used to endorse or promote products derived from
 *   this software without specific prior written permission.
 *
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
 * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
 * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
 * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
 * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 *
 */

/*
 * otf2xx - reference.hpp
 *
 * Copyright (c) 2014 TU Dresden
 *
 * All rights reserved.
 *
 * author: Mario Bielert <mario.bielert@tu-dresden.de>
 *
 */

#ifndef INCLUDE_OTF2XX_REFERENCE_GENERATOR_HPP
#define INCLUDE_OTF2XX_REFERENCE_GENERATOR_HPP

#include <otf2xx/fwd.hpp>
#include <otf2xx/reference.hpp>
#include <otf2xx/tmp/typelist.hpp>
#include <otf2xx/traits/definition.hpp>
#include <otf2xx/traits/reference.hpp>

#include <otf2xx/exception.hpp>

#include <cassert>
#include <type_traits>

namespace otf2
{

/**
 * @brief gives a free reference number for a set of definitions
 *
 * This class generates free reference numbers for definitons. For this
 * task, it needs to know every used reference number first.
 *
 * Therefore you need to register every definition.
 *
 * \note The algorithm for generating a number is undefined.
 *
 * \tparam Definition The definition for which it should generate numbers
 */
template <typename RefType>
class reference_generator
{
public:
    typedef RefType ref_type;

    template <typename Definition>
    void register_definition(const Definition& def)
    {
        static_assert(std::is_constructible<typename Definition::reference_type, RefType>::value,
                      "Trying to register a definition with a different id space");

        register_reference(static_cast<RefType>(def.ref()));
    }

    void register_reference(ref_type ref)
    {
        if (old_max == ref_type::undefined())
        {
            old_max = ref.get();
            return;
        }

        using std::max;

        old_max = max(ref.get(), old_max);
    }

    template <typename RefType2 = ref_type>
    RefType2 next()
    {
        static_assert(std::is_constructible<RefType2, ref_type>::value,
                      "Trying to get a reference for a definition with a different id space");

        if (ref_type::undefined() == old_max + 1)
        {
            make_exception("Cannot generate a new unused reference number");
        }

        return ++old_max;
    }

private:
    typename ref_type::ref_type old_max = -1;
};

class trace_reference_generator
{
    template <typename Tag>
    struct make_generator
    {
        using type = reference_generator<otf2::reference_impl<Tag, Tag>>;
    };

    using generators =
        tmp::apply_t<tmp::transform_t<traits::referable_definitions_base, make_generator>,
                     std::tuple>;

    template <class Definition>
    auto& get_generator()
    {
        using generator = typename make_generator<typename Definition::tag_type>::type;
        static_assert(tmp::contains<generators, generator>(),
                      "Cannot get a generator for this definition!");
        return std::get<generator>(ref_generators_);
    }

public:
    template <class Definition>
    void register_definition(const Definition& def)
    {
        get_generator<Definition>().register_definition(def);
    }

    template <typename Definition>
    void operator()(const Definition& def)
    {
        register_definition(def);
    }

    template <typename Definition>
    typename Definition::reference_type next()
    {
        // TMP-code-obfuscator was here
        return get_generator<Definition>().template next<typename Definition::reference_type>();
    }

private:
    /// std::tuple of reference_generator for each definition (tag)
    generators ref_generators_;
};

} // namespace otf2

#endif // INCLUDE_OTF2XX_REFERENCE_GENERATOR_HPP
<commit_msg>Adds peak() method to reference generators<commit_after>/*
 * This file is part of otf2xx (https://github.com/tud-zih-energy/otf2xx)
 * otf2xx - A wrapper for the Open Trace Format 2 library
 *
 * Copyright (c) 2013-2016, Technische Universität Dresden, Germany
 * All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions are met:
 *
 * * Redistributions of source code must retain the above copyright notice, this
 *   list of conditions and the following disclaimer.
 *
 * * Redistributions in binary form must reproduce the above copyright notice,
 *   this list of conditions and the following disclaimer in the documentation
 *   and/or other materials provided with the distribution.
 *
 * * Neither the name of the copyright holder nor the names of its
 *   contributors may be used to endorse or promote products derived from
 *   this software without specific prior written permission.
 *
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
 * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
 * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
 * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
 * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 *
 */

/*
 * otf2xx - reference.hpp
 *
 * Copyright (c) 2014 TU Dresden
 *
 * All rights reserved.
 *
 * author: Mario Bielert <mario.bielert@tu-dresden.de>
 *
 */

#ifndef INCLUDE_OTF2XX_REFERENCE_GENERATOR_HPP
#define INCLUDE_OTF2XX_REFERENCE_GENERATOR_HPP

#include <otf2xx/fwd.hpp>
#include <otf2xx/reference.hpp>
#include <otf2xx/tmp/typelist.hpp>
#include <otf2xx/traits/definition.hpp>
#include <otf2xx/traits/reference.hpp>

#include <otf2xx/exception.hpp>

#include <cassert>
#include <type_traits>

namespace otf2
{

/**
 * @brief gives a free reference number for a set of definitions
 *
 * This class generates free reference numbers for definitons. For this
 * task, it needs to know every used reference number first.
 *
 * Therefore you need to register every definition.
 *
 * \note The algorithm for generating a number is undefined.
 *
 * \tparam Definition The definition for which it should generate numbers
 */
template <typename RefType>
class reference_generator
{
public:
    typedef RefType ref_type;

    template <typename Definition>
    void register_definition(const Definition& def)
    {
        static_assert(std::is_constructible<typename Definition::reference_type, RefType>::value,
                      "Trying to register a definition with a different id space");

        register_reference(static_cast<RefType>(def.ref()));
    }

    void register_reference(ref_type ref)
    {
        if (old_max == ref_type::undefined())
        {
            old_max = ref.get();
            return;
        }

        using std::max;

        old_max = max(ref.get(), old_max);
    }

    template <typename RefType2 = ref_type>
    RefType2 next()
    {
        static_assert(std::is_constructible<RefType2, ref_type>::value,
                      "Trying to get a reference for a definition with a different id space");

        if (ref_type::undefined() == old_max + 1)
        {
            make_exception("Cannot generate a new unused reference number");
        }

        return ++old_max;
    }

    template <typename RefType2 = ref_type>
    RefType2 peak()
    {
        static_assert(std::is_constructible<RefType2, ref_type>::value,
                      "Trying to get a reference for a definition with a different id space");
        return old_max + 1;
    }

private:
    typename ref_type::ref_type old_max = -1;
};

class trace_reference_generator
{
    template <typename Tag>
    struct make_generator
    {
        using type = reference_generator<otf2::reference_impl<Tag, Tag>>;
    };

    using generators =
        tmp::apply_t<tmp::transform_t<traits::referable_definitions_base, make_generator>,
                     std::tuple>;

    template <class Definition>
    auto& get_generator()
    {
        using generator = typename make_generator<typename Definition::tag_type>::type;
        static_assert(tmp::contains<generators, generator>(),
                      "Cannot get a generator for this definition!");
        return std::get<generator>(ref_generators_);
    }

public:
    template <class Definition>
    void register_definition(const Definition& def)
    {
        get_generator<Definition>().register_definition(def);
    }

    template <typename Definition>
    void operator()(const Definition& def)
    {
        register_definition(def);
    }

    template <typename Definition>
    typename Definition::reference_type next()
    {
        // TMP-code-obfuscator was here
        return get_generator<Definition>().template next<typename Definition::reference_type>();
    }

    template <typename Definition>
    typename Definition::reference_type peak()
    {
        // TMP-code-obfuscator was here
        return get_generator<Definition>().template peak<typename Definition::reference_type>();
    }

private:
    /// std::tuple of reference_generator for each definition (tag)
    generators ref_generators_;
};

} // namespace otf2

#endif // INCLUDE_OTF2XX_REFERENCE_GENERATOR_HPP
<|endoftext|>


<commit_before>// This file is distributed under the MIT license.
// See the LICENSE file for details.

#include <array>

#include "../simd/type_traits.h"

namespace MATH_NAMESPACE
{

template <typename T>
MATH_FUNC
inline basic_ray<T>::basic_ray(vector<3, T> const& o, vector<3, T> const& d)
    : ori(o)
    , dir(d)
{
}

namespace simd
{

//-------------------------------------------------------------------------------------------------
// SIMD conversions
//

// pack ---------------------------------------------------

template <typename T, size_t N>
inline basic_ray<typename float_from_simd_width<N>::type> pack(
        std::array<basic_ray<T>, N> const& rays
        )
{
    using U = typename float_from_simd_width<N>::type;
    using float_array = typename aligned_array<U>::type;

    float_array ori_x;
    float_array ori_y;
    float_array ori_z;

    float_array dir_x;
    float_array dir_y;
    float_array dir_z;

    for (size_t i = 0; i < N; ++i)
    {
        ori_x[i] = rays[i].ori.x;
        ori_y[i] = rays[i].ori.y;
        ori_z[i] = rays[i].ori.z;

        dir_x[i] = rays[i].dir.x;
        dir_y[i] = rays[i].dir.y;
        dir_z[i] = rays[i].dir.z;
    }

    return basic_ray<U>(
            vector<3, U>(ori_x, ori_y, ori_z),
            vector<3, U>(dir_x, dir_y, dir_z)
            );
}

} // simd
} // MATH_NAMESPACE
<commit_msg>Add simd::unpack(basic_ray)<commit_after>// This file is distributed under the MIT license.
// See the LICENSE file for details.

#include <array>

#include "../simd/type_traits.h"

namespace MATH_NAMESPACE
{

template <typename T>
MATH_FUNC
inline basic_ray<T>::basic_ray(vector<3, T> const& o, vector<3, T> const& d)
    : ori(o)
    , dir(d)
{
}

namespace simd
{

//-------------------------------------------------------------------------------------------------
// SIMD conversions
//

// pack ---------------------------------------------------

template <typename T, size_t N>
inline basic_ray<typename float_from_simd_width<N>::type> pack(
        std::array<basic_ray<T>, N> const& rays
        )
{
    using U = typename float_from_simd_width<N>::type;
    using float_array = typename aligned_array<U>::type;

    float_array ori_x;
    float_array ori_y;
    float_array ori_z;

    float_array dir_x;
    float_array dir_y;
    float_array dir_z;

    for (size_t i = 0; i < N; ++i)
    {
        ori_x[i] = rays[i].ori.x;
        ori_y[i] = rays[i].ori.y;
        ori_z[i] = rays[i].ori.z;

        dir_x[i] = rays[i].dir.x;
        dir_y[i] = rays[i].dir.y;
        dir_z[i] = rays[i].dir.z;
    }

    return basic_ray<U>(
            vector<3, U>(ori_x, ori_y, ori_z),
            vector<3, U>(dir_x, dir_y, dir_z)
            );
}

// unpack -------------------------------------------------

template <
    typename FloatT,
    typename = typename std::enable_if<is_simd_vector<FloatT>::value>::type
    >
inline auto unpack(basic_ray<FloatT> const& ray)
    -> std::array<basic_ray<float>, num_elements<FloatT>::value>
{
    using float_array = typename aligned_array<FloatT>::type;

    float_array ori_x;
    float_array ori_y;
    float_array ori_z;

    float_array dir_x;
    float_array dir_y;
    float_array dir_z;

    store(ori_x, ray.ori.x);
    store(ori_y, ray.ori.y);
    store(ori_z, ray.ori.z);

    store(dir_x, ray.dir.x);
    store(dir_y, ray.dir.y);
    store(dir_z, ray.dir.z);

    std::array<basic_ray<float>, num_elements<FloatT>::value> result;

    for (int i = 0; i < num_elements<FloatT>::value; ++i)
    {
        result[i].ori.x = ori_x[i];
        result[i].ori.y = ori_y[i];
        result[i].ori.z = ori_z[i];

        result[i].dir.x = dir_x[i];
        result[i].dir.y = dir_y[i];
        result[i].dir.z = dir_z[i];
    }

    return result;
}

} // simd
} // MATH_NAMESPACE
<|endoftext|>


<commit_before>/* RTcmix - Copyright (C) 2004  The RTcmix Development Team
   See ``AUTHORS'' for a list of contributors. See ``LICENSE'' for
   the license to this software and for a DISCLAIMER OF ALL WARRANTIES.
*/
#include <Ocomb.h>
#include <math.h>
#include <assert.h>
#include <stdlib.h>
#include <stdio.h>

static float *newFloats(float *oldptr, int oldlen, int *newlen)
{
	float *ptr = NULL;
	if (oldptr == NULL) {
		ptr = (float *) malloc(*newlen * sizeof(float));
	}
	else {
		float *newptr = (float *) realloc(oldptr, *newlen * sizeof(float));
		if (newptr) {
			ptr = newptr;
			// Zero out new portion.
			for (int n = oldlen; n < *newlen; ++n)
				ptr[n] = 0.0f;
		}
		else {
			*newlen = oldlen;	// notify caller that realloc failed
			ptr = oldptr;
		}
	}
	return ptr;
}

Ocomb::Ocomb(float SR, float loopTime, float reverbTime) : _sr(SR)
{
	init(loopTime, loopTime, reverbTime);
}

Ocomb::Ocomb(float SR, float loopTime, float maxLoopTime, float reverbTime)
	: _sr(SR)
{
	init(loopTime, maxLoopTime, reverbTime);
}

void Ocomb::init(float loopTime, float maxLoopTime, float reverbTime)
{
	assert(maxLoopTime > 0.0);
	assert(maxLoopTime >= loopTime);

	_len = (int) (maxLoopTime * _sr + 0.5);
	_dline = newFloats(NULL, 0, &_len);
	clear();
	_delsamps = (int) (loopTime * _sr + 0.5);
	setReverbTime(reverbTime);
	_pointer = 0;
}

Ocomb::~Ocomb()
{
	free(_dline);
}

void Ocomb::clear()
{
	for (int i = 0; i < _len; i++)
		_dline[i] = 0.0;
}

void Ocomb::setReverbTime(float reverbTime)
{
	assert(reverbTime > 0.0);
	_gain = pow(0.001, ((float) _delsamps / _sr) / reverbTime);
}

float Ocomb::next(float input)
{
	if (_pointer == _len)
		_pointer = 0;
	float out = _dline[_pointer];
	_dline[_pointer++] = (out * _gain) + input;
	return out;
}

float Ocomb::next(float input, int delaySamps)
{
	if (delaySamps >= _len) {
		// Make a guess at how big the new array should be.
		int newlen = (delaySamps < _len * 2) ? _len * 2 : _len + delaySamps;
		printf("Ocomb resizing from %d to %d\n", _len, newlen);
		_dline = newFloats(_dline, _len, &newlen);
		if (newlen > _len) {
			_len = newlen;
		}
		else {
			printf("Ocomb resize failed!  Limiting delay.\n");
			delaySamps = _len - 1;
		}
	}
	_delsamps = delaySamps;
	if (_pointer >= _delsamps)
		_pointer = 0;
	float out = _dline[_pointer];
	_dline[_pointer++] = (out * _gain) + input;
	return out;
}

<commit_msg>Fixed >= which should be ><commit_after>/* RTcmix - Copyright (C) 2004  The RTcmix Development Team
   See ``AUTHORS'' for a list of contributors. See ``LICENSE'' for
   the license to this software and for a DISCLAIMER OF ALL WARRANTIES.
*/
#include <Ocomb.h>
#include <math.h>
#include <assert.h>
#include <stdlib.h>
#include <stdio.h>

static float *newFloats(float *oldptr, int oldlen, int *newlen)
{
	float *ptr = NULL;
	if (oldptr == NULL) {
		ptr = (float *) malloc(*newlen * sizeof(float));
	}
	else {
		float *newptr = (float *) realloc(oldptr, *newlen * sizeof(float));
		if (newptr) {
			ptr = newptr;
			// Zero out new portion.
			for (int n = oldlen; n < *newlen; ++n)
				ptr[n] = 0.0f;
		}
		else {
			*newlen = oldlen;	// notify caller that realloc failed
			ptr = oldptr;
		}
	}
	return ptr;
}

Ocomb::Ocomb(float SR, float loopTime, float reverbTime) : _sr(SR)
{
	init(loopTime, loopTime, reverbTime);
}

Ocomb::Ocomb(float SR, float loopTime, float maxLoopTime, float reverbTime)
	: _sr(SR)
{
	init(loopTime, maxLoopTime, reverbTime);
}

void Ocomb::init(float loopTime, float maxLoopTime, float reverbTime)
{
	assert(maxLoopTime > 0.0);
	assert(maxLoopTime >= loopTime);

	_len = (int) (maxLoopTime * _sr + 0.5);
	_dline = newFloats(NULL, 0, &_len);
	clear();
	_delsamps = (int) (loopTime * _sr + 0.5);
	setReverbTime(reverbTime);
	_pointer = 0;
}

Ocomb::~Ocomb()
{
	free(_dline);
}

void Ocomb::clear()
{
	for (int i = 0; i < _len; i++)
		_dline[i] = 0.0;
}

void Ocomb::setReverbTime(float reverbTime)
{
	assert(reverbTime > 0.0);
	_gain = pow(0.001, ((float) _delsamps / _sr) / reverbTime);
}

float Ocomb::next(float input)
{
	if (_pointer == _len)
		_pointer = 0;
	float out = _dline[_pointer];
	_dline[_pointer++] = (out * _gain) + input;
	return out;
}

float Ocomb::next(float input, int delaySamps)
{
	if (delaySamps > _len) {
		// Make a guess at how big the new array should be.
		int newlen = (delaySamps < _len * 2) ? _len * 2 : _len + delaySamps;
		printf("Ocomb resizing from %d to %d\n", _len, newlen);
		_dline = newFloats(_dline, _len, &newlen);
		if (newlen > _len) {
			_len = newlen;
		}
		else {
			printf("Ocomb resize failed!  Limiting delay.\n");
			delaySamps = _len - 1;
		}
	}
	_delsamps = delaySamps;
	if (_pointer >= _delsamps)
		_pointer = 0;
	float out = _dline[_pointer];
	_dline[_pointer++] = (out * _gain) + input;
	return out;
}

<|endoftext|>


<commit_before>/*
 *  Copyright 2010-2011 Fabric Technologies Inc. All rights reserved.
 */

#include <Fabric/Core/MR/ValueProducer.h>
#include <Fabric/Core/RT/Desc.h>
#include <Fabric/Core/MT/Impl.h>
#include <Fabric/Core/Util/JSONGenerator.h>

#include <alloca.h>
#include <string.h>

namespace Fabric
{
  namespace MR
  {
    ValueProducer::ValueProducer()
    {
    }

    ValueProducer::ComputeState::ComputeState( RC::ConstHandle<ValueProducer> const &valueProducer )
      : m_valueProducer( valueProducer )
    {
    }

    void ValueProducer::ComputeState::produceJSON( Util::JSONGenerator &jg ) const
    {
      RC::ConstHandle<RT::Desc> valueDesc = m_valueProducer->getValueDesc();

      size_t allocSize = valueDesc->getAllocSize();
      void *valueData = alloca( allocSize );
      memset( valueData, 0, allocSize );
      produce( valueData );
      valueDesc->generateJSON( valueData, jg );
      valueDesc->disposeData( valueData );
    }

    struct ProduceJSONAsyncCallbackData
    {
      RC::Handle<ValueProducer::ComputeState> computeState;
      Util::JSONObjectGenerator *jsonObjectGenerator;
    };

    void ValueProducer::ComputeState::produceJSONAsync(
      Util::JSONObjectGenerator &jsonObjectGenerator,
      void (*finishedCallback)( void * ),
      void *finishedUserdata
      )
    {
      ProduceJSONAsyncCallbackData *produceJSONAsyncCallbackData = new ProduceJSONAsyncCallbackData;
      produceJSONAsyncCallbackData->computeState = this;
      produceJSONAsyncCallbackData->jsonObjectGenerator = &jsonObjectGenerator;

      MT::ThreadPool::Instance()->executeParallelAsync(
        MT::tlsLogCollector.get(),
        1,
        &ValueProducer::ComputeState::ProduceJSONAsyncCallback,
        produceJSONAsyncCallbackData,
        MT::ThreadPool::Idle,
        finishedCallback,
        finishedUserdata
        );
    }

    void ValueProducer::ComputeState::ProduceJSONAsyncCallback(
      void *userdata,
      size_t index
      )
    {
      ProduceJSONAsyncCallbackData *produceJSONAsyncCallbackData = static_cast<ProduceJSONAsyncCallbackData *>( userdata );
      {
        Util::JSONGenerator jg = produceJSONAsyncCallbackData->jsonObjectGenerator->makeMember( "result" );
        produceJSONAsyncCallbackData->computeState->produceJSON( jg );
      }
      delete produceJSONAsyncCallbackData;
    }
  };
};
<commit_msg>MR: minor Windows build break<commit_after>/*
 *  Copyright 2010-2011 Fabric Technologies Inc. All rights reserved.
 */

#include <Fabric/Core/MR/ValueProducer.h>
#include <Fabric/Core/RT/Desc.h>
#include <Fabric/Core/MT/Impl.h>
#include <Fabric/Core/Util/JSONGenerator.h>

#if !defined(FABRIC_OS_WINDOWS)
  #include <alloca.h>
#endif

#include <string.h>

namespace Fabric
{
  namespace MR
  {
    ValueProducer::ValueProducer()
    {
    }

    ValueProducer::ComputeState::ComputeState( RC::ConstHandle<ValueProducer> const &valueProducer )
      : m_valueProducer( valueProducer )
    {
    }

    void ValueProducer::ComputeState::produceJSON( Util::JSONGenerator &jg ) const
    {
      RC::ConstHandle<RT::Desc> valueDesc = m_valueProducer->getValueDesc();

      size_t allocSize = valueDesc->getAllocSize();
      void *valueData = alloca( allocSize );
      memset( valueData, 0, allocSize );
      produce( valueData );
      valueDesc->generateJSON( valueData, jg );
      valueDesc->disposeData( valueData );
    }

    struct ProduceJSONAsyncCallbackData
    {
      RC::Handle<ValueProducer::ComputeState> computeState;
      Util::JSONObjectGenerator *jsonObjectGenerator;
    };

    void ValueProducer::ComputeState::produceJSONAsync(
      Util::JSONObjectGenerator &jsonObjectGenerator,
      void (*finishedCallback)( void * ),
      void *finishedUserdata
      )
    {
      ProduceJSONAsyncCallbackData *produceJSONAsyncCallbackData = new ProduceJSONAsyncCallbackData;
      produceJSONAsyncCallbackData->computeState = this;
      produceJSONAsyncCallbackData->jsonObjectGenerator = &jsonObjectGenerator;

      MT::ThreadPool::Instance()->executeParallelAsync(
        MT::tlsLogCollector.get(),
        1,
        &ValueProducer::ComputeState::ProduceJSONAsyncCallback,
        produceJSONAsyncCallbackData,
        MT::ThreadPool::Idle,
        finishedCallback,
        finishedUserdata
        );
    }

    void ValueProducer::ComputeState::ProduceJSONAsyncCallback(
      void *userdata,
      size_t index
      )
    {
      ProduceJSONAsyncCallbackData *produceJSONAsyncCallbackData = static_cast<ProduceJSONAsyncCallbackData *>( userdata );
      {
        Util::JSONGenerator jg = produceJSONAsyncCallbackData->jsonObjectGenerator->makeMember( "result" );
        produceJSONAsyncCallbackData->computeState->produceJSON( jg );
      }
      delete produceJSONAsyncCallbackData;
    }
  };
};
<|endoftext|>


<commit_before>#ifndef ecmdDataBuffer_H
#define ecmdDataBuffer_H

// Copyright **********************************************************
//
// File ecmdDataBuffer.H
//
// IBM Confidential
// OCO Source Materials
// 9400 Licensed Internal Code
// (C) COPYRIGHT IBM CORP. 2003
//
// The source code for this program is not published or otherwise
// divested of its trade secrets, irrespective of what has been
// deposited with the U.S. Copyright Office.
//
// End Copyright ******************************************************

/**
 * @file ecmdDataBuffer.H
 * @brief Provides a means to handle data from the eCMD C API
 *
 * DataBuffers handle data in a Big Endian fashion with Bit 0 being the MSB
*/

//--------------------------------------------------------------------
// Includes
//--------------------------------------------------------------------

//----------------------------------------------------------------------
//  Constants
//----------------------------------------------------------------------

//--------------------------------------------------------------------
// Macros
//--------------------------------------------------------------------

//----------------------------------------------------------------------
//  Global Variables
//----------------------------------------------------------------------

//----------------------------------------------------------------------
//  User Types
//----------------------------------------------------------------------

class ecmdDataBuffer {

};

#endif

<commit_msg>ecmdDataBuffer.H filled out with more functions<commit_after>#ifndef ecmdDataBuffer_H
#define ecmdDataBuffer_H

// Copyright **********************************************************
//
// File ecmdDataBuffer.H
//
// IBM Confidential
// OCO Source Materials
// 9400 Licensed Internal Code
// (C) COPYRIGHT IBM CORP. 2003
//
// The source code for this program is not published or otherwise
// divested of its trade secrets, irrespective of what has been
// deposited with the U.S. Copyright Office.
//
// End Copyright ******************************************************

/**
 * @file ecmdDataBuffer.H
 * @brief Provides a means to handle data from the eCMD C API
 *
 * DataBuffers handle data in a Big Endian fashion with Bit 0 being the MSB
*/

//--------------------------------------------------------------------
// Includes
//--------------------------------------------------------------------
#include <stdint.h>

//----------------------------------------------------------------------
//  Constants
//----------------------------------------------------------------------

//--------------------------------------------------------------------
// Macros
//--------------------------------------------------------------------

//----------------------------------------------------------------------
//  Global Variables
//----------------------------------------------------------------------

//----------------------------------------------------------------------
//  User Types
//----------------------------------------------------------------------

class ecmdDataBuffer {

   public:

     /**
      * @brief Default Constructor
      */
     ecmdDataBuffer();

     /**
      * @brief Constructor
      * @param numBits Size of data to initialize in bits
      * @post ecmdDataBuffer is initialzed with a buffer
      */
     ecmdDataBuffer(int numBits);

     /**
      * @brief Default Destructor
      */
     ~ecmdDataBuffer();

     // Member Functions
     /** @name Buffer Size Function */
     //@{
     /**
      * @brief Return the length of the buffer in words
      * @retval Buffer length in words
      */
     int   getWordLength() const;
     /**
      * @brief Return the length of the buffer in bits
      * @retval Buffer length in bits
      */
     int   getBitLength() const;
     /**
      * @brief Reinitialize the Buffer to specified length
      * @param newnumwords Length of new buffer in words
      * @post Buffer is reinitialized
      *
      * NOTE : All data stored in buffer will be lost
      */
     void  setWordLength(int newnumwords);
     /**
      * @brief Reinitialize the Buffer to specified length
      * @param newnumbits Length of new buffer in bits
      * @post Buffer is reinitialized
      *
      * NOTE : All data stored in buffer will be lost
      */
     void  setBitLength(int newnumbits);
     //@}

     /** @name Bit/Word Manipulation Functions */
     //@{
     /**
      * @brief Turn on a bit in buffer
      * @param bit Bit in buffer to turn on
      */
     void  setBit(int bit);
     /**
      * @brief Turn on a bit in buffer
      * @param bit start bit in buffer to turn on
      * @param len Number of consecutive bits from start bit to turn on
      */
     void  setBit(int bit, int len);
     /**
      * @brief Turn on a bit in buffer
      * @param bitoffset bit in buffer to turn on
      * @param datastr Character value to set bit - can be "0", "1", "X"
      */
     void  setBit(int bitoffset, const char* datastr); // data can be 0,1,'x','X'
     /**
      * @brief Set a word of data in buffer
      * @param wordoffset Offset of word to set
      * @param value 32 bits of data to put into word
      */
     void  setWord(int wordoffset, uint32_t value);

     /**
      * @brief Fetch a word from ecmdDataBuffer
      * @param wordoffset Offset of word to fetch
      * @retval Value of word requested
      */
     uint32_t getWord(int wordoffset);

     /**
      * @brief Clear a bit in buffer
      * @param bit Bit in buffer to turn off
      */
     void  clearBit(int bit);
     /**
      * @brief Clear multiple bits in buffer
      * @param bit Start bit in buffer to turn off
      * @param len Number of consecutive bits from start bit to off
      */
     void  clearBit(int bit, int len);

     /**
      * @brief Invert bit
      * @param bit Bit in buffer to invert
      */
     void  flipBit(int bit);
     /**
      * @brief Invert multiple bits
      * @param bit Start bit in buffer to invert
      * @param len Number of consecutive bits to invert
      */
     void  flipBit(int bit, int len);

     /**
      * @brief Test if bit is set
      * @param bit Bit to test
      * @retval 1 if bit is set - 0 if bit is clear
      */
     int   isBitSet(int bit);
     /**
      * @brief Test if multiple bits are set
      * @param bit Start bit to test
      * @param len Number of consecutive bits to test
      * @retval 1 if bit is set - 0 if bit is clear
      */
     int   isBitSet(int bit, int len);
     /**
      * @brief Test if bit is clear
      * @param bit Bit to test
      * @retval 1 if bit is clear - 0 if bit is set
      */
     int   isBitClear(int bit);
     /**
      * @brief Test if multiple bits are clear
      * @param bit Start bit to test
      * @param len Number of consecutive bits to test
      * @retval 1 if bit is clear - 0 if bit is set
      */
     int   isBitClear(int bit, int len);
     /**
      * @brief Count number of bits set in a range
      * @param bit Start bit to test
      * @param len Number of consecutive bits to test
      * @retval Number of bits set in range
      */
     int   getNumBitsSet(int bit, int len);
     //@}

     /** @name Buffer Manipulation Functions */
     //@{
     /**
      * @brief Shift data to right
      * @param shiftnum Number of bits to shift
      * @post Bits in buffer are shifted to right by specified number of bits - data is shifted off the end
      */
     void  shiftRight(int shiftnum);
     /**
      * @brief Shift data to left
      * @param shiftnum Number of bits to shift
      * @post Bits in buffer are shifted to left by specified number of bits - data is shifted off the beginning
      */
     void  shiftLeft(int shiftnum);
     /**
      * @brief Rotate data to right
      * @param rotatenum Number of bits to rotate
      * @post Bits in buffer are rotated to the right by specified number of bits - data is rotated to the beginning
      */
     void  rotateRight(int rotatenum);
     /**
      * @brief Rotate data to left
      * @param rotatenum Number of bits to rotate
      * @post Bits in buffer are rotated to the left by specified number of bits - data is rotated to the end
      */
     void  rotateLeft(int rotatenum);

     /**
      * @brief Clear entire buffer to 0's
      */
     void  flushTo0();
     /**
      * @brief Set entire buffer to 1's
      */
     void  flushTo1();
     /**
      * @brief Invert entire buffer
      */
     void  invert();  /* Performs bit inversion on entire DataBuffer class */

     /**
      * @brief Insert part of another DataBuffer into this one
      * @param bufferIn DataBuffer to copy data from - data is taken left aligned
      * @param start Start bit to insert to
      * @param len Length of bits to insert
      * @post Data is copied from bufferIn to this DataBuffer in specified location
      */
     void  insert(ecmdDataBuffer & bufferIn, int start, int len);
     /**
      * @brief Insert a uint32_t array into this DataBuffer
      * @param datain uint32_t array to copy into this DataBuffer - data is taken left aligned
      * @param start Start bit to insert into
      * @param len Length of bits to insert
      * @post Data is copied from datain into this DataBuffer at specified location
      */
     void  insert(uint32_t * datain, int start, int len);
     /**
      * @brief Insert a uint32_t into the DataBuffer
      * @param datain uint32_t value to copy into DataBuffer - data is taken left aligned
      * @param start Start bit to insert into
      * @param len Length of bits to insert (must be <= 32)
      * @post Data is copied from datain into this DataBuffer at specified location
      */
     void  insert(uint32_t datain, int start, int len);
     /**
      * @brief Copy data from this DataBuffer into another
      * @param bufferOut DataBuffer to copy into - data is placed left aligned
      * @param start Start bit of data to copy
      * @param len Length of consecutive bits to copy
      * @post Data is copied from specified location in this DataBuffer to bufferOut
      */
     void  extract(ecmdDataBuffer & bufferOut, int start, int len);
     /**
      * @brief Copy data from this DataBuffer into another
      * @param outdata uint32_t buffer to copy into - data is placed left aligned - must be pre-allocated
      * @param start Start bit of data to copy
      * @param len Length of consecutive bits to copy
      * @post Data is copied from specified location in this DataBuffer to outdata
      */
     void  extract(uint32_t * outdata, int start, int len);

     /* these functions OR the datain into the DataBuffer buffer */
     /**
      * @brief OR data into DataBuffer
      * @param bufferIn DataBuffer to OR data from - data is taken left aligned
      * @param startbit Start bit to OR to
      * @param len Length of bits to OR
      * @post Data is ORed from bufferIn to this DataBuffer in specified location
      */
     void setOr(ecmdDataBuffer & bufferIn, int startbit, int len);
     /**
      * @brief OR data into DataBuffer
      * @param datain uint32_t buffer to OR data from - data is taken left aligned
      * @param startbit Start bit to OR to
      * @param len Length of bits to OR
      * @post Data is ORed from datain to this DataBuffer in specified location
      */
     void setOr(uint32_t * datain, int startbit, int len);
     /**
      * @brief OR data into DataBuffer
      * @param datain uint32_t to OR data from - data is taken left aligned
      * @param startbit Start bit to OR to
      * @param len Length of bits to OR (must be <= 32)
      * @post Data is ORed from datain to this DataBuffer in specified location
      */
     void setOr(uint32_t datain, int startbit, int len);
     /**
      * @brief OR data into DataBuffer
      * @param bufferIn DataBuffer to OR data from - data is taken left aligned
      * @post Entire data is ORed from bufferIn to this DataBuffer
      */
     void merge(ecmdDataBuffer & bufferIn); // does a setor on the whole buffer

     /* these functions AND the datain into the DataBuffer buffer */
     /**
      * @brief AND data into DataBuffer
      * @param bufferIn Bitvector to AND data from - data is taken left aligned
      * @param startbit Start bit to AND to
      * @param len Length of bits to AND
      * @post Data is ANDed from bufferIn to this DataBuffer in specified location
      */
     void setAnd(ecmdDataBuffer & bufferIn, int startbit, int len);
     /**
      * @brief AND data into DataBuffer
      * @param datain uint32_t buffer to AND data from - data is taken left aligned
      * @param startbit Start bit to AND to
      * @param len Length of bits to AND
      * @post Data is ANDed from datain to this DataBuffer in specified location
      */
     void setAnd(uint32_t *datain, int startbit, int len);
     /**
      * @brief AND data into DataBuffer
      * @param datain uint32_t to AND data from - data is taken left aligned
      * @param startbit Start bit to AND to
      * @param len Length of bits to AND (must be <= 32)
      * @post Data is ANDed from datain to this DataBuffer in specified location
      */
     void setAnd(uint32_t datain, int startbit, int len);

     /**
      * @brief Copy entire contents of this ecmdDataBuffer into newcopy
      * @param copyBuffer DataBuffer to copy data into
      * @post copyBuffer is an exact duplicate of this DataBuffer
      */
     void  copy(ecmdDataBuffer & copyBuffer); // Copies data into other

     /* These are only to be used to apply a buffer to the entire ecmdDataBuffer, not just sections */
     /**
      * @brief Copy buffer into this ecmdDataBuffer
      * @param buf Buffer to copy from
      * @param bytes Byte length to copy
      */
     void  memCopyIn(uint32_t* buf, int bytes); /* Does a memcpy from supplied buffer into ecmdDataBuffer */
     /**
      * @brief Copy DataBuffer into supplied uint32_t buffer
      * @param buf Buffer to copy into - must be pre-allocated
      * @param bytes Byte length to copy
      */
     void  memCopyOut(uint32_t* buf, int bytes); /* Does a memcpy from ecmdDataBuffer into supplied buffer */

      //@}

      /** @name Parity Functions */
      //@{
      /**
       * @brief Generate odd parity over a range of bits
       * @param start Start bit of range
       * @param stop Stop bit of range
       * @retval 0 or 1 depending on parity of range
       */
     int  oddParity(int start, int stop);
      /**
       * @brief Generate even parity over a range of bits
       * @param start Start bit of range
       * @param stop Stop bit of range
       * @retval 0 or 1 depending on parity of range
       */
     int  evenParity(int start, int stop);
      /**
       * @brief Generate odd parity over a range of bits and insert into DataBuffer
       * @param start Start bit of range
       * @param stop Stop bit of range
       * @param insertpos Bit position to insert parity
       * @retval 0 on success - nonzero on failure
       */
     int  oddParity(int start, int stop, int insertpos);
      /**
       * @brief Generate even parity over a range of bits and insert into DataBuffer
       * @param start Start bit of range
       * @param stop Stop bit of range
       * @param insertpos Bit position to insert parity
       * @retval 0 on success - nonzero on failure
       */
     int  evenParity(int start, int stop, int insertpos);
     //@}

     /** @name Buffer Character Conversion Functions */
     //@{
     /**
      * @brief Return Data as a hex left aligned char string
      * @param start Start bit of data to convert
      * @param bitlen Number of consecutive bits to convert
      * @retval String containing requested data
      */
     const char* genHexLeftStr(int start, int bitlen);
     /**
      * @brief Return Data as a hex right aligned char string
      * @param start Start bit of data to convert
      * @param bitlen Number of consecutive bits to convert
      * @retval String containing requested data
      */
     const char* genHexRightStr(int start, int bitlen);
     /**
      * @brief Return Data as a binary char string
      * @param start Start bit of data to convert
      * @param bitlen Number of consecutive bits to convert
      * @retval String containing requested data
      */
     const char* genBinStr(int start, int bitlen);
     /**
      * @brief Return entire buffer as a hex left aligned char string
      * @retval String containing requested data
      */
     const char* genHexLeftStr();
     /**
      * @brief Return entire buffer as a hex right aligned char string
      * @retval String containing requested data
      */
     const char* genHexRightStr();
     /**
      * @brief Return entire buffer as a binary char string
      * @retval String containing requested data
      */
     const char* genBinStr();
     //@}

     /** @name Simulation Buffer Functions */
     //@{
     /**
      * @brief Check Entire buffer for any X-state values
      * @retval 1 if xstate found 0 if none
      */
     int   isXstate(); /* check the whole DataBuffer */
     /**
      * @brief Check section buffer for any X-state values
      * @param start Start bit to test
      * @param length Number of consecutive bits to test
      * @retval 1 if xstate found 0 if none
      */
     int   isXstate(int start, int length); /* check subset */

     //@}

     /** @name Error Functions */
     //@{
     int   getError() const { return err; } /* return > 0 if error */
     char* getErrorStr() { return errstr; }
     void  setErrorMode(int mode) { errmode = mode; }
                             /* mode & 0x1 : store in errstr */
                             /* mode & 0x2 : print to stdout */
                             /* mode & 0x4 : print to stderr */
     //@}

   private:
     int numwords;
     int numbits;
     uint32_t * data;
     uint32_t * real_data;
     char* dataoutstr; /* buffer for gethexlstr functions */
     char* datastr; /* binary or x data */
     void filldatastr(char fillchar);
     char* errstr;
     int err;
     int errmode;
     void seterr(int errcode, const char* str);

     ecmdDataBuffer(const ecmdDataBuffer &other);

};

#endif  /* ecmdDataBuffer_H */

<|endoftext|>


<commit_before>#ifndef STAN_MATH_OPENCL_KERNELS_NEG_BINOMIAL_2_LOG_GLM_LPMF_HPP
#define STAN_MATH_OPENCL_KERNELS_NEG_BINOMIAL_2_LOG_GLM_LPMF_HPP
#ifdef STAN_OPENCL

#include <stan/math/opencl/kernel_cl.hpp>
#include <stan/math/opencl/device_functions/digamma.hpp>

namespace stan {
namespace math {
namespace opencl_kernels {

// \cond
static const char* neg_binomial_2_log_glm_kernel_code = STRINGIFY(
    // \endcond

    /**
     * GPU implementation of Generalized Linear Model (GLM)
     * with Negative-Binomial-2 distribution and log link function.
     *
     * Must be run with at least N threads and local size equal to LOCAL_SIZE_.
     * @param[out] logp_global partially summed log probabilty (1 value per work
     * group)
     * @param[out] theta_derivative_global intermediate variable used in the model
     * @param[out] theta_derivative_sum partially summed theta_derivative_global
     * (1 value per work group)
     * @param[out] phi_derivative_global derivative with respect to phi
     * @param[in] y_global failures count vector parameter
     * @param[in] x design matrix
     * @param[in] alpha intercept (in log odds)
     * @param[in] beta weight vector
     * @param[in] phi_global (vector of) precision parameter(s)
     * @param N number of cases
     * @param M number of attributes
     * @param is_alpha_vector 0 or 1 - whether alpha is a vector (alternatively
     * it is a scalar)
     * @param is_phi_vector 0 or 1 - whether phi is a vector (alternatively it
     * is a scalar)
     * @param need_theta_derivative whether theta_derivative needs to be
     * computed
     * @param need_theta_derivative_sum whether theta_derivative_sum needs to be
     * computed
     * @param need_phi_derivative whether phi_derivative needs to be computed
     * @param need_phi_derivative_sum whether phi_derivative_sum needs to be
     * computed
     * @param need_logp1 interpreted as boolean - whether first part logp_global
     * needs to be computed
     * @param need_logp2 interpreted as boolean - whether second part logp_global
     * needs to be computed
     * @param need_logp3 interpreted as boolean - whether third part logp_global
     * needs to be computed
     * @param need_logp4 interpreted as boolean - whether fourth part logp_global
     * needs to be computed
     * @param need_logp5 interpreted as boolean - whether fifth part logp_global
     * needs to be computed
     */
    __kernel void neg_binomial_2_log_glm(
        __global double* logp_global, __global double* theta_derivative_global,
        __global double* theta_derivative_sum,
        __global double* phi_derivative_global, const __global int* y_global,
        const __global double* x, const __global double* alpha,
        const __global double* beta, const __global double* phi_global,
        const int N, const int M, const int is_alpha_vector,
        const int is_phi_vector, const int need_theta_derivative,
        const int need_theta_derivative_sum, const int need_phi_derivative,
        const int need_phi_derivative_sum, const int need_logp1,
        const int need_logp2, const int need_logp3, const int need_logp4,
        const int need_logp5) {
      const int gid = get_global_id(0);
      const int lid = get_local_id(0);
      const int lsize = get_local_size(0);
      const int wgid = get_group_id(0);

      __local double res_loc[LOCAL_SIZE_];
      double logp = 0;
      double phi_derivative = 0;
      double theta_derivative = 0;

      // Most calculations only happen for relevant data within next if.
      // Exceptions are reductions between threads that need barriers.
      if (gid < N) {
        double theta = 0;
        for (int i = 0, j = 0; i < M; i++, j += N) {
          theta += x[j + gid] * beta[i];
        }
        double phi = phi_global[gid * is_phi_vector];
        double y = y_global[gid];
        if (!isfinite(theta) || y < 0 || !isfinite(phi)) {
          logp = NAN;
        }
        theta += alpha[gid * is_alpha_vector];
        double log_phi = log(phi);
        double logsumexp_theta_logphi;
        if (theta > log_phi) {
          logsumexp_theta_logphi = theta + log1p(exp(log_phi - theta));
        } else {
          logsumexp_theta_logphi = log_phi + log1p(exp(theta - log_phi));
        }
        double y_plus_phi = y + phi;
        if (need_logp1) {
          logp -= lgamma(y + 1);
        }
        if (need_logp2) {
          logp -= lgamma(phi);
          if (phi != 0) {
            logp += phi * log(phi);
          }
        }
        if (need_logp3) {
          logp -= y_plus_phi * logsumexp_theta_logphi;
        }
        if (need_logp4) {
          logp += y * theta;
        }
        if (need_logp5) {
          logp += lgamma(y_plus_phi);
        }
        double theta_exp = exp(theta);
        theta_derivative = y - theta_exp * y_plus_phi / (theta_exp + phi);
        if (need_theta_derivative) {
          theta_derivative_global[gid] = theta_derivative;
        }
        if (need_phi_derivative) {
          phi_derivative = 1 - y_plus_phi / (theta_exp + phi) + log_phi
                           - logsumexp_theta_logphi + digamma(y_plus_phi)
                           - digamma(phi);
          if (!need_phi_derivative_sum) {
            phi_derivative_global[gid] = phi_derivative;
          }
        }
      }

      // Sum logp, calculated by different threads.
      // Since we can't sum between different work groups, we emit one number
      // per work group. These must be summed on CPU for final result.
      res_loc[lid] = logp;
      barrier(CLK_LOCAL_MEM_FENCE);
      for (int step = lsize / REDUCTION_STEP_SIZE; step > 0;
           step /= REDUCTION_STEP_SIZE) {
        if (lid < step) {
          for (int i = 1; i < REDUCTION_STEP_SIZE; i++) {
            res_loc[lid] += res_loc[lid + step * i];
          }
        }
        barrier(CLK_LOCAL_MEM_FENCE);
      }
      if (lid == 0) {
        logp_global[wgid] = res_loc[0];
      }

      if (need_theta_derivative_sum) {
        // Sum theta_derivative, calculated by different threads.
        barrier(CLK_LOCAL_MEM_FENCE);
        res_loc[lid] = theta_derivative;
        barrier(CLK_LOCAL_MEM_FENCE);
        for (int step = lsize / REDUCTION_STEP_SIZE; step > 0;
             step /= REDUCTION_STEP_SIZE) {
          if (lid < step) {
            for (int i = 1; i < REDUCTION_STEP_SIZE; i++) {
              res_loc[lid] += res_loc[lid + step * i];
            }
          }
          barrier(CLK_LOCAL_MEM_FENCE);
        }
        if (lid == 0) {
          theta_derivative_sum[wgid] = res_loc[0];
        }
      }

      if (need_phi_derivative_sum) {
        // Sum phi_derivative, calculated by different threads.
        barrier(CLK_LOCAL_MEM_FENCE);
        res_loc[lid] = phi_derivative;
        barrier(CLK_LOCAL_MEM_FENCE);
        for (int step = lsize / REDUCTION_STEP_SIZE; step > 0;
             step /= REDUCTION_STEP_SIZE) {
          if (lid < step) {
            for (int i = 1; i < REDUCTION_STEP_SIZE; i++) {
              res_loc[lid] += res_loc[lid + step * i];
            }
          }
          barrier(CLK_LOCAL_MEM_FENCE);
        }
        if (lid == 0) {
          phi_derivative_global[wgid] = res_loc[0];
        }
      }
    }
    // \cond
);
// \endcond

/**
 * See the docs for \link kernels/subtract.hpp subtract() \endlink
 */
const kernel_cl<out_buffer, out_buffer, out_buffer, out_buffer, in_buffer,
                in_buffer, in_buffer, in_buffer, in_buffer, int, int, int, int,
                int, int, int, int, int, int, int, int, int>
    neg_binomial_2_log_glm("neg_binomial_2_log_glm",
                           {digamma_device_function,
                            neg_binomial_2_log_glm_kernel_code},
                           {{"REDUCTION_STEP_SIZE", 4}, {"LOCAL_SIZE_", 64}});

}  // namespace opencl_kernels
}  // namespace math
}  // namespace stan

#endif
#endif
<commit_msg>[Jenkins] auto-formatting by clang-format version 5.0.0-3~16.04.1 (tags/RELEASE_500/final)<commit_after>#ifndef STAN_MATH_OPENCL_KERNELS_NEG_BINOMIAL_2_LOG_GLM_LPMF_HPP
#define STAN_MATH_OPENCL_KERNELS_NEG_BINOMIAL_2_LOG_GLM_LPMF_HPP
#ifdef STAN_OPENCL

#include <stan/math/opencl/kernel_cl.hpp>
#include <stan/math/opencl/device_functions/digamma.hpp>

namespace stan {
namespace math {
namespace opencl_kernels {

// \cond
static const char* neg_binomial_2_log_glm_kernel_code = STRINGIFY(
    // \endcond

    /**
     * GPU implementation of Generalized Linear Model (GLM)
     * with Negative-Binomial-2 distribution and log link function.
     *
     * Must be run with at least N threads and local size equal to LOCAL_SIZE_.
     * @param[out] logp_global partially summed log probabilty (1 value per work
     * group)
     * @param[out] theta_derivative_global intermediate variable used in the
     * model
     * @param[out] theta_derivative_sum partially summed theta_derivative_global
     * (1 value per work group)
     * @param[out] phi_derivative_global derivative with respect to phi
     * @param[in] y_global failures count vector parameter
     * @param[in] x design matrix
     * @param[in] alpha intercept (in log odds)
     * @param[in] beta weight vector
     * @param[in] phi_global (vector of) precision parameter(s)
     * @param N number of cases
     * @param M number of attributes
     * @param is_alpha_vector 0 or 1 - whether alpha is a vector (alternatively
     * it is a scalar)
     * @param is_phi_vector 0 or 1 - whether phi is a vector (alternatively it
     * is a scalar)
     * @param need_theta_derivative whether theta_derivative needs to be
     * computed
     * @param need_theta_derivative_sum whether theta_derivative_sum needs to be
     * computed
     * @param need_phi_derivative whether phi_derivative needs to be computed
     * @param need_phi_derivative_sum whether phi_derivative_sum needs to be
     * computed
     * @param need_logp1 interpreted as boolean - whether first part logp_global
     * needs to be computed
     * @param need_logp2 interpreted as boolean - whether second part
     * logp_global needs to be computed
     * @param need_logp3 interpreted as boolean - whether third part logp_global
     * needs to be computed
     * @param need_logp4 interpreted as boolean - whether fourth part
     * logp_global needs to be computed
     * @param need_logp5 interpreted as boolean - whether fifth part logp_global
     * needs to be computed
     */
    __kernel void neg_binomial_2_log_glm(
        __global double* logp_global, __global double* theta_derivative_global,
        __global double* theta_derivative_sum,
        __global double* phi_derivative_global, const __global int* y_global,
        const __global double* x, const __global double* alpha,
        const __global double* beta, const __global double* phi_global,
        const int N, const int M, const int is_alpha_vector,
        const int is_phi_vector, const int need_theta_derivative,
        const int need_theta_derivative_sum, const int need_phi_derivative,
        const int need_phi_derivative_sum, const int need_logp1,
        const int need_logp2, const int need_logp3, const int need_logp4,
        const int need_logp5) {
      const int gid = get_global_id(0);
      const int lid = get_local_id(0);
      const int lsize = get_local_size(0);
      const int wgid = get_group_id(0);

      __local double res_loc[LOCAL_SIZE_];
      double logp = 0;
      double phi_derivative = 0;
      double theta_derivative = 0;

      // Most calculations only happen for relevant data within next if.
      // Exceptions are reductions between threads that need barriers.
      if (gid < N) {
        double theta = 0;
        for (int i = 0, j = 0; i < M; i++, j += N) {
          theta += x[j + gid] * beta[i];
        }
        double phi = phi_global[gid * is_phi_vector];
        double y = y_global[gid];
        if (!isfinite(theta) || y < 0 || !isfinite(phi)) {
          logp = NAN;
        }
        theta += alpha[gid * is_alpha_vector];
        double log_phi = log(phi);
        double logsumexp_theta_logphi;
        if (theta > log_phi) {
          logsumexp_theta_logphi = theta + log1p(exp(log_phi - theta));
        } else {
          logsumexp_theta_logphi = log_phi + log1p(exp(theta - log_phi));
        }
        double y_plus_phi = y + phi;
        if (need_logp1) {
          logp -= lgamma(y + 1);
        }
        if (need_logp2) {
          logp -= lgamma(phi);
          if (phi != 0) {
            logp += phi * log(phi);
          }
        }
        if (need_logp3) {
          logp -= y_plus_phi * logsumexp_theta_logphi;
        }
        if (need_logp4) {
          logp += y * theta;
        }
        if (need_logp5) {
          logp += lgamma(y_plus_phi);
        }
        double theta_exp = exp(theta);
        theta_derivative = y - theta_exp * y_plus_phi / (theta_exp + phi);
        if (need_theta_derivative) {
          theta_derivative_global[gid] = theta_derivative;
        }
        if (need_phi_derivative) {
          phi_derivative = 1 - y_plus_phi / (theta_exp + phi) + log_phi
                           - logsumexp_theta_logphi + digamma(y_plus_phi)
                           - digamma(phi);
          if (!need_phi_derivative_sum) {
            phi_derivative_global[gid] = phi_derivative;
          }
        }
      }

      // Sum logp, calculated by different threads.
      // Since we can't sum between different work groups, we emit one number
      // per work group. These must be summed on CPU for final result.
      res_loc[lid] = logp;
      barrier(CLK_LOCAL_MEM_FENCE);
      for (int step = lsize / REDUCTION_STEP_SIZE; step > 0;
           step /= REDUCTION_STEP_SIZE) {
        if (lid < step) {
          for (int i = 1; i < REDUCTION_STEP_SIZE; i++) {
            res_loc[lid] += res_loc[lid + step * i];
          }
        }
        barrier(CLK_LOCAL_MEM_FENCE);
      }
      if (lid == 0) {
        logp_global[wgid] = res_loc[0];
      }

      if (need_theta_derivative_sum) {
        // Sum theta_derivative, calculated by different threads.
        barrier(CLK_LOCAL_MEM_FENCE);
        res_loc[lid] = theta_derivative;
        barrier(CLK_LOCAL_MEM_FENCE);
        for (int step = lsize / REDUCTION_STEP_SIZE; step > 0;
             step /= REDUCTION_STEP_SIZE) {
          if (lid < step) {
            for (int i = 1; i < REDUCTION_STEP_SIZE; i++) {
              res_loc[lid] += res_loc[lid + step * i];
            }
          }
          barrier(CLK_LOCAL_MEM_FENCE);
        }
        if (lid == 0) {
          theta_derivative_sum[wgid] = res_loc[0];
        }
      }

      if (need_phi_derivative_sum) {
        // Sum phi_derivative, calculated by different threads.
        barrier(CLK_LOCAL_MEM_FENCE);
        res_loc[lid] = phi_derivative;
        barrier(CLK_LOCAL_MEM_FENCE);
        for (int step = lsize / REDUCTION_STEP_SIZE; step > 0;
             step /= REDUCTION_STEP_SIZE) {
          if (lid < step) {
            for (int i = 1; i < REDUCTION_STEP_SIZE; i++) {
              res_loc[lid] += res_loc[lid + step * i];
            }
          }
          barrier(CLK_LOCAL_MEM_FENCE);
        }
        if (lid == 0) {
          phi_derivative_global[wgid] = res_loc[0];
        }
      }
    }
    // \cond
);
// \endcond

/**
 * See the docs for \link kernels/subtract.hpp subtract() \endlink
 */
const kernel_cl<out_buffer, out_buffer, out_buffer, out_buffer, in_buffer,
                in_buffer, in_buffer, in_buffer, in_buffer, int, int, int, int,
                int, int, int, int, int, int, int, int, int>
    neg_binomial_2_log_glm("neg_binomial_2_log_glm",
                           {digamma_device_function,
                            neg_binomial_2_log_glm_kernel_code},
                           {{"REDUCTION_STEP_SIZE", 4}, {"LOCAL_SIZE_", 64}});

}  // namespace opencl_kernels
}  // namespace math
}  // namespace stan

#endif
#endif
<|endoftext|>