<commit_before>/*
Copyright (c) 2013 Microsoft Corporation. All rights reserved.
Released under Apache 2.0 license as described in the file LICENSE.

Author: Leonardo de Moura
*/
#include <limits>
#include "util/exception.h"
#include "kernel/metavar.h"
#include "kernel/replace.h"
#include "kernel/free_vars.h"
#include "kernel/instantiate.h"
#include "kernel/occurs.h"
#include "kernel/for_each.h"

namespace lean {
void metavar_env::inc_timestamp() {
    if (m_timestamp == std::numeric_limits<unsigned>::max()) {
        // This should not happen in real examples. We add it just to be safe.
        throw exception("metavar_env timestamp overflow");
    }
    m_timestamp++;
}

metavar_env::metavar_env():m_timestamp(0) {}

expr metavar_env::mk_metavar(expr const & type, context const & ctx) {
    inc_timestamp();
    unsigned midx = m_env.size();
    m_env.push_back(data(type, ctx));
    return ::lean::mk_metavar(midx);
}

expr metavar_env::mk_metavar(context const & ctx) {
    return mk_metavar(expr(), ctx);
}

bool metavar_env::contains(unsigned midx) const {
    return midx < m_env.size();
}

bool metavar_env::is_assigned(unsigned midx) const {
    return m_env[midx].m_subst;
}

expr metavar_env::get_subst_core(unsigned midx) const {
    return m_env[midx].m_subst;
}

expr metavar_env::get_subst(unsigned midx) const {
    expr r = m_env[midx].m_subst;
    if (r && has_assigned_metavar(r, *this)) {
        r = instantiate_metavars(r, *this);
        expr t      = m_env[midx].m_type;
        context ctx = m_env[midx].m_ctx;
        const_cast<metavar_env*>(this)->m_env[midx] = data(r, t, ctx);
        return r;
    } else {
        return r;
    }
}

expr metavar_env::get_type(unsigned midx, unification_problems & up) {
    data const & d = m_env[midx];
    expr t = d.m_type;
    if (t) {
        return t;
    } else {
        t = mk_metavar();
        expr s = d.m_subst;
        m_env[midx] = data(s, t, d.m_ctx);
        if (s)
            up.add_type_of_eq(d.m_ctx, s, t);
        else
            up.add_type_of_eq(d.m_ctx, ::lean::mk_metavar(midx), t);
        return t;
    }
}

expr metavar_env::get_type(unsigned midx) const {
    return m_env[midx].m_type;
}

void metavar_env::assign(unsigned midx, expr const & v) {
    inc_timestamp();
    lean_assert(!is_assigned(midx));
    data const & d = m_env[midx];
    m_env[midx] = data(v, d.m_type, d.m_ctx);
}

context const & metavar_env::get_context(unsigned midx) const {
    return m_env[midx].m_ctx;
}

expr instantiate(expr const & s, meta_ctx const & ctx, metavar_env const & env) {
    if (ctx) {
        expr r = instantiate(s, tail(ctx), env);
        meta_entry const & e = head(ctx);
        if (e.is_lift()) {
            return lift_free_vars(r, e.s(), e.n());
        } else {
            lean_assert(e.is_inst());
            return ::lean::instantiate(r, e.s(), instantiate_metavars(e.v(), env));
        }
    } else {
        return s;
    }
}

expr metavar_env::get_subst(expr const & m) const {
    expr s = get_subst(metavar_idx(m));
    if (s)
        return instantiate(s, metavar_ctx(m), *this);
    else
        return s;
}

expr metavar_env::get_type(expr const & m, unification_problems & up) {
    expr s = get_type(metavar_idx(m), up);
    return instantiate(s, metavar_ctx(m), *this);
}

void metavar_env::assign(expr const & m, expr const & t) {
    lean_assert(!metavar_ctx(m));
    assign(metavar_idx(m), t);
}

expr instantiate_metavars(expr const & e, metavar_env const & env) {
    if (!has_metavar(e)) {
        return e;
    } else {
        auto f = [=](expr const & m, unsigned) -> expr {
            if (is_metavar(m) && env.contains(m)) {
                expr s = env.get_subst(m);
                return s ? s : m;
            } else {
                return m;
            }
        };
        return replace_fn<decltype(f)>(f)(e);
    }
}

meta_ctx add_lift(meta_ctx const & ctx, unsigned s, unsigned n) {
    if (n == 0) {
        return ctx;
    } else if (ctx) {
        meta_entry e = head(ctx);
        // Simplification rule
        //    lift:(s1+n1):n2 lift:s1:n1 --->  lift:s1:n1+n2
        if (e.is_lift() && s == e.s() + e.n()) {
            return add_lift(tail(ctx), e.s(), e.n() + n);
        }
    }
    return cons(mk_lift(s, n), ctx);
}

expr add_lift(expr const & m, unsigned s, unsigned n) {
    return mk_metavar(metavar_idx(m), add_lift(metavar_ctx(m), s, n));
}

meta_ctx add_inst(meta_ctx const & ctx, unsigned s, expr const & v) {
    if (ctx) {
        meta_entry e = head(ctx);
        if (e.is_lift() && e.s() <= s && s < e.s() + e.n()) {
            return add_lift(tail(ctx), e.s(), e.n() - 1);
        }
        // Simplifications such as
        //   inst:4 #6  lift:5:3  -->  lift:4:2
        //   inst:3 #7  lift:4:5 -->   lift:3:4
        // General rule is:
        //   inst:(s-1) #(s+n-2)  lift:s:n  --> lift:s-1:n-1
        if (e.is_lift() && is_var(v) && e.s() > 0 && s == e.s() - 1 && e.s() + e.n() > 2 && var_idx(v) == e.s() + e.n() - 2) {
            return add_lift(tail(ctx), e.s() - 1, e.n() - 1);
        }
    }
    return cons(mk_inst(s, v), ctx);
}

expr add_inst(expr const & m, unsigned s, expr const & v) {
    return mk_metavar(metavar_idx(m), add_inst(metavar_ctx(m), s, v));
}

bool has_meta_context(expr const & m) {
    return metavar_ctx(m);
}

expr pop_meta_context(expr const & m) {
    lean_assert(has_meta_context(m));
    return mk_metavar(metavar_idx(m), tail(metavar_ctx(m)));
}

struct found_assigned {};
bool has_assigned_metavar(expr const & e, metavar_env const & menv) {
    if (!has_metavar(e)) {
        return false;
    } else {
        auto proc = [&](expr const & n, unsigned) {
            if (is_metavar(n) && menv.contains(n) && menv.is_assigned(n))
                throw found_assigned();
        };
        for_each_fn<decltype(proc)> visitor(proc);
        try {
            visitor(e);
            return false;
        } catch (found_assigned&) {
            return true;
        }
    }
}

/**
   \brief Auxiliary exception used to sign that a metavariable was
   found in an expression.
*/
struct found_metavar {};

bool has_metavar(expr const & e, unsigned midx, metavar_env const & menv) {
    auto f = [&](expr const & m, unsigned) {
        if (is_metavar(m)) {
            unsigned midx2 = metavar_idx(m);
            if (midx2 == midx)
                throw found_metavar();
            if (menv.contains(midx2) &&
                menv.is_assigned(midx2) &&
                has_metavar(menv.get_subst(midx2), midx, menv))
                throw found_metavar();
        }
    };
    try {
        for_each_fn<decltype(f)> proc(f);
        proc(e);
        return false;
    } catch (found_metavar) {
        return true;
    }
}
}
<commit_msg>Fix memory corruption bug<commit_after>/*
Copyright (c) 2013 Microsoft Corporation. All rights reserved.
Released under Apache 2.0 license as described in the file LICENSE.

Author: Leonardo de Moura
*/
#include <limits>
#include "util/exception.h"
#include "kernel/metavar.h"
#include "kernel/replace.h"
#include "kernel/free_vars.h"
#include "kernel/instantiate.h"
#include "kernel/occurs.h"
#include "kernel/for_each.h"

namespace lean {
void metavar_env::inc_timestamp() {
    if (m_timestamp == std::numeric_limits<unsigned>::max()) {
        // This should not happen in real examples. We add it just to be safe.
        throw exception("metavar_env timestamp overflow");
    }
    m_timestamp++;
}

metavar_env::metavar_env():m_timestamp(0) {}

expr metavar_env::mk_metavar(expr const & type, context const & ctx) {
    inc_timestamp();
    unsigned midx = m_env.size();
    m_env.push_back(data(type, ctx));
    return ::lean::mk_metavar(midx);
}

expr metavar_env::mk_metavar(context const & ctx) {
    return mk_metavar(expr(), ctx);
}

bool metavar_env::contains(unsigned midx) const {
    return midx < m_env.size();
}

bool metavar_env::is_assigned(unsigned midx) const {
    return m_env[midx].m_subst;
}

expr metavar_env::get_subst_core(unsigned midx) const {
    return m_env[midx].m_subst;
}

expr metavar_env::get_subst(unsigned midx) const {
    expr r = m_env[midx].m_subst;
    if (r && has_assigned_metavar(r, *this)) {
        r = instantiate_metavars(r, *this);
        expr t      = m_env[midx].m_type;
        context ctx = m_env[midx].m_ctx;
        const_cast<metavar_env*>(this)->m_env[midx] = data(r, t, ctx);
        return r;
    } else {
        return r;
    }
}

expr metavar_env::get_type(unsigned midx, unification_problems & up) {
    data d = m_env[midx];
    expr t = d.m_type;
    if (t) {
        return t;
    } else {
        t = mk_metavar();
        expr s = d.m_subst;
        m_env[midx] = data(s, t, d.m_ctx);
        if (s)
            up.add_type_of_eq(d.m_ctx, s, t);
        else
            up.add_type_of_eq(d.m_ctx, ::lean::mk_metavar(midx), t);
        return t;
    }
}

expr metavar_env::get_type(unsigned midx) const {
    return m_env[midx].m_type;
}

void metavar_env::assign(unsigned midx, expr const & v) {
    inc_timestamp();
    lean_assert(!is_assigned(midx));
    data const & d = m_env[midx];
    m_env[midx] = data(v, d.m_type, d.m_ctx);
}

context const & metavar_env::get_context(unsigned midx) const {
    return m_env[midx].m_ctx;
}

expr instantiate(expr const & s, meta_ctx const & ctx, metavar_env const & env) {
    if (ctx) {
        expr r = instantiate(s, tail(ctx), env);
        meta_entry const & e = head(ctx);
        if (e.is_lift()) {
            return lift_free_vars(r, e.s(), e.n());
        } else {
            lean_assert(e.is_inst());
            return ::lean::instantiate(r, e.s(), instantiate_metavars(e.v(), env));
        }
    } else {
        return s;
    }
}

expr metavar_env::get_subst(expr const & m) const {
    expr s = get_subst(metavar_idx(m));
    if (s)
        return instantiate(s, metavar_ctx(m), *this);
    else
        return s;
}

expr metavar_env::get_type(expr const & m, unification_problems & up) {
    expr s = get_type(metavar_idx(m), up);
    return instantiate(s, metavar_ctx(m), *this);
}

void metavar_env::assign(expr const & m, expr const & t) {
    lean_assert(!metavar_ctx(m));
    assign(metavar_idx(m), t);
}

expr instantiate_metavars(expr const & e, metavar_env const & env) {
    if (!has_metavar(e)) {
        return e;
    } else {
        auto f = [=](expr const & m, unsigned) -> expr {
            if (is_metavar(m) && env.contains(m)) {
                expr s = env.get_subst(m);
                return s ? s : m;
            } else {
                return m;
            }
        };
        return replace_fn<decltype(f)>(f)(e);
    }
}

meta_ctx add_lift(meta_ctx const & ctx, unsigned s, unsigned n) {
    if (n == 0) {
        return ctx;
    } else if (ctx) {
        meta_entry e = head(ctx);
        // Simplification rule
        //    lift:(s1+n1):n2 lift:s1:n1 --->  lift:s1:n1+n2
        if (e.is_lift() && s == e.s() + e.n()) {
            return add_lift(tail(ctx), e.s(), e.n() + n);
        }
    }
    return cons(mk_lift(s, n), ctx);
}

expr add_lift(expr const & m, unsigned s, unsigned n) {
    return mk_metavar(metavar_idx(m), add_lift(metavar_ctx(m), s, n));
}

meta_ctx add_inst(meta_ctx const & ctx, unsigned s, expr const & v) {
    if (ctx) {
        meta_entry e = head(ctx);
        if (e.is_lift() && e.s() <= s && s < e.s() + e.n()) {
            return add_lift(tail(ctx), e.s(), e.n() - 1);
        }
        // Simplifications such as
        //   inst:4 #6  lift:5:3  -->  lift:4:2
        //   inst:3 #7  lift:4:5 -->   lift:3:4
        // General rule is:
        //   inst:(s-1) #(s+n-2)  lift:s:n  --> lift:s-1:n-1
        if (e.is_lift() && is_var(v) && e.s() > 0 && s == e.s() - 1 && e.s() + e.n() > 2 && var_idx(v) == e.s() + e.n() - 2) {
            return add_lift(tail(ctx), e.s() - 1, e.n() - 1);
        }
    }
    return cons(mk_inst(s, v), ctx);
}

expr add_inst(expr const & m, unsigned s, expr const & v) {
    return mk_metavar(metavar_idx(m), add_inst(metavar_ctx(m), s, v));
}

bool has_meta_context(expr const & m) {
    return metavar_ctx(m);
}

expr pop_meta_context(expr const & m) {
    lean_assert(has_meta_context(m));
    return mk_metavar(metavar_idx(m), tail(metavar_ctx(m)));
}

struct found_assigned {};
bool has_assigned_metavar(expr const & e, metavar_env const & menv) {
    if (!has_metavar(e)) {
        return false;
    } else {
        auto proc = [&](expr const & n, unsigned) {
            if (is_metavar(n) && menv.contains(n) && menv.is_assigned(n))
                throw found_assigned();
        };
        for_each_fn<decltype(proc)> visitor(proc);
        try {
            visitor(e);
            return false;
        } catch (found_assigned&) {
            return true;
        }
    }
}

/**
   \brief Auxiliary exception used to sign that a metavariable was
   found in an expression.
*/
struct found_metavar {};

bool has_metavar(expr const & e, unsigned midx, metavar_env const & menv) {
    auto f = [&](expr const & m, unsigned) {
        if (is_metavar(m)) {
            unsigned midx2 = metavar_idx(m);
            if (midx2 == midx)
                throw found_metavar();
            if (menv.contains(midx2) &&
                menv.is_assigned(midx2) &&
                has_metavar(menv.get_subst(midx2), midx, menv))
                throw found_metavar();
        }
    };
    try {
        for_each_fn<decltype(f)> proc(f);
        proc(e);
        return false;
    } catch (found_metavar) {
        return true;
    }
}
}
<|endoftext|>


