<commit_before>// -*- c++ -*-
/* $Id$ */

/* Copyright 1998-2002 The gtkmm Development Team
 *
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Lesser General Public
 * License as published by the Free Software Foundation; either
 * version 2.1 of the License, or (at your option) any later version.
 *
 * This library is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public
 * License along with this library; if not, write to the Free
 * Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
 */

#include <glibmm/threads.h> // Needed until the next ABI break.
#include <glibmm/object.h>
#include <glibmm/private/object_p.h>
#include <glibmm/property.h>

#include <glib-object.h>
#include <gobject/gvaluecollector.h>

#include <cstdarg>
#include <cstring>

#include <string.h>

//Weak references:
//I'm not sure what the point of these are apart from being a hacky way out of circular references,
//but maybe we could make it easier to use them by making a Java Reference Object -style class like so:
// Glib::WeakRef<SomeDerivedObject> weakrefSomeObject(object1);
// ...
// if(weakrefSomeObject->isStillAlive())
// {
//   weakrefSomeObject->some_method();
// }
// else
// {
//   //Deal with it, maybe recreating the object.
// }
//
// Without this, the coder has to define his own signal handler which sets his own isStillAlive boolean.
// weakrefSomeObject<> could still have its own signal_destroyed signal so that coders can choose to deal
// with the destruction as soon as it happens instead of just checking later before they try to use it.

namespace Glib
{

ConstructParams::ConstructParams(const Glib::Class& glibmm_class_)
:
  glibmm_class (glibmm_class_),
  n_parameters (0),
  parameters   (0)
{}

/*
 * The implementation is mostly copied from gobject.c, with some minor tweaks.
 * Basically, it looks up each property name to get its GType, and then uses
 * G_VALUE_COLLECT() to store the varargs argument in a GValue of the correct
 * type.
 *
 * Note that the property name arguments are assumed to be static string
 * literals.  No attempt is made to copy the string content.  This is no
 * different from g_object_new().
 */
ConstructParams::ConstructParams(const Glib::Class& glibmm_class_,
                                 const char* first_property_name, ...)
:
  glibmm_class (glibmm_class_),
  n_parameters (0),
  parameters   (0)
{
  va_list var_args;
  va_start(var_args, first_property_name);

  GObjectClass *const g_class =
      static_cast<GObjectClass*>(g_type_class_ref(glibmm_class.get_type()));

  unsigned int n_alloced_params = 0;
  char*        collect_error    = nullptr; // output argument of G_VALUE_COLLECT()

  for(const char* name = first_property_name;
      name != nullptr;
      name = va_arg(var_args, char*))
  {
    GParamSpec *const pspec = g_object_class_find_property(g_class, name);

    if(!pspec)
    {
      g_warning("Glib::ConstructParams::ConstructParams(): "
                "object class \"%s\" has no property named \"%s\"",
                g_type_name(glibmm_class.get_type()), name);
      break;
    }

    if(n_parameters >= n_alloced_params)
      parameters = g_renew(GParameter, parameters, n_alloced_params += 8);

    GParameter& param = parameters[n_parameters];

    param.name = name;
    param.value.g_type = 0;

    // Fill the GValue with the current vararg, and move on to the next one.
    g_value_init(&param.value, G_PARAM_SPEC_VALUE_TYPE(pspec));
    G_VALUE_COLLECT(&param.value, var_args, 0, &collect_error);

    if(collect_error)
    {
      g_warning("Glib::ConstructParams::ConstructParams(): %s", collect_error);
      g_free(collect_error);
      g_value_unset(&param.value);
      break;
    }

    ++n_parameters;
  }

  g_type_class_unref(g_class);

  va_end(var_args);
}

ConstructParams::~ConstructParams()
{
  while(n_parameters > 0)
    g_value_unset(&parameters[--n_parameters].value);

  g_free(parameters);
}

/*
 * Some compilers require the existence of a copy constructor in certain
 * usage contexts.  This implementation is fully functional, but unlikely
 * to be ever actually called due to optimization.
 */
ConstructParams::ConstructParams(const ConstructParams& other)
:
  glibmm_class  (other.glibmm_class),
  n_parameters  (other.n_parameters),
  parameters    (g_new(GParameter, n_parameters))
{
  for(unsigned int i = 0; i < n_parameters; ++i)
  {
    parameters[i].name = other.parameters[i].name;
    parameters[i].value.g_type = 0;

    g_value_init(&parameters[i].value, G_VALUE_TYPE(&other.parameters[i].value));
    g_value_copy(&other.parameters[i].value, &parameters[i].value);
  }
}

/**** Glib::Object_Class ***************************************************/

const Glib::Class& Object_Class::init()
{
  if(!gtype_)
  {
    class_init_func_ = &Object_Class::class_init_function;
    register_derived_type(G_TYPE_OBJECT);
  }

  return *this;
}

void Object_Class::class_init_function(void*, void*)
{}

Object* Object_Class::wrap_new(GObject* object)
{
  return new Object(object);
}

/**** Glib::Object *********************************************************/

// static data
Object::CppClassType Object::object_class_;

Object::Object()
{
  // This constructor is ONLY for derived classes that are NOT wrappers of
  // derived C objects.  For instance, Gtk::Object should NOT use this
  // constructor.

  //g_warning("Object::Object(): Did you really mean to call this?");

  // If Glib::ObjectBase has been constructed with a custom typeid, we derive
  // a new GType on the fly.  This works because ObjectBase is a virtual base
  // class, therefore its constructor is always executed first.

  GType object_type = G_TYPE_OBJECT; // the default -- not very useful

  if(custom_type_name_ && !is_anonymous_custom_())
  {
    Class::interface_class_vector_type custom_interface_classes;

    Threads::Mutex::Lock lock(*extra_object_base_data_mutex);
    const extra_object_base_data_type::iterator iter = extra_object_base_data.find(this);
    if (iter != extra_object_base_data.end())
    {
      custom_interface_classes = iter->second.custom_interface_classes;
      extra_object_base_data.erase(iter);
    }
    lock.release();

    object_class_.init();
    // This creates a type that is derived (indirectly) from GObject.
    object_type = object_class_.clone_custom_type(
      custom_type_name_, custom_interface_classes);
  }

  void *const new_object = g_object_newv(object_type, 0, 0);

  // Connect the GObject and Glib::Object instances.
  ObjectBase::initialize(static_cast<GObject*>(new_object));
}

Object::Object(const Glib::ConstructParams& construct_params)
{
  GType object_type = construct_params.glibmm_class.get_type();

  // If Glib::ObjectBase has been constructed with a custom typeid, we derive
  // a new GType on the fly.  This works because ObjectBase is a virtual base
  // class, therefore its constructor is always executed first.

  if(custom_type_name_ && !is_anonymous_custom_())
  {
    Class::interface_class_vector_type custom_interface_classes;

    Threads::Mutex::Lock lock(*extra_object_base_data_mutex);
    const extra_object_base_data_type::iterator iter = extra_object_base_data.find(this);
    if (iter != extra_object_base_data.end())
    {
      custom_interface_classes = iter->second.custom_interface_classes;
      extra_object_base_data.erase(iter);
    }
    lock.release();

    object_type = construct_params.glibmm_class.clone_custom_type(
      custom_type_name_, custom_interface_classes);
  }

  // Create a new GObject with the specified array of construct properties.
  // This works with custom types too, since those inherit the properties of
  // their base class.

  void *const new_object = g_object_newv(
      object_type, construct_params.n_parameters, construct_params.parameters);

  // Connect the GObject and Glib::Object instances.
  ObjectBase::initialize(static_cast<GObject*>(new_object));
}

Object::Object(GObject* castitem)
{
  //I disabled this check because libglademm really does need to do this.
  //(actually it tells libglade to instantiate "gtkmm_" types.
  //The 2nd instance bug will be caught elsewhere anyway.
/*
  static const char gtkmm_prefix[] = "gtkmm__";
  const char *const type_name = G_OBJECT_TYPE_NAME(castitem);

  if(strncmp(type_name, gtkmm_prefix, sizeof(gtkmm_prefix) - 1) == 0)
  {
    g_warning("Glib::Object::Object(GObject*): "
              "An object of type '%s' was created directly via g_object_new(). "
              "The Object::Object(const Glib::ConstructParams&) constructor "
              "should be used instead.\n"
              "This could happen if the C instance lived longer than the C++ instance, so that "
              "a second C++ instance was created automatically to wrap it. That would be a gtkmm bug that you should report.",
               type_name);
  }
*/

  // Connect the GObject and Glib::Object instances.
  ObjectBase::initialize(castitem);
}

Object::Object(Object&& src) noexcept
: ObjectBase(std::move(src))
{}

Object& Object::operator=(Object&& src) noexcept
{
  ObjectBase::operator=(std::move(src));
  return *this;
}

Object::~Object()
{
  cpp_destruction_in_progress_ = true;
}

/*
RefPtr<Object> Object::create()
{
  // Derived classes will actually return RefPtr<>s that contain useful instances.
  return RefPtr<Object>();
}
*/

GType Object::get_type()
{
  return object_class_.init().get_type();
}

GType Object::get_base_type()
{
  return G_TYPE_OBJECT;
}

// Data services
void* Object::get_data(const QueryQuark& id)
{
  return g_object_get_qdata(gobj(),id);
}

void Object::set_data(const Quark& id, void* data)
{
  g_object_set_qdata(gobj(),id,data);
}

void Object::set_data(const Quark& id, void* data, DestroyNotify destroy)
{
  g_object_set_qdata_full(gobj(), id, data, destroy);
}

void Object::remove_data(const QueryQuark& id)
{
  // missing in glib??
  g_return_if_fail(id.id() > 0);
  g_datalist_id_remove_data(&gobj()->qdata, id);
}

void* Object::steal_data(const QueryQuark& id)
{
  return g_object_steal_qdata(gobj(), id);
}

} // namespace Glib

<commit_msg>Object: Move constructor: Use initialize_move().<commit_after>// -*- c++ -*-
/* $Id$ */

/* Copyright 1998-2002 The gtkmm Development Team
 *
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Lesser General Public
 * License as published by the Free Software Foundation; either
 * version 2.1 of the License, or (at your option) any later version.
 *
 * This library is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public
 * License along with this library; if not, write to the Free
 * Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
 */

#include <glibmm/threads.h> // Needed until the next ABI break.
#include <glibmm/object.h>
#include <glibmm/private/object_p.h>
#include <glibmm/property.h>

#include <glib-object.h>
#include <gobject/gvaluecollector.h>

#include <cstdarg>
#include <cstring>

#include <string.h>

//Weak references:
//I'm not sure what the point of these are apart from being a hacky way out of circular references,
//but maybe we could make it easier to use them by making a Java Reference Object -style class like so:
// Glib::WeakRef<SomeDerivedObject> weakrefSomeObject(object1);
// ...
// if(weakrefSomeObject->isStillAlive())
// {
//   weakrefSomeObject->some_method();
// }
// else
// {
//   //Deal with it, maybe recreating the object.
// }
//
// Without this, the coder has to define his own signal handler which sets his own isStillAlive boolean.
// weakrefSomeObject<> could still have its own signal_destroyed signal so that coders can choose to deal
// with the destruction as soon as it happens instead of just checking later before they try to use it.

