<commit_before>/* COPYRIGHT (c) 2015 Sam Westrick, Laxman Dhulipala, Umut Acar,
 * Arthur Chargueraud, and Michael Rainey.
 * All rights reserved.
 *
 * \file pwsa.cpp
 *
 */

#include "benchmark.hpp"
#include "treap-frontier.hpp"
#include "weighted-graph.hpp"
#include "native.hpp"
#include "defaults.hpp"
#include <cstring>

static inline void pmemset(char * ptr, int value, size_t num) {
  const size_t cutoff = 100000;
  if (num <= cutoff) {
    std::memset(ptr, value, num);
  } else {
    long m = num/2;
    pasl::sched::native::fork2([&] {
      pmemset(ptr, value, m);
    }, [&] {
      pmemset(ptr+m, value, num-m);
    });
  }
}

template <class Number, class Size>
void fill_array_par(std::atomic<Number>* array, Size sz, Number val) {
  pmemset((char*)array, val, sz*sizeof(Number));
}

template <class Body>
void print(const Body& b) {
  pasl::util::atomic::msg(b);
}

template <class FRONTIER, class HEURISTIC, class VERTEX>
std::atomic<long>* pwsa(graph<VERTEX>& graph, const HEURISTIC& heuristic,
                        const intT& source, const intT& destination,
                        int split_cutoff, int poll_cutoff) {
  intT N = graph.number_vertices();
  std::atomic<long>* finalized = pasl::data::mynew_array<std::atomic<long>>(N);
  fill_array_par(finalized, N, -1l);

  FRONTIER initF = FRONTIER();
  int heur = heuristic(source);
  VertexPackage vtxPackage = graph.make_vertex_package(source, false, 0);
  initF.insert(heur, vtxPackage);

  pasl::data::perworker::array<int> work_since_split;
  work_since_split.init(0);

  auto size = [&] (FRONTIER& frontier) {
    auto sz = frontier.total_weight();
    if (sz == 0) {
      work_since_split.mine() = 0;
      return 0; // no work left
    }
    if (sz > split_cutoff || (work_since_split.mine() > split_cutoff && sz > 1)) {
      return 2; // split
    }
    else {
      return 1; // don't split
    }
  };

  auto fork = [&] (FRONTIER& src, FRONTIER& dst) {
    print([&] { std::cout << "splitting "; src.display(); std::cout << std::endl; });
    src.split_at(src.total_weight() / 2, dst);
    print([&] { std::cout << "produced "; src.display(); std::cout << "; "; dst.display(); std::cout << std::endl; });
    work_since_split.mine() = 0;
  };

  auto set_in_env = [&] (FRONTIER& f) {
    ; // nothing to do
  };

  auto do_work = [&] (FRONTIER& frontier) {
    print([&] { std::cout << "Frontier dump: "; frontier.display(); std::cout << std::endl; });

    int work_this_round = 0;
    while (work_this_round < poll_cutoff && frontier.total_weight() > 0) {
      auto pair = frontier.delete_min();
      VertexPackage vpack = pair.second;
      long orig = -1l;
      if (vpack.mustProcess || (finalized[vpack.vertexId].load() == -1 && finalized[vpack.vertexId].compare_exchange_strong(orig, vpack.distance))) {
        if (vpack.vertexId == destination) {
          print([&] { std::cout << "FOUND DESTINATION: distance " << finalized[destination].load() << std::endl; });
          return true;
        }
        if (work_this_round + vpack.weight() > poll_cutoff) {
          // need to split vpack
          VertexPackage other = VertexPackage();
          vpack.split_at(poll_cutoff - work_this_round, other);
          other.mustProcess = true;
          if (other.weight() != 0) frontier.insert(pair.first, other);
        }
        // Have to process our vpack
        graph.apply_to_each_in_range(vpack, [&] (intT ngh, intT weight) {
          VertexPackage nghpack = graph.make_vertex_package(ngh, false, vpack.distance + weight);
          int heur = heuristic(ngh) + vpack.distance + weight;
          frontier.insert(heur, nghpack);

          print([&] { std::cout << "inserted pack "; nghpack.display(); std::cout << ": "; frontier.display(); std::cout << std::endl; });
        });
        work_this_round += vpack.weight();
      } else {
        // Account 1 for popping.
        work_this_round += 1;
      }
    }
    work_since_split.mine() += work_this_round;
    return false;
  };

  pasl::sched::native::parallel_while_pwsa(initF, size, fork, set_in_env, do_work);
  return finalized;
}

int main(int argc, char** argv) {
  long n;
  int split_cutoff;
  int poll_cutoff;
  std::string fname;
  int src;
  int dst;

  auto init = [&] {
    n = (long)pasl::util::cmdline::parse_or_default_long("n", 24);
    split_cutoff = (int)pasl::util::cmdline::parse_or_default_int("K", 100);
    poll_cutoff = (int)pasl::util::cmdline::parse_or_default_int("D", 100);
    fname = pasl::util::cmdline::parse_or_default_string("graph", "simple_weighted.txt");
    src = (int)pasl::util::cmdline::parse_or_default_int("src", 0);
    dst = (int)pasl::util::cmdline::parse_or_default_int("dst", 0);
  };

  auto run = [&] (bool sequential) {
    std::cout << n << std::endl;

    //char const* fname = "simple_weighted.txt";
    //char const* fname = "simple_weighted_2.txt";
    bool isSym = false;
    graph<asymmetricVertex> g = readGraphFromFile<asymmetricVertex>(fname.c_str(), isSym);

    g.printGraph();
    auto heuristic = [] (intT vtx) { return 0; };
    std::atomic<long>* res = pwsa<Treap<intT, VertexPackage>, decltype(heuristic), asymmetricVertex>(g, heuristic, src, dst, split_cutoff, poll_cutoff);
    for (int i = 0; i < g.n; i++) {
      std::cout << "res[" << i << "] = " << res[i].load() << std::endl;
    }
  };

  auto output = [&] {
    ;
  };

  auto destroy = [&] {
    ;
  };

  pasl::sched::launch(argc, argv, init, run, output, destroy);
  return 0;
}
<commit_msg>cleanup<commit_after>/* COPYRIGHT (c) 2015 Sam Westrick, Laxman Dhulipala, Umut Acar,
 * Arthur Chargueraud, and Michael Rainey.
 * All rights reserved.
 *
 * \file pwsa.cpp
 *
 */

#include "benchmark.hpp"
#include "treap-frontier.hpp"
#include "weighted-graph.hpp"
#include "native.hpp"
#include "defaults.hpp"
#include <cstring>

static inline void pmemset(char * ptr, int value, size_t num) {
  const size_t cutoff = 100000;
  if (num <= cutoff) {
    std::memset(ptr, value, num);
  } else {
    long m = num/2;
    pasl::sched::native::fork2([&] {
      pmemset(ptr, value, m);
    }, [&] {
      pmemset(ptr+m, value, num-m);
    });
  }
}

template <class Number, class Size>
void fill_array_par(std::atomic<Number>* array, Size sz, Number val) {
  pmemset((char*)array, val, sz*sizeof(Number));
}

bool shouldPrint = false;
template <class Body>
void print(const Body& b) {
  if (shouldPrint) {
    pasl::util::atomic::msg(b);
  }
}

template <class FRONTIER, class HEURISTIC, class VERTEX>
std::atomic<long>* pwsa(graph<VERTEX>& graph, const HEURISTIC& heuristic,
                        const intT& source, const intT& destination,
                        int split_cutoff, int poll_cutoff) {
  intT N = graph.number_vertices();
  std::atomic<long>* finalized = pasl::data::mynew_array<std::atomic<long>>(N);
  fill_array_par(finalized, N, -1l);

  FRONTIER initF = FRONTIER();
  int heur = heuristic(source);
  VertexPackage vtxPackage = graph.make_vertex_package(source, false, 0);
  initF.insert(heur, vtxPackage);

  pasl::data::perworker::array<int> work_since_split;
  work_since_split.init(0);

  auto size = [&] (FRONTIER& frontier) {
    auto sz = frontier.total_weight();
    if (sz == 0) {
      work_since_split.mine() = 0;
      return 0; // no work left
    }
    if (sz > split_cutoff || (work_since_split.mine() > split_cutoff && sz > 1)) {
      return 2; // split
    }
    else {
      return 1; // don't split
    }
  };

  auto fork = [&] (FRONTIER& src, FRONTIER& dst) {
    print([&] {
      std::cout << "splitting "; src.display();
      std::cout << std::endl;
    });
    src.split_at(src.total_weight() / 2, dst);
    print([&] {
      std::cout << "produced "; src.display(); std::cout << "; ";
      dst.display(); std::cout << std::endl;
    });
    work_since_split.mine() = 0;
  };

  auto set_in_env = [&] (FRONTIER& f) {;};

  auto do_work = [&] (FRONTIER& frontier) {
    print([&] {
      std::cout << "Frontier dump: "; frontier.display();
      std::cout << std::endl;
    });

    int work_this_round = 0;
    while (work_this_round < poll_cutoff && frontier.total_weight() > 0) {
      auto pair = frontier.delete_min();
      VertexPackage vpack = pair.second;
      long orig = -1l;
      if (vpack.mustProcess ||
         (finalized[vpack.vertexId].load() == -1 &&
          finalized[vpack.vertexId].compare_exchange_strong(orig, vpack.distance))) {
        if (vpack.vertexId == destination) {
          print([&] {
            std::cout << "Found destination: distance = " <<
            finalized[destination].load() << std::endl;
          });
          return true;
        }
        if (work_this_round + vpack.weight() > poll_cutoff) {
          // need to split vpack
          VertexPackage other = VertexPackage();
          vpack.split_at(poll_cutoff - work_this_round, other);
          other.mustProcess = true;
          if (other.weight() != 0) {
            frontier.insert(pair.first, other);
          }
        }
        // Have to process our vpack
        graph.apply_to_each_in_range(vpack, [&] (intT ngh, intT weight) {
          VertexPackage nghpack = graph.make_vertex_package(ngh, false, vpack.distance + weight);
          int heur = heuristic(ngh) + vpack.distance + weight;
          frontier.insert(heur, nghpack);

          print([&] {
            std::cout << "inserted pack "; nghpack.display();
            std::cout << ": "; frontier.display(); std::cout << std::endl;
          });
        });
        work_this_round += vpack.weight();
      } else {
        // Account 1 for popping.
        work_this_round += 1;
      }
    }
    work_since_split.mine() += work_this_round;
    return false;
  };

  pasl::sched::native::parallel_while_pwsa(initF, size, fork, set_in_env, do_work);
  return finalized;
}

int main(int argc, char** argv) {
  int split_cutoff; // (K)
  int poll_cutoff; // (D)
  std::string fname;
  int src;
  int dst;

  auto init = [&] {
    split_cutoff = (int)pasl::util::cmdline::parse_or_default_int("K", 100);
    poll_cutoff = (int)pasl::util::cmdline::parse_or_default_int("D", 100);
    fname = pasl::util::cmdline::parse_or_default_string("graph", "graphs/simple_weighted.txt");
    src = (int)pasl::util::cmdline::parse_or_default_int("src", 0);
    dst = (int)pasl::util::cmdline::parse_or_default_int("dst", 0);
  };

  auto run = [&] (bool sequential) {

    bool isSym = false;
    graph<asymmetricVertex> g = readGraphFromFile<asymmetricVertex>(fname.c_str(), isSym);

    // g.printGraph();
    auto heuristic = [] (intT vtx) { return 0; };
    std::atomic<long>* res = pwsa<Treap<intT, VertexPackage>,
                                  decltype(heuristic),
                                  asymmetricVertex>(g, heuristic, src, dst,
                                                    split_cutoff, poll_cutoff);

    int numExpanded = 0;
    for (int i = 0; i < g.n; i++) {
      if (res[i].load() != -1) {
        numExpanded++;
      }
    }
    std::cout << "expanded : " << numExpanded << " many nodes out of " << g.n;
    std::cout << "path lengh is : " << res[dst].load();

//    for (int i = 0; i < g.n; i++) {
//      std::cout << "res[" << i << "] = " << res[i].load() << std::endl;
//    }
  };

  auto output = [&] {;};

  auto destroy = [&] {;};

  pasl::sched::launch(argc, argv, init, run, output, destroy);
  return 0;
}
<|endoftext|>