<commit_before>
//ros dependencies
#include "bfly_camera_node.h"

//node main
int main(int argc, char **argv)
{
      //init ros
      ros::init(argc, argv, "bfly_camera_node");

      //create ros wrapper object
      BflyCameraNode bfly;

      //set node loop rate
      ros::Rate loop_rate(bfly.rate());

      //node loop
      while ( ros::ok() )
      {
            //execute pending callbacks
            ros::spinOnce();

            //switch according run mode
            switch(bfly.runMode())
            {
                case SERVER:
                    //nothing to do, ROS spin will do the job
                    break;

                case PUBLISHER:
                    //just publish the cloud
                    bfly.publish();
                    break;

                default:
                    break;
            }

            //relax to fit output rate
            loop_rate.sleep();
      }

      //exit program
      return 0;
}
<commit_msg>main switch cahnged. Now server mode runs with ros::spin() and publisher mode with ros::spinOnce()<commit_after>
//ros dependencies
#include "bfly_camera_node.h"

//node main
int main(int argc, char **argv)
{
    //init ros
    ros::init(argc, argv, "bfly_camera_node");

    //create ros wrapper object
    BflyCameraNode bfly;

    //set node loop rate
    ros::Rate loop_rate(bfly.rate());

    switch(bfly.runMode())
    {
        case SERVER: //just spin to give service
            ros::spin();
            break;

        case PUBLISHER: //publish loop
            while ( ros::ok() )
            {
                //execute pending callbacks
                ros::spinOnce();

                //just publish the cloud
                bfly.publish();

                //relax to fit output rate
                loop_rate.sleep();
            }
            break;

        default:
            break;
    }

    //exit program
    return 0;
}
<|endoftext|>


<commit_before>/*
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation; either version 3 of the License, or
 * (at your option) any later version.
 *
 * Written (W) 2012 Chiyuan Zhang
 * Copyright (C) 2012 Chiyuan Zhang
 */

#include <algorithm>

#include <shogun/lib/Time.h>
#include <shogun/mathematics/Math.h>
#include <shogun/multiclass/ShareBoost.h>
#include <shogun/multiclass/ShareBoostOptimizer.h>
#include <shogun/features/DenseSubsetFeatures.h>
#include <shogun/labels/RegressionLabels.h>

using namespace shogun;

CShareBoost::CShareBoost()
	:CLinearMulticlassMachine(), m_nonzero_feas(0)
{
	init_sb_params();
}

CShareBoost::CShareBoost(CDenseFeatures<float64_t> *features, CMulticlassLabels *labs, int32_t num_nonzero_feas)
	:CLinearMulticlassMachine(new CMulticlassOneVsRestStrategy(), features, NULL, labs), m_nonzero_feas(num_nonzero_feas)
{
	init_sb_params();
}

void CShareBoost::init_sb_params()
{
	SG_ADD(&m_nonzero_feas, "m_nonzero_feas", "Number of non-zero features", MS_NOT_AVAILABLE);
}

SGVector<int32_t> CShareBoost::get_activeset()
{
	return m_activeset.clone();
}

bool CShareBoost::train_machine(CFeatures* data)
{
	if (data)
		set_features(data);

	if (m_features == NULL)
		SG_ERROR("No features given for training\n");
	if (m_labels == NULL)
		SG_ERROR("No labels given for training\n");

	if (m_nonzero_feas <= 0)
		SG_ERROR("Set a valid (> 0) number of non-zero features to seek before training\n");
	if (m_nonzero_feas >= dynamic_cast<CDenseFeatures<float64_t>*>(m_features)->get_num_features())
		SG_ERROR("It doesn't make sense to use ShareBoost with num non-zero features >= num features in the data\n");

	m_fea = dynamic_cast<CDenseFeatures<float64_t> *>(m_features)->get_feature_matrix();
	m_rho = SGMatrix<float64_t>(m_multiclass_strategy->get_num_classes(), m_fea.num_cols);
	m_rho_norm = SGVector<float64_t>(m_fea.num_cols);
	m_pred = SGMatrix<float64_t>(m_fea.num_cols, m_multiclass_strategy->get_num_classes());
	m_pred.zero();

	m_activeset = SGVector<int32_t>(m_fea.num_rows);
	m_activeset.vlen = 0;

	m_machines->reset_array();
	for (int32_t i=0; i < m_multiclass_strategy->get_num_classes(); ++i)
		m_machines->push_back(new CLinearMachine());

	CTime *timer = new CTime();

	float64_t t_compute_pred = 0; // t of 1st round is 0, since no pred to compute
	for (int32_t t=0; t < m_nonzero_feas; ++t)
	{
		timer->start();
		compute_rho();
		int32_t i_fea = choose_feature();
		m_activeset.vector[m_activeset.vlen] = i_fea;
		m_activeset.vlen += 1;
		float64_t t_choose_feature = timer->cur_time_diff();
		timer->start();
		optimize_coefficients();
		float64_t t_optimize = timer->cur_time_diff();

		SG_SPRINT(" SB[round %03d]: (%8.4f + %8.4f) sec.\n", t,
				float64_t(t_compute_pred + t_choose_feature),
				float64_t(t_optimize));

		timer->start();
		compute_pred();
		t_compute_pred = timer->cur_time_diff();
	}

	SG_UNREF(timer);

	// release memory
	m_fea = SGMatrix<float64_t>();
	m_rho = SGMatrix<float64_t>();
	m_rho_norm = SGVector<float64_t>();
	m_pred = SGMatrix<float64_t>();

	return true;
}

void CShareBoost::compute_pred()
{
	CDenseFeatures<float64_t> *fea = dynamic_cast<CDenseFeatures<float64_t> *>(m_features);
	CDenseSubsetFeatures<float64_t> *subset_fea = new CDenseSubsetFeatures<float64_t>(fea, m_activeset);
	SG_REF(subset_fea);
	for (int32_t i=0; i < m_multiclass_strategy->get_num_classes(); ++i)
	{
		CLinearMachine *machine = dynamic_cast<CLinearMachine *>(m_machines->get_element(i));
		CRegressionLabels *lab = machine->apply_regression(subset_fea);
		SGVector<float64_t> lab_raw = lab->get_labels();
		std::copy(lab_raw.vector, lab_raw.vector + lab_raw.vlen, m_pred.get_column_vector(i));
		SG_UNREF(machine);
		SG_UNREF(lab);
	}
	SG_UNREF(subset_fea);
}

void CShareBoost::compute_pred(const float64_t *W)
{
	int32_t w_len = m_activeset.vlen;

	for (int32_t i=0; i < m_multiclass_strategy->get_num_classes(); ++i)
	{
		CLinearMachine *machine = dynamic_cast<CLinearMachine *>(m_machines->get_element(i));
		SGVector<float64_t> w(w_len);
		std::copy(W + i*w_len, W + (i+1)*w_len, w.vector);
		machine->set_w(w);
		SG_UNREF(machine);
	}
	compute_pred();
}

void CShareBoost::compute_rho()
{
	CMulticlassLabels *lab = dynamic_cast<CMulticlassLabels *>(m_labels);
	for (int32_t i=0; i < m_rho.num_rows; ++i)
	{ // i loop classes
		for (int32_t j=0; j < m_rho.num_cols; ++j)
		{ // j loop samples
			int32_t label = lab->get_int_label(j);

			m_rho(i,j) = CMath::exp((label == i) - m_pred(j, label) + m_pred(j, i));
		}
	}

	// normalize
	for (int32_t j=0; j < m_rho.num_cols; ++j)
	{
		m_rho_norm[j] = 0;
		for (int32_t i=0; i < m_rho.num_rows; ++i)
			m_rho_norm[j] += m_rho(i,j);
	}
}

int32_t CShareBoost::choose_feature()
{
	SGVector<float64_t> l1norm(m_fea.num_rows);
	for (int32_t j=0; j < m_fea.num_rows; ++j)
	{
		if (std::find(&m_activeset[0], &m_activeset[m_activeset.vlen], j) !=
				&m_activeset[m_activeset.vlen])
		{
			l1norm[j] = 0;
		}
		else
		{
			l1norm[j] = 0;
			CMulticlassLabels *lab = dynamic_cast<CMulticlassLabels *>(m_labels);
			for (int32_t k=0; k < m_multiclass_strategy->get_num_classes(); ++k)
			{
				float64_t abssum = 0;
				for (int32_t ii=0; ii < m_fea.num_cols; ++ii)
				{
					abssum += m_fea(j, ii)*(m_rho(k, ii)/m_rho_norm[ii] -
							(j == lab->get_int_label(ii)));
				}
				l1norm[j] += CMath::abs(abssum);
			}
			l1norm[j] /= m_fea.num_cols;
		}
	}

	return SGVector<float64_t>::arg_max(l1norm.vector, 1, l1norm.vlen);
}

void CShareBoost::optimize_coefficients()
{
	ShareBoostOptimizer optimizer(this, false);
	optimizer.optimize();
}

void CShareBoost::set_features(CFeatures *f)
{
	CDenseFeatures<float64_t> *fea = dynamic_cast<CDenseFeatures<float64_t> *>(f);
	if (fea == NULL)
		SG_ERROR("Require DenseFeatures<float64_t>\n");
	CLinearMulticlassMachine::set_features(fea);
}
<commit_msg>remove unnecessary type casts.<commit_after>/*
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation; either version 3 of the License, or
 * (at your option) any later version.
 *
 * Written (W) 2012 Chiyuan Zhang
 * Copyright (C) 2012 Chiyuan Zhang
 */

#include <algorithm>

#include <shogun/lib/Time.h>
#include <shogun/mathematics/Math.h>
#include <shogun/multiclass/ShareBoost.h>
#include <shogun/multiclass/ShareBoostOptimizer.h>
#include <shogun/features/DenseSubsetFeatures.h>
#include <shogun/labels/RegressionLabels.h>

using namespace shogun;

CShareBoost::CShareBoost()
	:CLinearMulticlassMachine(), m_nonzero_feas(0)
{
	init_sb_params();
}

CShareBoost::CShareBoost(CDenseFeatures<float64_t> *features, CMulticlassLabels *labs, int32_t num_nonzero_feas)
	:CLinearMulticlassMachine(new CMulticlassOneVsRestStrategy(), features, NULL, labs), m_nonzero_feas(num_nonzero_feas)
{
	init_sb_params();
}

void CShareBoost::init_sb_params()
{
	SG_ADD(&m_nonzero_feas, "m_nonzero_feas", "Number of non-zero features", MS_NOT_AVAILABLE);
}

SGVector<int32_t> CShareBoost::get_activeset()
{
	return m_activeset.clone();
}