namespace Glib
{

ConstructParams::ConstructParams(const Glib::Class& glibmm_class_)
:
  glibmm_class (glibmm_class_),
  n_parameters (0),
  parameters   (0)
{}

/*
 * The implementation is mostly copied from gobject.c, with some minor tweaks.
 * Basically, it looks up each property name to get its GType, and then uses
 * G_VALUE_COLLECT() to store the varargs argument in a GValue of the correct
 * type.
 *
 * Note that the property name arguments are assumed to be static string
 * literals.  No attempt is made to copy the string content.  This is no
 * different from g_object_new().
 */
ConstructParams::ConstructParams(const Glib::Class& glibmm_class_,
                                 const char* first_property_name, ...)
:
  glibmm_class (glibmm_class_),
  n_parameters (0),
  parameters   (0)
{
  va_list var_args;
  va_start(var_args, first_property_name);

  GObjectClass *const g_class =
      static_cast<GObjectClass*>(g_type_class_ref(glibmm_class.get_type()));

  unsigned int n_alloced_params = 0;
  char*        collect_error    = nullptr; // output argument of G_VALUE_COLLECT()

  for(const char* name = first_property_name;
      name != nullptr;
      name = va_arg(var_args, char*))
  {
    GParamSpec *const pspec = g_object_class_find_property(g_class, name);

    if(!pspec)
    {
      g_warning("Glib::ConstructParams::ConstructParams(): "
                "object class \"%s\" has no property named \"%s\"",
                g_type_name(glibmm_class.get_type()), name);
      break;
    }

    if(n_parameters >= n_alloced_params)
      parameters = g_renew(GParameter, parameters, n_alloced_params += 8);

    GParameter& param = parameters[n_parameters];

    param.name = name;
    param.value.g_type = 0;

    // Fill the GValue with the current vararg, and move on to the next one.
    g_value_init(&param.value, G_PARAM_SPEC_VALUE_TYPE(pspec));
    G_VALUE_COLLECT(&param.value, var_args, 0, &collect_error);

    if(collect_error)
    {
      g_warning("Glib::ConstructParams::ConstructParams(): %s", collect_error);
      g_free(collect_error);
      g_value_unset(&param.value);
      break;
    }

    ++n_parameters;
  }

  g_type_class_unref(g_class);

  va_end(var_args);
}

ConstructParams::~ConstructParams()
{
  while(n_parameters > 0)
    g_value_unset(&parameters[--n_parameters].value);

  g_free(parameters);
}

/*
 * Some compilers require the existence of a copy constructor in certain
 * usage contexts.  This implementation is fully functional, but unlikely
 * to be ever actually called due to optimization.
 */
ConstructParams::ConstructParams(const ConstructParams& other)
:
  glibmm_class  (other.glibmm_class),
  n_parameters  (other.n_parameters),
  parameters    (g_new(GParameter, n_parameters))
{
  for(unsigned int i = 0; i < n_parameters; ++i)
  {
    parameters[i].name = other.parameters[i].name;
    parameters[i].value.g_type = 0;

    g_value_init(&parameters[i].value, G_VALUE_TYPE(&other.parameters[i].value));
    g_value_copy(&other.parameters[i].value, &parameters[i].value);
  }
}

/**** Glib::Object_Class ***************************************************/

const Glib::Class& Object_Class::init()
{
  if(!gtype_)
  {
    class_init_func_ = &Object_Class::class_init_function;
    register_derived_type(G_TYPE_OBJECT);
  }

  return *this;
}

void Object_Class::class_init_function(void*, void*)
{}

Object* Object_Class::wrap_new(GObject* object)
{
  return new Object(object);
}

/**** Glib::Object *********************************************************/

// static data
Object::CppClassType Object::object_class_;

Object::Object()
{
  // This constructor is ONLY for derived classes that are NOT wrappers of
  // derived C objects.  For instance, Gtk::Object should NOT use this
  // constructor.

  //g_warning("Object::Object(): Did you really mean to call this?");

  // If Glib::ObjectBase has been constructed with a custom typeid, we derive
  // a new GType on the fly.  This works because ObjectBase is a virtual base
  // class, therefore its constructor is always executed first.

  GType object_type = G_TYPE_OBJECT; // the default -- not very useful

  if(custom_type_name_ && !is_anonymous_custom_())
  {
    Class::interface_class_vector_type custom_interface_classes;

    Threads::Mutex::Lock lock(*extra_object_base_data_mutex);
    const extra_object_base_data_type::iterator iter = extra_object_base_data.find(this);
    if (iter != extra_object_base_data.end())
    {
      custom_interface_classes = iter->second.custom_interface_classes;
      extra_object_base_data.erase(iter);
    }
    lock.release();

    object_class_.init();
    // This creates a type that is derived (indirectly) from GObject.
    object_type = object_class_.clone_custom_type(
      custom_type_name_, custom_interface_classes);
  }

  void *const new_object = g_object_newv(object_type, 0, 0);

  // Connect the GObject and Glib::Object instances.
  ObjectBase::initialize(static_cast<GObject*>(new_object));
}

Object::Object(const Glib::ConstructParams& construct_params)
{
  GType object_type = construct_params.glibmm_class.get_type();

  // If Glib::ObjectBase has been constructed with a custom typeid, we derive
  // a new GType on the fly.  This works because ObjectBase is a virtual base
  // class, therefore its constructor is always executed first.

  if(custom_type_name_ && !is_anonymous_custom_())
  {
    Class::interface_class_vector_type custom_interface_classes;

    Threads::Mutex::Lock lock(*extra_object_base_data_mutex);
    const extra_object_base_data_type::iterator iter = extra_object_base_data.find(this);
    if (iter != extra_object_base_data.end())
    {
      custom_interface_classes = iter->second.custom_interface_classes;
      extra_object_base_data.erase(iter);
    }
    lock.release();

    object_type = construct_params.glibmm_class.clone_custom_type(
      custom_type_name_, custom_interface_classes);
  }

  // Create a new GObject with the specified array of construct properties.
  // This works with custom types too, since those inherit the properties of
  // their base class.

  void *const new_object = g_object_newv(
      object_type, construct_params.n_parameters, construct_params.parameters);

  // Connect the GObject and Glib::Object instances.
  ObjectBase::initialize(static_cast<GObject*>(new_object));
}

Object::Object(GObject* castitem)
{
  //I disabled this check because libglademm really does need to do this.
  //(actually it tells libglade to instantiate "gtkmm_" types.
  //The 2nd instance bug will be caught elsewhere anyway.
/*
  static const char gtkmm_prefix[] = "gtkmm__";
  const char *const type_name = G_OBJECT_TYPE_NAME(castitem);

  if(strncmp(type_name, gtkmm_prefix, sizeof(gtkmm_prefix) - 1) == 0)
  {
    g_warning("Glib::Object::Object(GObject*): "
              "An object of type '%s' was created directly via g_object_new(). "
              "The Object::Object(const Glib::ConstructParams&) constructor "
              "should be used instead.\n"
              "This could happen if the C instance lived longer than the C++ instance, so that "
              "a second C++ instance was created automatically to wrap it. That would be a gtkmm bug that you should report.",
               type_name);
  }
*/

  // Connect the GObject and Glib::Object instances.
  ObjectBase::initialize(castitem);
}

Object::Object(Object&& src) noexcept
: ObjectBase(std::move(src)) //not actually called because it's a virtual base
{
  ObjectBase::initialize_move(src.gobject_, &src);
}

Object& Object::operator=(Object&& src) noexcept
{
  ObjectBase::operator=(std::move(src));
  return *this;
}

Object::~Object()
{
  cpp_destruction_in_progress_ = true;
}

/*
RefPtr<Object> Object::create()
{
  // Derived classes will actually return RefPtr<>s that contain useful instances.
  return RefPtr<Object>();
}
*/

GType Object::get_type()
{
  return object_class_.init().get_type();
}

GType Object::get_base_type()
{
  return G_TYPE_OBJECT;
}

// Data services
void* Object::get_data(const QueryQuark& id)
{
  return g_object_get_qdata(gobj(),id);
}

void Object::set_data(const Quark& id, void* data)
{
  g_object_set_qdata(gobj(),id,data);
}

void Object::set_data(const Quark& id, void* data, DestroyNotify destroy)
{
  g_object_set_qdata_full(gobj(), id, data, destroy);
}

void Object::remove_data(const QueryQuark& id)
{
  // missing in glib??
  g_return_if_fail(id.id() > 0);
  g_datalist_id_remove_data(&gobj()->qdata, id);
}

void* Object::steal_data(const QueryQuark& id)
{
  return g_object_steal_qdata(gobj(), id);
}

} // namespace Glib

<|endoftext|>


<commit_before>#pragma once
#include "layer_base.hpp"
#include "variable.hpp"

namespace nnk
{

	template <class T>
	class linear_layer : public layer_base
	{
	public:

		typedef T scalar_type;
		typedef std::valarray<scalar_type> tensor_type;

		linear_layer(
			std::size_t input_dimension,
			std::size_t output_dimension,
			scalar_type weight_scale = static_cast<scalar_type>(1.0))
			: input_dimension_(input_dimension)
			, output_dimension_(output_dimension)
		{
			std::mt19937 engine;
			std::normal_distribution<scalar_type> distribution(
				static_cast<scalar_type>(0.0),
				static_cast<scalar_type>(weight_scale * std::sqrt(1.0 / input_dimension)));

			weight_.value() = tensor_type(output_dimension * input_dimension);

			for (std::size_t i = 0; i < weight_.value().size(); ++i)
				weight_.value()[i] = distribution(engine);

			bias_.value() = tensor_type(output_dimension);
		}

		virtual void enumerate_parameters(optimizer_base& optimizer) override
		{
			optimizer.add_parameter(weight_);
			optimizer.add_parameter(bias_);
		}

		expression<scalar_type> operator ()(const expression<scalar_type>& v) const
		{
			return matrix_product(weight_.expr(), v, output_dimension_, input_dimension_, input_dimension_, 1) + bias_.expr();
		}

	private:

		std::size_t input_dimension_;
		std::size_t output_dimension_;

		variable<scalar_type> weight_;
		variable<scalar_type> bias_;

	};

}
<commit_msg>Add accessors in linear_layer<commit_after>#pragma once
#include "layer_base.hpp"
#include "variable.hpp"

namespace nnk
{

	template <class T>
	class linear_layer : public layer_base
	{
	public:

		typedef T scalar_type;
		typedef std::valarray<scalar_type> tensor_type;

		linear_layer(
			std::size_t input_dimension,
			std::size_t output_dimension,
			scalar_type weight_scale = static_cast<scalar_type>(1.0))
			: input_dimension_(input_dimension)
			, output_dimension_(output_dimension)
		{
			std::mt19937 engine;
			std::normal_distribution<scalar_type> distribution(
				static_cast<scalar_type>(0.0),
				static_cast<scalar_type>(weight_scale * std::sqrt(1.0 / input_dimension)));

			weight_.value() = tensor_type(output_dimension * input_dimension);

			for (std::size_t i = 0; i < weight_.value().size(); ++i)
				weight_.value()[i] = distribution(engine);

			bias_.value() = tensor_type(output_dimension);
		}

		virtual void enumerate_parameters(optimizer_base& optimizer) override
		{
			optimizer.add_parameter(weight_);
			optimizer.add_parameter(bias_);
		}

		expression<scalar_type> weight()
		{
			return weight_.expr();
		}

		expression<scalar_type> bias()
		{
			return bias_.expr();
		}

		expression<scalar_type> operator ()(const expression<scalar_type>& v) const
		{
			return matrix_product(weight_.expr(), v, output_dimension_, input_dimension_, input_dimension_, 1) + bias_.expr();
		}

	private:

		std::size_t input_dimension_;
		std::size_t output_dimension_;

		variable<scalar_type> weight_;
		variable<scalar_type> bias_;

	};

}
<|endoftext|>


<commit_before>/*
 * Copyright (c) 2013 Nicholas Corgan (n.corgan@gmail.com)
 *
 * Distributed under the MIT License (MIT) (See accompanying file LICENSE.txt
 * or copy at http://opensource.org/licenses/MIT)
 */
#ifndef INCLUDED_DATABASE_QUERIES_HPP
#define INCLUDED_DATABASE_QUERIES_HPP

#include <string>

#include <pkmnsim/config.hpp>