<commit_before>/*
 * Priority.cpp
 *
 * Copyright 2000, LifeLine Networks BV (www.lifeline.nl). All rights reserved.
 * Copyright 2000, Bastiaan Bakker. All rights reserved.
 *
 * See the COPYING file for the terms of usage and distribution.
 */

#include "PortabilityImpl.hh"
#include <log4cpp/Priority.hh>
#include <cstdlib>

namespace log4cpp {

    namespace {
        const std::string names[10] = {
            "FATAL",
			"ALERT",
			"CRIT",
			"ERROR",
			"WARN",
            "NOTICE",
			"INFO",
			"DEBUG",
			"NOTSET",
			"UNKNOWN"
        };
    }

    const int log4cpp::Priority::MESSAGE_SIZE = 8;

    const std::string& Priority::getPriorityName(int priority) throw() {

        priority++;
        priority /= 100;
        return names[((priority < 0) || (priority > 8)) ? 8 : priority];
    }

    Priority::Value Priority::getPriorityValue(const std::string& priorityName)
    throw(std::invalid_argument) {
	Priority::Value value = -1;

	for (unsigned int i = 0; i < 10; i++) {
	    if (priorityName == names[i]) {
		value = i * 100;
		break;
	    }
	}

	if (value == -1) {
	    if (priorityName == "EMERG") {
		    value = 0;
	    } else {
		    char* endPointer;
		    value = std::strtoul(priorityName.c_str(), &endPointer, 10);
		    if (*endPointer != 0) {
		        throw std::invalid_argument(
					std::string("unknown priority name: '") + priorityName + "'"
				);
		    }
	    }
	}

	return value;
    }
}
<commit_msg>Fix for bug#3198140<commit_after>/*
 * Priority.cpp
 *
 * Copyright 2000, LifeLine Networks BV (www.lifeline.nl). All rights reserved.
 * Copyright 2000, Bastiaan Bakker. All rights reserved.
 *
 * See the COPYING file for the terms of usage and distribution.
 */

#include "PortabilityImpl.hh"
#include <log4cpp/Priority.hh>
#include <cstdlib>

namespace log4cpp {

    namespace {
	const std::string *names() {
	    static const std::string priority_names[10] = {
			"FATAL",
			"ALERT",
			"CRIT",
			"ERROR",
			"WARN",
			"NOTICE",
			"INFO",
			"DEBUG",
			"NOTSET",
			"UNKNOWN"
	    };
	    return priority_names;
	}
    }

    const int log4cpp::Priority::MESSAGE_SIZE = 8;

    const std::string& Priority::getPriorityName(int priority) throw() {

        priority++;
        priority /= 100;
        return names()[((priority < 0) || (priority > 8)) ? 8 : priority];
    }

    Priority::Value Priority::getPriorityValue(const std::string& priorityName)
    throw(std::invalid_argument) {
	Priority::Value value = -1;

	for (unsigned int i = 0; i < 10; i++) {
	    if (priorityName == names()[i]) {
		value = i * 100;
		break;
	    }
	}

	if (value == -1) {
	    if (priorityName == "EMERG") {
		    value = 0;
	    } else {
		    char* endPointer;
		    value = std::strtoul(priorityName.c_str(), &endPointer, 10);
		    if (*endPointer != 0) {
		        throw std::invalid_argument(
					std::string("unknown priority name: '") + priorityName + "'"
				);
		    }
	    }
	}

	return value;
    }
}
<|endoftext|>


<commit_before>/*

Copyright (c) 2015, Project OSRM contributors
All rights reserved.

Redistribution and use in source and binary forms, with or without modification,
are permitted provided that the following conditions are met:

Redistributions of source code must retain the above copyright notice, this list
of conditions and the following disclaimer.
Redistributions in binary form must reproduce the above copyright notice, this
list of conditions and the following disclaimer in the documentation and/or
other materials provided with the distribution.

THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR
ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

*/

// based on
// https://svn.apache.org/repos/asf/mesos/tags/release-0.9.0-incubating-RC0/src/common/json.hpp

#ifndef JSON_V8_RENDERER_HPP
#define JSON_V8_RENDERER_HPP

#include <osrm/json_container.hpp>

// v8
#include <nan.h>

#include <functional>

namespace node_osrm
{

struct V8Renderer : mapbox::util::static_visitor<>
{
    explicit V8Renderer(v8::Local<v8::Value> &_out) : out(_out) {}

    void operator()(const osrm::json::String &string) const
    {
        out = Nan::New(std::cref(string.value)).ToLocalChecked();
    }

    void operator()(const osrm::json::Number &number) const { out = Nan::New(number.value); }

    void operator()(const osrm::json::Object &object) const
    {
        v8::Local<v8::Object> obj = Nan::New<v8::Object>();
        for (const auto &keyValue : object.values)
        {
            v8::Local<v8::Value> child;
            mapbox::util::apply_visitor(v8_renderer(child), keyValue.second);
            obj->Set(Nan::New(keyValue.first).ToLocalChecked(), child);
        }
        out = obj;
    }

    void operator()(const osrm::json::Array &array) const
    {
        v8::Local<v8::Array> a = Nan::New<v8::Array>(array.values.size());
        for (auto i = 0u; i < array.values.size(); ++i)
        {
            v8::Local<v8::Value> child;
            mapbox::util::apply_visitor(v8_renderer(child), array.values[i]);
            a->Set(i, child);
        }
        out = a;
    }

    void operator()(const osrm::json::True &) const { out = Nan::New(true); }

    void operator()(const osrm::json::False &) const { out = Nan::New(false); }

    void operator()(const osrm::json::Null &) const { out = Nan::Null(); }

  private:
    v8::Local<v8::Value> &out;
};

inline void renderToV8(v8::Local<v8::Value> &out, const osrm::json::Object &object)
{
    // FIXME this should be a cast?
    osrm::json::Value value = object;
    mapbox::util::apply_visitor(V8Renderer(out), value);
}

}

#endif // JSON_V8_RENDERER_HPP
<commit_msg>Fix v8 renderer<commit_after>/*

Copyright (c) 2015, Project OSRM contributors
All rights reserved.

Redistribution and use in source and binary forms, with or without modification,
are permitted provided that the following conditions are met:

Redistributions of source code must retain the above copyright notice, this list
of conditions and the following disclaimer.
Redistributions in binary form must reproduce the above copyright notice, this
list of conditions and the following disclaimer in the documentation and/or
other materials provided with the distribution.

THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR
ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

*/

// based on
// https://svn.apache.org/repos/asf/mesos/tags/release-0.9.0-incubating-RC0/src/common/json.hpp

#ifndef JSON_V8_RENDERER_HPP
#define JSON_V8_RENDERER_HPP

#include <osrm/json_container.hpp>

// v8
#include <nan.h>

#include <functional>

namespace node_osrm
{

struct V8Renderer : mapbox::util::static_visitor<>
{
    explicit V8Renderer(v8::Local<v8::Value> &_out) : out(_out) {}

    void operator()(const osrm::json::String &string) const
    {
        out = Nan::New(std::cref(string.value)).ToLocalChecked();
    }

    void operator()(const osrm::json::Number &number) const { out = Nan::New(number.value); }

    void operator()(const osrm::json::Object &object) const
    {
        v8::Local<v8::Object> obj = Nan::New<v8::Object>();
        for (const auto &keyValue : object.values)
        {
            v8::Local<v8::Value> child;
            mapbox::util::apply_visitor(V8Renderer(child), keyValue.second);
            obj->Set(Nan::New(keyValue.first).ToLocalChecked(), child);
        }
        out = obj;
    }

    void operator()(const osrm::json::Array &array) const
    {
        v8::Local<v8::Array> a = Nan::New<v8::Array>(array.values.size());
        for (auto i = 0u; i < array.values.size(); ++i)
        {
            v8::Local<v8::Value> child;
            mapbox::util::apply_visitor(V8Renderer(child), array.values[i]);
            a->Set(i, child);
        }
        out = a;
    }

    void operator()(const osrm::json::True &) const { out = Nan::New(true); }

    void operator()(const osrm::json::False &) const { out = Nan::New(false); }

    void operator()(const osrm::json::Null &) const { out = Nan::Null(); }

  private:
    v8::Local<v8::Value> &out;
};

inline void renderToV8(v8::Local<v8::Value> &out, const osrm::json::Object &object)
{
    // FIXME this should be a cast?
    osrm::json::Value value = object;
    mapbox::util::apply_visitor(V8Renderer(out), value);
}

}

#endif // JSON_V8_RENDERER_HPP
<|endoftext|>


<commit_before>/******************************************************************************
 *  Copyright (c) 2015 Jamis Hoo
 *  Distributed under the MIT license
 *  (See accompanying file LICENSE or copy at http://opensource.org/licenses/MIT)
 *
 *  Project:
 *  Filename: k_means_iteration.cc
 *  Version: 1.0
 *  Author: Jamis Hoo
 *  E-mail: hjm211324@gmail.com
 *  Date: Jul 19, 2015
 *  Time: 20:55:38
 *  Description:
 *****************************************************************************/
#include <iostream>
#include <fstream>
#include <cassert>
#include <unordered_map>
#include <algorithm>

#include "hadoop/Pipes.hh"
#include "hadoop/TemplateFactory.hh"
#include "hadoop/StringUtils.hh"

#include "netflix_movie.h"

constexpr size_t canopy_threshold = 2;
const std::string canopy_centers_path = "canopy_centers";
const std::string k_means_center_path = "k_means_centers";

inline std::string to_hex_string(const size_t x) {
    char buff[32] = { 0 };
    sprintf(buff, "%zx", x);

    return buff;
}

inline std::vector<uint32_t> string_split(const std::string& str) {
    std::vector<uint32_t> numbers;

    char* offset;

    const char* end = str.data() + str.length();
    const char* tmp = str.data();
    while (tmp < end) {
        uint32_t movie_id = strtoul(tmp, &offset, 16);
        numbers.emplace_back(movie_id);
        tmp = offset + 1;
    }

    return numbers;
}

class kMeansMapper: public HadoopPipes::Mapper {
public:
    kMeansMapper(HadoopPipes::TaskContext& /* context */) {
        load_canopy_centers();
        load_kmeans_centers();

        // no use anymore
        canopy_centers.clear();
    }

    void map(HadoopPipes::MapContext& context) {
        std::string input_value = context.getInputValue();

        std::string movie_string =
            input_value.substr(0, input_value.find_first_of('\t')) + ':' +
            input_value.substr(input_value.find_first_of(';') + 1);

        Movie movie = movie_string;

        size_t start_pos = input_value.find_first_of('\t');
        size_t end_pos = input_value.find_first_of(';', start_pos);
        std::vector<uint32_t> canopy_ids = string_split(input_value.substr(start_pos + 1, end_pos - start_pos - 1));

        float max_distance = -1;
        const Movie* max_distance_movie = nullptr;
        for (const auto canopy_id: canopy_ids) {
            if (canopy_id == movie.movie_id()) continue;
            for (const auto& k_means_center: centers[canopy_id]) {
                float distance = movie.cos_distance(k_means_center);
                if (distance > max_distance) {
                    max_distance = distance;
                    max_distance_movie = &k_means_center;
                }
            }
        }

        std::string emit_key = max_distance_movie->to_string();
        std::string emit_value = movie_string;

        context.emit(emit_key, emit_value);
    }

private:
    void load_canopy_centers() {
        std::ifstream fin(canopy_centers_path);

        std::string line;
        while (std::getline(fin, line))
            canopy_centers.emplace_back(line);

    }

    void load_kmeans_centers() {
        std::ifstream fin(k_means_center_path);

        std::string line;
        while (std::getline(fin, line)) {
            Movie k_means_center(line);

            for (const auto& canopy_center: canopy_centers)
                if (k_means_center.user_match_count(canopy_center) > canopy_threshold) {
                    auto ite = centers.emplace(canopy_center.movie_id(), std::vector<Movie>()).first;
                    ite->second.push_back(k_means_center);
                }
        }
    }