bool CShareBoost::train_machine(CFeatures* data)
{
	if (data)
		set_features(data);

	if (m_features == NULL)
		SG_ERROR("No features given for training\n");
	if (m_labels == NULL)
		SG_ERROR("No labels given for training\n");

	if (m_nonzero_feas <= 0)
		SG_ERROR("Set a valid (> 0) number of non-zero features to seek before training\n");
	if (m_nonzero_feas >= dynamic_cast<CDenseFeatures<float64_t>*>(m_features)->get_num_features())
		SG_ERROR("It doesn't make sense to use ShareBoost with num non-zero features >= num features in the data\n");

	m_fea = dynamic_cast<CDenseFeatures<float64_t> *>(m_features)->get_feature_matrix();
	m_rho = SGMatrix<float64_t>(m_multiclass_strategy->get_num_classes(), m_fea.num_cols);
	m_rho_norm = SGVector<float64_t>(m_fea.num_cols);
	m_pred = SGMatrix<float64_t>(m_fea.num_cols, m_multiclass_strategy->get_num_classes());
	m_pred.zero();

	m_activeset = SGVector<int32_t>(m_fea.num_rows);
	m_activeset.vlen = 0;

	m_machines->reset_array();
	for (int32_t i=0; i < m_multiclass_strategy->get_num_classes(); ++i)
		m_machines->push_back(new CLinearMachine());

	CTime *timer = new CTime();

	float64_t t_compute_pred = 0; // t of 1st round is 0, since no pred to compute
	for (int32_t t=0; t < m_nonzero_feas; ++t)
	{
		timer->start();
		compute_rho();
		int32_t i_fea = choose_feature();
		m_activeset.vector[m_activeset.vlen] = i_fea;
		m_activeset.vlen += 1;
		float64_t t_choose_feature = timer->cur_time_diff();
		timer->start();
		optimize_coefficients();
		float64_t t_optimize = timer->cur_time_diff();

		SG_SPRINT(" SB[round %03d]: (%8.4f + %8.4f) sec.\n", t,
				t_compute_pred + t_choose_feature, t_optimize);

		timer->start();
		compute_pred();
		t_compute_pred = timer->cur_time_diff();
	}

	SG_UNREF(timer);

	// release memory
	m_fea = SGMatrix<float64_t>();
	m_rho = SGMatrix<float64_t>();
	m_rho_norm = SGVector<float64_t>();
	m_pred = SGMatrix<float64_t>();

	return true;
}

void CShareBoost::compute_pred()
{
	CDenseFeatures<float64_t> *fea = dynamic_cast<CDenseFeatures<float64_t> *>(m_features);
	CDenseSubsetFeatures<float64_t> *subset_fea = new CDenseSubsetFeatures<float64_t>(fea, m_activeset);
	SG_REF(subset_fea);
	for (int32_t i=0; i < m_multiclass_strategy->get_num_classes(); ++i)
	{
		CLinearMachine *machine = dynamic_cast<CLinearMachine *>(m_machines->get_element(i));
		CRegressionLabels *lab = machine->apply_regression(subset_fea);
		SGVector<float64_t> lab_raw = lab->get_labels();
		std::copy(lab_raw.vector, lab_raw.vector + lab_raw.vlen, m_pred.get_column_vector(i));
		SG_UNREF(machine);
		SG_UNREF(lab);
	}
	SG_UNREF(subset_fea);
}

void CShareBoost::compute_pred(const float64_t *W)
{
	int32_t w_len = m_activeset.vlen;

	for (int32_t i=0; i < m_multiclass_strategy->get_num_classes(); ++i)
	{
		CLinearMachine *machine = dynamic_cast<CLinearMachine *>(m_machines->get_element(i));
		SGVector<float64_t> w(w_len);
		std::copy(W + i*w_len, W + (i+1)*w_len, w.vector);
		machine->set_w(w);
		SG_UNREF(machine);
	}
	compute_pred();
}

void CShareBoost::compute_rho()
{
	CMulticlassLabels *lab = dynamic_cast<CMulticlassLabels *>(m_labels);
	for (int32_t i=0; i < m_rho.num_rows; ++i)
	{ // i loop classes
		for (int32_t j=0; j < m_rho.num_cols; ++j)
		{ // j loop samples
			int32_t label = lab->get_int_label(j);

			m_rho(i,j) = CMath::exp((label == i) - m_pred(j, label) + m_pred(j, i));
		}
	}

	// normalize
	for (int32_t j=0; j < m_rho.num_cols; ++j)
	{
		m_rho_norm[j] = 0;
		for (int32_t i=0; i < m_rho.num_rows; ++i)
			m_rho_norm[j] += m_rho(i,j);
	}
}

int32_t CShareBoost::choose_feature()
{
	SGVector<float64_t> l1norm(m_fea.num_rows);
	for (int32_t j=0; j < m_fea.num_rows; ++j)
	{
		if (std::find(&m_activeset[0], &m_activeset[m_activeset.vlen], j) !=
				&m_activeset[m_activeset.vlen])
		{
			l1norm[j] = 0;
		}
		else
		{
			l1norm[j] = 0;
			CMulticlassLabels *lab = dynamic_cast<CMulticlassLabels *>(m_labels);
			for (int32_t k=0; k < m_multiclass_strategy->get_num_classes(); ++k)
			{
				float64_t abssum = 0;
				for (int32_t ii=0; ii < m_fea.num_cols; ++ii)
				{
					abssum += m_fea(j, ii)*(m_rho(k, ii)/m_rho_norm[ii] -
							(j == lab->get_int_label(ii)));
				}
				l1norm[j] += CMath::abs(abssum);
			}
			l1norm[j] /= m_fea.num_cols;
		}
	}

	return SGVector<float64_t>::arg_max(l1norm.vector, 1, l1norm.vlen);
}

void CShareBoost::optimize_coefficients()
{
	ShareBoostOptimizer optimizer(this, false);
	optimizer.optimize();
}

void CShareBoost::set_features(CFeatures *f)
{
	CDenseFeatures<float64_t> *fea = dynamic_cast<CDenseFeatures<float64_t> *>(f);
	if (fea == NULL)
		SG_ERROR("Require DenseFeatures<float64_t>\n");
	CLinearMulticlassMachine::set_features(fea);
}
<|endoftext|>


<commit_before>// This example computes the eigenvalues of largest magnitude of an
// eigenvalue problem $A x = \lambda x$, using Anasazi's
// implementation of the Block Davidson method.

#include "sparse_matrix.h"
#include "vertex.h"
#include "vertex_index.h"
#include "in_mem_storage.h"
#include "io_interface.h"

// Include header for block Davidson eigensolver
#include "AnasaziBlockDavidsonSolMgr.hpp"
// Include header to define eigenproblem Ax = \lambda*x
#include "AnasaziBasicEigenproblem.hpp"
#include "AnasaziOperator.hpp"
#include "AnasaziTpetraAdapter.hpp"
#include "Tpetra_Map.hpp"
#include "Tpetra_MultiVector.hpp"
#include "Tpetra_DefaultPlatform.hpp"
#include "Tpetra_CrsMatrix_decl.hpp"
#include "Tpetra_CrsMatrix_def.hpp"

// ****************************************************************************
// BEGIN MAIN ROUTINE
// ****************************************************************************

using namespace fm;

using Teuchos::RCP;
using Teuchos::rcp;
using Teuchos::ArrayRCP;
using std::cerr;
using std::cout;
using std::endl;

std::atomic<size_t> iter_no;

typedef fg::vsize_t local_ordinal_type;
typedef fg::vsize_t global_ordinal_type;

typedef Tpetra::DefaultPlatform::DefaultPlatformType::NodeType  Node;
typedef Tpetra::MultiVector<double, global_ordinal_type, global_ordinal_type, Node> MV;
typedef Tpetra::Operator<double, global_ordinal_type, global_ordinal_type, Node> OP;
typedef Anasazi::OperatorTraits<double, MV, OP> OPT;

typedef Tpetra::Map<local_ordinal_type, global_ordinal_type, Node> map_type;
typedef Tpetra::CrsMatrix<double, local_ordinal_type, global_ordinal_type> crs_matrix_type;

size_t edge_data_size = 0;

ArrayRCP<size_t> getNumEntriesPerRow(fg::vertex_index::ptr index,
		size_t &num_rows)
{
	fg::in_mem_query_vertex_index::ptr query_index
		= fg::in_mem_query_vertex_index::create(index, false);

	ArrayRCP<size_t> numEntries(index->get_num_vertices());
	for (size_t i = 0; i < index->get_num_vertices(); i++)
		numEntries[i] = query_index->get_num_edges(i, fg::edge_type::IN_EDGE);

	num_rows = index->get_num_vertices();
	return numEntries;
}

RCP<crs_matrix_type> create_crs(fg::in_mem_graph::ptr g,
		fg::vertex_index::ptr index, RCP<map_type> map)
{
	safs::io_interface::ptr io = create_io(g->create_io_factory(),
			thread::get_curr_thread());
	const size_t numMyElements = map->getNodeNumElements ();

	size_t numRows;
	ArrayRCP<const size_t> numEntriesPerRow = getNumEntriesPerRow(index, numRows);
	assert(numRows == numMyElements);
	// Create a Tpetra sparse matrix whose rows have distribution given by the Map.
	RCP<crs_matrix_type> A (new crs_matrix_type (map, numEntriesPerRow,
				Tpetra::ProfileType::StaticProfile));

	const size_t vheader_size = fg::ext_mem_undirected_vertex::get_header_size();
	char vheader_buf[vheader_size];
	const fg::ext_mem_undirected_vertex *vheader
		= (const fg::ext_mem_undirected_vertex *) vheader_buf;
	off_t off = fg::graph_header::get_header_size();
	// Fill the sparse matrix, one row at a time.
	for (local_ordinal_type lclRow = 0;
			lclRow < static_cast<local_ordinal_type> (numMyElements); ++lclRow) {
		io->access(vheader_buf, off, vheader_size, READ);
		fg::vsize_t num_edges = vheader->get_num_edges();
		assert(num_edges > 0);
		size_t size = fg::ext_mem_undirected_vertex::num_edges2vsize(num_edges,
				edge_data_size);
		std::unique_ptr<char[]> buf(new char[size]);
		io->access(buf.get(), off, size, READ);

		const fg::ext_mem_undirected_vertex *v
			= (const fg::ext_mem_undirected_vertex *) buf.get();
		std::vector<global_ordinal_type> cols(num_edges);
		std::vector<double> vals(num_edges);
		for (fg::vsize_t i = 0; i < num_edges; i++) {
			cols[i] = v->get_neighbor(i);
			vals[i] = 1;
		}
		const global_ordinal_type gblRow = map->getGlobalElement (lclRow);
		A->insertGlobalValues (gblRow, cols, vals);
		off += size;
	}

	// Tell the sparse matrix that we are done adding entries to it.
	A->fillComplete ();
	return A;
}