namespace pkmnsim
{
    namespace database
    {
        /*
         * Returns given string in a format to be used with database
         */
        std::string to_database_format(std::string identifier);

        /*
         * Get the database ability ID associated with the specified name.
         */
        int get_ability_id_from_name(std::string ability_name);

        /*
         * Get the ability name associated with the specified ID.
         */
        std::string get_ability_name_from_id(int ability_id);

        /*
         * Get the database move ID associated with the specified name.
         */
        int get_move_id_from_name(std::string move_name);

        /*
         * Get the move name associated with the specified ID.
         */
        std::string get_move_name_from_id(int move_id);

        /*
         * Get the database nature ID associated with the specified name.
         */
        int get_nature_id_from_name(std::string nature_name);

        /*
         * Get the nature name associated with the specified ID.
         */
        std::string get_nature_name_from_id(int nature_id);

        /*
         * Get the Pokedex entry associated with the given species ID
         * and version enum.
         */
        std::string get_pokedex_entry_from_species_id(int species_id, int version);

        /*
         * Get the Pokedex entry associated with the given species name
         * and version enum.
         */
        std::string get_pokedex_entry_from_species_name(std::string species_name, int version);

        /*
         * Get the Pokemon species name associated with the specified ID.
         */
        std::string get_species_name_from_id(int species_id);

        /*
         * Get the database type ID associated with the specified name.
         */
        int get_type_id_from_name(std::string type_name);

        /*
         * Get the type name associated with the specified ID.
         */
        std::string get_type_name_from_id(int type_id);
    }
}

#endif /* INCLUDED_DATABASE_QUERIES_HPP */
<commit_msg>Added PKMNSIM_API to database/queries.hpp<commit_after>/*
 * Copyright (c) 2013 Nicholas Corgan (n.corgan@gmail.com)
 *
 * Distributed under the MIT License (MIT) (See accompanying file LICENSE.txt
 * or copy at http://opensource.org/licenses/MIT)
 */
#ifndef INCLUDED_DATABASE_QUERIES_HPP
#define INCLUDED_DATABASE_QUERIES_HPP

#include <string>

#include <pkmnsim/config.hpp>

namespace pkmnsim
{
    namespace database
    {
        /*
         * Returns given string in a format to be used with database
         */
        std::string PKMNSIM_API to_database_format(std::string identifier);

        /*
         * Get the database ability ID associated with the specified name.
         */
        int PKMNSIM_API get_ability_id_from_name(std::string ability_name);

        /*
         * Get the ability name associated with the specified ID.
         */
        std::string PKMNSIM_API get_ability_name_from_id(int ability_id);

        /*
         * Get the database move ID associated with the specified name.
         */
        int PKMNSIM_API get_move_id_from_name(std::string move_name);

        /*
         * Get the move name associated with the specified ID.
         */
        std::string PKMNSIM_API get_move_name_from_id(int move_id);

        /*
         * Get the database nature ID associated with the specified name.
         */
        int PKMNSIM_API get_nature_id_from_name(std::string nature_name);

        /*
         * Get the nature name associated with the specified ID.
         */
        std::string PKMNSIM_API get_nature_name_from_id(int nature_id);

        /*
         * Get the Pokedex entry associated with the given species ID
         * and version enum.
         */
        std::string PKMNSIM_API get_pokedex_entry_from_species_id(int species_id, int version);

        /*
         * Get the Pokedex entry associated with the given species name
         * and version enum.
         */
        std::string PKMNSIM_API get_pokedex_entry_from_species_name(std::string species_name, int version);

        /*
         * Get the Pokemon species name associated with the specified ID.
         */
        std::string PKMNSIM_API get_species_name_from_id(int species_id);

        /*
         * Get the database type ID associated with the specified name.
         */
        int PKMNSIM_API get_type_id_from_name(std::string type_name);

        /*
         * Get the type name associated with the specified ID.
         */
        std::string PKMNSIM_API get_type_name_from_id(int type_id);
    }
}

#endif /* INCLUDED_DATABASE_QUERIES_HPP */
<|endoftext|>


<commit_before>#ifndef BMP_MANIP_HH
#define BMP_MANIP_HH

#include <string>
#include <fstream>
#include <sstream>
#include <iostream>

typedef std::string bmp_t;

bmp_t open_bmp(const std::string& fname) {
  std::ifstream ifs(fname, std::ios::binary);
  std::ostringstream ost;
  ost << ifs.rdbuf();
  bmp_t bmp(ost.str());
  return bmp;
}

// returns the offset at which the pixel array begins (The data after the BMP header info)
unsigned bmp_image_offset(const bmp_t& bmp) {
  return 0;
}

unsigned bmp_bits_per_pixel(const bmp_t& bmp) {
  return 0;
}

// we only support Windows BMP
bool is_bmp_valid(const bmp_t& bmp) {
  std::string validation = bmp.substr(0, 2);
  return validation == "BM";
}

#endif // BMP_MANIP_HH
<commit_msg>Test BmpBitsPerPixel now passes<commit_after>#ifndef BMP_MANIP_HH
#define BMP_MANIP_HH

#include <string>
#include <fstream>
#include <sstream>
#include <iostream>

typedef std::string bmp_t;

bmp_t open_bmp(const std::string& fname) {
  std::ifstream ifs(fname, std::ios::binary);
  std::ostringstream ost;
  ost << ifs.rdbuf();
  bmp_t bmp(ost.str());
  return bmp;
}

// returns the offset at which the pixel array begins (The data after the BMP header info)
unsigned bmp_image_offset(const bmp_t& bmp) {
  return 0;
}

unsigned bmp_bits_per_pixel(const bmp_t& bmp) {
  return (unsigned)bmp[28];
}

// we only support Windows BMP
bool is_bmp_valid(const bmp_t& bmp) {
  std::string validation = bmp.substr(0, 2);
  return validation == "BM";
}

#endif // BMP_MANIP_HH
<|endoftext|>


<commit_before>/**
 * @file quicsvd_main.cc
 *
 * This file implements command line interface for the QUIC-SVD
 * method. It approximate the original matrix by another matrix
 * with smaller dimension to a certain accuracy degree specified by the
 * user and then make SVD decomposition in the projected supspace.
 *
 * Run with --help for more usage.
 *
 * @see quicsvd.h
 */

#include <fastlib/fastlib.h>
#include "quicsvd.h"

const fx_entry_doc quicsvd_main_entries[] = {
  {"A_in", FX_REQUIRED, FX_STR, NULL,
   " File consists of matrix A to be decomposed A = U S VT. \n"},
  {"relErr", FX_PARAM, FX_DOUBLE, NULL,
   " Target relative error |A|-|A'|/|A|, default = 0.1.\n"},
  {"U_out", FX_PARAM, FX_STR, NULL,
   " File to hold matrix U.\n"},
  {"s_out", FX_PARAM, FX_STR, NULL,
   " File to hold the singular values vector s.\n"},
  {"VT_out", FX_PARAM, FX_STR, NULL,
   " File to hold matrix VT (V transposed).\n"},
  {"quicsvd_time", FX_TIMER, FX_CUSTOM, NULL,
   " time to run the QUIC-SVD algorithm.\n"},
  {"lasvd_time", FX_TIMER, FX_CUSTOM, NULL,
   " time to run the SVD algorithm from LAPACK.\n"},
  {"actualErr", FX_RESULT, FX_DOUBLE, NULL,
   " actual relative norm error.\n"},
  FX_ENTRY_DOC_DONE
};

const fx_submodule_doc quicsvd_main_submodules[] = {
  FX_SUBMODULE_DOC_DONE
};

const fx_module_doc quicsvd_main_doc = {
  quicsvd_main_entries, quicsvd_main_submodules,
  "This is a program calculating an approximated Singular "
  "Value Decomposition using QUIC-SVD method.\n"
};

double norm(const Matrix& A) {
  double s = 0;
  for (int i = 0; i < A.n_cols(); i++) {
    Vector col;
    A.MakeColumnVector(i, &col);
    s += math::Sqr(la::LengthEuclidean(col));
  }
  return sqrt(s);
}

int main(int argc, char* argv[]) {
  fx_init(argc, argv, &quicsvd_main_doc);

  Matrix A, U, VT;
  Vector s;

  // parse input file to get matrix A
  const char* A_in = fx_param_str(NULL, "A_in", NULL);

  printf("Loading data ... ");
  fflush(stdout);
  data::Load(A_in, &A);
  printf("n_rows = %d, n_cols = %d, done.\n", A.n_rows(), A.n_cols());

  // parse target relative error, default = 0.1
  const double targetRelErr = fx_param_double(NULL, "relErr", 0.1);

  printf("QUIC-SVD start ... ");
  fflush(stdout);
  fx_timer_start(NULL, "quicsvd_time");
  // call the QUIC-SVD method
  double actualErr = QuicSVD::SVDInit(A, targetRelErr, &s, &U, &VT);
  fx_timer_stop(NULL, "quicsvd_time");
  printf("stop.\n");

  if (fx_param_exists(NULL, "U_out"))
    data::Save(fx_param_str(NULL, "U_out", NULL), U);
  else // use OT to write to standard output
    ot::Print(U, "U", stdout);

  if (fx_param_exists(NULL, "s_out")) {
    Matrix S;
    S.AliasColVector(s);
    data::Save(fx_param_str(NULL, "s_out", NULL), S);
  }
  else
    ot::Print(s, "s", stdout);

  if (fx_param_exists(NULL, "VT_out"))
    data::Save(fx_param_str(NULL, "VT_out", NULL), VT);
  else
    ot::Print(VT, "VT", stdout);

  fx_result_double(NULL, "actualErr", actualErr);

  Matrix B, V;
  la::TransposeInit(VT, &V);
  B.Init(A.n_rows(), A.n_cols());
  B.SetZero();

  for (index_t i = 0; i < s.length(); i++) {
    Vector ucol, vcol;
    U.MakeColumnVector(i, &ucol);
    V.MakeColumnVector(i, &vcol);
    Matrix ucol_i, vcol_i;
    ucol_i.AliasColVector(ucol);
    vcol_i.AliasColVector(vcol);
    la::MulExpert(s[i], false, ucol_i, true, vcol_i, 1, &B);
  }

  la::SubFrom(A, &B);

  printf("relative error: %f\n", norm(B)/norm(A));

  s.Destruct();
  U.Destruct();
  VT.Destruct();
  printf("LAPACK-SVD start ... ");
  fflush(stdout);
  fx_timer_start(NULL, "lasvd_time");
  // call the QUIC-SVD method
  la::SVDInit(A, &s, &U, &VT);
  fx_timer_stop(NULL, "lasvd_time");
  printf("stop.\n");

  fx_done(NULL);
}
<commit_msg>quicsvd_main add S*VT to output options<commit_after>/**
 * @file quicsvd_main.cc
 *
 * This file implements command line interface for the QUIC-SVD
 * method. It approximate the original matrix by another matrix
 * with smaller dimension to a certain accuracy degree specified by the
 * user and then make SVD decomposition in the projected supspace.
 *
 * Run with --help for more usage.
 *
 * @see quicsvd.h
 */

#include <fastlib/fastlib.h>
#include "quicsvd.h"