    std::vector<Movie> canopy_centers;
    // canopy movie_id, vector of k-means centers
    std::unordered_map< uint32_t, std::vector<Movie> > centers;
};

class kMeansReducer: public HadoopPipes::Reducer {
public:
    kMeansReducer(const HadoopPipes::TaskContext& /* context */) { }

    void reduce(HadoopPipes::ReduceContext& context) {
        Movie k_means_center(context.getInputKey());

        // <user id, < number of users, total user ratings > >
        std::unordered_map<uint32_t, std::pair<uint32_t, uint32_t> > new_features;

        while (context.nextValue()) {
            Movie movie(context.getInputValue());

            for (size_t i = 0; i < movie.num_users(); ++i) {
                auto ite = new_features.emplace(movie.user_id(i), std::make_pair(0, 0)).first;

                ite->second.first += 1;
                ite->second.second += movie.rating(i);
            }
        }

        std::vector< std::pair<uint32_t, uint32_t> > new_features_vec;
        for (const auto i: new_features)
            new_features_vec.push_back({ i.first, i.second.second / i.second.first });

        sort(new_features_vec.begin(), new_features_vec.end());

        std::string emit_key = to_hex_string(k_means_center.movie_id());

        std::string emit_value;
        for (const auto i: new_features_vec)
            emit_value += to_hex_string(i.first) + ',' + to_hex_string(i.second) + ',';

        if (emit_value.size()) {
            emit_value.pop_back();
            context.emit(emit_key, emit_value);
        }
    }
};

int main(int, char**) {
    return HadoopPipes::runTask(HadoopPipes::TemplateFactory<kMeansMapper, kMeansReducer>());
}

<commit_msg>fix bug<commit_after>/******************************************************************************
 *  Copyright (c) 2015 Jamis Hoo
 *  Distributed under the MIT license
 *  (See accompanying file LICENSE or copy at http://opensource.org/licenses/MIT)
 *
 *  Project:
 *  Filename: k_means_iteration.cc
 *  Version: 1.0
 *  Author: Jamis Hoo
 *  E-mail: hjm211324@gmail.com
 *  Date: Jul 19, 2015
 *  Time: 20:55:38
 *  Description:
 *****************************************************************************/
#include <iostream>
#include <fstream>
#include <cassert>
#include <unordered_map>
#include <algorithm>

#include "hadoop/Pipes.hh"
#include "hadoop/TemplateFactory.hh"
#include "hadoop/StringUtils.hh"

#include "netflix_movie.h"

constexpr size_t canopy_threshold = 2;
const std::string canopy_centers_path = "canopy_centers";
const std::string k_means_center_path = "k_means_centers";

inline std::string to_hex_string(const size_t x) {
    char buff[32] = { 0 };
    sprintf(buff, "%zx", x);

    return buff;
}

inline std::vector<uint32_t> string_split(const std::string& str) {
    std::vector<uint32_t> numbers;

    char* offset;

    const char* end = str.data() + str.length();
    const char* tmp = str.data();
    while (tmp < end) {
        uint32_t movie_id = strtoul(tmp, &offset, 16);
        numbers.emplace_back(movie_id);
        tmp = offset + 1;
    }

    return numbers;
}

class kMeansMapper: public HadoopPipes::Mapper {
public:
    kMeansMapper(HadoopPipes::TaskContext& /* context */) {
        load_canopy_centers();
        load_kmeans_centers();

        // no use anymore
        canopy_centers.clear();
    }

    void map(HadoopPipes::MapContext& context) {
        std::string input_value = context.getInputValue();

        std::string movie_string =
            input_value.substr(0, input_value.find_first_of('\t')) + ':' +
            input_value.substr(input_value.find_first_of(';') + 1);

        Movie movie = movie_string;

        std::cout << "Load input movie: " << movie.to_string() << std::endl;

        size_t start_pos = input_value.find_first_of('\t');
        size_t end_pos = input_value.find_first_of(';', start_pos);
        std::vector<uint32_t> canopy_ids = string_split(input_value.substr(start_pos + 1, end_pos - start_pos - 1));

        std::cout << "canopy_ids: "; for (const auto i: canopy_ids) std::cout << i << ' '; std::cout << std::endl;

        float max_distance = -1;
        const Movie* max_distance_movie = nullptr;
        for (const auto canopy_id: canopy_ids) {
            if (canopy_id == movie.movie_id()) continue;
            for (const auto& k_means_center: centers[canopy_id]) {
                float distance = movie.cos_distance(k_means_center);
                std::cout << "Distance with " << k_means_center.to_string() << " is " << distance;
                if (distance > max_distance) {
                    std::cout << " is max. ";
                    max_distance = distance;
                    max_distance_movie = &k_means_center;
                }
                std::cout << std::endl;
            }
        }

        if (max_distance_movie == nullptr) return;

        std::string emit_key = max_distance_movie->to_string();
        std::string emit_value = movie_string;

        std::cout << "emit_key = " << emit_key << std::endl;
        std::cout << "emit_value = " << emit_value << std::endl;

        context.emit(emit_key, emit_value);
    }

private:
    void load_canopy_centers() {
        std::ifstream fin(canopy_centers_path);

        std::string line;
        while (std::getline(fin, line)) {
            canopy_centers.emplace_back(line);
            std::cout << "Load cannopy center: " << canopy_centers.back().to_string() << std::endl;
        }

    }

    void load_kmeans_centers() {
        std::ifstream fin(k_means_center_path);

        std::string line;
        while (std::getline(fin, line)) {
            Movie k_means_center(line);

            std::cout << "k-means center: " << k_means_center.to_string() << " ";
            for (const auto& canopy_center: canopy_centers)
                if (k_means_center.user_match_count(canopy_center) > canopy_threshold) {
                    std::cout << "applied to canopy " << canopy_center.to_string() << " ";
                    auto ite = centers.emplace(canopy_center.movie_id(), std::vector<Movie>()).first;
                    ite->second.push_back(k_means_center);
                }
            std::cout << std::endl;
        }
    }

    std::vector<Movie> canopy_centers;
    // canopy movie_id, vector of k-means centers
    std::unordered_map< uint32_t, std::vector<Movie> > centers;
};

class kMeansReducer: public HadoopPipes::Reducer {
public:
    kMeansReducer(const HadoopPipes::TaskContext& /* context */) { }

    void reduce(HadoopPipes::ReduceContext& context) {
        Movie k_means_center(context.getInputKey());

        // <user id, < number of users, total user ratings > >
        std::unordered_map<uint32_t, std::pair<uint32_t, uint32_t> > new_features;

        while (context.nextValue()) {
            Movie movie(context.getInputValue());

            for (size_t i = 0; i < movie.num_users(); ++i) {
                auto ite = new_features.emplace(movie.user_id(i), std::make_pair(0, 0)).first;

                ite->second.first += 1;
                ite->second.second += movie.rating(i);
            }
        }

        std::vector< std::pair<uint32_t, uint32_t> > new_features_vec;
        for (const auto i: new_features)
            new_features_vec.push_back({ i.first, i.second.second / i.second.first });

        sort(new_features_vec.begin(), new_features_vec.end());

        std::string emit_key = to_hex_string(k_means_center.movie_id());

        std::string emit_value;
        for (const auto i: new_features_vec)
            emit_value += to_hex_string(i.first) + ',' + to_hex_string(i.second) + ',';

        if (emit_value.size()) {
            emit_value.pop_back();
            context.emit(emit_key, emit_value);
        }
    }
};

int main(int, char**) {
    return HadoopPipes::runTask(HadoopPipes::TemplateFactory<kMeansMapper, kMeansReducer>());
}

<|endoftext|>


<commit_before>/* GG is a GUI for SDL and OpenGL.
   Copyright (C) 2003 T. Zachary Laine

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

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

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

   If you do not wish to comply with the terms of the LGPL please
   contact the author as other terms are available for a fee.

   Zach Laine
   whatwasthataddress@hotmail.com */

/* $Header$ */

#include "SDLGGApp.h"

using std::string;

// member functions
SDLGGApp::SDLGGApp(int w/* = 1024*/, int h/* = 768*/, bool calc_FPS/* = false*/, const std::string& app_name/* = "GG"*/) :
        GG::App(this, app_name),
        m_app_width(w),
        m_app_height(h),
        m_delta_t(1),
        m_FPS(-1.0),
        m_calc_FPS(calc_FPS)
{
}

SDLGGApp::~SDLGGApp()
{
    SDLQuit();
}

SDLGGApp* SDLGGApp::GetApp()
{
    return dynamic_cast<SDLGGApp*>(GG::App::GetApp());
}

void SDLGGApp::Exit(int code)
{
    Logger().fatalStream() << "Initiating Exit (code " << code << " - " << (code ? "error" : "normal") << " termination)";
    SDLQuit();
    exit(code);
}

void SDLGGApp::CalcuateFPS(bool b/* = true*/)
{
    m_calc_FPS = b;
    if (!b) m_FPS = -1.0f;
}

const string& SDLGGApp::FPSString() const
{
    static string retval;
    char buf[64];
    sprintf(buf, "%.2f frames per second", m_FPS);
    retval = buf;
    return retval;
}

GG::Key SDLGGApp::GGKeyFromSDLKey(const SDL_keysym& key)
{
    GG::Key retval = GG::Key(key.sym);
    bool shift = key.mod & KMOD_SHIFT;
    bool caps_lock = key.mod & KMOD_CAPS;

    // this code works because both SDLKey and GG::Key map (at least
    // partially) to the printable ASCII characters
    if (shift || caps_lock) {
        if (shift != caps_lock && (retval >= 'a' && retval <= 'z')) {
            retval = GG::Key(toupper(retval));
        } else if (shift) { // the caps lock key should not affect these
            // this assumes a US keyboard layout
            switch (retval) {
            case '`': retval = GG::Key('~'); break;
            case '1': retval = GG::Key('!'); break;
            case '2': retval = GG::Key('@'); break;
            case '3': retval = GG::Key('#'); break;
            case '4': retval = GG::Key('$'); break;
            case '5': retval = GG::Key('%'); break;
            case '6': retval = GG::Key('^'); break;
            case '7': retval = GG::Key('&'); break;
            case '8': retval = GG::Key('*'); break;
            case '9': retval = GG::Key('('); break;
            case '0': retval = GG::Key(')'); break;
            case '-': retval = GG::Key('_'); break;
            case '=': retval = GG::Key('+'); break;
            case '[': retval = GG::Key('{'); break;
            case ']': retval = GG::Key('}'); break;
            case '\\': retval = GG::Key('|'); break;
            case ';': retval = GG::Key(':'); break;
            case '\'': retval = GG::Key('"'); break;
            case ',': retval = GG::Key('<'); break;
            case '.': retval = GG::Key('>'); break;
            case '/': retval = GG::Key('?'); break;
            default: break;
            }
        }
    }
    return retval;
}

void SDLGGApp::SDLInit()
{
    const SDL_VideoInfo* vid_info = 0;

    if (SDL_Init(SDL_INIT_VIDEO | SDL_INIT_NOPARACHUTE) < 0) {
        Logger().errorStream() << "SDL initialization failed: " << SDL_GetError();
        Exit(1);
    }

    if (SDLNet_Init() < 0) {
        Logger().errorStream() << "SDL Net initialization failed: " << SDLNet_GetError();
        Exit(1);
    }

    if (TTF_Init() < 0) {
        Logger().errorStream() << "TTF initialization failed: " << TTF_GetError();
        Exit(1);
    }

    if (FE_Init() < 0) {
        Logger().errorStream() << "FastEvents initialization failed: " << FE_GetError();
        Exit(1);
    }

    vid_info = SDL_GetVideoInfo();

    if (!vid_info) {
        Logger().errorStream() << "Video info query failed: " << SDL_GetError();
        Exit(1);
    }

    SDL_GL_SetAttribute(SDL_GL_DOUBLEBUFFER, 1);

    if (SDL_SetVideoMode(m_app_width, m_app_height, 16, SDL_OPENGL) == 0) {
        Logger().errorStream() << "Video mode set failed: " << SDL_GetError();
        Exit(1);
    }

    if (NET2_Init() < 0) {
        Logger().errorStream() << "SDL Net2 initialization failed: " << NET2_GetError();
        Exit(1);
    }

    SDL_EnableKeyRepeat(SDL_DEFAULT_REPEAT_DELAY, SDL_DEFAULT_REPEAT_INTERVAL);
    EnableMouseDragRepeat(SDL_DEFAULT_REPEAT_DELAY / 2, SDL_DEFAULT_REPEAT_INTERVAL / 2);

    Logger().debugStream() << "SDLInit() complete.";
    GLInit();
}