int main (int argc, char *argv[])
{

	if (argc < 5) {
		fprintf(stderr, "eigensolver conf_file graph_file index_file nev\n");
		exit(1);
	}

	std::string conf_file = argv[1];
	std::string graph_file = argv[2];
	std::string index_file = argv[3];
	int nev = atoi(argv[4]); // number of eigenvalues for which to solve

	// Anasazi solvers have the following template parameters:
	//
	//   - Scalar: The type of dot product results.
	//   - MV: The type of (multi)vectors.
	//   - OP: The type of operators (functions from multivector to
	//     multivector).  A matrix (like Epetra_CrsMatrix) is an example
	//     of an operator; an Ifpack preconditioner is another example.
	//
	// Here, Scalar is double, MV is Tpetra::MultiVector, and OP is FMTp_Operator.
	typedef Anasazi::MultiVecTraits<double, MV> MVT;
	typedef Tpetra::DefaultPlatform::DefaultPlatformType Platform;

	//
	// Set up the test problem.
	//
	config_map::ptr configs = config_map::create(conf_file);
	init_flash_matrix(configs);

	fg::FG_graph::ptr fg = fg::FG_graph::create(graph_file, index_file, configs);

	// Set eigensolver parameters.
	const double tol = 1.0e-12; // convergence tolerance
	const int blockSize = nev + 1; // block size (number of eigenvectors processed at once)
	const int numBlocks = 3; // restart length
	const int maxRestarts = 100; // maximum number of restart cycles

	Platform &platform = Tpetra::DefaultPlatform::getDefaultPlatform();
	RCP<const Teuchos::Comm<int> > comm = platform.getComm();
	RCP<map_type> Map = rcp (new map_type(
				fg->get_graph_header().get_num_vertices(), 0, comm));
	RCP<crs_matrix_type> A = create_crs(fg->get_graph_data(), fg->get_index_data(), Map);
	// Create a set of initial vectors to start the eigensolver.
	// This needs to have the same number of columns as the block size.
	RCP<MV> ivec = rcp (new MV (Map, (size_t) blockSize));
	ivec->randomize ();

	// Create the eigenproblem.  This object holds all the stuff about
	// your problem that Anasazi will see.  In this case, it knows about
	// the matrix A and the inital vectors.
	RCP<Anasazi::BasicEigenproblem<double, MV, OP> > problem =
		rcp (new Anasazi::BasicEigenproblem<double, MV, OP> (A, ivec));

	// Tell the eigenproblem that the operator A is symmetric.
	problem->setHermitian (true);

	// Set the number of eigenvalues requested
	problem->setNEV (nev);

	// Tell the eigenproblem that you are finishing passing it information.
	const bool boolret = problem->setProblem();
	if (boolret != true) {
		cerr << "Anasazi::BasicEigenproblem::setProblem() returned an error." << endl;
		return -1;
	}

	// Create a ParameterList, to pass parameters into the Block
	// Davidson eigensolver.
	Teuchos::ParameterList anasaziPL;
	anasaziPL.set ("Which", "LM");
	anasaziPL.set ("Block Size", blockSize);
	anasaziPL.set ("Num Blocks", numBlocks);
	anasaziPL.set ("Maximum Restarts", maxRestarts);
	anasaziPL.set ("Convergence Tolerance", tol);
	anasaziPL.set ("Verbosity", Anasazi::Errors + Anasazi::Warnings +
			Anasazi::TimingDetails + Anasazi::FinalSummary);

	// Create the Block Davidson eigensolver.
	Anasazi::BlockDavidsonSolMgr<double, MV, OP> anasaziSolver (problem, anasaziPL);

	// Solve the eigenvalue problem.
	//
	// Note that creating the eigensolver is separate from solving it.
	// After creating the eigensolver, you may call solve() multiple
	// times with different parameters or initial vectors.  This lets
	// you reuse intermediate state, like allocated basis vectors.
	Anasazi::ReturnType returnCode = anasaziSolver.solve ();
	if (returnCode != Anasazi::Converged) {
		cout << "Anasazi eigensolver did not converge." << endl;
	}

	// Get the eigenvalues and eigenvectors from the eigenproblem.
	Anasazi::Eigensolution<double,MV> sol = problem->getSolution ();
	// Anasazi returns eigenvalues as Anasazi::Value, so that if
	// Anasazi's Scalar type is real-valued (as it is in this case), but
	// some eigenvalues are complex, you can still access the
	// eigenvalues correctly.  In this case, there are no complex
	// eigenvalues, since the matrix pencil is symmetric.
	std::vector<Anasazi::Value<double> > evals = sol.Evals;
	RCP<MV> evecs = sol.Evecs;

	// Compute residuals.
	std::vector<double> normR (sol.numVecs);
	if (sol.numVecs > 0) {
		Teuchos::SerialDenseMatrix<int,double> T (sol.numVecs, sol.numVecs);
		MV tempAevec (Map, sol.numVecs);
		T.putScalar (0.0);
		for (int i=0; i<sol.numVecs; ++i) {
			T(i,i) = evals[i].realpart;
		}
		OPT::Apply( *A, *evecs, tempAevec );
		MVT::MvTimesMatAddMv (-1.0, *evecs, T, 1.0, tempAevec);
		MVT::MvNorm (tempAevec, normR);
	}

	// Print the results on MPI process 0.
	cout << "Solver manager returned "
		<< (returnCode == Anasazi::Converged ? "converged." : "unconverged.")
		<< endl << endl
		<< "------------------------------------------------------" << endl
		<< std::setw(16) << "Eigenvalue"
		<< std::setw(18) << "Direct Residual"
		<< endl
		<< "------------------------------------------------------" << endl;
	for (int i=0; i<sol.numVecs; ++i) {
		cout << std::setw(16) << evals[i].realpart
			<< std::setw(18) << normR[i] / evals[i].realpart
			<< endl;
	}
	cout << "------------------------------------------------------" << endl;
	cout << iter_no << endl;

	return 0;
}
<commit_msg>[Matrix]: test more original eigensolvers.<commit_after>// This example computes the eigenvalues of largest magnitude of an
// eigenvalue problem $A x = \lambda x$, using Anasazi's
// implementation of the Block Davidson method.

#include "sparse_matrix.h"
#include "vertex.h"
#include "vertex_index.h"
#include "in_mem_storage.h"
#include "io_interface.h"

// Include header for block Davidson eigensolver
#include "AnasaziBlockDavidsonSolMgr.hpp"
// Include header for LOBPCG eigensolver
#include "AnasaziLOBPCGSolMgr.hpp"
// Include header for block Davidson eigensolver
#include "AnasaziBlockKrylovSchurSolMgr.hpp"
// Include header to define eigenproblem Ax = \lambda*x
#include "AnasaziBasicEigenproblem.hpp"
#include "AnasaziOperator.hpp"
#include "AnasaziTpetraAdapter.hpp"
#include "Tpetra_Map.hpp"
#include "Tpetra_MultiVector.hpp"
#include "Tpetra_DefaultPlatform.hpp"
#include "Tpetra_CrsMatrix_decl.hpp"
#include "Tpetra_CrsMatrix_def.hpp"

// ****************************************************************************
// BEGIN MAIN ROUTINE
// ****************************************************************************

using namespace fm;

using Teuchos::RCP;
using Teuchos::rcp;
using Teuchos::ArrayRCP;
using std::cerr;
using std::cout;
using std::endl;

std::atomic<size_t> iter_no;

typedef fg::vsize_t local_ordinal_type;
typedef fg::vsize_t global_ordinal_type;

typedef Tpetra::DefaultPlatform::DefaultPlatformType::NodeType  Node;
typedef Tpetra::MultiVector<double, global_ordinal_type, global_ordinal_type, Node> MV;
typedef Tpetra::Operator<double, global_ordinal_type, global_ordinal_type, Node> OP;
typedef Anasazi::OperatorTraits<double, MV, OP> OPT;

typedef Tpetra::Map<local_ordinal_type, global_ordinal_type, Node> map_type;
typedef Tpetra::CrsMatrix<double, local_ordinal_type, global_ordinal_type> crs_matrix_type;

size_t edge_data_size = 0;

ArrayRCP<size_t> getNumEntriesPerRow(fg::vertex_index::ptr index,
		size_t &num_rows)
{
	fg::in_mem_query_vertex_index::ptr query_index
		= fg::in_mem_query_vertex_index::create(index, false);

	ArrayRCP<size_t> numEntries(index->get_num_vertices());
	for (size_t i = 0; i < index->get_num_vertices(); i++)
		numEntries[i] = query_index->get_num_edges(i, fg::edge_type::IN_EDGE);

	num_rows = index->get_num_vertices();
	return numEntries;
}

RCP<crs_matrix_type> create_crs(fg::in_mem_graph::ptr g,
		fg::vertex_index::ptr index, RCP<map_type> map)
{
	safs::io_interface::ptr io = create_io(g->create_io_factory(),
			thread::get_curr_thread());
	const size_t numMyElements = map->getNodeNumElements ();

	size_t numRows;
	ArrayRCP<const size_t> numEntriesPerRow = getNumEntriesPerRow(index, numRows);
	assert(numRows == numMyElements);
	// Create a Tpetra sparse matrix whose rows have distribution given by the Map.
	RCP<crs_matrix_type> A (new crs_matrix_type (map, numEntriesPerRow,
				Tpetra::ProfileType::StaticProfile));

	const size_t vheader_size = fg::ext_mem_undirected_vertex::get_header_size();
	char vheader_buf[vheader_size];
	const fg::ext_mem_undirected_vertex *vheader
		= (const fg::ext_mem_undirected_vertex *) vheader_buf;
	off_t off = fg::graph_header::get_header_size();
	// Fill the sparse matrix, one row at a time.
	for (local_ordinal_type lclRow = 0;
			lclRow < static_cast<local_ordinal_type> (numMyElements); ++lclRow) {
		io->access(vheader_buf, off, vheader_size, READ);
		fg::vsize_t num_edges = vheader->get_num_edges();
		assert(num_edges > 0);
		size_t size = fg::ext_mem_undirected_vertex::num_edges2vsize(num_edges,
				edge_data_size);
		std::unique_ptr<char[]> buf(new char[size]);
		io->access(buf.get(), off, size, READ);

		const fg::ext_mem_undirected_vertex *v
			= (const fg::ext_mem_undirected_vertex *) buf.get();
		std::vector<global_ordinal_type> cols(num_edges);
		std::vector<double> vals(num_edges);
		for (fg::vsize_t i = 0; i < num_edges; i++) {
			cols[i] = v->get_neighbor(i);
			vals[i] = 1;
		}
		const global_ordinal_type gblRow = map->getGlobalElement (lclRow);
		A->insertGlobalValues (gblRow, cols, vals);
		off += size;
	}

	// Tell the sparse matrix that we are done adding entries to it.
	A->fillComplete ();
	return A;
}

RCP<map_type> Map;

void compute_eigen(RCP<crs_matrix_type> A, int nev, const std::string &solver,
		int blockSize, int numBlocks, double tol)
{
	// Here, Scalar is double, MV is Tpetra::MultiVector, and OP is FMTp_Operator.
	typedef Anasazi::MultiVecTraits<double, MV> MVT;

	// Set eigensolver parameters.
	const int maxRestarts = 100; // maximum number of restart cycles
	const int maxIters = 500;

	printf("solver: %s\n", solver.c_str());
	printf("block size: %d\n", blockSize);
	printf("#blocks: %d\n", numBlocks);
	printf("tol: %f\n", tol);

	// Create a set of initial vectors to start the eigensolver.
	// This needs to have the same number of columns as the block size.
	RCP<MV> ivec = rcp (new MV (Map, (size_t) blockSize));
	ivec->randomize ();

	// Create the eigenproblem.  This object holds all the stuff about
	// your problem that Anasazi will see.  In this case, it knows about
	// the matrix A and the inital vectors.
	RCP<Anasazi::BasicEigenproblem<double, MV, OP> > problem =
		rcp (new Anasazi::BasicEigenproblem<double, MV, OP> (A, ivec));

	// Tell the eigenproblem that the operator A is symmetric.
	problem->setHermitian (true);

	// Set the number of eigenvalues requested
	problem->setNEV (nev);

	// Tell the eigenproblem that you are finishing passing it information.
	const bool boolret = problem->setProblem();
	if (boolret != true) {
		cerr << "Anasazi::BasicEigenproblem::setProblem() returned an error." << endl;
		return;
	}

	// Create a ParameterList, to pass parameters into the Block
	// Davidson eigensolver.
	Teuchos::ParameterList anasaziPL;
	anasaziPL.set ("Which", "LM");
	anasaziPL.set ("Block Size", blockSize);
	anasaziPL.set ("Convergence Tolerance", tol);
	anasaziPL.set ("Verbosity", Anasazi::Errors + Anasazi::Warnings +
			Anasazi::TimingDetails + Anasazi::FinalSummary);

	Anasazi::ReturnType returnCode;
	// Create the Block Davidson eigensolver.
	if (solver == "Davidson") {
		anasaziPL.set ("Num Blocks", numBlocks);
		anasaziPL.set ("Maximum Restarts", maxRestarts);

		Anasazi::BlockDavidsonSolMgr<double, MV, OP> anasaziSolver (problem,
				anasaziPL);
		// Solve the eigenvalue problem.
		returnCode = anasaziSolver.solve ();
	}
	else if (solver == "KrylovSchur") {
		anasaziPL.set ("Num Blocks", numBlocks);
		anasaziPL.set ("Maximum Restarts", maxRestarts);

		Anasazi::BlockKrylovSchurSolMgr<double, MV, OP> anasaziSolver (problem,
				anasaziPL);
		// Solve the eigenvalue problem.
		returnCode = anasaziSolver.solve ();
	}
	else if (solver == "LOBPCG") {
		anasaziPL.set ("Maximum Iterations", maxIters);
		anasaziPL.set ("Full Ortho", true);
		anasaziPL.set ("Use Locking", true);

		// Create the LOBPCG eigensolver.
		Anasazi::LOBPCGSolMgr<double, MV, OP> anasaziSolver (problem, anasaziPL);
		// Solve the eigenvalue problem.
		returnCode = anasaziSolver.solve ();
	}
	else
		assert(0);

	if (returnCode != Anasazi::Converged) {
		cout << "Anasazi eigensolver did not converge." << endl;
	}
	// Get the eigenvalues and eigenvectors from the eigenproblem.
	Anasazi::Eigensolution<double,MV> sol = problem->getSolution ();

	// Anasazi returns eigenvalues as Anasazi::Value, so that if
	// Anasazi's Scalar type is real-valued (as it is in this case), but
	// some eigenvalues are complex, you can still access the
	// eigenvalues correctly.  In this case, there are no complex
	// eigenvalues, since the matrix pencil is symmetric.
	std::vector<Anasazi::Value<double> > evals = sol.Evals;
	RCP<MV> evecs = sol.Evecs;

	// Compute residuals.
	std::vector<double> normR (sol.numVecs);
	if (sol.numVecs > 0) {
		Teuchos::SerialDenseMatrix<int,double> T (sol.numVecs, sol.numVecs);
		MV tempAevec (Map, sol.numVecs);
		T.putScalar (0.0);
		for (int i=0; i<sol.numVecs; ++i) {
			T(i,i) = evals[i].realpart;
		}
		OPT::Apply( *A, *evecs, tempAevec );
		MVT::MvTimesMatAddMv (-1.0, *evecs, T, 1.0, tempAevec);
		MVT::MvNorm (tempAevec, normR);
	}

	// Print the results on MPI process 0.
	cout << "Solver manager returned "
		<< (returnCode == Anasazi::Converged ? "converged." : "unconverged.")
		<< endl << endl
		<< "------------------------------------------------------" << endl
		<< std::setw(16) << "Eigenvalue"
		<< std::setw(18) << "Direct Residual"
		<< endl
		<< "------------------------------------------------------" << endl;
	for (int i=0; i<sol.numVecs; ++i) {
		cout << std::setw(16) << evals[i].realpart
			<< std::setw(18) << normR[i] / evals[i].realpart
			<< endl;
	}
	cout << "------------------------------------------------------" << endl;
	cout << iter_no << endl;
}