const fx_entry_doc quicsvd_main_entries[] = {
  {"A_in", FX_REQUIRED, FX_STR, NULL,
   " File consists of matrix A to be decomposed A = U S VT. \n"},
  {"relErr", FX_PARAM, FX_DOUBLE, NULL,
   " Target relative error |A|-|A'|/|A|, default = 0.1.\n"},
  {"U_out", FX_PARAM, FX_STR, NULL,
   " File to hold matrix U.\n"},
  {"s_out", FX_PARAM, FX_STR, NULL,
   " File to hold the singular values vector s.\n"},
  {"VT_out", FX_PARAM, FX_STR, NULL,
   " File to hold matrix VT (V transposed).\n"},
  {"SVT_out", FX_PARAM, FX_STR, NULL,
   " File to hold matrix S * VT (the dimension reduced data).\n"},
  {"lasvd", FX_PARAM, FX_STR, NULL,
   " Use this parameter to compare running time to that of la::SVDInit().\n"},
  {"quicsvd_time", FX_TIMER, FX_CUSTOM, NULL,
   " time to run the QUIC-SVD algorithm.\n"},
  {"lasvd_time", FX_TIMER, FX_CUSTOM, NULL,
   " time to run the SVD algorithm from LAPACK.\n"},
  {"actualErr", FX_RESULT, FX_DOUBLE, NULL,
   " actual relative norm error.\n"},
  {"dimension", FX_RESULT, FX_INT, NULL,
   " the reduced dimension of the data.\n"},
  FX_ENTRY_DOC_DONE
};

const fx_submodule_doc quicsvd_main_submodules[] = {
  FX_SUBMODULE_DOC_DONE
};

const fx_module_doc quicsvd_main_doc = {
  quicsvd_main_entries, quicsvd_main_submodules,
  "This is a program calculating an approximated Singular "
  "Value Decomposition using QUIC-SVD method.\n"
};

double norm(const Matrix& A) {
  double s = 0;
  for (int i = 0; i < A.n_cols(); i++) {
    Vector col;
    A.MakeColumnVector(i, &col);
    s += math::Sqr(la::LengthEuclidean(col));
  }
  return sqrt(s);
}

int main(int argc, char* argv[]) {
  fx_init(argc, argv, &quicsvd_main_doc);

  Matrix A, U, VT;
  Vector s;

  // parse input file to get matrix A
  const char* A_in = fx_param_str(NULL, "A_in", NULL);

  printf("Loading data ... ");
  fflush(stdout);
  data::Load(A_in, &A);
  printf("n_rows = %d, n_cols = %d, done.\n", A.n_rows(), A.n_cols());

  // parse target relative error, default = 0.1
  const double targetRelErr = fx_param_double(NULL, "relErr", 0.1);

  printf("QUIC-SVD start ... ");
  fflush(stdout);
  fx_timer_start(NULL, "quicsvd_time");
  // call the QUIC-SVD method
  double actualErr = QuicSVD::SVDInit(A, targetRelErr, &s, &U, &VT);
  fx_timer_stop(NULL, "quicsvd_time");
  printf("stop.\n");

  fx_result_double(NULL, "actualErr", actualErr);
  fx_result_int(NULL, "dimension", s.length());

  if (fx_param_exists(NULL, "U_out"))
    data::Save(fx_param_str(NULL, "U_out", NULL), U);
  //else // use OT to write to standard output
  //  ot::Print(U, "U", stdout);

  if (fx_param_exists(NULL, "s_out")) {
    Matrix S;
    S.AliasColVector(s);
    data::Save(fx_param_str(NULL, "s_out", NULL), S);
  }
  //else
  //  ot::Print(s, "s", stdout);

  if (fx_param_exists(NULL, "VT_out"))
    data::Save(fx_param_str(NULL, "VT_out", NULL), VT);
  //else
  //  ot::Print(VT, "VT", stdout);

  if (fx_param_exists(NULL, "SVT_out")) {
    la::ScaleRows(s, &VT);
    data::Save(fx_param_str(NULL, "SVT_out", NULL), VT);
  }

  /*
  Matrix B, V;
  la::TransposeInit(VT, &V);
  B.Init(A.n_rows(), A.n_cols());
  B.SetZero();

  for (index_t i = 0; i < s.length(); i++) {
    Vector ucol, vcol;
    U.MakeColumnVector(i, &ucol);
    V.MakeColumnVector(i, &vcol);
    Matrix ucol_i, vcol_i;
    ucol_i.AliasColVector(ucol);
    vcol_i.AliasColVector(vcol);
    la::MulExpert(s[i], false, ucol_i, true, vcol_i, 1, &B);
  }

  la::SubFrom(A, &B);

  printf("relative error: %f\n", norm(B)/norm(A));
  */

  if (fx_param_exists(NULL, "lasvd")) {
    s.Destruct();
    U.Destruct();
    VT.Destruct();
    printf("LAPACK-SVD start ... ");
    fflush(stdout);
    fx_timer_start(NULL, "lasvd_time");
    // call the QUIC-SVD method
    la::SVDInit(A, &s, &U, &VT);
    fx_timer_stop(NULL, "lasvd_time");
    printf("stop.\n");
  }

  fx_done(NULL);
}
<|endoftext|>


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

#include "utest/utest_shim.h"
#include "utest/utest_stack_trace.h"

#if UTEST_SHIM_SCHEDULER_USE_MINAR
#include "minar/minar.h"

static int32_t utest_minar_init()
{
    return 0;
}
static void *utest_minar_post(const utest_v1_harness_callback_t callback, const uint32_t delay_ms)
{
    void *handle = minar::Scheduler::postCallback(callback).delay(minar::milliseconds(delay_ms)).getHandle();
    return handle;
}
static int32_t utest_minar_cancel(void *handle)
{
    int32_t ret = minar::Scheduler::cancelCallback(handle);
    return ret;
}
static int32_t utest_minar_run()
{
    return 0;
}
extern "C" {
static const utest_v1_scheduler_t utest_v1_scheduler =
{
    utest_minar_init,
    utest_minar_post,
    utest_minar_cancel,
    utest_minar_run
};
utest_v1_scheduler_t utest_v1_get_scheduler()
{
    return utest_v1_scheduler;
}
}

#elif UTEST_SHIM_SCHEDULER_USE_US_TICKER
#ifdef YOTTA_MBED_HAL_VERSION_STRING
#   include "mbed-hal/us_ticker_api.h"
#else
#   include "mbed.h"
#endif

// only one callback is active at any given time
static volatile utest_v1_harness_callback_t minimal_callback;
static volatile utest_v1_harness_callback_t ticker_callback;

// Timeout object used to control the scheduling of test case callbacks
Timeout utest_timeout_object;

static void ticker_handler()
{
    UTEST_LOG_FUNCTION();
    minimal_callback = ticker_callback;
}

static int32_t utest_us_ticker_init()
{
    UTEST_LOG_FUNCTION();
    // Ticker scheduler does not require any initialisation so return immediately
    return 0;
}
static void *utest_us_ticker_post(const utest_v1_harness_callback_t callback, timestamp_t delay_ms)
{
    UTEST_LOG_FUNCTION();
    timestamp_t delay_us = delay_ms *1000;

    if (delay_ms) {
        ticker_callback = callback;
        // fire the interrupt in 1000us * delay_ms
        utest_timeout_object.attach_us(ticker_handler, delay_us);

    }
    else {
        minimal_callback = callback;
    }

    // return a bogus handle
    return (void*)1;
}
static int32_t utest_us_ticker_cancel(void *handle)
{
    UTEST_LOG_FUNCTION();
    (void) handle;
    utest_timeout_object.detach();
    return 0;
}
static int32_t utest_us_ticker_run()
{
    UTEST_LOG_FUNCTION();
    while(1)
    {
        // check if a new callback has been set
        if (minimal_callback)
        {
            // copy the callback
            utest_v1_harness_callback_t callback = minimal_callback;
            // reset the shared callback
            minimal_callback = NULL;
            // execute the copied callback
            callback();
        }
    }
    return 0;
}

extern "C" {
static const utest_v1_scheduler_t utest_v1_scheduler =
{
    utest_us_ticker_init,
    utest_us_ticker_post,
    utest_us_ticker_cancel,
    utest_us_ticker_run
};
utest_v1_scheduler_t utest_v1_get_scheduler()
{
    UTEST_LOG_FUNCTION();
    return utest_v1_scheduler;
}
}
#endif

#ifdef YOTTA_CORE_UTIL_VERSION_STRING
// their functionality is implemented using the CriticalSectionLock class
void utest_v1_enter_critical_section(void) {}
void utest_v1_leave_critical_section(void) {}
#endif
<commit_msg>Move global Timeout object from utest_shim in static function.<commit_after>/****************************************************************************
 * Copyright (c) 2015, ARM Limited, All Rights Reserved
 * SPDX-License-Identifier: Apache-2.0
 *
 * Licensed under the Apache License, Version 2.0 (the "License"); you may
 * not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 * http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
 * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 ****************************************************************************
 */

#include "utest/utest_shim.h"
#include "utest/utest_stack_trace.h"

#if UTEST_SHIM_SCHEDULER_USE_MINAR
#include "minar/minar.h"

static int32_t utest_minar_init()
{
    return 0;
}
static void *utest_minar_post(const utest_v1_harness_callback_t callback, const uint32_t delay_ms)
{
    void *handle = minar::Scheduler::postCallback(callback).delay(minar::milliseconds(delay_ms)).getHandle();
    return handle;
}
static int32_t utest_minar_cancel(void *handle)
{
    int32_t ret = minar::Scheduler::cancelCallback(handle);
    return ret;
}
static int32_t utest_minar_run()
{
    return 0;
}
extern "C" {
static const utest_v1_scheduler_t utest_v1_scheduler =
{
    utest_minar_init,
    utest_minar_post,
    utest_minar_cancel,
    utest_minar_run
};
utest_v1_scheduler_t utest_v1_get_scheduler()
{
    return utest_v1_scheduler;
}
}

#elif UTEST_SHIM_SCHEDULER_USE_US_TICKER
#ifdef YOTTA_MBED_HAL_VERSION_STRING
#   include "mbed-hal/us_ticker_api.h"
#else
#   include "mbed.h"
#endif

// only one callback is active at any given time
static volatile utest_v1_harness_callback_t minimal_callback;
static volatile utest_v1_harness_callback_t ticker_callback;

// Timeout object used to control the scheduling of test case callbacks
static Timeout& utest_timeout_object() {
    static Timeout timeout;
    return timeout;
}

static void ticker_handler()
{
    UTEST_LOG_FUNCTION();
    minimal_callback = ticker_callback;
}

static int32_t utest_us_ticker_init()
{
    UTEST_LOG_FUNCTION();
    // Ticker scheduler does not require any initialisation so return immediately
    return 0;
}
static void *utest_us_ticker_post(const utest_v1_harness_callback_t callback, timestamp_t delay_ms)
{
    UTEST_LOG_FUNCTION();
    timestamp_t delay_us = delay_ms *1000;

    if (delay_ms) {
        ticker_callback = callback;
        // fire the interrupt in 1000us * delay_ms
        utest_timeout_object().attach_us(ticker_handler, delay_us);

    }
    else {
        minimal_callback = callback;
    }

    // return a bogus handle
    return (void*)1;
}
static int32_t utest_us_ticker_cancel(void *handle)
{
    UTEST_LOG_FUNCTION();
    (void) handle;
    utest_timeout_object().detach();
    return 0;
}
static int32_t utest_us_ticker_run()
{
    UTEST_LOG_FUNCTION();
    while(1)
    {
        // check if a new callback has been set
        if (minimal_callback)
        {
            // copy the callback
            utest_v1_harness_callback_t callback = minimal_callback;
            // reset the shared callback
            minimal_callback = NULL;
            // execute the copied callback
            callback();
        }
    }
    return 0;
}

extern "C" {
static const utest_v1_scheduler_t utest_v1_scheduler =
{
    utest_us_ticker_init,
    utest_us_ticker_post,
    utest_us_ticker_cancel,
    utest_us_ticker_run
};
utest_v1_scheduler_t utest_v1_get_scheduler()
{
    UTEST_LOG_FUNCTION();
    return utest_v1_scheduler;
}
}
#endif

#ifdef YOTTA_CORE_UTIL_VERSION_STRING
// their functionality is implemented using the CriticalSectionLock class
void utest_v1_enter_critical_section(void) {}
void utest_v1_leave_critical_section(void) {}
#endif
<|endoftext|>