void SDLGGApp::GLInit()
{
    double ratio = m_app_width / (float)(m_app_height);

    glEnable(GL_LIGHTING);
    glEnable(GL_LIGHT0);
    glEnable(GL_DEPTH_TEST);
    glEnable(GL_CULL_FACE);
    glEnable(GL_BLEND);
    glShadeModel(GL_SMOOTH);
    glClearColor(0, 0, 0, 0);
    glViewport(0, 0, m_app_width - 1, m_app_height - 1);
    glMatrixMode(GL_PROJECTION);
    glLoadIdentity();
    gluPerspective(50.0, ratio, 1.0, 10.0);

    Logger().debugStream() << "GLInit() complete.";
}

void SDLGGApp::HandleSDLEvent(const SDL_Event& event)
{
    bool send_to_gg = false;
    GG::App::EventType gg_event;
    GG::Key key = GGKeyFromSDLKey(event.key.keysym);
    Uint32 key_mods = SDL_GetModState();
    GG::Pt mouse_pos(event.motion.x, event.motion.y);
    GG::Pt mouse_rel(event.motion.xrel, event.motion.yrel);

    switch(event.type) {
    case SDL_KEYDOWN:
        if (key < GG::GGK_NUMLOCK)
            send_to_gg = true;
        gg_event = GG::App::KEYPRESS;
        break;
    case SDL_MOUSEMOTION:
        send_to_gg = true;
        gg_event = GG::App::MOUSEMOVE;
        break;
    case SDL_MOUSEBUTTONDOWN:
        send_to_gg = true;
        switch (event.button.button) {
        case SDL_BUTTON_LEFT:      gg_event = GG::App::LPRESS; break;
        case SDL_BUTTON_MIDDLE:    gg_event = GG::App::MPRESS; break;
        case SDL_BUTTON_RIGHT:     gg_event = GG::App::RPRESS; break;
        case SDL_BUTTON_WHEELUP:   gg_event = GG::App::MOUSEWHEEL; mouse_rel = GG::Pt(0, 1); break;
        case SDL_BUTTON_WHEELDOWN: gg_event = GG::App::MOUSEWHEEL; mouse_rel = GG::Pt(0, -1); break;
        }
        key_mods = SDL_GetModState();
        break;
    case SDL_MOUSEBUTTONUP:
        send_to_gg = true;
        switch (event.button.button) {
        case SDL_BUTTON_LEFT:   gg_event = GG::App::LRELEASE; break;
        case SDL_BUTTON_MIDDLE: gg_event = GG::App::MRELEASE; break;
        case SDL_BUTTON_RIGHT:  gg_event = GG::App::RRELEASE; break;
        }
        key_mods = SDL_GetModState();
        break;
    case SDL_QUIT:
        Exit(0);
        break;
    }
    if (send_to_gg)
        GG::App::HandleEvent(gg_event, key, key_mods, mouse_pos, mouse_rel);
}

void SDLGGApp::RenderBegin()
{
    glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
}

void SDLGGApp::RenderEnd()
{
    SDL_GL_SwapBuffers();
}

void SDLGGApp::SDLQuit()
{
    FinalCleanup();
    NET2_Quit();
    FE_Quit();
    TTF_Quit();
    SDLNet_Quit();
    SDL_Quit();
    Logger().debugStream() << "SDLQuit() complete.";
}

void SDLGGApp::PollAndRender()
{
    static int last_FPS_time = 0;
    static int most_recent_time = 0;
    static int time = 0;
    static int frames = 0;

    static int last_mouse_event_time = 0;
    static int mouse_drag_repeat_start_time = 0;
    static int last_mouse_drag_repeat_time = 0;
    static int old_mouse_repeat_delay = MouseRepeatDelay();
    static int old_mouse_repeat_interval = MouseRepeatInterval();

    // handle events
    SDL_Event event;
    while (0 < FE_PollEvent(&event)) {
        if (event.type  == SDL_MOUSEBUTTONDOWN || event.type  == SDL_MOUSEBUTTONUP || event.type == SDL_MOUSEMOTION)
            last_mouse_event_time = time;
        HandleSDLEvent(event);
    }

    // update time and track FPS if needed
    time = SDL_GetTicks();
    m_delta_t = time - most_recent_time;
    if (m_calc_FPS) {
        ++frames;
        if (time - last_FPS_time > 1000) { // calculate FPS at most once a second
            m_FPS = frames / ((time - last_FPS_time) / 1000.0f);
            last_FPS_time = time;
            frames = 0;
        }
    }
    most_recent_time = time;

    // handle mouse drag repeats
    if (old_mouse_repeat_delay != MouseRepeatDelay() || old_mouse_repeat_interval != MouseRepeatInterval()) { // if there's a change in the values, zero everything out and start the counting over
        old_mouse_repeat_delay = MouseRepeatDelay();
        old_mouse_repeat_interval = MouseRepeatInterval();
        mouse_drag_repeat_start_time = 0;
        last_mouse_drag_repeat_time = 0;
    }
    int x, y;
    // if drag repeat is enabled, the left mouse button is depressed (a drag is ocurring), and the last event processed wasn't too recent
    if (MouseRepeatDelay() && SDL_GetMouseState(&x, &y) & SDL_BUTTON_LEFT && time - last_mouse_event_time > old_mouse_repeat_interval) {
        if (!mouse_drag_repeat_start_time) { // if we're just starting the drag, mark the time we started
            mouse_drag_repeat_start_time = time;
        } else if (mouse_drag_repeat_start_time == MouseRepeatDelay()) { // if we're counting repeat intervals
            if (time - last_mouse_drag_repeat_time > MouseRepeatInterval()) {
                last_mouse_drag_repeat_time = time;
                event.type = SDL_MOUSEMOTION;
                event.motion.x = x;
                event.motion.y = y;
                event.motion.xrel = event.motion.yrel = 0; // this is just an update, so set the motion to 0
                HandleSDLEvent(event);
            }
        } else if (time - mouse_drag_repeat_start_time > MouseRepeatDelay()) { // if we're done waiting for the initial delay period
            mouse_drag_repeat_start_time = MouseRepeatDelay(); // set this as equal so we know later that we've passed the delay interval
            last_mouse_drag_repeat_time = time;
            event.type = SDL_MOUSEMOTION;
            event.motion.x = x;
            event.motion.y = y;
            event.motion.xrel = event.motion.yrel = 0;
            HandleSDLEvent(event);
        }
    } else { // otherwise, reset the mouse drag repeat start time to zero
        mouse_drag_repeat_start_time = 0;
    }

    // do one iteration of the render loop
    Update();
    RenderBegin();
    Render();
    RenderEnd();
}

void SDLGGApp::Run()
{
    try {
        SDLInit();
        Initialize();
        while (1)
            PollAndRender();
    } catch (const std::invalid_argument& exception) {
        Logger().fatal("std::invalid_argument Exception caught in App::Run(): " + string(exception.what()));
        Exit(1);
    } catch (const std::runtime_error& exception) {
        Logger().fatal("std::runtime_error Exception caught in App::Run(): " + string(exception.what()));
        Exit(1);
    } catch (const GG::GGException& exception) {
        Logger().fatal("GG::GGException (subclass " + string(exception.what()) + ") caught in App::Run(): " + exception.Message());
        Exit(1);
    }
}

<commit_msg>Moved to its own directory.<commit_after><|endoftext|>


<commit_before>// This file is a part of the IncludeOS unikernel - www.includeos.org
//
// Copyright 2015 Oslo and Akershus University College of Applied Sciences
// and Alfred Bratterud
//
// 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 <service>
#include <info>
#define ARGS_MAX    64

__attribute__((weak))
extern "C" int main(int, const char*[]);

__attribute__((weak))
void Service::start(const std::string& cmd)
{
  std::string st(cmd); // mangled copy
  int argc = 0;
  const char* argv[ARGS_MAX];

  // Populate argv
  char* begin = (char*) st.data();
  char* end   = begin + st.size();

  for (char* ptr = begin; ptr < end; ptr++)
  if (std::isspace(*ptr)) {
    argv[argc++] = begin;
    *ptr = 0;      // zero terminate
    begin = ptr+1; // next arg
    if (argc >= ARGS_MAX) break;
  }

  int exit_status = main(argc, argv);
  INFO("main","returned with status %d", exit_status);
  //exit(exit_status);
}
<commit_msg>main: new argparser now finds last arg and handles n spaces<commit_after>// This file is a part of the IncludeOS unikernel - www.includeos.org
//
// Copyright 2015 Oslo and Akershus University College of Applied Sciences
// and Alfred Bratterud
//
// 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 <service>
#include <info>
#define ARGS_MAX    64

__attribute__((weak))
extern "C" int main(int, const char*[]);

__attribute__((weak))
void Service::start(const std::string& cmd)
{
  std::string st(cmd); // mangled copy
  int argc = 0;
  const char* argv[ARGS_MAX];

  // Get pointers to null-terminated string
  char* word = (char*) st.c_str();
  char* end   = word + st.size() + 1;
  bool new_word = false;

  for (char* ptr = word; ptr < end; ptr++) {

    // Replace all spaces with 0
    if(std::isspace(*ptr)) {
      *ptr = 0;
      new_word = true;
      continue;
    }

    // At the start of each word, or last byte, add previous pointer to array
    if (new_word or ptr == end - 1) {
      argv[argc++] = word;
      word = ptr; // next arg
      if (argc >= ARGS_MAX) break;
      new_word = false;
    }
  }

  int exit_status = main(argc, argv);
  INFO("main","returned with status %d", exit_status);

}
<|endoftext|>


<commit_before>/*************************************************************************
	> Author: Wayne Ho
	> Purpose: TODO
	> Created Time: Wed 03 Jun 2015 11:01:35 AM CST
	> Mail: hewr2010@gmail.com
 ************************************************************************/
#include "storage/graph_builder.h"
#include <iostream>
#include <cstdio>
#include <fstream>
using namespace std;
using namespace sae::io;

int main(int argc, char **argv) {
    GraphBuilder<int> graph;
    ifstream fin("./resource/amazon0312.txt");
    string buf;
    for (int i = 0; i < 4; ++i) getline(fin, buf);
    int v_cnt(-1);
    while (1) {
        int x, y;
        if (!(fin >> x >> y)) break;
        int z = max(max(v_cnt, x), y);
        while (v_cnt < z) graph.AddVertex(++v_cnt, 0);
        graph.AddEdge(x, y, 0);
    }
    cout << graph.VertexCount() << " " << graph.EdgeCount() << endl;
    graph.Save("./data/graph");
    return 0;
}

<commit_msg>update<commit_after>/*************************************************************************
	> Author: Wayne Ho
	> Purpose: TODO
	> Created Time: Wed 03 Jun 2015 11:01:35 AM CST
	> Mail: hewr2010@gmail.com
 ************************************************************************/
#include "storage/graph_builder.h"
#include <iostream>
#include <cstdio>
#include <fstream>
#include <map>
using namespace std;
using namespace sae::io;

map<string, int> nodeMap;

int GetOrInsert(const string& key)
{
    map<string, int>::iterator it = nodeMap.find(key);
    if (it != nodeMap.end())
        return it -> second;
    int id = (int) nodeMap.size();
    nodeMap.insert(make_pair(key, id));
    return id;
}