void print_usage()
{
	fprintf(stderr, "eigensolver conf_file matrix_file index_file nev [options]\n");
	fprintf(stderr, "-b block_size\n");
	fprintf(stderr, "-n num_blocks\n");
	fprintf(stderr, "-s solver: Davidson, KrylovSchur, LOBPCG\n");
	fprintf(stderr, "-t tolerance\n");
	fprintf(stderr, "-S: run SVD\n");
}

int main (int argc, char *argv[])
{
	int opt;
	int num_opts = 0;
	size_t blockSize = 4;
	size_t numBlocks = 8;
	std::string solver = "LOBPCG";
	double tol = 1e-8;
	while ((opt = getopt(argc, argv, "b:n:s:t:")) != -1) {
		num_opts++;
		switch (opt) {
			case 'b':
				blockSize = atoi(optarg);
				num_opts++;
				break;
			case 'n':
				numBlocks = atoi(optarg);
				num_opts++;
				break;
			case 's':
				solver = optarg;
				num_opts++;
				break;
			case 't':
				tol = atof(optarg);
				num_opts++;
				break;
			default:
				print_usage();
				abort();
		}
	}

	argv += 1 + num_opts;
	argc -= 1 + num_opts;
	if (argc < 4) {
		print_usage();
		exit(1);
	}

	std::string conf_file = argv[0];
	std::string graph_file = argv[1];
	std::string index_file = argv[2];
	int nev = atoi(argv[3]); // number of eigenvalues for which to solve;

	// Anasazi solvers have the following template parameters:
	//
	//   - Scalar: The type of dot product results.
	//   - MV: The type of (multi)vectors.
	//   - OP: The type of operators (functions from multivector to
	//     multivector).  A matrix (like Epetra_CrsMatrix) is an example
	//     of an operator; an Ifpack preconditioner is another example.
	//
	typedef Tpetra::DefaultPlatform::DefaultPlatformType Platform;

	//
	// Set up the test problem.
	//
	config_map::ptr configs = config_map::create(conf_file);
	init_flash_matrix(configs);

	fg::FG_graph::ptr fg = fg::FG_graph::create(graph_file, index_file, configs);

	Platform &platform = Tpetra::DefaultPlatform::getDefaultPlatform();
	RCP<const Teuchos::Comm<int> > comm = platform.getComm();
	Map = rcp (new map_type(fg->get_graph_header().get_num_vertices(),
				0, comm));
	RCP<crs_matrix_type> A = create_crs(fg->get_graph_data(),
			fg->get_index_data(), Map);
	compute_eigen(A, nev, solver, blockSize, numBlocks, tol);

	return 0;
}
<|endoftext|>


<commit_before>/*!
@file

@copyright Edouard Alligand and Joel Falcou 2015-2017
(See accompanying file LICENSE.md or copy at http://boost.org/LICENSE_1_0.txt)
*/
#ifndef BOOST_BRIGAND_VERSION_HPP
#define BOOST_BRIGAND_VERSION_HPP

#define BRIGAND_MAJOR_VERSION 1
#define BRIGAND_MINOR_VERSION 3
#define BRIGAND_PATCH_VERSION 0

#define BRIGAND_VERSION "1.3.0"

#endif // BOOST_BRIGAND_VERSION_HPP
<commit_msg>Delete version.hpp<commit_after><|endoftext|>


<commit_before>/*
 * Copyright (c) 2015 PLUMgrid, Inc.
 *
 * 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 <fstream>
#include <iostream>

#include <dirent.h>
#include <fcntl.h>
#include <stdlib.h>
#include <sys/utsname.h>
#include <unistd.h>

#include "kbuild_helper.h"

namespace ebpf {

using std::string;
using std::vector;

KBuildHelper::KBuildHelper(const std::string &kdir, bool has_source_dir) : kdir_(kdir),
                                                                           has_source_dir_(has_source_dir) {
}

// read the flags from cache or learn
int KBuildHelper::get_flags(const char *uname_machine, vector<string> *cflags) {
  //uname -m | sed -e s/i.86/x86/ -e s/x86_64/x86/ -e s/sun4u/sparc64/ -e s/arm.*/arm/
  //               -e s/sa110/arm/ -e s/s390x/s390/ -e s/parisc64/parisc/
  //               -e s/ppc.*/powerpc/ -e s/mips.*/mips/ -e s/sh[234].*/sh/
  //               -e s/aarch64.*/arm64/

  string arch;
  const char *archenv = getenv("ARCH");
  // If ARCH env is defined, use it over uname
  if (archenv)
    arch = string(archenv);
  else
    arch = string(uname_machine);

  if (!arch.compare(0, 6, "x86_64")) {
    arch = "x86";
  } else if (arch[0] == 'i' && !arch.compare(2, 2, "86")) {
    arch = "x86";
  } else if (!arch.compare(0, 7, "aarch64") || !arch.compare(0, 5, "arm64")) {
    arch = "arm64";
  } else if (!arch.compare(0, 3, "arm")) {
    arch = "arm";
  } else if (!arch.compare(0, 5, "sa110")) {
    arch = "arm";
  } else if (!arch.compare(0, 5, "s390x")) {
    arch = "s390";
  } else if (!arch.compare(0, 8, "parisc64")) {
    arch = "parisc";
  } else if (!arch.compare(0, 3, "ppc")) {
    arch = "powerpc";
  } else if (!arch.compare(0, 4, "mips")) {
    arch = "mips";
  } else if (!arch.compare(0, 2, "sh")) {
    arch = "sh";
  }

  cflags->push_back("-nostdinc");
  cflags->push_back("-isystem");
  cflags->push_back("/virtual/lib/clang/include");

  // some module build directories split headers between source/ and build/
  if (has_source_dir_) {
    cflags->push_back("-I" + kdir_ + "/build/arch/"+arch+"/include");
    cflags->push_back("-I" + kdir_ + "/build/arch/"+arch+"/include/generated/uapi");
    cflags->push_back("-I" + kdir_ + "/build/arch/"+arch+"/include/generated");
    cflags->push_back("-I" + kdir_ + "/build/include");
    cflags->push_back("-I" + kdir_ + "/build/./arch/"+arch+"/include/uapi");
    cflags->push_back("-I" + kdir_ + "/build/arch/"+arch+"/include/generated/uapi");
    cflags->push_back("-I" + kdir_ + "/build/include/uapi");
    cflags->push_back("-I" + kdir_ + "/build/include/generated");
    cflags->push_back("-I" + kdir_ + "/build/include/generated/uapi");
  }

  cflags->push_back("-I./arch/"+arch+"/include");
  cflags->push_back("-Iarch/"+arch+"/include/generated/uapi");
  cflags->push_back("-Iarch/"+arch+"/include/generated");
  cflags->push_back("-Iinclude");
  cflags->push_back("-I./arch/"+arch+"/include/uapi");
  cflags->push_back("-Iarch/"+arch+"/include/generated/uapi");
  cflags->push_back("-I./include/uapi");
  cflags->push_back("-Iinclude/generated/uapi");
  cflags->push_back("-include");
  cflags->push_back("./include/linux/kconfig.h");
  cflags->push_back("-D__KERNEL__");
  cflags->push_back("-D__HAVE_BUILTIN_BSWAP16__");
  cflags->push_back("-D__HAVE_BUILTIN_BSWAP32__");
  cflags->push_back("-D__HAVE_BUILTIN_BSWAP64__");
  cflags->push_back("-DKBUILD_MODNAME=\"bcc\"");

  // If ARCH env variable is set, pass this along.
  if (archenv)
	cflags->push_back("-D__TARGET_ARCH_" + arch);

  cflags->push_back("-Wno-unused-value");
  cflags->push_back("-Wno-pointer-sign");
  cflags->push_back("-fno-stack-protector");

  return 0;
}

static inline int file_exists(const char *f)
{
  struct stat buffer;
  return (stat(f, &buffer) == 0);
}

static inline int proc_kheaders_exists(void)
{
  return file_exists(PROC_KHEADERS_PATH);
}

static inline int extract_kheaders(const std::string &dirpath,
                                   const struct utsname &uname_data)
{
  char tar_cmd[256], dirpath_tmp[256];
  int ret;
  bool module = false;

  if (!proc_kheaders_exists()) {
    ret = system("modprobe kheaders");
    if (ret)
      return ret;
    module = true;
    if (!proc_kheaders_exists()) {
      ret = -1;
      goto cleanup;
    }
  }

  snprintf(dirpath_tmp, sizeof(dirpath_tmp), "/tmp/kheaders-%s-XXXXXX", uname_data.release);
  if (mkdtemp(dirpath_tmp) == NULL) {
    ret = -1;
    goto cleanup;
  }

  if ((size_t)snprintf(tar_cmd, sizeof(tar_cmd), "tar -xf %s -C %s", PROC_KHEADERS_PATH, dirpath_tmp) >= sizeof(tar_cmd)) {
    ret = -1;
    goto cleanup;
  }
  ret = system(tar_cmd);
  if (ret) {
    system(("rm -rf " + std::string(dirpath_tmp)).c_str());
    goto cleanup;
  }

  /*
   * If the new directory exists, it could have raced with a parallel
   * extraction, in this case just delete the old directory and ignore.
   */
  ret = rename(dirpath_tmp, dirpath.c_str());
  if (ret)
    ret = system(("rm -rf " + std::string(dirpath_tmp)).c_str());

cleanup:
  if (module) {
    int ret1 = system("rmmod kheaders");
    if (ret1)
      return ret1;
  }

  return ret;
}

int get_proc_kheaders(std::string &dirpath)
{
  struct utsname uname_data;
  char dirpath_tmp[256];

  if (uname(&uname_data))
    return -errno;

  snprintf(dirpath_tmp, 256, "/tmp/kheaders-%s", uname_data.release);
  dirpath = std::string(dirpath_tmp);

  if (file_exists(dirpath_tmp))
    return 0;

  // First time so extract it
  return extract_kheaders(dirpath, uname_data);
}

}  // namespace ebpf
<commit_msg>Adjust the order of linux kernel header include paths<commit_after>/*
 * Copyright (c) 2015 PLUMgrid, Inc.
 *
 * 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 <fstream>
#include <iostream>

#include <dirent.h>
#include <fcntl.h>
#include <stdlib.h>
#include <sys/utsname.h>
#include <unistd.h>

#include "kbuild_helper.h"

namespace ebpf {

using std::string;
using std::vector;

KBuildHelper::KBuildHelper(const std::string &kdir, bool has_source_dir) : kdir_(kdir),
                                                                           has_source_dir_(has_source_dir) {
}

// read the flags from cache or learn
int KBuildHelper::get_flags(const char *uname_machine, vector<string> *cflags) {
  //uname -m | sed -e s/i.86/x86/ -e s/x86_64/x86/ -e s/sun4u/sparc64/ -e s/arm.*/arm/
  //               -e s/sa110/arm/ -e s/s390x/s390/ -e s/parisc64/parisc/
  //               -e s/ppc.*/powerpc/ -e s/mips.*/mips/ -e s/sh[234].*/sh/
  //               -e s/aarch64.*/arm64/

  string arch;
  const char *archenv = getenv("ARCH");
  // If ARCH env is defined, use it over uname
  if (archenv)
    arch = string(archenv);
  else
    arch = string(uname_machine);

  if (!arch.compare(0, 6, "x86_64")) {
    arch = "x86";
  } else if (arch[0] == 'i' && !arch.compare(2, 2, "86")) {
    arch = "x86";
  } else if (!arch.compare(0, 7, "aarch64") || !arch.compare(0, 5, "arm64")) {
    arch = "arm64";
  } else if (!arch.compare(0, 3, "arm")) {
    arch = "arm";
  } else if (!arch.compare(0, 5, "sa110")) {
    arch = "arm";
  } else if (!arch.compare(0, 5, "s390x")) {
    arch = "s390";
  } else if (!arch.compare(0, 8, "parisc64")) {
    arch = "parisc";
  } else if (!arch.compare(0, 3, "ppc")) {
    arch = "powerpc";
  } else if (!arch.compare(0, 4, "mips")) {
    arch = "mips";
  } else if (!arch.compare(0, 2, "sh")) {
    arch = "sh";
  }

  cflags->push_back("-nostdinc");
  cflags->push_back("-isystem");
  cflags->push_back("/virtual/lib/clang/include");

  // The include order from kernel top Makefile:
  //
  // # Use USERINCLUDE when you must reference the UAPI directories only.
  // USERINCLUDE    := \
  //                 -I$(srctree)/arch/$(SRCARCH)/include/uapi \
  //                 -I$(objtree)/arch/$(SRCARCH)/include/generated/uapi \
  //                 -I$(srctree)/include/uapi \
  //                 -I$(objtree)/include/generated/uapi \
  //                 -include $(srctree)/include/linux/kconfig.h
  //
  // # Use LINUXINCLUDE when you must reference the include/ directory.
  // # Needed to be compatible with the O= option
  // LINUXINCLUDE    := \
  //                 -I$(srctree)/arch/$(SRCARCH)/include \
  //                 -I$(objtree)/arch/$(SRCARCH)/include/generated \
  //                 $(if $(building_out_of_srctree),-I$(srctree)/include) \
  //                 -I$(objtree)/include \
  //                 $(USERINCLUDE)
  //
  // Some distros such as openSUSE/SUSE and Debian splits the headers between
  // source/ and build/. In this case, just $(srctree) is source/ and
  // $(objtree) is build/.
  if (has_source_dir_) {
    cflags->push_back("-Iarch/"+arch+"/include/");
    cflags->push_back("-I" + kdir_ + "/build/arch/"+arch+"/include/generated");
    cflags->push_back("-Iinclude");
    cflags->push_back("-I" + kdir_ + "/build/include");
    cflags->push_back("-Iarch/"+arch+"/include/uapi");
    cflags->push_back("-I" + kdir_ + "/build/arch/"+arch+"/include/generated/uapi");
    cflags->push_back("-Iinclude/uapi");
    cflags->push_back("-I" + kdir_ + "/build/include/generated/uapi");
  } else {
    cflags->push_back("-Iarch/"+arch+"/include/");
    cflags->push_back("-Iarch/"+arch+"/include/generated");
    cflags->push_back("-Iinclude");
    cflags->push_back("-Iarch/"+arch+"/include/uapi");
    cflags->push_back("-Iarch/"+arch+"/include/generated/uapi");
    cflags->push_back("-Iinclude/uapi");
    cflags->push_back("-Iinclude/generated/uapi");
  }

  cflags->push_back("-include");
  cflags->push_back("./include/linux/kconfig.h");
  cflags->push_back("-D__KERNEL__");
  cflags->push_back("-D__HAVE_BUILTIN_BSWAP16__");
  cflags->push_back("-D__HAVE_BUILTIN_BSWAP32__");
  cflags->push_back("-D__HAVE_BUILTIN_BSWAP64__");
  cflags->push_back("-DKBUILD_MODNAME=\"bcc\"");

  // If ARCH env variable is set, pass this along.
  if (archenv)
	cflags->push_back("-D__TARGET_ARCH_" + arch);

  cflags->push_back("-Wno-unused-value");
  cflags->push_back("-Wno-pointer-sign");
  cflags->push_back("-fno-stack-protector");

  return 0;
}