<commit_before>#include <jsapi.h>
#include <cstring>
#include <iostream>
#include <stdexcept>
#include <string>
#include <vector>
namespace perl6_spidermonkey
{

#ifndef SPIDERMONKEY_VERSION
#   error "You need to set SPIDERMONKEY_VERSION"
#endif

#if SPIDERMONKEY_VERSION <= 24
#   define  SPIDERMONKEY_INIT          /* JS_Init() doesn't exist */
#   define _SPIDERMONKEY_PARAM_THREADS ,JS_USE_HELPER_THREADS
#   define _SPIDERMONKEY_PARAM_FIRE    /* parameter doesn't exist */
#   define  SPIDERMONKEY_ADDRESS(X)    (X).address()
#else
#   define  SPIDERMONKEY_INIT          JS_Init()
#   define _SPIDERMONKEY_PARAM_THREADS /* parameter removed */
#   define _SPIDERMONKEY_PARAM_FIRE    ,JS::FireOnNewGlobalHook
#   define  SPIDERMONKEY_ADDRESS(X)    &(X)
#endif

static JSClass global_class = {
    "global",
    JSCLASS_GLOBAL_FLAGS,
# if SPIDERMONKEY_VERSION < 38
    JS_PropertyStub,
    JS_DeletePropertyStub,
    JS_PropertyStub,
    JS_StrictPropertyStub,
    JS_EnumerateStub,
    JS_ResolveStub,
    JS_ConvertStub,
# endif
};

static JSBool dispatch(JSContext* context, unsigned int argc, JS::Value* vp)
{
    JS::CallArgs args = CallArgsFromVp(argc, vp);

    JSFunction* fun = JS_ValueToFunction(context, args.calleev());
    char* name = JS_EncodeStringToUTF8(context, JS_GetFunctionId(fun));
    std::cerr << name << '\n';
    JS_free(context, name);

    return true;
}

/* Simple auto pointer that calls `delete` on abnormal scope exit. */
template <typename T> class Auto
{
public:
    Auto(T* p) : ptr(p) {}

    ~Auto()         { delete ptr; }
    T* operator->() { return ptr; }
    T* get()        { return ptr; }

    T* ret() /* normal return */
    {
        T* p = ptr;
        ptr  = NULL;
        return p;
    }

private:
    T* ptr;

    Auto<T>           (Auto<T> const&); /* no copying    */
    Auto<T>& operator=(Auto<T> const&); /* no assignment */
};

class Value
{
public:

    JSContext*      context;
    JS::RootedValue rval;

    Value(JSContext* ctx) : context(ctx), rval(ctx) {}

    ~Value()
    {
        JS_free(context, strval);
    }

    const char* type()
    {
        switch (JS_TypeOfValue(context, rval))
        {
            case JSTYPE_VOID    : return "undefined";
            case JSTYPE_OBJECT  : return "object";
            case JSTYPE_FUNCTION: return "function";
            case JSTYPE_STRING  : return "string";
            case JSTYPE_NUMBER  : return "number";
            case JSTYPE_BOOLEAN : return "boolean";
            default             : return NULL;
        }
    }

    const char* str()
    {
        if (!strval)
            strval = JS_EncodeStringToUTF8(context,
                                           JS_ValueToString(context, rval));
        return strval;
    }

    bool num(double* number)
    {
        return JS_ValueToNumber(context, rval, number);
    }

    bool boolean(JSBool* b)
    {
        return JS_ValueToBoolean(context, rval, b);
    }

    bool accessible()
    {
        return rval.isObject() && !rval.isNull();
    }

    JSObject* to_object(const char* fun)
    {
        if (!rval.isObject())
        {
            JS_ReportError(context, "%s: not an object", fun);
            return NULL;
        }

        JSObject* obj;
        if (!JS_ValueToObject(context, rval, &obj))
            return NULL;

        if (!obj)
        {
            JS_ReportError(context, "%s: object is null", fun);
            return NULL;
        }

        return obj;
    }

    Value* at_key(const char* key)
    {
        JSObject* obj = to_object("AT-KEY");
        if (!obj)
            return NULL;

        Auto<Value> out(new Value(context));
        if (JS_GetProperty(context, obj, key, SPIDERMONKEY_ADDRESS(out->rval)))
            return out.ret();

        return NULL;
    }

    Value* at_pos(uint32_t pos)
    {
        JSObject* obj = to_object("AT-POS");

        if (!obj)
            return NULL;

        Auto<Value> out(new Value(context));
        if (JS_GetElement(context, obj, pos, SPIDERMONKEY_ADDRESS(out->rval)))
            return out.ret();

        return NULL;
    }

private:
    char* strval = NULL;
};

struct Error
{
    bool         handled;
    std::string  message;
    std::string  file;
    unsigned int line;
    unsigned int column;
};

class Context
{
public:
    Context(JSRuntime* rt, size_t stack_size)
    {
        error.handled = true;

        context = JS_NewContext(rt, stack_size);
        if (!context)
            throw std::runtime_error("can't create context");

        JS_SetContextPrivate(context, this);
        /* FIXME maybe?
         * JS_SetErrorReport is documented to take a JSRuntime* as its
         * first argument, but it totally doesn't. Maybe it got changed
         * in a later version, in which case this needs to be ifdef'd.
         */
        JS_SetErrorReporter(context, Context::on_error);

        JSObject* gobj = JS_NewGlobalObject(context, &global_class, NULL
                                            _SPIDERMONKEY_PARAM_FIRE);
        global = new JS::RootedObject(context, gobj);
        if (!*global)
            throw std::runtime_error("can't create global object");

        {
            JSAutoCompartment ac(context, *global);

            if (!JS_InitStandardClasses(context, *global))
                throw std::runtime_error("can't initialize standard classes");

            if (!JS_DefineFunction(context, *global, "doit", dispatch, 0, 0))
                throw std::runtime_error("can't register dispatch function");

        }
    }

    ~Context()
    {
        if (context)
        {
            JS_DestroyContext(context);
        }
        delete global;
    }

    Value* eval(const char* script, const char* file, int line)
    {
        Auto<Value> val(new Value(context));
        bool ok;

        {
            JSAutoCompartment ac(context, *global);
#         if SPIDERMONKEY_VERSION < 38
            ok = JS_EvaluateScript(context, *global,
#         else
            JS::CompileOptions opts(context);
            opts.setFileAndLine(filename, lineno);
            ok = JS::Evaluate(context, *global, opts,
#         endif
                              script, std::strlen(script), file,
                              line, SPIDERMONKEY_ADDRESS(val->rval));
        }

        return ok ? val.ret() : NULL;
    }

    Value* call(Value* val, unsigned int argc, Value* argv)
    {
        JSObject* obj = val->to_object("CALL-ME");
        if (!obj)
            return NULL;

        std::vector<JS::Value> args;
        for (unsigned int i = 0; i < argc; ++i)
            args.push_back(argv[i].rval.get());

        Auto<Value> out(new Value(context));
        bool ok;

        {
            JSAutoCompartment ac(context, *global);
            ok = JS_CallFunctionValue(context, obj,
                                      *SPIDERMONKEY_ADDRESS(val->rval),
                                      argc, argc ? &args[0] : NULL,
                                      SPIDERMONKEY_ADDRESS(out->rval));
        }

        return ok ? out.ret() : NULL;
    }

    static Context* from_js(JSContext* context)
    {
        return static_cast<Context*>(JS_GetContextPrivate(context));
    }

    static void on_error(JSContext* context, const char* msg, JSErrorReport* report)
    {
        if (report->flags & JSREPORT_WARNING)
        {
            std::cerr << msg << '\n';
        }
        else
        {
            Context* cx = Context::from_js(context);
            if (!cx->error.handled)
            {
                std::cerr << "JavaScript::Spidermonkey: Whoa, unhandled error!\n"
                          << cx->error.message << '\n';
            }
            cx->error.handled = false;
            cx->error.message = msg;
            cx->error.file    = report->filename ? report->filename : "";
            cx->error.line    = report->lineno;
            cx->error.column  = report->column;
        }
    }

    Error* get_error()
    {
        if (error.handled)
            return NULL;
        error.handled = true;
        return &error;
    }

private:
    JSContext       * context = NULL;
    JS::RootedObject* global  = NULL;
    Error             error;
};

}

using namespace perl6_spidermonkey;

extern "C"
{
    int p6sm_version()
    {
        return SPIDERMONKEY_VERSION;
    }

    void p6sm_shutdown()
    {
        JS_ShutDown();
    }

    JSRuntime* p6sm_runtime_new(long memory)
    {
        SPIDERMONKEY_INIT;
        return JS_NewRuntime(memory _SPIDERMONKEY_PARAM_THREADS);
    }

    void p6sm_runtime_free(JSRuntime* rt)
    {
        JS_DestroyRuntime(rt);
    }

    const char*  p6sm_error_message(Error* e) { return e->message.c_str(); }
    const char*  p6sm_error_file   (Error* e) { return e->file.c_str();    }
    unsigned int p6sm_error_line   (Error* e) { return e->line;            }
    unsigned int p6sm_error_column (Error* e) { return e->column;          }

    Context* p6sm_context_new(JSRuntime* rt, int stack_size)
    {
        try
        {
            Auto<Context> cx(new Context(rt, stack_size));
            return cx.ret();
        }
        catch(std::runtime_error& e)
        {
            std::cerr << e.what() << '\n';
        }
        return NULL;
    }

    void p6sm_context_free(Context* cx)
    {
        delete cx;
    }

    Error* p6sm_context_error(Context* cx)
    {
        return cx->get_error();
    }

    Value* p6sm_context_eval(Context   * cx,
                     const char* script,
                     const char* file,
                     int         line)
    {
        return cx->eval(script, file, line);
    }

    void p6sm_value_free(Value* val)
    {
        delete val;
    }

    Error* p6sm_value_error(Value* val)
    {
        Context* cx = Context::from_js(val->context);
        return cx->get_error();
    }

    const char* p6sm_value_type(Value* val)
    {
        return val->type();
    }

    const char* p6sm_value_str(Value* val)
    {
        return val->str();
    }

    int p6sm_value_num(Value* val, double* number)
    {
        return val->num(number);
    }

    int p6sm_value_bool(Value* val, int* boolean)
    {
        JSBool b;
        if (val->boolean(&b))
        {
            *boolean = b;
            return 1;
        }
        return 0;
    }

    Value* p6sm_value_call(Value* val, unsigned int argc, Value* argv)
    {
        Context* cx = Context::from_js(val->context);
        return cx->call(val, argc, argv);
    }

    int p6sm_value_accessible(Value* val)
    {
        return val->accessible();
    }

    Value* p6sm_value_at_key(Value* val, const char* key)
    {
        return val->at_key(key);
    }

    Value* p6sm_value_at_pos(Value* val, uint32_t pos)
    {
        return val->at_pos(pos);
    }
}
<commit_msg>Make attributes public<commit_after>#include <jsapi.h>
#include <cstring>
#include <iostream>
#include <stdexcept>
#include <string>
#include <vector>
namespace perl6_spidermonkey
{

#ifndef SPIDERMONKEY_VERSION
#   error "You need to set SPIDERMONKEY_VERSION"
#endif

#if SPIDERMONKEY_VERSION <= 24
#   define  SPIDERMONKEY_INIT          /* JS_Init() doesn't exist */
#   define _SPIDERMONKEY_PARAM_THREADS ,JS_USE_HELPER_THREADS
#   define _SPIDERMONKEY_PARAM_FIRE    /* parameter doesn't exist */
#   define  SPIDERMONKEY_ADDRESS(X)    (X).address()
#else
#   define  SPIDERMONKEY_INIT          JS_Init()
#   define _SPIDERMONKEY_PARAM_THREADS /* parameter removed */
#   define _SPIDERMONKEY_PARAM_FIRE    ,JS::FireOnNewGlobalHook
#   define  SPIDERMONKEY_ADDRESS(X)    &(X)
#endif

static JSClass global_class = {
    "global",
    JSCLASS_GLOBAL_FLAGS,
# if SPIDERMONKEY_VERSION < 38
    JS_PropertyStub,
    JS_DeletePropertyStub,
    JS_PropertyStub,
    JS_StrictPropertyStub,
    JS_EnumerateStub,
    JS_ResolveStub,
    JS_ConvertStub,
# endif
};

static JSBool dispatch(JSContext* context, unsigned int argc, JS::Value* vp)
{
    JS::CallArgs args = CallArgsFromVp(argc, vp);

    JSFunction* fun = JS_ValueToFunction(context, args.calleev());
    char* name = JS_EncodeStringToUTF8(context, JS_GetFunctionId(fun));
    std::cerr << name << '\n';
    JS_free(context, name);

    return true;
}

/* Simple auto pointer that calls `delete` on abnormal scope exit. */
template <typename T> class Auto
{
public:
    Auto(T* p) : ptr(p) {}

    ~Auto()         { delete ptr; }
    T* operator->() { return ptr; }
    T* get()        { return ptr; }

    T* ret() /* normal return */
    {
        T* p = ptr;
        ptr  = NULL;
        return p;
    }

private:
    T* ptr;

    Auto<T>           (Auto<T> const&); /* no copying    */
    Auto<T>& operator=(Auto<T> const&); /* no assignment */
};

class Value
{
public:

    JSContext*      context;
    JS::RootedValue rval;
    char*           strval = NULL;

    Value(JSContext* ctx) : context(ctx), rval(ctx) {}

    ~Value()
    {
        JS_free(context, strval);
    }

    const char* type()
    {
        switch (JS_TypeOfValue(context, rval))
        {
            case JSTYPE_VOID    : return "undefined";
            case JSTYPE_OBJECT  : return "object";
            case JSTYPE_FUNCTION: return "function";
            case JSTYPE_STRING  : return "string";
            case JSTYPE_NUMBER  : return "number";
            case JSTYPE_BOOLEAN : return "boolean";
            default             : return NULL;
        }
    }

    const char* str()
    {
        if (!strval)
            strval = JS_EncodeStringToUTF8(context,
                                           JS_ValueToString(context, rval));
        return strval;
    }

    bool num(double* number)
    {
        return JS_ValueToNumber(context, rval, number);
    }

    bool boolean(JSBool* b)
    {
        return JS_ValueToBoolean(context, rval, b);
    }

    bool accessible()
    {
        return rval.isObject() && !rval.isNull();
    }

    JSObject* to_object(const char* fun)
    {
        if (!rval.isObject())
        {
            JS_ReportError(context, "%s: not an object", fun);
            return NULL;
        }

        JSObject* obj;
        if (!JS_ValueToObject(context, rval, &obj))
            return NULL;

        if (!obj)
        {
            JS_ReportError(context, "%s: object is null", fun);
            return NULL;
        }

        return obj;
    }

    Value* at_key(const char* key)
    {
        JSObject* obj = to_object("AT-KEY");
        if (!obj)
            return NULL;

        Auto<Value> out(new Value(context));
        if (JS_GetProperty(context, obj, key, SPIDERMONKEY_ADDRESS(out->rval)))
            return out.ret();

        return NULL;
    }

    Value* at_pos(uint32_t pos)
    {
        JSObject* obj = to_object("AT-POS");

        if (!obj)
            return NULL;

        Auto<Value> out(new Value(context));
        if (JS_GetElement(context, obj, pos, SPIDERMONKEY_ADDRESS(out->rval)))
            return out.ret();

        return NULL;
    }
};

struct Error
{
    bool         handled;
    std::string  message;
    std::string  file;
    unsigned int line;
    unsigned int column;
};

class Context
{
public:
    JSContext       * context = NULL;
    JS::RootedObject* global  = NULL;
    Error             error;

    Context(JSRuntime* rt, size_t stack_size)
    {
        error.handled = true;

        context = JS_NewContext(rt, stack_size);
        if (!context)
            throw std::runtime_error("can't create context");

        JS_SetContextPrivate(context, this);
        /* FIXME maybe?
         * JS_SetErrorReport is documented to take a JSRuntime* as its
         * first argument, but it totally doesn't. Maybe it got changed
         * in a later version, in which case this needs to be ifdef'd.
         */
        JS_SetErrorReporter(context, Context::on_error);

        JSObject* gobj = JS_NewGlobalObject(context, &global_class, NULL
                                            _SPIDERMONKEY_PARAM_FIRE);
        global = new JS::RootedObject(context, gobj);
        if (!*global)
            throw std::runtime_error("can't create global object");

        {
            JSAutoCompartment ac(context, *global);

            if (!JS_InitStandardClasses(context, *global))
                throw std::runtime_error("can't initialize standard classes");

            if (!JS_DefineFunction(context, *global, "doit", dispatch, 0, 0))
                throw std::runtime_error("can't register dispatch function");

        }
    }

    ~Context()
    {
        if (context)
        {
            JS_DestroyContext(context);
        }
        delete global;
    }