int main(int argc, char **argv) {
    GraphBuilder<int> graph;
    //ifstream fin("./resource/amazon0312.txt");
    ifstream fin("./resource/twitter_combined.txt");
    string buf;
    //for (int i = 0; i < 4; ++i) getline(fin, buf);
    int v_cnt(-1);
    map<string, int> nodeMap;
    while (1) {
        string x, y;
        if (!(fin >> x >> y)) break;
        int a = GetOrInsert(x);
        int b = GetOrInsert(y);
        int c = max(max(v_cnt, a), b);
        while (v_cnt < c) graph.AddVertex(++v_cnt, 0);
        graph.AddEdge(a, b, 0);
    }
    cout << graph.VertexCount() << " " << graph.EdgeCount() << endl;
    graph.Save("./data/twitter");
    return 0;
}

<|endoftext|>


<commit_before>//  illarionserver - server for the game Illarion
//  Copyright 2011 Illarion e.V.
//
//  This file is part of illarionserver.
//
//  illarionserver is free software: you can redistribute it and/or modify
//  it under the terms of the GNU Affero General Public License as published by
//  the Free Software Foundation, either version 3 of the License, or
//  (at your option) any later version.
//
//  illarionserver 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 Affero General Public License for more details.
//
//  You should have received a copy of the GNU Affero General Public License
//  along with illarionserver.  If not, see <http://www.gnu.org/licenses/>.

#ifndef _WORLDMAP_HPP_
#define _WORLDMAP_HPP_

#include <memory>
#include <vector>
#include <unordered_map>
#include "globals.hpp"

class Field;
class Map;

class WorldMap {
    using map_t = std::shared_ptr<Map>;
    using map_vector_t = std::vector<map_t>;

    map_vector_t maps;
    std::unordered_map<position, map_t> world_map;
    size_t ageIndex = 0;

public:
    void clear();

    Field &at(const position &pos) const;
    Field &walkableNear(position &pos) const;
    bool intersects(const Map &map) const;

    bool insert(map_t newMap);

    bool allMapsAged();

    bool import(const std::string &importDir, const std::string &mapName);
    bool exportTo(const std::string &exportDir) const;
    bool loadFromDisk(const std::string &prefix);
    void saveToDisk(const std::string &prefix) const;
    bool createMap(const std::string &name, const position &origin,
                   uint16_t width, uint16_t height, uint16_t tile);

private:
  static map_t createMapFromHeaderFile(const std::string &importDir,
                                      const std::string &mapName);
  static int16_t readHeaderLine(const std::string &mapName, char header,
                                std::ifstream &headerFile, int &lineNumber);
  static bool isCommentOrEmpty(const std::string &line);
};
#endif
<commit_msg>Make inserting maps private to WorldMap<commit_after>//  illarionserver - server for the game Illarion
//  Copyright 2011 Illarion e.V.
//
//  This file is part of illarionserver.
//
//  illarionserver is free software: you can redistribute it and/or modify
//  it under the terms of the GNU Affero General Public License as published by
//  the Free Software Foundation, either version 3 of the License, or
//  (at your option) any later version.
//
//  illarionserver 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 Affero General Public License for more details.
//
//  You should have received a copy of the GNU Affero General Public License
//  along with illarionserver.  If not, see <http://www.gnu.org/licenses/>.

#ifndef _WORLDMAP_HPP_
#define _WORLDMAP_HPP_

#include <memory>
#include <vector>
#include <unordered_map>
#include "globals.hpp"

class Field;
class Map;

class WorldMap {
    using map_t = std::shared_ptr<Map>;
    using map_vector_t = std::vector<map_t>;

    map_vector_t maps;
    std::unordered_map<position, map_t> world_map;
    size_t ageIndex = 0;

public:
    void clear();

    Field &at(const position &pos) const;
    Field &walkableNear(position &pos) const;
    bool intersects(const Map &map) const;

    bool allMapsAged();

    bool import(const std::string &importDir, const std::string &mapName);
    bool exportTo(const std::string &exportDir) const;
    bool loadFromDisk(const std::string &prefix);
    void saveToDisk(const std::string &prefix) const;
    bool createMap(const std::string &name, const position &origin,
                   uint16_t width, uint16_t height, uint16_t tile);

private:
    bool insert(map_t newMap);
    static map_t createMapFromHeaderFile(const std::string &importDir,
                                         const std::string &mapName);
    static int16_t readHeaderLine(const std::string &mapName, char header,
                                  std::ifstream &headerFile, int &lineNumber);
    static bool isCommentOrEmpty(const std::string &line);
};
#endif
<|endoftext|>


<commit_before><commit_msg>Grabber class now receives objects names when collision<commit_after><|endoftext|>


<commit_before>//
//#include <unistd.h>
#include <cstdio>
#include <cstdlib>
#include <string>
#include <ctime>
#include <algorithm>
#include <cmath>
#include "GPIOClass.h"

using namespace std;

void Pulse(GPIOClass* pin, double cycles);
void Wait(double seconds);
clock_t timer;
double time_to_complete;
double resolution = 100;

#define PI 4*atan(1)

int main (int argc, char *argv[]) {
	string type = argv[1];
	transform(type.begin(), type.end(), type.begin(), :: tolower);
	// lets assume that the way to run this is
	// pwm.exe [rising/falling/sine/constant]
	if (argc != 2) {
		cout << "Usage: pwm [rising/falling/sine/constant/blink]" << endl;
		return -1;
	}

	while (time_to_complete <= 0) {
		cout << "Input How Long To Run (in seconds)" << endl;
		cin >> time_to_complete;
	}

	GPIOClass* out1 = new GPIOClass("4");
	GPIOClass* in2 = new GPIOClass("17");

	out1->export_gpio();
	in2->export_gpio();

	out1->setdir_gpio("out");
	in2->setdir_gpio("in");

	cout << "Pins are setup." << endl;
	// avoiding flickering will be at 100hz
	// aka turn on and off 100 times a sec
	// a cycle of 0 is off
	// a cycle of 100 is on

	if (type == "rising") {
		clock_t finish = clock() + time_to_complete * CLOCKS_PER_SEC;
		while (clock() < finish) {
			// pulse for however long we need to to achieve brightness.
				Pulse(out1, sin((PI/2) * time_to_complete));
				Wait(sin((PI/2) * time_to_complete));
		}
	}
	if (type == "falling") {

	}
	if (type == "sine") {

	}
	if (type == "constant") {
		out1->setval_gpio("1"); // turn the pin on
		Wait(time_to_complete); // sleep for number of cycles / 1/100 sec
		//cout << "Waiting during pulse" << endl;
		out1->setval_gpio("0"); // turn the pin off
	}
	if (type == "blink") { // aka. TESTR
		clock_t finish = clock() + time_to_complete * CLOCKS_PER_SEC;
		while (clock() < finish) {
			// pulse for however long we need to to achieve brightness.
			Pulse(out1, 1 * resolution);
			Wait(0.5);
		}
	}
	cout << "Done." << endl;
}

//1 cycle is 1/100th of a second
//100 cycles is 1 sec
void Pulse(GPIOClass* pin, double cycles) {
	bool running = true;
	while (running) {
		pin->setval_gpio("1"); // turn the pin on
		Wait(cycles / resolution); // sleep for number of cycles / 1/100 sec
		//cout << "Waiting during pulse" << endl;
		pin->setval_gpio("0"); // turn the pin off
		running = false; // this is unnessesary but could be useful if modified a bit.
	}
}

void Wait ( double seconds )
{
	clock_t endwait;
	endwait = clock () + seconds * CLOCKS_PER_SEC ;
	while (clock() < endwait) {}
}
<commit_msg>Update pwm.cpp<commit_after>//
//#include <unistd.h>
#include <cstdio>
#include <cstdlib>
#include <string>
#include <ctime>
#include <algorithm>
#include <cmath>
#include "GPIOClass.h"

using namespace std;

void Pulse(GPIOClass* pin, double cycles);
void Wait(double seconds);
clock_t timer;
double time_to_complete;
double resolution = 100;

#define PI 4*atan(1)

int main (int argc, char *argv[]) {
	string type = argv[1];
	transform(type.begin(), type.end(), type.begin(), :: tolower);
	// lets assume that the way to run this is
	// pwm.exe [rising/falling/sine/constant]
	if (argc != 2) {
		cout << "Usage: pwm [rising/falling/sine/constant/blink]" << endl;
		return -1;
	}

	while (time_to_complete <= 0) {
		cout << "Input How Long To Run (in seconds)" << endl;
		cin >> time_to_complete;
	}

	GPIOClass* out1 = new GPIOClass("4");
	GPIOClass* in2 = new GPIOClass("17");

	out1->export_gpio();
	in2->export_gpio();

	out1->setdir_gpio("out");
	in2->setdir_gpio("in");

	cout << "Pins are setup." << endl;
	// avoiding flickering will be at 100hz
	// aka turn on and off 100 times a sec
	// a cycle of 0 is off
	// a cycle of 100 is on

	if (type == "rising") {
		clock_t finish = clock() + time_to_complete * CLOCKS_PER_SEC;
		while (clock() < finish) {
			// pulse for however long we need to to achieve brightness.
				Pulse(out1, sin((PI/2) * (1/time_to_complete)));
				Wait(sin((PI/2) * (1/time_to_complete)));
		}
	}
	if (type == "falling") {

	}
	if (type == "sine") {

	}
	if (type == "constant") {
		out1->setval_gpio("1"); // turn the pin on
		Wait(time_to_complete); // sleep for number of cycles / 1/100 sec
		//cout << "Waiting during pulse" << endl;
		out1->setval_gpio("0"); // turn the pin off
	}
	if (type == "blink") { // aka. TESTR
		clock_t finish = clock() + time_to_complete * CLOCKS_PER_SEC;
		while (clock() < finish) {
			// pulse for however long we need to to achieve brightness.
			Pulse(out1, 1 * resolution);
			Wait(0.5);
		}
	}
	cout << "Done." << endl;
}

//1 cycle is 1/100th of a second
//100 cycles is 1 sec
void Pulse(GPIOClass* pin, double cycles) {
	bool running = true;
	while (running) {
		pin->setval_gpio("1"); // turn the pin on
		Wait(cycles / resolution); // sleep for number of cycles / 1/100 sec
		//cout << "Waiting during pulse" << endl;
		pin->setval_gpio("0"); // turn the pin off
		running = false; // this is unnessesary but could be useful if modified a bit.
	}
}

void Wait ( double seconds )
{
	clock_t endwait;
	endwait = clock () + seconds * CLOCKS_PER_SEC ;
	while (clock() < endwait) {}
}
<|endoftext|>


<commit_before><commit_msg>Fix voxel grid<commit_after><|endoftext|>


<commit_before>
#include "pin.H"
#include "Triton.h"

static std::string replaceEq(std::string str, const std::string from, const std::string to)
{
  size_t start_pos = str.find(from);
  if(start_pos == std::string::npos)
      return NULL;
  str.replace(start_pos, from.length(), to);
  return str;
}

static std::string formulaReconstruction(UINT64 id)
{
  int value;
  std::size_t found;
  std::stringstream formula;

  std::stringstream from;
  std::stringstream to;

  formula.str(symbolicEngine->getElementFromId(id)->getSource());
  while (formula.str().find("#") != std::string::npos){

    from.str("");
    to.str("");

    found = formula.str().find("#") + 1;
    std::string subs = formula.str().substr(found, std::string::npos);
    value = atoi(subs.c_str());
    from << "#" << value;
    to.str(symbolicEngine->getElementFromId(value)->getSource());

    formula.str(replaceEq(formula.str(), from.str(), to.str()));
  }

  return formula.str();
}

SolverEngine::SolverEngine(SymbolicEngine *symEngine)
{
  this->symEngine = symEngine;
}

SolverEngine::~SolverEngine()
{
}

VOID SolverEngine::solveFromID(UINT64 id)
{
  std::stringstream formula;

  std::cout << 1 << std::endl;

  formula.str(formulaReconstruction(symEngine->symbolicReg[ID_ZF]));

  this->formula << this->symEngine->getSmt2LibVarsDecl();
  this->formula << formula.str();

  this->ctx = new z3::context();

  Z3_ast ast = Z3_parse_smtlib2_string(*this->ctx, this->formula.str().c_str(), 0, 0, 0, 0, 0, 0);
  z3::expr eq(*this->ctx, ast);
  this->solver = new z3::solver(*this->ctx);
  this->solver->add(eq);
  this->solver->check();
}