static inline int file_exists(const char *f)
{
  struct stat buffer;
  return (stat(f, &buffer) == 0);
}

static inline int proc_kheaders_exists(void)
{
  return file_exists(PROC_KHEADERS_PATH);
}

static inline int extract_kheaders(const std::string &dirpath,
                                   const struct utsname &uname_data)
{
  char tar_cmd[256], dirpath_tmp[256];
  int ret;
  bool module = false;

  if (!proc_kheaders_exists()) {
    ret = system("modprobe kheaders");
    if (ret)
      return ret;
    module = true;
    if (!proc_kheaders_exists()) {
      ret = -1;
      goto cleanup;
    }
  }

  snprintf(dirpath_tmp, sizeof(dirpath_tmp), "/tmp/kheaders-%s-XXXXXX", uname_data.release);
  if (mkdtemp(dirpath_tmp) == NULL) {
    ret = -1;
    goto cleanup;
  }

  if ((size_t)snprintf(tar_cmd, sizeof(tar_cmd), "tar -xf %s -C %s", PROC_KHEADERS_PATH, dirpath_tmp) >= sizeof(tar_cmd)) {
    ret = -1;
    goto cleanup;
  }
  ret = system(tar_cmd);
  if (ret) {
    system(("rm -rf " + std::string(dirpath_tmp)).c_str());
    goto cleanup;
  }

  /*
   * If the new directory exists, it could have raced with a parallel
   * extraction, in this case just delete the old directory and ignore.
   */
  ret = rename(dirpath_tmp, dirpath.c_str());
  if (ret)
    ret = system(("rm -rf " + std::string(dirpath_tmp)).c_str());

cleanup:
  if (module) {
    int ret1 = system("rmmod kheaders");
    if (ret1)
      return ret1;
  }

  return ret;
}

int get_proc_kheaders(std::string &dirpath)
{
  struct utsname uname_data;
  char dirpath_tmp[256];

  if (uname(&uname_data))
    return -errno;

  snprintf(dirpath_tmp, 256, "/tmp/kheaders-%s", uname_data.release);
  dirpath = std::string(dirpath_tmp);

  if (file_exists(dirpath_tmp))
    return 0;

  // First time so extract it
  return extract_kheaders(dirpath, uname_data);
}

}  // namespace ebpf
<|endoftext|>


<commit_before>#include <sys/types.h>
#include <sys/sysctl.h>
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>

#include <iostream>
#include <fstream>

#include <CoreFoundation/CoreFoundation.h>
#include <SystemConfiguration/SystemConfiguration.h>

namespace {
  bool
  verifyUser(void)
  {
    uid_t consoleUID;
    CFStringRef result = SCDynamicStoreCopyConsoleUser(NULL, &consoleUID, NULL);
    // TRUE if no user is logged in
    if (result == NULL) return true;

    bool isvalid = false;
    // If the current console user is "loginwindow", treat that as TRUE.
    if (CFEqual(result, CFSTR("loginwindow"))) {
      isvalid = true;
    } else {
      isvalid = (getuid() == consoleUID);
    }
    CFRelease(result);

    return isvalid;
  }

  void
  set(const char* name, int value)
  {
    char entry[512];
    snprintf(entry, sizeof(entry), "keyremap4macbook.%s", name);

    size_t oldlen = 0;
    size_t newlen = sizeof(value);
    if (sysctlbyname(entry, NULL, &oldlen, &value, newlen) == -1) {
      perror("sysctl");
    }
  }

  void
  set_string(const char* name, char* value)
  {
    char entry[512];
    snprintf(entry, sizeof(entry), "keyremap4macbook.%s", name);

    size_t oldlen = 0;
    size_t newlen = strlen(value) + 1;
    if (sysctlbyname(entry, NULL, &oldlen, value, newlen) == -1) {
      perror("sysctl");
    }
  }
}

int
main(int argc, char** argv)
{
  if (! verifyUser()) {
    std::cerr << "Permission denied" << std::endl;
    return 1;
  }

  std::ifstream ifs("/Library/org.pqrs/KeyRemap4MacBook/share/reset");
  if (! ifs) return 1;

  while (! ifs.eof()) {
    char line[512];

    ifs.getline(line, sizeof(line));

    char* p = strchr(line, ' ');
    if (! p) continue;
    *p = '\0';

    set(line, atoi(p + 1));
  }

  if (argc == 2 && strcmp(argv[1], "terminate") == 0) {
    char socket_path[] = "";
    set_string("socket_path", socket_path);

    set("initialized", 0);
  }

  return 0;
}
<commit_msg>suppress log message @ src/bin/sysctl_reset<commit_after>#include <sys/types.h>
#include <sys/sysctl.h>
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>

#include <iostream>
#include <fstream>

#include <CoreFoundation/CoreFoundation.h>
#include <SystemConfiguration/SystemConfiguration.h>

namespace {
  bool
  verifyUser(void)
  {
    uid_t consoleUID;
    CFStringRef result = SCDynamicStoreCopyConsoleUser(NULL, &consoleUID, NULL);
    // TRUE if no user is logged in
    if (result == NULL) return true;

    bool isvalid = false;
    // If the current console user is "loginwindow", treat that as TRUE.
    if (CFEqual(result, CFSTR("loginwindow"))) {
      isvalid = true;
    } else {
      isvalid = (getuid() == consoleUID);
    }
    CFRelease(result);

    return isvalid;
  }

  void
  set(const char* name, int value)
  {
    char entry[512];
    snprintf(entry, sizeof(entry), "keyremap4macbook.%s", name);

    size_t oldlen = 0;
    size_t newlen = sizeof(value);
    if (sysctlbyname(entry, NULL, &oldlen, &value, newlen) == -1) {
      perror("sysctl");
    }
  }

  void
  set_string(const char* name, char* value)
  {
    char entry[512];
    snprintf(entry, sizeof(entry), "keyremap4macbook.%s", name);

    size_t oldlen = 0;
    size_t newlen = strlen(value) + 1;
    if (sysctlbyname(entry, NULL, &oldlen, value, newlen) == -1) {
      perror("sysctl");
    }
  }
}

int
main(int argc, char** argv)
{
  if (! verifyUser()) {
    return 1;
  }

  std::ifstream ifs("/Library/org.pqrs/KeyRemap4MacBook/share/reset");
  if (! ifs) return 1;

  while (! ifs.eof()) {
    char line[512];

    ifs.getline(line, sizeof(line));

    char* p = strchr(line, ' ');
    if (! p) continue;
    *p = '\0';

    set(line, atoi(p + 1));
  }

  if (argc == 2 && strcmp(argv[1], "terminate") == 0) {
    char socket_path[] = "";
    set_string("socket_path", socket_path);

    set("initialized", 0);
  }

  return 0;
}
<|endoftext|>


<commit_before>#include <SDL.h>
#include <stdio.h>
#include "world.h"
#include "actor.h"
#include "map.h"
#include "font.h"
#include "sound.h"

Actor::Actor()
{
    x=128;
    y=160;
    jump=false;
    // Animation state
    frame=0;
    frameTimer=150;
    // Power up
    powerup=0;
    timer=0;
    // physics
    ay=0;
    vy=0;
    score=0;
    physicsTimer=0;
}

Actor::~Actor()
{

}

void Actor::init()

{
    sprite=new Image(World::getRenderer(),"Trump.png");

    sprite->setCellSize(32);

    score=0;
}

void Actor::update(int elapsed, Map *map)
{
    // Update the animation frame
    if (jump==true){
        frame=8;
    }else{
        frameTimer-=elapsed;
        if (frameTimer<=0){
            if (frame==8){
                frame=0;
            }else{
                frame++;
            }
            if(frame==5){
                frame=0;
            }
            frameTimer+=150;
        }
    }
    // Apply the physics.
    physicsTimer+=elapsed;
    while(physicsTimer>16) {
        physicsTimer-=16;
        updateGravity(map);
    }
}

void Actor::updateGravity(Map *map)
{
        if( ay!=0) {
                printf("y=%.2f; vy=%.2f; ay=%.2f\n",y,vy,ay);
        }
        vy=vy+ay;
        vy=vy+GRAVITY;   // earth gravity is 9.8 m/s^2, or whatever it works out to in your units.
        // apply terminal velocity
        if( vy<MINVEL) {
                vy=MINVEL;
                ay=0;  // hit minimum negative velocity so stop jumping.
        }
        if( vy>MAXVEL) {
                vy=MAXVEL;
                ay=0;  // hit maximum velocity so stop jumping.
        }
        // propose new position, and test for collision:
        float newy=y+vy;
        int i;
        for( i=0; i<8; i++) {
                int item=map->collide(x, newy+32, 32, 32 );
                if( item==MAP_SKY ) break; // a safe place to move the item to.
                if( item!=MAP_BARRIER_A && item!=MAP_BARRIER_B) {
                    item=map->collect(x,newy+32, 32, 32);
                    collectedItem(item);
                    break;
                }
                if( item==MAP_BARRIER_A || item==MAP_BARRIER_B) {
                    if(vy<0) break;     // Jump up through walls!
                }
                // we don't want to be inside the object, so guess we can move half the distance.
                vy/=2.0f;
                newy=y+vy;
        }
        if( i==8) {
                newy=y; // we can't find a place closer to the ground/ceiling so we need to stop moving.
                vy=0;
                ay=0;
        }
        y=newy; // our new vertical position with gravity and jumping factored in!
}

void Actor::handle(bool down)
{
    ay=down?JUMP:0;
    if(down && !jump) {
        Sound::playSfx(SFX_JUMP);
    }

    jump=down;
}

void Actor::collectedItem(int item)
{
    if(item==MAP_BLUESTAR) {
        Sound::playSfx(SFX_MATCH);
        score+=1;
    } else if(item==MAP_REDSTAR) {
        Sound::playSfx(SFX_MATCH);
        score+=2;
    } else if(item==MAP_WHITESTART) {
        Sound::playSfx(SFX_MATCH);
        score+=3;
    } else if(item==MAP_SIGN) {
        Sound::playSfx(SFX_SIGN);
    } else if(item==MAP_POTATO) {
        Sound::playSfx(SFX_POTATO);
    } else if(item==MAP_MONEY) {
        Sound::playSfx(SFX_MONEY);
    } else if(item==MAP_MEATLOAF) {
        Sound::playSfx(SFX_MEATLOAF);
    } else if(item==MAP_BABY) {
        Sound::playSfx(SFX_BABY);
    }
}

void Actor::draw(SDL_Renderer *renderer)
{
    if(sprite) {
        sprite->draw(renderer,x,y,frame);
    }
    if (jump==true){
        Font::draw(renderer, FF_BODY,"Currently Jumping",0,350);
    }

}