    Value* eval(const char* script, const char* file, int line)
    {
        Auto<Value> val(new Value(context));
        bool ok;

        {
            JSAutoCompartment ac(context, *global);
#         if SPIDERMONKEY_VERSION < 38
            ok = JS_EvaluateScript(context, *global,
#         else
            JS::CompileOptions opts(context);
            opts.setFileAndLine(filename, lineno);
            ok = JS::Evaluate(context, *global, opts,
#         endif
                              script, std::strlen(script), file,
                              line, SPIDERMONKEY_ADDRESS(val->rval));
        }

        return ok ? val.ret() : NULL;
    }

    Value* call(Value* val, unsigned int argc, Value* argv)
    {
        JSObject* obj = val->to_object("CALL-ME");
        if (!obj)
            return NULL;

        std::vector<JS::Value> args;
        for (unsigned int i = 0; i < argc; ++i)
            args.push_back(argv[i].rval.get());

        Auto<Value> out(new Value(context));
        bool ok;

        {
            JSAutoCompartment ac(context, *global);
            ok = JS_CallFunctionValue(context, obj,
                                      *SPIDERMONKEY_ADDRESS(val->rval),
                                      argc, argc ? &args[0] : NULL,
                                      SPIDERMONKEY_ADDRESS(out->rval));
        }

        return ok ? out.ret() : NULL;
    }

    static Context* from_js(JSContext* context)
    {
        return static_cast<Context*>(JS_GetContextPrivate(context));
    }

    static void on_error(JSContext* context, const char* msg, JSErrorReport* report)
    {
        if (report->flags & JSREPORT_WARNING)
        {
            std::cerr << msg << '\n';
        }
        else
        {
            Context* cx = Context::from_js(context);
            if (!cx->error.handled)
            {
                std::cerr << "JavaScript::Spidermonkey: Whoa, unhandled error!\n"
                          << cx->error.message << '\n';
            }
            cx->error.handled = false;
            cx->error.message = msg;
            cx->error.file    = report->filename ? report->filename : "";
            cx->error.line    = report->lineno;
            cx->error.column  = report->column;
        }
    }

    Error* get_error()
    {
        if (error.handled)
            return NULL;
        error.handled = true;
        return &error;
    }
};

}

using namespace perl6_spidermonkey;

extern "C"
{
    int p6sm_version()
    {
        return SPIDERMONKEY_VERSION;
    }

    void p6sm_shutdown()
    {
        JS_ShutDown();
    }

    JSRuntime* p6sm_runtime_new(long memory)
    {
        SPIDERMONKEY_INIT;
        return JS_NewRuntime(memory _SPIDERMONKEY_PARAM_THREADS);
    }

    void p6sm_runtime_free(JSRuntime* rt)
    {
        JS_DestroyRuntime(rt);
    }

    const char*  p6sm_error_message(Error* e) { return e->message.c_str(); }
    const char*  p6sm_error_file   (Error* e) { return e->file.c_str();    }
    unsigned int p6sm_error_line   (Error* e) { return e->line;            }
    unsigned int p6sm_error_column (Error* e) { return e->column;          }

    Context* p6sm_context_new(JSRuntime* rt, int stack_size)
    {
        try
        {
            Auto<Context> cx(new Context(rt, stack_size));
            return cx.ret();
        }
        catch(std::runtime_error& e)
        {
            std::cerr << e.what() << '\n';
        }
        return NULL;
    }

    void p6sm_context_free(Context* cx)
    {
        delete cx;
    }

    Error* p6sm_context_error(Context* cx)
    {
        return cx->get_error();
    }

    Value* p6sm_context_eval(Context   * cx,
                     const char* script,
                     const char* file,
                     int         line)
    {
        return cx->eval(script, file, line);
    }

    void p6sm_value_free(Value* val)
    {
        delete val;
    }

    Error* p6sm_value_error(Value* val)
    {
        Context* cx = Context::from_js(val->context);
        return cx->get_error();
    }

    const char* p6sm_value_type(Value* val)
    {
        return val->type();
    }

    const char* p6sm_value_str(Value* val)
    {
        return val->str();
    }

    int p6sm_value_num(Value* val, double* number)
    {
        return val->num(number);
    }

    int p6sm_value_bool(Value* val, int* boolean)
    {
        JSBool b;
        if (val->boolean(&b))
        {
            *boolean = b;
            return 1;
        }
        return 0;
    }

    Value* p6sm_value_call(Value* val, unsigned int argc, Value* argv)
    {
        Context* cx = Context::from_js(val->context);
        return cx->call(val, argc, argv);
    }

    int p6sm_value_accessible(Value* val)
    {
        return val->accessible();
    }

    Value* p6sm_value_at_key(Value* val, const char* key)
    {
        return val->at_key(key);
    }

    Value* p6sm_value_at_pos(Value* val, uint32_t pos)
    {
        return val->at_pos(pos);
    }
}
<|endoftext|>


<commit_before>// Copyright 2020 Google LLC
//
// 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
//
//      https://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

#include "iree/compiler/Dialect/HAL/Target/LLVM/LLVMTargetOptions.h"

#include "llvm/ADT/APFloat.h"
#include "llvm/MC/SubtargetFeature.h"
#include "llvm/Support/CommandLine.h"
#include "llvm/Support/Host.h"
#include "llvm/Target/TargetOptions.h"

namespace mlir {
namespace iree_compiler {
namespace IREE {
namespace HAL {

LLVMTargetOptions getDefaultLLVMTargetOptions() {
  LLVMTargetOptions targetOptions;

  // Host target triple.
  targetOptions.targetTriple = llvm::sys::getDefaultTargetTriple();
  targetOptions.targetCPU = llvm::sys::getHostCPUName().str();
  {
    llvm::SubtargetFeatures features;
    llvm::StringMap<bool> hostFeatures;
    if (llvm::sys::getHostCPUFeatures(hostFeatures)) {
      for (auto &feature : hostFeatures) {
        features.AddFeature(feature.first(), feature.second);
      }
    }
    targetOptions.targetCPUFeatures = features.getString();
  }

  // LLVM loop optimization options.
  targetOptions.pipelineTuningOptions.LoopInterleaving = true;
  targetOptions.pipelineTuningOptions.LoopVectorization = true;
  targetOptions.pipelineTuningOptions.LoopUnrolling = true;

  // LLVM SLP Auto vectorizer.
  targetOptions.pipelineTuningOptions.SLPVectorization = true;

  // LLVM -O3.
  // TODO(benvanik): add an option for this.
  targetOptions.optLevel = llvm::PassBuilder::OptimizationLevel::O3;
  targetOptions.options.FloatABIType = llvm::FloatABI::Hard;

  return targetOptions;
}

LLVMTargetOptions getLLVMTargetOptionsFromFlags() {
  auto llvmTargetOptions = getDefaultLLVMTargetOptions();

  static llvm::cl::opt<std::string> clTargetTriple(
      "iree-llvm-target-triple", llvm::cl::desc("LLVM target machine triple"),
      llvm::cl::init(llvmTargetOptions.targetTriple));
  static llvm::cl::opt<std::string> clTargetCPU(
      "iree-llvm-target-cpu",
      llvm::cl::desc(
          "LLVM target machine CPU; use 'host' for your host native CPU"),
      llvm::cl::init("generic"));
  static llvm::cl::opt<std::string> clTargetCPUFeatures(
      "iree-llvm-target-cpu-features",
      llvm::cl::desc("LLVM target machine CPU features; use 'host' for your "
                     "host native CPU"),
      llvm::cl::init(""));
  llvmTargetOptions.targetTriple = clTargetTriple;
  if (clTargetCPU != "host") {
    llvmTargetOptions.targetCPU = clTargetCPU;
  }
  if (clTargetCPUFeatures != "host") {
    llvmTargetOptions.targetCPUFeatures = clTargetCPUFeatures;
  }

  static llvm::cl::opt<SanitizerKind> clSanitizerKind(
      "iree-llvm-sanitize", llvm::cl::desc("Apply LLVM sanitize feature"),
      llvm::cl::init(SanitizerKind::kNone),
      llvm::cl::values(clEnumValN(SanitizerKind::kAddress, "address",
                                  "Address sanitizer support")));
  llvmTargetOptions.sanitizerKind = clSanitizerKind;

  static llvm::cl::opt<std::string> clTargetABI(
      "iree-llvm-target-abi",
      llvm::cl::desc("LLVM target machine ABI; specify for -mabi"),
      llvm::cl::init(""));
  llvmTargetOptions.options.MCOptions.ABIName = clTargetABI;

  static llvm::cl::opt<llvm::FloatABI::ABIType> clTargetFloatABI(
      "iree-llvm-target-float-abi",
      llvm::cl::desc("LLVM target codegen enables soft float abi e.g "
                     "-mfloat-abi=softfp"),
      llvm::cl::init(llvmTargetOptions.options.FloatABIType),
      llvm::cl::values(
          clEnumValN(llvm::FloatABI::Default, "default", "Default (softfp)"),
          clEnumValN(llvm::FloatABI::Soft, "soft",
                     "Software floating-point emulation"),
          clEnumValN(llvm::FloatABI::Hard, "hard",
                     "Hardware floating-point instructions")));
  llvmTargetOptions.options.FloatABIType = clTargetFloatABI;

  static llvm::cl::opt<bool> clDebugSymbols(
      "iree-llvm-debug-symbols",
      llvm::cl::desc("Generate and embed debug information (DWARF, PDB, etc)"),
      llvm::cl::init(llvmTargetOptions.debugSymbols));
  llvmTargetOptions.debugSymbols = clDebugSymbols;

  static llvm::cl::opt<bool> clLinkStatic(
      "iree-llvm-link-static",
      llvm::cl::desc(
          "Links system libraries into binaries statically to isolate them "
          "from platform dependencies needed at runtime"),
      llvm::cl::init(llvmTargetOptions.linkStatic));
  llvmTargetOptions.linkStatic = clLinkStatic;

  static llvm::cl::opt<bool> clKeepLinkerArtifacts(
      "iree-llvm-keep-linker-artifacts",
      llvm::cl::desc("Keep LLVM linker target artifacts (.so/.dll/etc)"),
      llvm::cl::init(llvmTargetOptions.keepLinkerArtifacts));
  llvmTargetOptions.keepLinkerArtifacts = clKeepLinkerArtifacts;

  return llvmTargetOptions;
}

}  // namespace HAL
}  // namespace IREE
}  // namespace iree_compiler
}  // namespace mlir
<commit_msg>Add LLVM flags for controlling various llvm-opt options (#5002)<commit_after>// Copyright 2020 Google LLC
//
// 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
//
//      https://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

#include "iree/compiler/Dialect/HAL/Target/LLVM/LLVMTargetOptions.h"

#include "llvm/ADT/APFloat.h"
#include "llvm/MC/SubtargetFeature.h"
#include "llvm/Support/CommandLine.h"
#include "llvm/Support/Host.h"
#include "llvm/Target/TargetOptions.h"

namespace mlir {
namespace iree_compiler {
namespace IREE {
namespace HAL {

LLVMTargetOptions getDefaultLLVMTargetOptions() {
  LLVMTargetOptions targetOptions;

  // Host target triple.
  targetOptions.targetTriple = llvm::sys::getDefaultTargetTriple();
  targetOptions.targetCPU = llvm::sys::getHostCPUName().str();
  {
    llvm::SubtargetFeatures features;
    llvm::StringMap<bool> hostFeatures;
    if (llvm::sys::getHostCPUFeatures(hostFeatures)) {
      for (auto &feature : hostFeatures) {
        features.AddFeature(feature.first(), feature.second);
      }
    }
    targetOptions.targetCPUFeatures = features.getString();
  }

  // LLVM loop optimization options.
  targetOptions.pipelineTuningOptions.LoopInterleaving = true;
  targetOptions.pipelineTuningOptions.LoopVectorization = true;
  targetOptions.pipelineTuningOptions.LoopUnrolling = true;

  // LLVM SLP Auto vectorizer.
  targetOptions.pipelineTuningOptions.SLPVectorization = true;

  // LLVM -O3.
  // TODO(benvanik): add an option for this.
  targetOptions.optLevel = llvm::PassBuilder::OptimizationLevel::O3;
  targetOptions.options.FloatABIType = llvm::FloatABI::Hard;

  return targetOptions;
}

LLVMTargetOptions getLLVMTargetOptionsFromFlags() {
  auto llvmTargetOptions = getDefaultLLVMTargetOptions();

  static llvm::cl::opt<std::string> clTargetTriple(
      "iree-llvm-target-triple", llvm::cl::desc("LLVM target machine triple"),
      llvm::cl::init(llvmTargetOptions.targetTriple));
  static llvm::cl::opt<std::string> clTargetCPU(
      "iree-llvm-target-cpu",
      llvm::cl::desc(
          "LLVM target machine CPU; use 'host' for your host native CPU"),
      llvm::cl::init("generic"));
  static llvm::cl::opt<std::string> clTargetCPUFeatures(
      "iree-llvm-target-cpu-features",
      llvm::cl::desc("LLVM target machine CPU features; use 'host' for your "
                     "host native CPU"),
      llvm::cl::init(""));

  static llvm::cl::opt<bool> llvmLoopInterleaving(
      "iree-llvm-loop-interleaving", llvm::cl::init(false),
      llvm::cl::desc("Enable LLVM loop interleaving opt"));
  static llvm::cl::opt<bool> llvmLoopVectorization(
      "iree-llvm-loop-vectorization", llvm::cl::init(true),
      llvm::cl::desc("Enable LLVM loop vectorization opt"));
  static llvm::cl::opt<bool> llvmLoopUnrolling(
      "iree-llvm-loop-unrolling", llvm::cl::init(false),
      llvm::cl::desc("Enable LLVM loop unrolling opt"));
  static llvm::cl::opt<bool> llvmSLPVectorization(
      "iree-llvm-slp-vectorization", llvm::cl::init(false),
      llvm::cl::desc("Enable LLVM SLP Vectorization opt"));

  llvmTargetOptions.targetTriple = clTargetTriple;
  if (clTargetCPU != "host") {
    llvmTargetOptions.targetCPU = clTargetCPU;
  }
  if (clTargetCPUFeatures != "host") {
    llvmTargetOptions.targetCPUFeatures = clTargetCPUFeatures;
  }

  // LLVM opt options.
  llvmTargetOptions.pipelineTuningOptions.LoopInterleaving =
      llvmLoopInterleaving;
  llvmTargetOptions.pipelineTuningOptions.LoopVectorization =
      llvmLoopVectorization;
  llvmTargetOptions.pipelineTuningOptions.LoopUnrolling = llvmLoopUnrolling;
  llvmTargetOptions.pipelineTuningOptions.SLPVectorization =
      llvmSLPVectorization;

  static llvm::cl::opt<SanitizerKind> clSanitizerKind(
      "iree-llvm-sanitize", llvm::cl::desc("Apply LLVM sanitize feature"),
      llvm::cl::init(SanitizerKind::kNone),
      llvm::cl::values(clEnumValN(SanitizerKind::kAddress, "address",
                                  "Address sanitizer support")));
  llvmTargetOptions.sanitizerKind = clSanitizerKind;

  static llvm::cl::opt<std::string> clTargetABI(
      "iree-llvm-target-abi",
      llvm::cl::desc("LLVM target machine ABI; specify for -mabi"),
      llvm::cl::init(""));
  llvmTargetOptions.options.MCOptions.ABIName = clTargetABI;

  static llvm::cl::opt<llvm::FloatABI::ABIType> clTargetFloatABI(
      "iree-llvm-target-float-abi",
      llvm::cl::desc("LLVM target codegen enables soft float abi e.g "
                     "-mfloat-abi=softfp"),
      llvm::cl::init(llvmTargetOptions.options.FloatABIType),
      llvm::cl::values(
          clEnumValN(llvm::FloatABI::Default, "default", "Default (softfp)"),
          clEnumValN(llvm::FloatABI::Soft, "soft",
                     "Software floating-point emulation"),
          clEnumValN(llvm::FloatABI::Hard, "hard",
                     "Hardware floating-point instructions")));
  llvmTargetOptions.options.FloatABIType = clTargetFloatABI;

  static llvm::cl::opt<bool> clDebugSymbols(
      "iree-llvm-debug-symbols",
      llvm::cl::desc("Generate and embed debug information (DWARF, PDB, etc)"),
      llvm::cl::init(llvmTargetOptions.debugSymbols));
  llvmTargetOptions.debugSymbols = clDebugSymbols;

  static llvm::cl::opt<bool> clLinkStatic(
      "iree-llvm-link-static",
      llvm::cl::desc(
          "Links system libraries into binaries statically to isolate them "
          "from platform dependencies needed at runtime"),
      llvm::cl::init(llvmTargetOptions.linkStatic));
  llvmTargetOptions.linkStatic = clLinkStatic;

  static llvm::cl::opt<bool> clKeepLinkerArtifacts(
      "iree-llvm-keep-linker-artifacts",
      llvm::cl::desc("Keep LLVM linker target artifacts (.so/.dll/etc)"),
      llvm::cl::init(llvmTargetOptions.keepLinkerArtifacts));
  llvmTargetOptions.keepLinkerArtifacts = clKeepLinkerArtifacts;

  return llvmTargetOptions;
}

}  // namespace HAL
}  // namespace IREE
}  // namespace iree_compiler
}  // namespace mlir
<|endoftext|>


<commit_before>#pragma once
//=====================================================================//
/*! @file
    @brief  菊水電源インターフェース・クラス
    @author 平松邦仁 (hira@rvf-rc45.net)
	@copyright	Copyright (C) 2018 Kunihito Hiramatsu @n
				Released under the MIT license @n
				https://github.com/hirakuni45/RX/blob/master/LICENSE
*/
//=====================================================================//
#include <boost/format.hpp>
#include "utils/serial_win32.hpp"
#include "utils/fixed_fifo.hpp"
#include "utils/input.hpp"
#include "utils/string_utils.hpp"

namespace app {

	//+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++//
	/*!
		@brief  菊水電源インターフェース・クラス
	*/
	//+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++//
	class kikusui {

		device::serial_win32&	serial_;

		typedef utils::fixed_fifo<char, 1024> FIFO;
		FIFO		fifo_;

		enum class task {
			idle,
			volt,
			curr,
		};
		task		task_;

		float		volt_;
		float		curr_;

	   uint32_t		volt_id_;
	   uint32_t		curr_id_;

	public:
		//-----------------------------------------------------------------//
		/*!
			@brief  コンストラクター
		*/
		//-----------------------------------------------------------------//
		kikusui(device::serial_win32& serial) : serial_(serial),
			fifo_(), task_(task::idle), volt_(0.0f), curr_(0.0f),
			volt_id_(0), curr_id_(0)
		{ }

		//-----------------------------------------------------------------//
		/*!
			@brief  開始
		*/
		//-----------------------------------------------------------------//
		void start()
		{
			std::string s = "INST:NSEL 6\r\n";
			serial_.write(s.c_str(), s.size());
// std::cout << "Kikusui start" << std::endl;
		}

		//-----------------------------------------------------------------//
		/*!
			@brief  停止
		*/
		//-----------------------------------------------------------------//
		void stop()
		{
			std::string s = "CURR 0 A\r\n";
			serial_.write(s.c_str(), s.size());
			s = "VOLT 0 V\r\n";
			serial_.write(s.c_str(), s.size());
			s = "OUTP 0\r\n";
			serial_.write(s.c_str(), s.size());
		}

		//-----------------------------------------------------------------//
		/*!
			@brief  出力設定
			@param[in]	ena		許可の場合「true」
		*/
		//-----------------------------------------------------------------//
		void set_output(bool ena)
		{
			std::string s;
			if(ena) {
				s = "OUTP 1\r\n";
			} else {
				s = "OUTP 0\r\n";
			}
			serial_.write(s.c_str(), s.size());
// std::cout << s << std::flush;
		}

		//-----------------------------------------------------------------//
		/*!
			@brief  電圧設定
			@param[in]	volt	設定電圧
			@param[in]	curr	最大電流
		*/
		//-----------------------------------------------------------------//
		void set_volt(float volt, float curr)
		{
			auto s = (boost::format("CURR %5.4f A;VOLT %5.4f V\r\n") % curr % volt).str();
			serial_.write(s.c_str(), s.size());
std::cout << "VOLT: " << s << std::flush;
		}

		//-----------------------------------------------------------------//
		/*!
			@brief  電流設定
			@param[in]	curr	設定電流
			@param[in]	volt	最大電圧
		*/
		//-----------------------------------------------------------------//
		void set_curr(float curr, float volt)
		{
			auto s = (boost::format("VOLT %5.4f V;CURR %5.4f A\r\n") % volt % curr).str();
			serial_.write(s.c_str(), s.size());
std::cout << "CURR: " << s << std::flush;
		}

		//-----------------------------------------------------------------//
		/*!
			@brief  電圧測定要求
		*/
		//-----------------------------------------------------------------//
		void req_volt()
		{
			std::string s = "MEAS:VOLT:DC?\r\n";
			serial_.write(s.c_str(), s.size());
			task_ = task::volt;
		}

		//-----------------------------------------------------------------//
		/*!
			@brief  電流測定要求
		*/
		//-----------------------------------------------------------------//
		void req_curr()
		{
			std::string s = "MEAS:CURR:DC?\r\n";
			serial_.write(s.c_str(), s.size());
			task_ = task::curr;
		}

		//-----------------------------------------------------------------//
		/*!
			@brief  電流 ID を取得
			@return 電流 ID
		*/
		//-----------------------------------------------------------------//
		uint32_t get_curr_id() const { return curr_id_; }

		//-----------------------------------------------------------------//
		/*!
			@brief  電圧 ID を取得
			@return 電圧 ID
		*/
		//-----------------------------------------------------------------//
		uint32_t get_volt_id() const { return volt_id_; }

		//-----------------------------------------------------------------//
		/*!
			@brief  電圧を取得
			@return 電圧
		*/
		//-----------------------------------------------------------------//
		float get_volt() const { return volt_; }

		//-----------------------------------------------------------------//
		/*!
			@brief  電流を取得
			@return 電流
		*/
		//-----------------------------------------------------------------//
		float get_curr() const { return curr_; }

		//-----------------------------------------------------------------//
		/*!
			@brief  アップデート
		*/
		//-----------------------------------------------------------------//
		void update()
		{
			char tmp[256];
			auto rl = serial_.read(tmp, sizeof(tmp));
			for(uint32_t i = 0; i < rl; ++i) {
				fifo_.put(tmp[i]);
// std::cout << tmp[i] << std::endl;
			}
			switch(task_) {
			case task::volt:
				if(fifo_.length() >= 9) {
					std::string s;
					for(uint32_t i = 0; i < 9; ++i) {
						auto ch = fifo_.get();
						if(ch == '\r' || ch == '\n') ch = 0;
						s += ch;
					}
					if((utils::input("%f", s.c_str()) % volt_).status()) {
						++volt_id_;
					}
					task_ = task::idle;
				}
				break;

			case task::curr:
				if(fifo_.length() >= 9) {
					std::string s;
					for(uint32_t i = 0; i < 9; ++i) {
						auto ch = fifo_.get();
						if(ch == '\r' || ch == '\n') ch = 0;
						s += ch;
					}
std::cout << s << std::endl;
					if((utils::input("%f", s.c_str()) % curr_).status()) {
						++curr_id_;
					}
					task_ = task::idle;
				}
				break;

			case task::idle:
			default:
				while(fifo_.length() > 0) {
					fifo_.get();
				}
				break;
			}
		}
	};
}
<commit_msg>update: delay mesure management<commit_after>#pragma once
//=====================================================================//
/*! @file
    @brief  菊水電源インターフェース・クラス
    @author 平松邦仁 (hira@rvf-rc45.net)
	@copyright	Copyright (C) 2018 Kunihito Hiramatsu @n
				Released under the MIT license @n
				https://github.com/hirakuni45/RX/blob/master/LICENSE
*/
//=====================================================================//
#include <boost/format.hpp>
#include "utils/serial_win32.hpp"
#include "utils/fixed_fifo.hpp"
#include "utils/input.hpp"
#include "utils/string_utils.hpp"

namespace app {

	//+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++//
	/*!
		@brief  菊水電源インターフェース・クラス
	*/
	//+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++//
	class kikusui {

		device::serial_win32&	serial_;

		typedef utils::fixed_fifo<char, 1024> FIFO;
		FIFO		fifo_;

		enum class task {
			idle,
			volt,
			curr,
		};
		task		task_;

		float		volt_;
		float		curr_;

	   uint32_t		volt_id_;
	   uint32_t		curr_id_;

	public:
		//-----------------------------------------------------------------//
		/*!
			@brief  コンストラクター
		*/
		//-----------------------------------------------------------------//
		kikusui(device::serial_win32& serial) : serial_(serial),
			fifo_(), task_(task::idle), volt_(0.0f), curr_(0.0f),
			volt_id_(0), curr_id_(0)
		{ }

		//-----------------------------------------------------------------//
		/*!
			@brief  開始
		*/
		//-----------------------------------------------------------------//
		void start()
		{
			std::string s = "INST:NSEL 6\r\n";
			serial_.write(s.c_str(), s.size());
// std::cout << "Kikusui start" << std::endl;
		}

		//-----------------------------------------------------------------//
		/*!
			@brief  停止
		*/
		//-----------------------------------------------------------------//
		void stop()
		{
			std::string s = "CURR 0 A\r\n";
			serial_.write(s.c_str(), s.size());
			s = "VOLT 0 V\r\n";
			serial_.write(s.c_str(), s.size());
			s = "OUTP 0\r\n";
			serial_.write(s.c_str(), s.size());
		}

		//-----------------------------------------------------------------//
		/*!
			@brief  出力設定
			@param[in]	ena		許可の場合「true」
		*/
		//-----------------------------------------------------------------//
		void set_output(bool ena)
		{
			std::string s;
			if(ena) {
				s = "OUTP 1\r\n";
			} else {
				s = "OUTP 0\r\n";
			}
			serial_.write(s.c_str(), s.size());
// std::cout << s << std::flush;
		}

		//-----------------------------------------------------------------//
		/*!
			@brief  電圧設定
			@param[in]	volt	設定電圧
			@param[in]	curr	最大電流
		*/
		//-----------------------------------------------------------------//
		void set_volt(float volt, float curr)
		{
			auto s = (boost::format("CURR %5.4f A;VOLT %5.4f V\r\n") % curr % volt).str();
			serial_.write(s.c_str(), s.size());
// std::cout << "VOLT: " << s << std::flush;
		}

		//-----------------------------------------------------------------//
		/*!
			@brief  電流設定
			@param[in]	curr	設定電流
			@param[in]	volt	最大電圧
		*/
		//-----------------------------------------------------------------//
		void set_curr(float curr, float volt)
		{
			auto s = (boost::format("VOLT %5.4f V;CURR %5.4f A\r\n") % volt % curr).str();
			serial_.write(s.c_str(), s.size());
// std::cout << "CURR: " << s << std::flush;
		}

		//-----------------------------------------------------------------//
		/*!
			@brief  電圧測定要求
		*/
		//-----------------------------------------------------------------//
		void req_volt()
		{
			std::string s = "MEAS:VOLT:DC?\r\n";
			serial_.write(s.c_str(), s.size());
			task_ = task::volt;
		}

		//-----------------------------------------------------------------//
		/*!
			@brief  電流測定要求
		*/
		//-----------------------------------------------------------------//
		void req_curr()
		{
			std::string s = "MEAS:CURR:DC?\r\n";
			serial_.write(s.c_str(), s.size());
			task_ = task::curr;
		}

		//-----------------------------------------------------------------//
		/*!
			@brief  電流 ID を取得
			@return 電流 ID
		*/
		//-----------------------------------------------------------------//
		uint32_t get_curr_id() const { return curr_id_; }

		//-----------------------------------------------------------------//
		/*!
			@brief  電圧 ID を取得
			@return 電圧 ID
		*/
		//-----------------------------------------------------------------//
		uint32_t get_volt_id() const { return volt_id_; }

		//-----------------------------------------------------------------//
		/*!
			@brief  電圧を取得
			@return 電圧
		*/
		//-----------------------------------------------------------------//
		float get_volt() const { return volt_; }

		//-----------------------------------------------------------------//
		/*!
			@brief  電流を取得
			@return 電流
		*/
		//-----------------------------------------------------------------//
		float get_curr() const { return curr_; }

		//-----------------------------------------------------------------//
		/*!
			@brief  アップデート
		*/
		//-----------------------------------------------------------------//
		void update()
		{
			char tmp[256];
			auto rl = serial_.read(tmp, sizeof(tmp));
			for(uint32_t i = 0; i < rl; ++i) {
				fifo_.put(tmp[i]);
// std::cout << tmp[i] << std::endl;
			}
			switch(task_) {
			case task::volt:
				if(fifo_.length() >= 9) {
					std::string s;
					for(uint32_t i = 0; i < 9; ++i) {
						auto ch = fifo_.get();
						if(ch == '\r' || ch == '\n') ch = 0;
						s += ch;
					}
					if((utils::input("%f", s.c_str()) % volt_).status()) {
						++volt_id_;
					}
					task_ = task::idle;
				}
				break;

			case task::curr:
				if(fifo_.length() >= 9) {
					std::string s;
					for(uint32_t i = 0; i < 9; ++i) {
						auto ch = fifo_.get();
						if(ch == '\r' || ch == '\n') ch = 0;
						s += ch;
					}
std::cout << s << std::endl;
					if((utils::input("%f", s.c_str()) % curr_).status()) {
						++curr_id_;
					}
					task_ = task::idle;
				}
				break;

			case task::idle:
			default:
				while(fifo_.length() > 0) {
					fifo_.get();
				}
				break;
			}
		}
	};
}
<|endoftext|>


<commit_before><commit_msg>visual tweaks to CountdownMode<commit_after><|endoftext|>