VOID SolverEngine::displayModel()
{
  z3::model m = this->solver->get_model();
  std::cout << "----- Model -----" << std::endl << m << std::endl << "-----------------" << std::endl;
}

z3::model SolverEngine::getModel()
{
  return this->solver->get_model();
}

std::string SolverEngine::getFormula()
{
  return this->formula.str();
}

<commit_msg>Feature #10: Use QF_AUFBV<commit_after>
#include "pin.H"
#include "Triton.h"

static std::string replaceEq(std::string str, const std::string from, const std::string to)
{
  size_t start_pos = str.find(from);
  if(start_pos == std::string::npos)
      return NULL;
  str.replace(start_pos, from.length(), to);
  return str;
}

static std::string formulaReconstruction(UINT64 id)
{
  int value;
  std::size_t found;
  std::stringstream formula;

  std::stringstream from;
  std::stringstream to;

  formula.str(symbolicEngine->getElementFromId(id)->getSource());
  while (formula.str().find("#") != std::string::npos){

    from.str("");
    to.str("");

    found = formula.str().find("#") + 1;
    std::string subs = formula.str().substr(found, std::string::npos);
    value = atoi(subs.c_str());
    from << "#" << value;
    to.str(symbolicEngine->getElementFromId(value)->getSource());

    formula.str(replaceEq(formula.str(), from.str(), to.str()));
  }

  return formula.str();
}

SolverEngine::SolverEngine(SymbolicEngine *symEngine)
{
  this->symEngine = symEngine;
}

SolverEngine::~SolverEngine()
{
}

VOID SolverEngine::solveFromID(UINT64 id)
{
  std::stringstream formula;

  formula.str(formulaReconstruction(symEngine->symbolicReg[ID_ZF]));

  this->formula << "(set-logic QF_AUFBV)";
  this->formula << this->symEngine->getSmt2LibVarsDecl();
  this->formula << formula.str();

  this->ctx = new z3::context();

  Z3_ast ast = Z3_parse_smtlib2_string(*this->ctx, this->formula.str().c_str(), 0, 0, 0, 0, 0, 0);
  z3::expr eq(*this->ctx, ast);
  this->solver = new z3::solver(*this->ctx);
  this->solver->add(eq);
  this->solver->check();
}

VOID SolverEngine::displayModel()
{
  z3::model m = this->solver->get_model();
  std::cout << "----- Model -----" << std::endl << m << std::endl << "-----------------" << std::endl;
}

z3::model SolverEngine::getModel()
{
  return this->solver->get_model();
}

std::string SolverEngine::getFormula()
{
  return this->formula.str();
}

<|endoftext|>


<commit_before>#ifndef STAN_IO_ARRAY_VAR_CONTEXT_HPP
#define STAN_IO_ARRAY_VAR_CONTEXT_HPP

#include <stan/io/var_context.hpp>
#include <boost/throw_exception.hpp>
#include <stan/math/prim/mat/fun/Eigen.hpp>
#include <algorithm>
#include <functional>
#include <numeric>
#include <sstream>
#include <string>
#include <type_traits>
#include <vector>
#include <utility>

namespace stan {

namespace io {

/**
 * An array_var_context object represents a named arrays
 * with dimensions constructed from an array, a vector
 * of names, and a vector of all dimensions for each element.
 */
class array_var_context : public var_context {
 private:
  // Pairs
  template <typename T>
  using pair_ = std::pair<std::string, std::pair<std::vector<T>,
    std::vector<size_t>>>;

  // Map holding reals
  using map_r_ = std::vector<pair_<double>>;
  map_r_ vars_r_;
  using map_i_ = std::vector<pair_<int>>;
  map_i_ vars_i_;
  // When search for variable name fails, return one these
  std::vector<double> const empty_vec_r_;
  std::vector<int> const empty_vec_i_;
  std::vector<size_t> const empty_vec_ui_;

  template <typename Str>
  auto find_var_r(Str&& name) const {
    return std::find_if(vars_r_.begin(), vars_r_.end(),
     [&](auto&& element){ return element.first == name;});
  }

  template <typename Str>
  auto find_var_i(Str&& name) const {
    return std::find_if(vars_i_.begin(), vars_i_.end(),
     [&](auto&& element){ return element.first == name;});
  }

  // Find method
  bool contains_r_only(const std::string& name) const {
    return find_var_r(name) != vars_r_.end();
  }

  /**
   * Check (1) if the vector size of dimensions is no smaller
   * than the name vector size; (2) if the size of the input
   * array is large enough for what is needed.
   *
   * @param names The names for each variable
   * @param array_size The total size of the vector holding the values we want
   * to access.
   * @param dims Vector holding the dimensions for each variable.
   * @return If the array size is equal to the number of dimensions,
   * a vector of the cumulative sum of the dimensions of each inner element of
   * dims. The return of this function is used in the add_* methods to get the
   * sequence of values For each variable.
   */

  template <typename T>
  std::vector<size_t> validate_dims(
      const std::vector<std::string>& names, const T array_size,
      const std::vector<std::vector<size_t>>& dims) {
    const size_t num_par = names.size();
    if (num_par > dims.size()) {
      std::stringstream msg;
      msg << "size of vector of dimensions (found " << dims.size() << ") "
          << "should be no smaller than number of parameters (found " << num_par
          << ").";
      BOOST_THROW_EXCEPTION(std::invalid_argument(msg.str()));
    }
    std::vector<size_t> elem_dims_total(dims.size() + 1);
    elem_dims_total[0] = 0;
    int i = 0;
    for (i = 0; i < dims.size(); i++) {
      elem_dims_total[i + 1] = std::accumulate(dims[i].begin(), dims[i].end(),
                                               1, std::multiplies<T>());
      elem_dims_total[i + 1] += elem_dims_total[i];
    }
    if (elem_dims_total[i] > array_size) {
      std::stringstream msg;
      msg << "array is not long enough for all elements: " << array_size
          << " is found, but " << elem_dims_total[i] << " is needed.";
      BOOST_THROW_EXCEPTION(std::invalid_argument(msg.str()));
    }
    return elem_dims_total;
  }

  /**
   * Adds a set of floating point variables to the floating point map.
   * @param names Names of each variable.
   * @param values The real values of variable in a contiguous
   * column major order container.
   * @param dims the dimensions for each variable.
   */
  void add_r(const std::vector<std::string>& names,
             const std::vector<double>& values,
             const std::vector<std::vector<size_t>>& dims) {
    std::vector<size_t> dim_vec = validate_dims(names, values.size(), dims);
    for (size_t i = 0; i < names.size(); i++) {
      vars_r_[i] =
          {names[i], {{values.data() + dim_vec[i],
             values.data() + dim_vec[i + 1]}, dims[i]}};
    }
  }

  void add_r(const std::vector<std::string>& names,
             const Eigen::VectorXd& values,
             const std::vector<std::vector<size_t>>& dims) {
    std::vector<size_t> dim_vec = validate_dims(names, values.size(), dims);
    using val_d_t = decltype(values.data());
    for (size_t i = 0; i < names.size(); i++) {
      vars_r_[i] =
          {names[i], {{values.data() + dim_vec[i],
             values.data() + dim_vec[i + 1]}, dims[i]}};
    }
  }

  /**
   * Adds a set of integer variables to the integer map.
   * @param names Names of each variable.
   * @param values The integer values of variable in a vector.
   * @param dims the dimensions for each variable.
   */
  void add_i(const std::vector<std::string>& names,
             const std::vector<int>& values,
             const std::vector<std::vector<size_t>>& dims) {
    std::vector<size_t> dim_vec = validate_dims(names, values.size(), dims);
    for (size_t i = 0; i < names.size(); i++) {
      vars_i_[i] =
          {names[i], {{values.data() + dim_vec[i],
             values.data() + dim_vec[i + 1]}, dims[i]}};
    }
  }

 public:
  /**
   * Construct an array_var_context from only real value arrays.
   *
   * @param names_r  names for each element
   * @param values_r a vector of double values for all elements
   * @param dim_r   a vector of dimensions
   */
  array_var_context(const std::vector<std::string>& names_r,
                    const std::vector<double>& values_r,
                    const std::vector<std::vector<size_t>>& dim_r)
      : vars_r_(names_r.size()) {
    add_r(names_r, values_r, dim_r);
  }

  array_var_context(const std::vector<std::string>& names_r,
                    const Eigen::VectorXd& values_r,
                    const std::vector<std::vector<size_t>>& dim_r)
      : vars_r_(names_r.size()) {
    add_r(names_r, values_r, dim_r);
  }

  /**
   * Construct an array_var_context from only integer value arrays.
   *
   * @param names_i  names for each element
   * @param values_i a vector of integer values for all elements
   * @param dim_i   a vector of dimensions
   */
  array_var_context(const std::vector<std::string>& names_i,
                    const std::vector<int>& values_i,
                    const std::vector<std::vector<size_t>>& dim_i)
      : vars_i_(names_i.size()) {
    add_i(names_i, values_i, dim_i);
  }

  /**
   * Construct an array_var_context from arrays of both double
   * and integer separately
   *
   */
  array_var_context(const std::vector<std::string>& names_r,
                    const std::vector<double>& values_r,
                    const std::vector<std::vector<size_t>>& dim_r,
                    const std::vector<std::string>& names_i,
                    const std::vector<int>& values_i,
                    const std::vector<std::vector<size_t>>& dim_i)
      : vars_r_(names_r.size()), vars_i_(names_i.size()) {
    add_i(names_i, values_i, dim_i);
    add_r(names_r, values_r, dim_r);
  }

  array_var_context(const std::vector<std::string>& names_r,
                    const Eigen::VectorXd& values_r,
                    const std::vector<std::vector<size_t>>& dim_r,
                    const std::vector<std::string>& names_i,
                    const std::vector<int>& values_i,
                    const std::vector<std::vector<size_t>>& dim_i)
      : vars_r_(names_r.size()), vars_i_(names_i.size()) {
    add_i(names_i, values_i, dim_i);
    add_r(names_r, values_r, dim_r);
  }

  /**
   * Return true if this dump contains the specified
   * variable name is defined. This method returns true
   * even if the values are all integers.
   *
   * @param name Variable name to test.
   * @return true if the variable exists.
   */
  bool contains_r(const std::string& name) const {
    return contains_r_only(name) || contains_i(name);
  }

  /**
   * Return true if this dump contains an integer
   * valued array with the specified name.
   *
   * @param name Variable name to test.
   * @return true if the variable name has an integer
   * array value.
   */
  bool contains_i(const std::string& name) const {
    return find_var_i(name) != vars_i_.end();
  }

  /**
   * Return the double values for the variable with the specified
   * name or null.
   *
   * @param name Name of variable.
   * @return Values of variable.
   *
   */
  std::vector<double> vals_r(const std::string& name) const {
    auto ret_val_r = find_var_r(name);
    if (ret_val_r != vars_r_.end()) {
      return ret_val_r->second.first;
    } else {
      auto ret_val_i = find_var_i(name);
      if (ret_val_i != vars_i_.end()) {
        return {ret_val_i->second.first.begin(), ret_val_i->second.first.end()};
      }
    }
    return empty_vec_r_;
  }

  /**
   * Return the dimensions for the double variable with the specified
   * name.
   *
   * @param name Name of variable.
   * @return Dimensions of variable.
   */
  std::vector<size_t> dims_r(const std::string& name) const {
    auto ret_val_r = find_var_r(name);
    if (ret_val_r != vars_r_.end()) {
      return ret_val_r->second.second;
    } else {
      auto ret_val_i = find_var_i(name);
      if (ret_val_i != vars_i_.end()) {
        return ret_val_i->second.second;
      }
    }
    return empty_vec_ui_;
  }

  /**
   * Return the integer values for the variable with the specified
   * name.
   *
   * @param name Name of variable.
   * @return Values.
   */
  std::vector<int> vals_i(const std::string& name) const {
    auto ret_val_i = find_var_i(name);
    if (ret_val_i != vars_i_.end()) {
      return ret_val_i->second.first;
    }
    return empty_vec_i_;
  }