int Actor::getScore()
{
    return score;
}

void Actor::resetScore()
{
    score=0;
}
<commit_msg>extra point for collision detection invocation<commit_after>#include <SDL.h>
#include <stdio.h>
#include "world.h"
#include "actor.h"
#include "map.h"
#include "font.h"
#include "sound.h"

Actor::Actor()
{
    x=128;
    y=160;
    jump=false;
    // Animation state
    frame=0;
    frameTimer=150;
    // Power up
    powerup=0;
    timer=0;
    // physics
    ay=0;
    vy=0;
    score=0;
    physicsTimer=0;
}

Actor::~Actor()
{

}

void Actor::init()

{
    sprite=new Image(World::getRenderer(),"Trump.png");

    sprite->setCellSize(32);

    score=0;
}

void Actor::update(int elapsed, Map *map)
{
    // Update the animation frame
    if (jump==true){
        frame=8;
    }else{
        frameTimer-=elapsed;
        if (frameTimer<=0){
            if (frame==8){
                frame=0;
            }else{
                frame++;
            }
            if(frame==5){
                frame=0;
            }
            frameTimer+=150;
        }
    }
    // Apply the physics.
    physicsTimer+=elapsed;
    while(physicsTimer>16) {
        physicsTimer-=16;
        updateGravity(map);
    }
}

void Actor::updateGravity(Map *map)
{
        if( ay!=0) {
                printf("y=%.2f; vy=%.2f; ay=%.2f\n",y,vy,ay);
        }
        vy=vy+ay;
        vy=vy+GRAVITY;   // earth gravity is 9.8 m/s^2, or whatever it works out to in your units.
        // apply terminal velocity
        if( vy<MINVEL) {
                vy=MINVEL;
                ay=0;  // hit minimum negative velocity so stop jumping.
        }
        if( vy>MAXVEL) {
                vy=MAXVEL;
                ay=0;  // hit maximum velocity so stop jumping.
        }
        // propose new position, and test for collision:
        float newy=y+vy;
        int i;
        for( i=0; i<8; i++) {
                int item=map->collide(x, newy+32, 32, 32 );
                int item2=map->collide(x+16, newy, 32, 32 );
                if( item==MAP_SKY ) break; // a safe place to move the item to.
                if( (item!=MAP_BARRIER_A && item!=MAP_BARRIER_B) && (item2!=MAP_BARRIER_A && item2!=MAP_BARRIER_B)) {
                    item=map->collect(x,newy+32, 32, 32);
                    item2=map->collect(x+16,newy, 32, 32);
                    collectedItem(item);
                    break;
                }
                if( item==MAP_BARRIER_A || item==MAP_BARRIER_B) {
                    if(vy<0) break;     // Jump up through walls!
                }
                // we don't want to be inside the object, so guess we can move half the distance.
                vy/=2.0f;
                newy=y+vy;
        }
        if( i==8) {
                newy=y; // we can't find a place closer to the ground/ceiling so we need to stop moving.
                vy=0;
                ay=0;
        }
        y=newy; // our new vertical position with gravity and jumping factored in!
}

void Actor::handle(bool down)
{
    ay=down?JUMP:0;
    if(down && !jump) {
        Sound::playSfx(SFX_JUMP);
    }

    jump=down;
}

void Actor::collectedItem(int item)
{
    if(item==MAP_BLUESTAR) {
        Sound::playSfx(SFX_MATCH);
        score+=1;
    } else if(item==MAP_REDSTAR) {
        Sound::playSfx(SFX_MATCH);
        score+=2;
    } else if(item==MAP_WHITESTART) {
        Sound::playSfx(SFX_MATCH);
        score+=3;
    } else if(item==MAP_SIGN) {
        Sound::playSfx(SFX_SIGN);
    } else if(item==MAP_POTATO) {
        Sound::playSfx(SFX_POTATO);
    } else if(item==MAP_MONEY) {
        Sound::playSfx(SFX_MONEY);
    } else if(item==MAP_MEATLOAF) {
        Sound::playSfx(SFX_MEATLOAF);
    } else if(item==MAP_BABY) {
        Sound::playSfx(SFX_BABY);
    }
}

void Actor::draw(SDL_Renderer *renderer)
{
    if(sprite) {
        sprite->draw(renderer,x,y,frame);
    }
    if (jump==true){
        Font::draw(renderer, FF_BODY,"Currently Jumping",0,350);
    }

}

int Actor::getScore()
{
    return score;
}

void Actor::resetScore()
{
    score=0;
}
<|endoftext|>


<commit_before>#include "node.h"
#include "devisPattern.hpp"

namespace devisPattern {

    using v8::FunctionCallbackInfo;
    using v8::Isolate;
    using v8::Local;
    using v8::Object;
    using v8::String;
    using v8::Value;

    void CreateObject(const FunctionCallbackInfo<Value>& args) {
        devisPattern::NewInstance(args);
    }

    void InitAll(Local<Object> exports) {
        devisPattern::Init(exports);

            }

    NODE_MODULE(addon, InitAll)

}<commit_msg>Update addon.cpp<commit_after>/* Copyright (c) 2016 Devis, MIT License */
#include "node.h"
#include "devisPattern.hpp"

namespace devisPattern {

    using v8::FunctionCallbackInfo;
    using v8::Isolate;
    using v8::Local;
    using v8::Object;
    using v8::String;
    using v8::Value;

    void CreateObject(const FunctionCallbackInfo<Value>& args) {
        devisPattern::NewInstance(args);
    }

    void InitAll(Local<Object> exports) {
        devisPattern::Init(exports);

            }

    NODE_MODULE(addon, InitAll)

}
<|endoftext|>


<commit_before>/*
  A hacky replacement for backtrace_symbols in glibc

  backtrace_symbols in glibc looks up symbols using dladdr which is limited in
  the symbols that it sees. libbacktracesymbols opens the executable and shared
  libraries using libbfd and will look up backtrace information using the symbol
  table and the dwarf line information.

  It may make more sense for this program to use libelf instead of libbfd.
  However, I have not investigated that yet.

  Derived from addr2line.c from GNU Binutils by Jeff Muizelaar

  Copyright 2007 Jeff Muizelaar
*/

/* addr2line.c -- convert addresses to line number and function name
   Copyright 1997, 1998, 1999, 2000, 2001, 2002 Free Software Foundation, Inc.
   Contributed by Ulrich Lauther <Ulrich.Lauther@mchp.siemens.de>

   This file was part of GNU Binutils.

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

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

   You should have received a copy of the GNU General Public License
   along with this program; if not, write to the Free Software
   Foundation, 51 Franklin Street, Suite 500, Boston, MA 02110-1335, USA.  */

#ifdef HASBFD

#include "util/Result.h"
#include "FindFile.h" // GetBinaryFilename

/* 2 characters for each byte, plus 1 each for 0, x, and NULL */
#define PTRSTR_LEN (sizeof(void *) * 2 + 3)

#define _GNU_SOURCE
#include <string.h>
#include <stdio.h>
#include <stdlib.h>
#include <execinfo.h>
#ifdef __APPLE__
#include <bfd.h>
#include <dlfcn.h>
#else
#include <bfd.h>
#include <libiberty.h>
#include <dlfcn.h>
#include <link.h>
#endif

#if 0

void (*dbfd_init)(void);
bfd_vma (*dbfd_scan_vma)(const char *string, const char **end, int base);
bfd* (*dbfd_openr)(const char *filename, const char *target);
bfd_boolean (*dbfd_check_format)(bfd *abfd, bfd_format format);
bfd_boolean (*dbfd_check_format_matches)(bfd *abfd, bfd_format format, char ***matching);
bfd_boolean (*dbfd_close)(bfd *abfd);
bfd_boolean (*dbfd_map_over_sections)(bfd *abfd, void (*func)(bfd *abfd, asection *sect, void *obj),
		void *obj);
#define bfd_init dbfd_init

static void load_funcs(void)
{
	void * handle = dlopen("libbfd.so", RTLD_NOW);
	dbfd_init = dlsym(handle, "bfd_init");
	dbfd_scan_vma = dlsym(handle, "bfd_scan_vma");
	dbfd_openr = dlsym(handle, "bfd_openr");
	dbfd_check_format = dlsym(handle, "bfd_check_format");
	dbfd_check_format_matches = dlsym(handle, "bfd_check_format_matches");
	dbfd_close = dlsym(handle, "bfd_close");
	dbfd_map_over_sections = dlsym(handle, "bfd_map_over_sections");
}

#endif

static asymbol **syms;		/* Symbol table.  */

static Result slurp_symtab(bfd * abfd);
static void find_address_in_section(bfd *abfd, asection *section, void *data);

/* Read in the symbol table.  */

static Result slurp_symtab(bfd * abfd)
{
	if ((bfd_get_file_flags(abfd) & HAS_SYMS) == 0)
		return true;

	unsigned int size = 0;
	long symcount = bfd_read_minisymbols(abfd, false, (void**) &syms, &size);
	if (symcount == 0)
		symcount = bfd_read_minisymbols(abfd, true /* dynamic */ ,
						(void**) &syms, &size);

	if (symcount < 0)
		return false; //bfd_get_filename(abfd));

	return true;
}

/* These global variables are used to pass information between
   translate_addresses and find_address_in_section.  */

static bfd_vma pc;
static const char *filename;
static const char *functionname;
static unsigned int line;
static Result found(true);

/* Look for an address in a section.  This is called via
   bfd_map_over_sections.  */

static void find_address_in_section(bfd *abfd, asection *section, void *data __attribute__ ((__unused__)) )
{
	bfd_vma vma;
	bfd_size_type size;

	if (found)
		return;

	if ((bfd_get_section_flags(abfd, section) & SEC_ALLOC) == 0) {
		found = "not SEC_ALLOC";
		return;
	}

	vma = bfd_get_section_vma(abfd, section);
	if (pc < vma) {
		found = "pc < vma";
		return;
	}

	size = bfd_section_size(abfd, section);
	if (pc >= vma + size) {
		found = "pc >= vma + size";
		return;
	}

	found = bfd_find_nearest_line(abfd, section, syms, pc/* - vma*/,
				      &filename, &functionname, &line);
}

static char** translate_addresses_buf(bfd * abfd, bfd_vma *addr, int naddr)
{
	int naddr_orig = naddr;
	char b;
	int total  = 0;
	enum State { Count, Print } state;
	char *buf = &b;
	int len = 0;
	char **ret_buf = NULL;
	/* iterate over the formating twice.
	 * the first time we count how much space we need
	 * the second time we do the actual printing */
	for (state=Count; state<=Print; state = State(int(state) + 1)) {
	if (state == Print) {
		ret_buf = (char**)malloc(total + sizeof(char*)*naddr);
		buf = (char*)(ret_buf + naddr);
		len = total;
	}
	while (naddr) {
		if (state == Print)
			ret_buf[naddr-1] = buf;
		pc = addr[naddr-1];

		found = false;
		bfd_map_over_sections(abfd, find_address_in_section, (PTR) NULL);

		if (!found) {
			total += snprintf(buf, len, "[0x%llx] <%s>", (long long unsigned int) addr[naddr-1], found.humanErrorMsg.c_str()) + 1;
		} else {
			const char *name;

			name = functionname;
			if (name == NULL || *name == '\0')
				name = "??";
			if (filename != NULL) {
				char *h;

				h = strrchr(filename, '/');
				if (h != NULL)
					filename = h + 1;
			}
			total += snprintf(buf, len, "%s:%u\t%s()", filename ? filename : "??",
			       line, name) + 1;

		}
		if (state == Print) {
			/* set buf just past the end of string */
			buf = buf + total + 1;
		}
		naddr--;
	}
	naddr = naddr_orig;
	}
	return ret_buf;
}
/* Process a file.  */

static Result process_file(const char *file_name, bfd_vma *addr, int naddr, char**& ret_buf)
{
	bfd *abfd;
	char **matching;

	abfd = bfd_openr(file_name, NULL);

	if (abfd == NULL)
		return "no abfd";

	if (bfd_check_format(abfd, bfd_archive))
		return "can not get addresses from archive";

	if (!bfd_check_format_matches(abfd, bfd_object, &matching)) {
		//bfd_nonfatal(bfd_get_filename(abfd));
		if (bfd_get_error() ==
		    bfd_error_file_ambiguously_recognized) {
			//list_matching_formats(matching);
			free(matching);
		}
		return "format does not match";
	}

	slurp_symtab(abfd);

	ret_buf = translate_addresses_buf(abfd, addr, naddr);

	free (syms);
	syms = NULL;

	bfd_close(abfd);
	return true;
}

#define MAX_DEPTH 16

struct file_match {
	const char *file;
	void *address;
	void *base;
	void *hdr;
};

#ifndef __APPLE__
static int find_matching_file(struct dl_phdr_info *info,
		size_t size, void *data)
{
	struct file_match *match = (struct file_match*) data;
	/* This code is modeled from Gfind_proc_info-lsb.c:callback() from libunwind */
	long n;
	const ElfW(Phdr) *phdr;
	ElfW(Addr) load_base = info->dlpi_addr;
	phdr = info->dlpi_phdr;
	for (n = info->dlpi_phnum; --n >= 0; phdr++) {
		if (phdr->p_type == PT_LOAD) {
			ElfW(Addr) vaddr = phdr->p_vaddr + load_base;
			if (match->address >= vaddr && match->address < vaddr + phdr->p_memsz) {
				/* we found a match */
				match->file = info->dlpi_name;
				match->base = info->dlpi_addr;
			}
		}
	}
	return 0;
}
#endif

char **backtrace_symbols(void *const *buffer, int size)
{
	int stack_depth = size - 1;
	int x,y;
	/* discard calling function */
	int total = 0;

	char **final;
	char *f_strings;

	char*** locations = (char***)malloc(sizeof(char**) * (stack_depth+1));

	bfd_init();
	for(x=stack_depth, y=0; x>=0; x--, y++){
		char **ret_buf;
		bfd_vma addr = (bfd_vma)buffer[x];
		Result r = true;
#ifndef __APPLE__
		struct file_match match;
		match.address = buffer[x];
		dl_iterate_phdr(find_matching_file, &match);
		addr = buffer[x] - match.base;
		if (match.file && strlen(match.file))
			r = process_file(match.file, &addr, 1, ret_buf);
		else
#endif
			r = process_file(GetBinaryFilename(), &addr, 1, ret_buf);
		if(r)
			locations[x] = ret_buf;
		else {
			locations[x] = (char**)malloc(sizeof(char*));
			locations[x][0] = (char*)"<error>";
		}
		total += strlen(locations[x][0]) + 1;
	}

	/* allocate the array of char* we are going to return and extra space for
	 * all of the strings */
	final = (char**)malloc(total + (stack_depth + 1) * sizeof(char*));
	/* get a pointer to the extra space */
	f_strings = (char*)(final + stack_depth + 1);

	/* fill in all of strings and pointers */
	for(x=stack_depth; x>=0; x--){
		strcpy(f_strings, locations[x][0]);
		free(locations[x]);
		final[x] = f_strings;
		f_strings += strlen(f_strings) + 1;
	}

	free(locations);

	return final;
}

void
backtrace_symbols_fd(void *const *buffer, int size, int fd)
{
        int j;
        char **strings;

        strings = backtrace_symbols(buffer, size);
		if (strings == NULL) return;

        for (j = 0; j < size; j++)
		printf("%s\n", strings[j]);

        free(strings);
}

// Not sure on this. Linking failed on Mac.
// Found it here: http://www.mail-archive.com/uclinux-dev@uclinux.org/msg02347.html
#ifndef HAVE_LIBINTL_DGETTEXT
extern "C"
const char *libintl_dgettext (const char *domain, const char *msg)
{
  return msg;
}
#endif /* !HAVE_LIBINTL_DGETTEXT */

#endif // HASBFD
<commit_msg>better dbg msg<commit_after>/*
  A hacky replacement for backtrace_symbols in glibc

  backtrace_symbols in glibc looks up symbols using dladdr which is limited in
  the symbols that it sees. libbacktracesymbols opens the executable and shared
  libraries using libbfd and will look up backtrace information using the symbol
  table and the dwarf line information.

  It may make more sense for this program to use libelf instead of libbfd.
  However, I have not investigated that yet.

  Derived from addr2line.c from GNU Binutils by Jeff Muizelaar

  Copyright 2007 Jeff Muizelaar
*/

/* addr2line.c -- convert addresses to line number and function name
   Copyright 1997, 1998, 1999, 2000, 2001, 2002 Free Software Foundation, Inc.
   Contributed by Ulrich Lauther <Ulrich.Lauther@mchp.siemens.de>

   This file was part of GNU Binutils.

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

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

   You should have received a copy of the GNU General Public License
   along with this program; if not, write to the Free Software
   Foundation, 51 Franklin Street, Suite 500, Boston, MA 02110-1335, USA.  */

#ifdef HASBFD

#include "util/Result.h"
#include "FindFile.h" // GetBinaryFilename

/* 2 characters for each byte, plus 1 each for 0, x, and NULL */
#define PTRSTR_LEN (sizeof(void *) * 2 + 3)

#define _GNU_SOURCE
#include <string.h>
#include <stdio.h>
#include <stdlib.h>
#include <execinfo.h>
#ifdef __APPLE__
#include <bfd.h>
#include <dlfcn.h>
#else
#include <bfd.h>
#include <libiberty.h>
#include <dlfcn.h>
#include <link.h>
#endif

#if 0

void (*dbfd_init)(void);
bfd_vma (*dbfd_scan_vma)(const char *string, const char **end, int base);
bfd* (*dbfd_openr)(const char *filename, const char *target);
bfd_boolean (*dbfd_check_format)(bfd *abfd, bfd_format format);
bfd_boolean (*dbfd_check_format_matches)(bfd *abfd, bfd_format format, char ***matching);
bfd_boolean (*dbfd_close)(bfd *abfd);
bfd_boolean (*dbfd_map_over_sections)(bfd *abfd, void (*func)(bfd *abfd, asection *sect, void *obj),
		void *obj);
#define bfd_init dbfd_init

static void load_funcs(void)
{
	void * handle = dlopen("libbfd.so", RTLD_NOW);
	dbfd_init = dlsym(handle, "bfd_init");
	dbfd_scan_vma = dlsym(handle, "bfd_scan_vma");
	dbfd_openr = dlsym(handle, "bfd_openr");
	dbfd_check_format = dlsym(handle, "bfd_check_format");
	dbfd_check_format_matches = dlsym(handle, "bfd_check_format_matches");
	dbfd_close = dlsym(handle, "bfd_close");
	dbfd_map_over_sections = dlsym(handle, "bfd_map_over_sections");
}

#endif

static asymbol **syms;		/* Symbol table.  */

static Result slurp_symtab(bfd * abfd);
static void find_address_in_section(bfd *abfd, asection *section, void *data);

/* Read in the symbol table.  */

static Result slurp_symtab(bfd * abfd)
{
	if ((bfd_get_file_flags(abfd) & HAS_SYMS) == 0)
		return true;

	unsigned int size = 0;
	long symcount = bfd_read_minisymbols(abfd, false, (void**) &syms, &size);
	if (symcount == 0)
		symcount = bfd_read_minisymbols(abfd, true /* dynamic */ ,
						(void**) &syms, &size);

	if (symcount < 0)
		return false; //bfd_get_filename(abfd));

	return true;
}

/* These global variables are used to pass information between
   translate_addresses and find_address_in_section.  */

static bfd_vma pc;
static const char *filename;
static const char *functionname;
static unsigned int line;
static bool found = false;
static bool sectionFound = false;

/* Look for an address in a section.  This is called via
   bfd_map_over_sections.  */

static void find_address_in_section(bfd *abfd, asection *section, void *data __attribute__ ((__unused__)) )
{
	bfd_vma vma;
	bfd_size_type size;

	if (found)
		return;

	if ((bfd_get_section_flags(abfd, section) & SEC_ALLOC) == 0)
		return;

	vma = bfd_get_section_vma(abfd, section);
	if (pc < vma)
		return;

	size = bfd_section_size(abfd, section);
	if (pc >= vma + size)
		return;

	sectionFound = true;
	found = bfd_find_nearest_line(abfd, section, syms, pc - vma,
				      &filename, &functionname, &line);
}

static char** translate_addresses_buf(bfd * abfd, bfd_vma *addr, int naddr)
{
	int naddr_orig = naddr;
	char b;
	int total  = 0;
	enum State { Count, Print } state;
	char *buf = &b;
	int len = 0;
	char **ret_buf = NULL;
	/* iterate over the formating twice.
	 * the first time we count how much space we need
	 * the second time we do the actual printing */
	for (state=Count; state<=Print; state = State(int(state) + 1)) {
	if (state == Print) {
		ret_buf = (char**)malloc(total + sizeof(char*)*naddr);
		buf = (char*)(ret_buf + naddr);
		len = total;
	}
	while (naddr) {
		if (state == Print)
			ret_buf[naddr-1] = buf;
		pc = addr[naddr-1];

		sectionFound = false;
		found = false;
		bfd_map_over_sections(abfd, find_address_in_section, (PTR) NULL);

		if (!found) {
			std::string errMsg = "function not found";
			if(!sectionFound) errMsg = "section not found";
			total += snprintf(buf, len, "[0x%llx] <%s>", (long long unsigned int) addr[naddr-1], errMsg.c_str()) + 1;
		} else {
			const char *name;

			name = functionname;
			if (name == NULL || *name == '\0')
				name = "??";
			if (filename != NULL) {
				char *h;

				h = strrchr(filename, '/');
				if (h != NULL)
					filename = h + 1;
			}
			total += snprintf(buf, len, "%s:%u\t%s()", filename ? filename : "??",
			       line, name) + 1;

		}
		if (state == Print) {
			/* set buf just past the end of string */
			buf = buf + total + 1;
		}
		naddr--;
	}
	naddr = naddr_orig;
	}
	return ret_buf;
}
/* Process a file.  */

static Result process_file(const char *file_name, bfd_vma *addr, int naddr, char**& ret_buf)
{
	bfd *abfd;
	char **matching;

	abfd = bfd_openr(file_name, NULL);

	if (abfd == NULL)
		return "no abfd";

	if (bfd_check_format(abfd, bfd_archive))
		return "can not get addresses from archive";

	if (!bfd_check_format_matches(abfd, bfd_object, &matching)) {
		//bfd_nonfatal(bfd_get_filename(abfd));
		if (bfd_get_error() ==
		    bfd_error_file_ambiguously_recognized) {
			//list_matching_formats(matching);
			free(matching);
		}
		return "format does not match";
	}

	slurp_symtab(abfd);

	ret_buf = translate_addresses_buf(abfd, addr, naddr);

	free (syms);
	syms = NULL;

	bfd_close(abfd);
	return true;
}

#define MAX_DEPTH 16

struct file_match {
	const char *file;
	void *address;
	void *base;
	void *hdr;
};

#ifndef __APPLE__
static int find_matching_file(struct dl_phdr_info *info,
		size_t size, void *data)
{
	struct file_match *match = (struct file_match*) data;
	/* This code is modeled from Gfind_proc_info-lsb.c:callback() from libunwind */
	long n;
	const ElfW(Phdr) *phdr;
	ElfW(Addr) load_base = info->dlpi_addr;
	phdr = info->dlpi_phdr;
	for (n = info->dlpi_phnum; --n >= 0; phdr++) {
		if (phdr->p_type == PT_LOAD) {
			ElfW(Addr) vaddr = phdr->p_vaddr + load_base;
			if (match->address >= vaddr && match->address < vaddr + phdr->p_memsz) {
				/* we found a match */
				match->file = info->dlpi_name;
				match->base = info->dlpi_addr;
			}
		}
	}
	return 0;
}
#endif

char **backtrace_symbols(void *const *buffer, int size)
{
	int stack_depth = size - 1;
	int x,y;
	/* discard calling function */
	int total = 0;

	char **final;
	char *f_strings;

	char*** locations = (char***)malloc(sizeof(char**) * (stack_depth+1));

	bfd_init();
	for(x=stack_depth, y=0; x>=0; x--, y++){
		char **ret_buf;
		bfd_vma addr = (bfd_vma)buffer[x];
		Result r = true;
#ifndef __APPLE__
		struct file_match match;
		match.address = buffer[x];
		dl_iterate_phdr(find_matching_file, &match);
		addr = buffer[x] - match.base;
		if (match.file && strlen(match.file))
			r = process_file(match.file, &addr, 1, ret_buf);
		else
#endif
			r = process_file(GetBinaryFilename(), &addr, 1, ret_buf);
		if(r)
			locations[x] = ret_buf;
		else {
			locations[x] = (char**)malloc(sizeof(char*));
			locations[x][0] = (char*)"<error>";
		}
		total += strlen(locations[x][0]) + 1;
	}

	/* allocate the array of char* we are going to return and extra space for
	 * all of the strings */
	final = (char**)malloc(total + (stack_depth + 1) * sizeof(char*));
	/* get a pointer to the extra space */
	f_strings = (char*)(final + stack_depth + 1);

	/* fill in all of strings and pointers */
	for(x=stack_depth; x>=0; x--){
		strcpy(f_strings, locations[x][0]);
		free(locations[x]);
		final[x] = f_strings;
		f_strings += strlen(f_strings) + 1;
	}

	free(locations);

	return final;
}

void
backtrace_symbols_fd(void *const *buffer, int size, int fd)
{
        int j;
        char **strings;

        strings = backtrace_symbols(buffer, size);
		if (strings == NULL) return;

        for (j = 0; j < size; j++)
		printf("%s\n", strings[j]);

        free(strings);
}

// Not sure on this. Linking failed on Mac.
// Found it here: http://www.mail-archive.com/uclinux-dev@uclinux.org/msg02347.html
#ifndef HAVE_LIBINTL_DGETTEXT
extern "C"
const char *libintl_dgettext (const char *domain, const char *msg)
{
  return msg;
}
#endif /* !HAVE_LIBINTL_DGETTEXT */

#endif // HASBFD
<|endoftext|>