  /**
   * Return the dimensions for the integer variable with the specified
   * name.
   *
   * @param name Name of variable.
   * @return Dimensions of variable.
   */
  std::vector<size_t> dims_i(const std::string& name) const {
    auto ret_val_i = find_var_i(name);
    if (ret_val_i != vars_i_.end()) {
      return ret_val_i->second.second;
    }
    return empty_vec_ui_;
  }

  /**
   * Return a list of the names of the floating point variables in
   * the dump.
   *
   * @param names Vector to store the list of names in.
   */
  virtual void names_r(std::vector<std::string>& names) const {
    names.clear();
    for (const auto& vars_r_iter : vars_r_) {
      names.push_back(vars_r_iter.first);
    }
  }

  /**
   * Return a list of the names of the integer variables in
   * the dump.
   *
   * @param names Vector to store the list of names in.
   */
  virtual void names_i(std::vector<std::string>& names) const {
    names.clear();
    for (const auto& vars_i_iter : vars_r_) {
      names.push_back(vars_i_iter.first);
    }
  }

  /**
   * Remove variable from the object.
   *
   * @param name Name of the variable to remove.
   * @return If variable is removed returns true, else
   *   returns false.
   */
  bool remove(const std::string& name) {
    vars_i_.erase(find_var_i(name));
    vars_r_.erase(find_var_r(name));
    return true;
  }
};
}  // namespace io
}  // namespace stan
#endif
<commit_msg>testing with an unordered map and emplace<commit_after>#ifndef STAN_IO_ARRAY_VAR_CONTEXT_HPP
#define STAN_IO_ARRAY_VAR_CONTEXT_HPP

#include <stan/io/var_context.hpp>
#include <boost/throw_exception.hpp>
#include <stan/math/prim/mat/fun/Eigen.hpp>
#include <unordered_map>
#include <algorithm>
#include <functional>
#include <numeric>
#include <sstream>
#include <string>
#include <type_traits>
#include <vector>
#include <utility>

namespace stan {

namespace io {

/**
 * An array_var_context object represents a named arrays
 * with dimensions constructed from an array, a vector
 * of names, and a vector of all dimensions for each element.
 */
class array_var_context : public var_context {
 private:
  // Pairs
  template <typename T>
  using pair_ = std::pair<std::vector<T>, std::vector<size_t>>;

  // Map holding reals
  using map_r_ = std::unordered_map<std::string, pair_<double>>;
  map_r_ vars_r_;
  using map_i_ = std::unordered_map<std::string, pair_<int>>;
  map_i_ vars_i_;
  // When search for variable name fails, return one these
  std::vector<double> const empty_vec_r_{0};
  std::vector<int> const empty_vec_i_{0};
  std::vector<size_t> const empty_vec_ui_{0};

  // Find method
  bool contains_r_only(const std::string& name) const {
    return vars_r_.find(name) != vars_r_.end();
  }

  /**
   * Check (1) if the vector size of dimensions is no smaller
   * than the name vector size; (2) if the size of the input
   * array is large enough for what is needed.
   *
   * @param names The names for each variable
   * @param array_size The total size of the vector holding the values we want
   * to access.
   * @param dims Vector holding the dimensions for each variable.
   * @return If the array size is equal to the number of dimensions,
   * a vector of the cumulative sum of the dimensions of each inner element of
   * dims. The return of this function is used in the add_* methods to get the
   * sequence of values For each variable.
   */

  template <typename T>
  std::vector<size_t> validate_dims(
      const std::vector<std::string>& names, const T array_size,
      const std::vector<std::vector<size_t>>& dims) {
    const size_t num_par = names.size();
    if (num_par > dims.size()) {
      std::stringstream msg;
      msg << "size of vector of dimensions (found " << dims.size() << ") "
          << "should be no smaller than number of parameters (found " << num_par
          << ").";
      BOOST_THROW_EXCEPTION(std::invalid_argument(msg.str()));
    }
    std::vector<size_t> elem_dims_total(dims.size() + 1);
    elem_dims_total[0] = 0;
    int i = 0;
    for (i = 0; i < dims.size(); i++) {
      elem_dims_total[i + 1] = std::accumulate(dims[i].begin(), dims[i].end(),
                                               1, std::multiplies<T>())
                                + elem_dims_total[i];;
    }
    if (elem_dims_total[i] > array_size) {
      std::stringstream msg;
      msg << "array is not long enough for all elements: " << array_size
          << " is found, but " << elem_dims_total[i] << " is needed.";
      BOOST_THROW_EXCEPTION(std::invalid_argument(msg.str()));
    }
    return elem_dims_total;
  }

  /**
   * Adds a set of floating point variables to the floating point map.
   * @param names Names of each variable.
   * @param values The real values of variable in a contiguous
   * column major order container.
   * @param dims the dimensions for each variable.
   */
  void add_r(const std::vector<std::string>& names,
             const std::vector<double>& values,
             const std::vector<std::vector<size_t>>& dims) {
    std::vector<size_t> dim_vec = validate_dims(names, values.size(), dims);
    for (size_t i = 0; i < names.size(); i++) {
      vars_r_.emplace(names[i], pair_<double>{{values.data() + dim_vec[i],
         values.data() + dim_vec[i + 1]}, dims[i]});
    }
  }

  void add_r(const std::vector<std::string>& names,
             const Eigen::VectorXd& values,
             const std::vector<std::vector<size_t>>& dims) {
    std::vector<size_t> dim_vec = validate_dims(names, values.size(), dims);
    const auto name_size = names.size();
    for (size_t i = 0; i < name_size; i++) {
      vars_r_.emplace(names[i], pair_<double>{{values.data() + dim_vec[i],
          values.data() + dim_vec[i + 1]}, dims[i]});
    }
  }

  /**
   * Adds a set of integer variables to the integer map.
   * @param names Names of each variable.
   * @param values The integer values of variable in a vector.
   * @param dims the dimensions for each variable.
   */
  void add_i(const std::vector<std::string>& names,
             const std::vector<int>& values,
             const std::vector<std::vector<size_t>>& dims) {
    std::vector<size_t> dim_vec = validate_dims(names, values.size(), dims);
    for (size_t i = 0; i < names.size(); i++) {
      vars_i_.emplace(names[i], pair_<int>{{values.data() + dim_vec[i],
        values.data() + dim_vec[i + 1]}, dims[i]});
    }
  }

 public:
  /**
   * Construct an array_var_context from only real value arrays.
   *
   * @param names_r  names for each element
   * @param values_r a vector of double values for all elements
   * @param dim_r   a vector of dimensions
   */
  array_var_context(const std::vector<std::string>& names_r,
                    const std::vector<double>& values_r,
                    const std::vector<std::vector<size_t>>& dim_r)
      : vars_r_(names_r.size()) {
    add_r(names_r, values_r, dim_r);
  }

  array_var_context(const std::vector<std::string>& names_r,
                    const Eigen::VectorXd& values_r,
                    const std::vector<std::vector<size_t>>& dim_r)
      : vars_r_(names_r.size()) {
    add_r(names_r, values_r, dim_r);
  }

  /**
   * Construct an array_var_context from only integer value arrays.
   *
   * @param names_i  names for each element
   * @param values_i a vector of integer values for all elements
   * @param dim_i   a vector of dimensions
   */
  array_var_context(const std::vector<std::string>& names_i,
                    const std::vector<int>& values_i,
                    const std::vector<std::vector<size_t>>& dim_i)
      : vars_i_(names_i.size()) {
    add_i(names_i, values_i, dim_i);
  }

  /**
   * Construct an array_var_context from arrays of both double
   * and integer separately
   *
   */
  array_var_context(const std::vector<std::string>& names_r,
                    const std::vector<double>& values_r,
                    const std::vector<std::vector<size_t>>& dim_r,
                    const std::vector<std::string>& names_i,
                    const std::vector<int>& values_i,
                    const std::vector<std::vector<size_t>>& dim_i)
      : vars_r_(names_r.size()), vars_i_(names_i.size()) {
    add_i(names_i, values_i, dim_i);
    add_r(names_r, values_r, dim_r);
  }

  array_var_context(const std::vector<std::string>& names_r,
                    const Eigen::VectorXd& values_r,
                    const std::vector<std::vector<size_t>>& dim_r,
                    const std::vector<std::string>& names_i,
                    const std::vector<int>& values_i,
                    const std::vector<std::vector<size_t>>& dim_i)
      : vars_r_(names_r.size()), vars_i_(names_i.size()) {
    add_i(names_i, values_i, dim_i);
    add_r(names_r, values_r, dim_r);
  }

  /**
   * Return true if this dump contains the specified
   * variable name is defined. This method returns true
   * even if the values are all integers.
   *
   * @param name Variable name to test.
   * @return true if the variable exists.
   */
  bool contains_r(const std::string& name) const {
    return contains_r_only(name) || contains_i(name);
  }

  /**
   * Return true if this dump contains an integer
   * valued array with the specified name.
   *
   * @param name Variable name to test.
   * @return true if the variable name has an integer
   * array value.
   */
  bool contains_i(const std::string& name) const {
    return vars_i_.find(name) != vars_i_.end();
  }

  /**
   * Return the double values for the variable with the specified
   * name or null.
   *
   * @param name Name of variable.
   * @return Values of variable.
   *
   */
  std::vector<double> vals_r(const std::string& name) const {
    const auto ret_val_r = vars_r_.find(name);
    if (ret_val_r != vars_r_.end()) {
      return ret_val_r->second.first;
    } else {
      const auto ret_val_i = vars_i_.find(name);
      if (ret_val_i != vars_i_.end()) {
        return {ret_val_i->second.first.begin(), ret_val_i->second.first.end()};
      }
    }
    return empty_vec_r_;
  }

  /**
   * Return the dimensions for the double variable with the specified
   * name.
   *
   * @param name Name of variable.
   * @return Dimensions of variable.
   */
  std::vector<size_t> dims_r(const std::string& name) const {
    const auto ret_val_r = vars_r_.find(name);
    if (ret_val_r != vars_r_.end()) {
      return ret_val_r->second.second;
    } else {
      const auto ret_val_i = vars_i_.find(name);
      if (ret_val_i != vars_i_.end()) {
        return ret_val_i->second.second;
      }
    }
    return empty_vec_ui_;
  }

  /**
   * Return the integer values for the variable with the specified
   * name.
   *
   * @param name Name of variable.
   * @return Values.
   */
  std::vector<int> vals_i(const std::string& name) const {
    auto ret_val_i = vars_i_.find(name);
    if (ret_val_i != vars_i_.end()) {
      return ret_val_i->second.first;
    }
    return empty_vec_i_;
  }

  /**
   * Return the dimensions for the integer variable with the specified
   * name.
   *
   * @param name Name of variable.
   * @return Dimensions of variable.
   */
  std::vector<size_t> dims_i(const std::string& name) const {
    auto ret_val_i = vars_i_.find(name);
    if (ret_val_i != vars_i_.end()) {
      return ret_val_i->second.second;
    }
    return empty_vec_ui_;
  }

  /**
   * Return a list of the names of the floating point variables in
   * the dump.
   *
   * @param names Vector to store the list of names in.
   */
  virtual void names_r(std::vector<std::string>& names) const {
    names.clear();
    names.reserve(vars_r_.size());
    for (const auto& vars_r_iter : vars_r_) {
      names.push_back(vars_r_iter.first);
    }
  }

  /**
   * Return a list of the names of the integer variables in
   * the dump.
   *
   * @param names Vector to store the list of names in.
   */
  virtual void names_i(std::vector<std::string>& names) const {
    names.clear();
    names.reserve(vars_i_.size());
    for (const auto& vars_i_iter : vars_r_) {
      names.push_back(vars_i_iter.first);
    }
  }

  /**
   * Remove variable from the object.
   *
   * @param name Name of the variable to remove.
   * @return If variable is removed returns true, else
   *   returns false.
   */
  bool remove(const std::string& name) {
    vars_i_.erase(name);
    vars_r_.erase(name);
    return true;
  }
};
}  // namespace io
}  // namespace stan
#endif
<|endoftext|>


<commit_before>/*
Copyright (c) 2012 Carsten Burstedde, Donna Calhoun
All rights reserved.

Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are met:

 * Redistributions of source code must retain the above copyright notice, this
list of conditions and the following disclaimer.
 * Redistributions in binary form must reproduce the above copyright notice,
this list of conditions and the following disclaimer in the documentation
and/or other materials provided with the distribution.

THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
DISCLAIMED.  IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/

#include <fclaw2d_forestclaw.h>
#include <fclaw2d_clawpatch.hpp>
#include <fclaw2d_partition.h>

#include <sc_statistics.h>

#define FCLAW2D_STATS_SET(stats,ddata,NAME) do {                               \
    SC_CHECK_ABORT (!(ddata)->timers[FCLAW2D_TIMER_ ## NAME].running,          \
                    "Timer " #NAME " still running in amrreset");              \
    sc_stats_set1 ((stats) + FCLAW2D_TIMER_ ## NAME,                           \
                   (ddata)->timers[FCLAW2D_TIMER_ ## NAME].cumulative, #NAME); \
} while (0)

static
void delete_ghost_patches(fclaw2d_domain_t* domain)
{
    for(int i = 0; i < domain->num_ghost_patches; i++)
    {
        fclaw2d_patch_t* ghost_patch = &domain->ghost_patches[i];

        fclaw2d_patch_delete_cp(ghost_patch);
        fclaw2d_patch_delete_data(ghost_patch);
    }
}

void amrreset(fclaw2d_domain_t **domain)
{
    fclaw2d_domain_data_t *ddata = get_domain_data (*domain);

    for(int i = 0; i < (*domain)->num_blocks; i++)
    {
        fclaw2d_block_t *block = (*domain)->blocks + i;
        fclaw2d_block_data_t *bd = (fclaw2d_block_data_t *) block->user;

        for(int j = 0; j < block->num_patches; j++)
        {
            fclaw2d_patch_t *patch = block->patches + j;
            fclaw2d_patch_delete_cp(patch);
            fclaw2d_patch_delete_data(patch);
#if 0
            fclaw2d_patch_data_t *pdata = (fclaw2d_patch_data_t *) patch->user;
            delete pdata->cp;
            pdata->cp = NULL;
            FCLAW2D_FREE (pdata);
            patch->user = NULL;
#endif
            ++ddata->count_delete_clawpatch;
        }

        FCLAW2D_FREE (bd);
        block->user = NULL;
    }

    // Free old parallel ghost patch data structure, must exist by construction.
    delete_ghost_patches(*domain);
    fclaw2d_domain_exchange_t *e_old = fclaw2d_partition_get_exchange_data(*domain);
    fclaw2d_domain_free_after_exchange (*domain, e_old);

    // Output memory discrepancy for the ClawPatch
    if (ddata->count_set_clawpatch != ddata->count_delete_clawpatch) {
        printf ("[%d] This domain had Clawpatch set %d and deleted %d times\n",
                (*domain)->mpirank,
                ddata->count_set_clawpatch, ddata->count_delete_clawpatch);
    }

    // Evaluate timers if this domain has not been superseded yet.
    if (ddata->is_latest_domain) {
        sc_statinfo_t stats[FCLAW2D_TIMER_COUNT];

        fclaw2d_timer_stop (&ddata->timers[FCLAW2D_TIMER_WALLTIME]);

        FCLAW2D_STATS_SET (stats, ddata, INIT);
        FCLAW2D_STATS_SET (stats, ddata, REGRID);
        FCLAW2D_STATS_SET (stats, ddata, OUTPUT);
        FCLAW2D_STATS_SET (stats, ddata, CHECK);
        FCLAW2D_STATS_SET (stats, ddata, ADVANCE);
        FCLAW2D_STATS_SET (stats, ddata, EXCHANGE);
        FCLAW2D_STATS_SET (stats, ddata, BUILDPATCHES);
        FCLAW2D_STATS_SET (stats, ddata, WALLTIME);
        sc_stats_set1 (&stats[FCLAW2D_TIMER_UNACCOUNTED],
                       ddata->timers[FCLAW2D_TIMER_WALLTIME].cumulative -
                       (ddata->timers[FCLAW2D_TIMER_INIT].cumulative +
                        ddata->timers[FCLAW2D_TIMER_REGRID].cumulative +
                        ddata->timers[FCLAW2D_TIMER_OUTPUT].cumulative +
                        ddata->timers[FCLAW2D_TIMER_CHECK].cumulative +
                        ddata->timers[FCLAW2D_TIMER_ADVANCE].cumulative +
                        ddata->timers[FCLAW2D_TIMER_EXCHANGE].cumulative),
                       "UNACCOUNTED");
        sc_stats_compute ((*domain)->mpicomm, FCLAW2D_TIMER_COUNT, stats);
        sc_stats_print (sc_package_id, SC_LP_PRODUCTION, FCLAW2D_TIMER_COUNT,
                        stats, 1, 0);
        SC_GLOBAL_PRODUCTIONF ("Procs %d advance %d %g exchange %d %g "
                               "regrid %d %g\n", (*domain)->mpisize,
                               ddata->count_amr_advance,
                               stats[FCLAW2D_TIMER_ADVANCE].average,
                               ddata->count_ghost_exchange,
                               stats[FCLAW2D_TIMER_EXCHANGE].average,
                               ddata->count_amr_regrid,
                               stats[FCLAW2D_TIMER_REGRID].average);
        SC_GLOBAL_PRODUCTIONF ("Max/P %d advance %d %g exchange %d %g "
                               "regrid %d %g\n", (*domain)->mpisize,
                               ddata->count_amr_advance,
                               stats[FCLAW2D_TIMER_ADVANCE].max,
                               ddata->count_ghost_exchange,
                               stats[FCLAW2D_TIMER_EXCHANGE].max,
                               ddata->count_amr_regrid,
                               stats[FCLAW2D_TIMER_REGRID].max);
    }

    delete_domain_data(*domain);  // Delete allocated pointers to set of functions.

    fclaw2d_domain_destroy(*domain);
    *domain = NULL;
}
<commit_msg>Lowered log level for timing stats output at end of run<commit_after>/*
Copyright (c) 2012 Carsten Burstedde, Donna Calhoun
All rights reserved.

Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are met:

 * Redistributions of source code must retain the above copyright notice, this
list of conditions and the following disclaimer.
 * Redistributions in binary form must reproduce the above copyright notice,
this list of conditions and the following disclaimer in the documentation
and/or other materials provided with the distribution.

THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
DISCLAIMED.  IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/

#include <fclaw2d_forestclaw.h>
#include <fclaw2d_clawpatch.hpp>
#include <fclaw2d_partition.h>

#include <sc_statistics.h>

#define FCLAW2D_STATS_SET(stats,ddata,NAME) do {                               \
    SC_CHECK_ABORT (!(ddata)->timers[FCLAW2D_TIMER_ ## NAME].running,          \
                    "Timer " #NAME " still running in amrreset");              \
    sc_stats_set1 ((stats) + FCLAW2D_TIMER_ ## NAME,                           \
                   (ddata)->timers[FCLAW2D_TIMER_ ## NAME].cumulative, #NAME); \
} while (0)

static
void delete_ghost_patches(fclaw2d_domain_t* domain)
{
    for(int i = 0; i < domain->num_ghost_patches; i++)
    {
        fclaw2d_patch_t* ghost_patch = &domain->ghost_patches[i];

        fclaw2d_patch_delete_cp(ghost_patch);
        fclaw2d_patch_delete_data(ghost_patch);
    }
}

void amrreset(fclaw2d_domain_t **domain)
{
    fclaw2d_domain_data_t *ddata = get_domain_data (*domain);

    for(int i = 0; i < (*domain)->num_blocks; i++)
    {
        fclaw2d_block_t *block = (*domain)->blocks + i;
        fclaw2d_block_data_t *bd = (fclaw2d_block_data_t *) block->user;

        for(int j = 0; j < block->num_patches; j++)
        {
            fclaw2d_patch_t *patch = block->patches + j;
            fclaw2d_patch_delete_cp(patch);
            fclaw2d_patch_delete_data(patch);
#if 0
            fclaw2d_patch_data_t *pdata = (fclaw2d_patch_data_t *) patch->user;
            delete pdata->cp;
            pdata->cp = NULL;
            FCLAW2D_FREE (pdata);
            patch->user = NULL;
#endif
            ++ddata->count_delete_clawpatch;
        }

        FCLAW2D_FREE (bd);
        block->user = NULL;
    }

    // Free old parallel ghost patch data structure, must exist by construction.
    delete_ghost_patches(*domain);
    fclaw2d_domain_exchange_t *e_old = fclaw2d_partition_get_exchange_data(*domain);
    fclaw2d_domain_free_after_exchange (*domain, e_old);

    // Output memory discrepancy for the ClawPatch
    if (ddata->count_set_clawpatch != ddata->count_delete_clawpatch) {
        printf ("[%d] This domain had Clawpatch set %d and deleted %d times\n",
                (*domain)->mpirank,
                ddata->count_set_clawpatch, ddata->count_delete_clawpatch);
    }

    // Evaluate timers if this domain has not been superseded yet.
    if (ddata->is_latest_domain) {
        sc_statinfo_t stats[FCLAW2D_TIMER_COUNT];

        fclaw2d_timer_stop (&ddata->timers[FCLAW2D_TIMER_WALLTIME]);

        FCLAW2D_STATS_SET (stats, ddata, INIT);
        FCLAW2D_STATS_SET (stats, ddata, REGRID);
        FCLAW2D_STATS_SET (stats, ddata, OUTPUT);
        FCLAW2D_STATS_SET (stats, ddata, CHECK);
        FCLAW2D_STATS_SET (stats, ddata, ADVANCE);
        FCLAW2D_STATS_SET (stats, ddata, EXCHANGE);
        FCLAW2D_STATS_SET (stats, ddata, BUILDPATCHES);
        FCLAW2D_STATS_SET (stats, ddata, WALLTIME);
        sc_stats_set1 (&stats[FCLAW2D_TIMER_UNACCOUNTED],
                       ddata->timers[FCLAW2D_TIMER_WALLTIME].cumulative -
                       (ddata->timers[FCLAW2D_TIMER_INIT].cumulative +
                        ddata->timers[FCLAW2D_TIMER_REGRID].cumulative +
                        ddata->timers[FCLAW2D_TIMER_OUTPUT].cumulative +
                        ddata->timers[FCLAW2D_TIMER_CHECK].cumulative +
                        ddata->timers[FCLAW2D_TIMER_ADVANCE].cumulative +
                        ddata->timers[FCLAW2D_TIMER_EXCHANGE].cumulative),
                       "UNACCOUNTED");
        sc_stats_compute ((*domain)->mpicomm, FCLAW2D_TIMER_COUNT, stats);
        sc_stats_print (sc_package_id, SC_LP_ESSENTIAL, FCLAW2D_TIMER_COUNT,
                        stats, 1, 0);
        SC_GLOBAL_ESSENTIALF ("Procs %d advance %d %g exchange %d %g "
                               "regrid %d %g\n", (*domain)->mpisize,
                               ddata->count_amr_advance,
                               stats[FCLAW2D_TIMER_ADVANCE].average,
                               ddata->count_ghost_exchange,
                               stats[FCLAW2D_TIMER_EXCHANGE].average,
                               ddata->count_amr_regrid,
                               stats[FCLAW2D_TIMER_REGRID].average);
        SC_GLOBAL_ESSENTIALF ("Max/P %d advance %d %g exchange %d %g "
                               "regrid %d %g\n", (*domain)->mpisize,
                               ddata->count_amr_advance,
                               stats[FCLAW2D_TIMER_ADVANCE].max,
                               ddata->count_ghost_exchange,
                               stats[FCLAW2D_TIMER_EXCHANGE].max,
                               ddata->count_amr_regrid,
                               stats[FCLAW2D_TIMER_REGRID].max);
    }

    delete_domain_data(*domain);  // Delete allocated pointers to set of functions.

    fclaw2d_domain_destroy(*domain);
    *domain = NULL;
}
<|endoftext|>