<commit_before>// Copyright (C) 2017 Elviss Strazdins
// This file is part of the Ouzel engine.

#include <algorithm>
#include "XML.hpp"
#include "core/Engine.hpp"
#include "Log.hpp"
#include "Utils.hpp"

namespace ouzel
{
    namespace xml
    {
        Node::Node()
        {
        }

        bool Node::parse(const std::vector<uint32_t>& utf32,
                         std::vector<uint32_t>::iterator& iterator)
        {
            if (iterator == utf32.end())
            {
                Log(Log::Level::ERR) << "Unexpected end of file";
                return false;
            }

            if (*iterator == '<')
            {
                ++iterator;

                if (iterator == utf32.end())
                {
                    Log(Log::Level::ERR) << "Unexpected end of file";
                    return false;
                }

                if (*iterator == '!') // <!
                {
                    ++iterator;

                    if (iterator == utf32.end())
                    {
                        Log(Log::Level::ERR) << "Unexpected end of file";
                        return false;
                    }

                    if (*iterator == '-') // <!-
                    {
                        ++iterator;

                        if (iterator == utf32.end())
                        {
                            Log(Log::Level::ERR) << "Unexpected end of file";
                            return false;
                        }

                        if (*iterator != '-') // <!--
                        {
                            Log(Log::Level::ERR) << "Expected a comment";
                            return false;
                        }

                        ++iterator;

                        for (;;)
                        {
                            if (iterator == utf32.end())
                            {
                                Log(Log::Level::ERR) << "Unexpected end of file";
                                return false;
                            }

                            if (*iterator == '-')
                            {
                                if (iterator + 1 == utf32.end())
                                {
                                    Log(Log::Level::ERR) << "Unexpected end of file";
                                    return false;
                                }

                                if (*(iterator + 1) == '-') // --
                                {
                                    iterator += 2;

                                    if (iterator == utf32.end())
                                    {
                                        Log(Log::Level::ERR) << "Unexpected end of file";
                                        return false;
                                    }

                                    if (*iterator == '>') // -->
                                    {
                                        ++iterator;
                                        break;
                                    }
                                    else
                                    {
                                        Log(Log::Level::ERR) << "Unexpected double-hyphen inside comment";
                                        return false;
                                    }
                                }
                            }

                            value += utf32to8(*iterator);
                            ++iterator;
                        }

                        type = Type::COMMENT;
                    }
                    else if (*iterator == '[') // <![
                    {
                        return true;
                    }
                    else
                    {
                        return true;
                    }
                }
                else if (*iterator == '?') // <?
                {
                    // TODO: parse xml declaration <?xml ... ?>
                    return true;
                }
                else // <
                {
                    ++iterator;

                    for (;;)
                    {
                        if (iterator == utf32.end())
                        {
                            Log(Log::Level::ERR) << "Unexpected end of file";
                            return false;
                        }

                        if (*iterator == '=' || *iterator == '<')
                        {
                            Log(Log::Level::ERR) << "Illegal character in tag name";
                            return false;
                        }

                        if (*iterator == ' ' || *iterator == '\r' || *iterator == '\n' || *iterator == '\t') // whitespace
                        {
                            break;
                        }
                        else
                        {
                            value += utf32to8(*iterator);
                            ++iterator;
                        }
                    }

                    for (;;)
                    {
                        // skip whitespaces
                        for (;;)
                        {
                            if (iterator == utf32.end())
                            {
                                Log(Log::Level::ERR) << "Unexpected end of file";
                                return false;
                            }

                            if (*iterator == ' ' || *iterator == '\r' || *iterator == '\n' || *iterator == '\t')
                            {
                                ++iterator;
                            }
                            else
                            {
                                break;
                            }
                        }

                        // TODO: parse attributes
                    }

                    // TODO: parse end of tag
                    // TODO: parse child tags

                    return true;
                }
            }
            else
            {
                for (;;)
                {
                    if (iterator == utf32.end() || // end of a file
                        *iterator == '<') // start of a tag
                    {
                        break;
                    }
                    else
                    {
                        value += utf32to8(*iterator);
                        ++iterator;
                    }
                }

                type = Node::Type::TEXT;

                return true;
            }

            return true;
        }

        bool Node::encode(std::vector<uint8_t>& data) const
        {
            switch (type)
            {
                case Node::Type::COMMENT:
                    data.insert(data.end(), {'<', '!', '-', '-'});
                    data.insert(data.end(), value.begin(), value.end());
                    data.insert(data.end(), {'-', '-', '>'});
                    break;
                case Node::Type::CDATA:
                    break;
                case Node::Type::DOCTYPE_DEFINITION:
                    break;
                case Node::Type::PROCESSING_INSTRUCTION:
                    data.insert(data.end(), {'<', '?'});
                    data.insert(data.end(), value.begin(), value.end());

                    if (attributes.empty())
                    {
                        data.insert(data.end(), ' ');
                    }
                    else
                    {
                        for (const auto& attribute : attributes)
                        {
                            data.insert(data.end(), attribute.first.begin(), attribute.first.end());
                            data.insert(data.end(), {'=', '"'});
                            data.insert(data.end(), attribute.second.begin(), attribute.second.end());
                            data.insert(data.end(), '"');
                        }
                    }

                    data.insert(data.end(), {'?', '>'});
                    break;
                case Node::Type::TAG:
                    data.insert(data.end(), '<');
                    data.insert(data.end(), value.begin(), value.end());

                    if (attributes.empty())
                    {
                        data.insert(data.end(), ' ');
                    }
                    else
                    {
                        for (const auto& attribute : attributes)
                        {
                            data.insert(data.end(), attribute.first.begin(), attribute.first.end());
                            data.insert(data.end(), {'=', '"'});
                            data.insert(data.end(), attribute.second.begin(), attribute.second.end());
                            data.insert(data.end(), '"');
                        }
                    }

                    if (children.empty())
                    {
                        data.insert(data.end(), {'/', '>'});
                    }
                    else
                    {
                        data.insert(data.end(), '>');

                        for (const Node& node : children)
                        {
                            node.encode(data);
                        }

                        data.insert(data.end(), {'<', '/'});
                        data.insert(data.end(), value.begin(), value.end());
                        data.insert(data.end(), '>');
                    }
                    break;
                case Node::Type::TEXT:
                    data.insert(data.end(), value.begin(), value.end());
                    break;
                default:
                    return false;
            }

            for (const Node& node : children)
            {
                node.encode(data);
            }

            return true;
        }

        Data::Data()
        {
        }

        Data::Data(const std::string& filename, bool preserveComments, bool preserveProcessingInstructions)
        {
            init(filename, preserveComments, preserveProcessingInstructions);
        }

        Data::Data(const std::vector<uint8_t>& data, bool preserveComments, bool preserveProcessingInstructions)
        {
            init(data, preserveComments, preserveProcessingInstructions);
        }

        bool Data::init(const std::string& filename, bool preserveComments, bool preserveProcessingInstructions)
        {
            std::vector<uint8_t> data;

            if (!engine->getFileSystem()->readFile(filename, data))
            {
                return false;
            }

            return init(data, preserveComments, preserveProcessingInstructions);
        }

        bool Data::init(const std::vector<uint8_t>& data, bool preserveComments, bool preserveProcessingInstructions)
        {
            std::vector<uint32_t> utf32;

            // BOM
            if (data.size() >= 3 &&
                data[0] == 0xEF &&
                data[1] == 0xBB &&
                data[2] == 0xBF)
            {
                bom = true;
                utf32 = utf8to32(std::vector<uint8_t>(data.begin() + 3, data.end()));
            }
            else
            {
                bom = false;
                utf32 = utf8to32(data);
            }

            std::vector<uint32_t>::iterator iterator = utf32.begin();

            while (iterator != utf32.end())
            {
                Node node;
                if (!node.parse(utf32, iterator))
                {
                    return false;
                }

                if ((preserveComments || node.getType() != Node::Type::COMMENT) &&
                    (preserveProcessingInstructions || node.getType() != Node::Type::PROCESSING_INSTRUCTION))
                {
                    children.push_back(node);
                }
            }

            // TODO: check if only single tag is in the children list

            return true;
        }

        bool Data::save(const std::string& filename) const
        {
            std::vector<uint8_t> data;

            if (!encode(data)) return false;

            return engine->getFileSystem()->writeFile(filename, data);
        }

        bool Data::encode(std::vector<uint8_t>& data) const
        {
            data.clear();

            if (bom) data.insert(data.end(), {0xEF, 0xBB, 0xBF});

            for (const Node& node : children)
            {
                if (!node.encode(data)) return false;
            }

            return true;
        }
    } // namespace xml
}
<commit_msg>Check for + and end of the tag Check if tag does not start with the . or -<commit_after>// Copyright (C) 2017 Elviss Strazdins
// This file is part of the Ouzel engine.

#include <algorithm>
#include "XML.hpp"
#include "core/Engine.hpp"
#include "Log.hpp"
#include "Utils.hpp"

namespace ouzel
{
    namespace xml
    {
        Node::Node()
        {
        }

        bool Node::parse(const std::vector<uint32_t>& utf32,
                         std::vector<uint32_t>::iterator& iterator)
        {
            if (iterator == utf32.end())
            {
                Log(Log::Level::ERR) << "Unexpected end of file";
                return false;
            }

            if (*iterator == '<')
            {
                ++iterator;

                if (iterator == utf32.end())
                {
                    Log(Log::Level::ERR) << "Unexpected end of file";
                    return false;
                }

                if (*iterator == '!') // <!
                {
                    ++iterator;

                    if (iterator == utf32.end())
                    {
                        Log(Log::Level::ERR) << "Unexpected end of file";
                        return false;
                    }

                    if (*iterator == '-') // <!-
                    {
                        ++iterator;

                        if (iterator == utf32.end())
                        {
                            Log(Log::Level::ERR) << "Unexpected end of file";
                            return false;
                        }

                        if (*iterator != '-') // <!--
                        {
                            Log(Log::Level::ERR) << "Expected a comment";
                            return false;
                        }

                        ++iterator;

                        for (;;)
                        {
                            if (iterator == utf32.end())
                            {
                                Log(Log::Level::ERR) << "Unexpected end of file";
                                return false;
                            }

                            if (*iterator == '-')
                            {
                                if (iterator + 1 == utf32.end())
                                {
                                    Log(Log::Level::ERR) << "Unexpected end of file";
                                    return false;
                                }

                                if (*(iterator + 1) == '-') // --
                                {
                                    iterator += 2;

                                    if (iterator == utf32.end())
                                    {
                                        Log(Log::Level::ERR) << "Unexpected end of file";
                                        return false;
                                    }

                                    if (*iterator == '>') // -->
                                    {
                                        ++iterator;
                                        break;
                                    }
                                    else
                                    {
                                        Log(Log::Level::ERR) << "Unexpected double-hyphen inside comment";
                                        return false;
                                    }
                                }
                            }

                            value += utf32to8(*iterator);
                            ++iterator;
                        }

                        type = Type::COMMENT;
                    }
                    else if (*iterator == '[') // <![
                    {
                        return true;
                    }
                    else
                    {
                        return true;
                    }
                }
                else if (*iterator == '?') // <?
                {
                    // TODO: parse xml declaration <?xml ... ?>
                    return true;
                }
                else // <
                {
                    ++iterator;

                    if (iterator == utf32.end())
                    {
                        Log(Log::Level::ERR) << "Unexpected end of file";
                        return false;
                    }

                    if (*iterator == '-' || *iterator == '.') // tag name can not start with - or .
                    {
                        Log(Log::Level::ERR) << "Invalid tag name";
                        return false;
                    }

                    for (;;)
                    {
                        if (iterator == utf32.end())
                        {
                            Log(Log::Level::ERR) << "Unexpected end of file";
                            return false;
                        }

                        if (*iterator == '+' || *iterator == '=' || *iterator == '<')
                        {
                            Log(Log::Level::ERR) << "Illegal character in tag name";
                            return false;
                        }

                        if (*iterator == ' ' || *iterator == '\r' || *iterator == '\n' || *iterator == '\t' || // whitespace
                            *iterator == '>') // end of the opening
                        {
                            break;
                        }
                        else
                        {
                            value += utf32to8(*iterator);
                            ++iterator;
                        }
                    }

                    for (;;)
                    {
                        // skip whitespaces
                        for (;;)
                        {
                            if (iterator == utf32.end())
                            {
                                Log(Log::Level::ERR) << "Unexpected end of file";
                                return false;
                            }

                            if (*iterator == ' ' || *iterator == '\r' || *iterator == '\n' || *iterator == '\t')
                            {
                                ++iterator;
                            }
                            else
                            {
                                break;
                            }
                        }

                        // TODO: parse attributes
                    }

                    // TODO: parse end of tag
                    // TODO: parse child tags

                    return true;
                }
            }
            else
            {
                for (;;)
                {
                    if (iterator == utf32.end() || // end of a file
                        *iterator == '<') // start of a tag
                    {
                        break;
                    }
                    else
                    {
                        value += utf32to8(*iterator);
                        ++iterator;
                    }
                }

                type = Node::Type::TEXT;

                return true;
            }

            return true;
        }

        bool Node::encode(std::vector<uint8_t>& data) const
        {
            switch (type)
            {
                case Node::Type::COMMENT:
                    data.insert(data.end(), {'<', '!', '-', '-'});
                    data.insert(data.end(), value.begin(), value.end());
                    data.insert(data.end(), {'-', '-', '>'});
                    break;
                case Node::Type::CDATA:
                    break;
                case Node::Type::DOCTYPE_DEFINITION:
                    break;
                case Node::Type::PROCESSING_INSTRUCTION:
                    data.insert(data.end(), {'<', '?'});
                    data.insert(data.end(), value.begin(), value.end());

                    if (attributes.empty())
                    {
                        data.insert(data.end(), ' ');
                    }
                    else
                    {
                        for (const auto& attribute : attributes)
                        {
                            data.insert(data.end(), attribute.first.begin(), attribute.first.end());
                            data.insert(data.end(), {'=', '"'});
                            data.insert(data.end(), attribute.second.begin(), attribute.second.end());
                            data.insert(data.end(), '"');
                        }
                    }

                    data.insert(data.end(), {'?', '>'});
                    break;
                case Node::Type::TAG:
                    data.insert(data.end(), '<');
                    data.insert(data.end(), value.begin(), value.end());

                    if (attributes.empty())
                    {
                        data.insert(data.end(), ' ');
                    }
                    else
                    {
                        for (const auto& attribute : attributes)
                        {
                            data.insert(data.end(), attribute.first.begin(), attribute.first.end());
                            data.insert(data.end(), {'=', '"'});
                            data.insert(data.end(), attribute.second.begin(), attribute.second.end());
                            data.insert(data.end(), '"');
                        }
                    }

                    if (children.empty())
                    {
                        data.insert(data.end(), {'/', '>'});
                    }
                    else
                    {
                        data.insert(data.end(), '>');

                        for (const Node& node : children)
                        {
                            node.encode(data);
                        }

                        data.insert(data.end(), {'<', '/'});
                        data.insert(data.end(), value.begin(), value.end());
                        data.insert(data.end(), '>');
                    }
                    break;
                case Node::Type::TEXT:
                    data.insert(data.end(), value.begin(), value.end());
                    break;
                default:
                    return false;
            }

            for (const Node& node : children)
            {
                node.encode(data);
            }

            return true;
        }

        Data::Data()
        {
        }

        Data::Data(const std::string& filename, bool preserveComments, bool preserveProcessingInstructions)
        {
            init(filename, preserveComments, preserveProcessingInstructions);
        }

        Data::Data(const std::vector<uint8_t>& data, bool preserveComments, bool preserveProcessingInstructions)
        {
            init(data, preserveComments, preserveProcessingInstructions);
        }

        bool Data::init(const std::string& filename, bool preserveComments, bool preserveProcessingInstructions)
        {
            std::vector<uint8_t> data;

            if (!engine->getFileSystem()->readFile(filename, data))
            {
                return false;
            }

            return init(data, preserveComments, preserveProcessingInstructions);
        }

        bool Data::init(const std::vector<uint8_t>& data, bool preserveComments, bool preserveProcessingInstructions)
        {
            std::vector<uint32_t> utf32;

            // BOM
            if (data.size() >= 3 &&
                data[0] == 0xEF &&
                data[1] == 0xBB &&
                data[2] == 0xBF)
            {
                bom = true;
                utf32 = utf8to32(std::vector<uint8_t>(data.begin() + 3, data.end()));
            }
            else
            {
                bom = false;
                utf32 = utf8to32(data);
            }

            std::vector<uint32_t>::iterator iterator = utf32.begin();

            while (iterator != utf32.end())
            {
                Node node;
                if (!node.parse(utf32, iterator))
                {
                    return false;
                }

                if ((preserveComments || node.getType() != Node::Type::COMMENT) &&
                    (preserveProcessingInstructions || node.getType() != Node::Type::PROCESSING_INSTRUCTION))
                {
                    children.push_back(node);
                }
            }

            // TODO: check if only single tag is in the children list

            return true;
        }

        bool Data::save(const std::string& filename) const
        {
            std::vector<uint8_t> data;

            if (!encode(data)) return false;

            return engine->getFileSystem()->writeFile(filename, data);
        }

        bool Data::encode(std::vector<uint8_t>& data) const
        {
            data.clear();

            if (bom) data.insert(data.end(), {0xEF, 0xBB, 0xBF});

            for (const Node& node : children)
            {
                if (!node.encode(data)) return false;
            }

            return true;
        }
    } // namespace xml
}
<|endoftext|>


<commit_before>#include "genetic.h"

#include <string>
#include <iostream>
#include <functional>
#include <utility>    // std::map
#include <algorithm>  // std::max
#include <random>     // std::mt19937

#include <cstdio>
#include <cstdlib>
#include <ctime>  // std::time

#include "utility.h"

using std::string;
using std::vector;
using std::srand;
using std::rand;
using std::time;

// don't we want this in genetic.h (outside class)? if it's here it's global

Genetic::Genetic(int n, BooleanTable outputs) : population(), input_no(n), expected_outputs(outputs), rand_engine(std::random_device{}()){ population = spawnPopulation(1000);}

Genetic::Genetic(int n, BooleanTable outputs, std::map<int, Circuit> pop)
    : population(pop), input_no(n), expected_outputs(outputs), rand_engine(std::random_device{}()) { };
Genetic::~Genetic() {}

int Genetic::fitness(GeneticCircuit c) {
  int score = 0;
  score += c.getNotCount() * 10000;
  score += c.getAndCount() * 10;
  score += c.getOrCount() * 1;
  return score;
}

void Genetic::split(Circuit c1, Circuit c2) {
  // random numbers should be in normal distribution
  std::uniform_int_distribution<> dist{input_no,
                                       (int)expected_outputs.front().size()};
  for (int i = 0; i < 50; ++i) {
    std::string errmsg =
        "Genetic::split: random number: " + std::to_string(dist(rand_engine));
    errlog(errmsg);
  }
}

void Genetic::splice() {}

void Genetic::splitAndSplice() {}

std::map<int, Circuit> Genetic::spawnPopulation(int populationSize) {
  std::map<int, Circuit> spawned_pop;
  for (int i = 0; i < populationSize; ++i) {
    GeneticCircuit c =
        GeneticCircuit(input_no, expected_outputs.front().size());
    int circuit_fitness = fitness(c);
    c.setFitness(circuit_fitness);

    std::string errmsg =
        "Genetic::spawnPopulation inserting Circuit fitness: " +
        std::to_string(circuit_fitness);
    errlog(errmsg);

    std::pair<int, Circuit> zergling(hash_circ(c), c);
    spawned_pop.insert(zergling);
  }
  return spawned_pop;
}

size_t hash_circ(GeneticCircuit c) {
  std::string s = "";
  std::hash<std::string> hash_fn;
  BooleanTable outputs = c.evaluateAllInputs();
  for (std::vector<bool> row : outputs) {
    for (bool bit : row) {
      s += std::to_string((int)bit);
    }
  }

  std::cout << "Hashing..." << std::endl;
  size_t hash = hash_fn(s);
  std::cout << "Done Hashing..: " << hash << std::endl;
  std::cout << " NOT: " << c.getNotCount() << " AND: " << c.getAndCount()
            << " OR: " << c.getOrCount();
  return hash;
}
<commit_msg>clang-formatted<commit_after>#include "genetic.h"

#include <string>
#include <iostream>
#include <functional>
#include <utility>    // std::map
#include <algorithm>  // std::max
#include <random>     // std::mt19937

#include <cstdio>
#include <cstdlib>
#include <ctime>  // std::time

#include "utility.h"

using std::string;
using std::vector;
using std::srand;
using std::rand;
using std::time;

// don't we want this in genetic.h (outside class)? if it's here it's global

Genetic::Genetic(int n, BooleanTable outputs)
    : population(),
      input_no(n),
      expected_outputs(outputs),
      rand_engine(std::random_device{}()) {
  population = spawnPopulation(1000);
}

Genetic::Genetic(int n, BooleanTable outputs, std::map<int, Circuit> pop)
    : population(pop),
      input_no(n),
      expected_outputs(outputs),
      rand_engine(std::random_device{}()){};
Genetic::~Genetic() {}

int Genetic::fitness(GeneticCircuit c) {
  int score = 0;
  score += c.getNotCount() * 10000;
  score += c.getAndCount() * 10;
  score += c.getOrCount() * 1;
  return score;
}

void Genetic::split(Circuit c1, Circuit c2) {
  // random numbers should be in normal distribution
  std::uniform_int_distribution<> dist{input_no,
                                       (int)expected_outputs.front().size()};
  for (int i = 0; i < 50; ++i) {
    std::string errmsg =
        "Genetic::split: random number: " + std::to_string(dist(rand_engine));
    errlog(errmsg);
  }
}

void Genetic::splice() {}

void Genetic::splitAndSplice() {}

std::map<int, Circuit> Genetic::spawnPopulation(int populationSize) {
  std::map<int, Circuit> spawned_pop;
  for (int i = 0; i < populationSize; ++i) {
    GeneticCircuit c =
        GeneticCircuit(input_no, expected_outputs.front().size());
    int circuit_fitness = fitness(c);
    c.setFitness(circuit_fitness);

    std::string errmsg =
        "Genetic::spawnPopulation inserting Circuit fitness: " +
        std::to_string(circuit_fitness);
    errlog(errmsg);

    std::pair<int, Circuit> zergling(hash_circ(c), c);
    spawned_pop.insert(zergling);
  }
  return spawned_pop;
}

size_t hash_circ(GeneticCircuit c) {
  std::string s = "";
  std::hash<std::string> hash_fn;
  BooleanTable outputs = c.evaluateAllInputs();
  for (std::vector<bool> row : outputs) {
    for (bool bit : row) {
      s += std::to_string((int)bit);
    }
  }

  std::cout << "Hashing..." << std::endl;
  size_t hash = hash_fn(s);
  std::cout << "Done Hashing..: " << hash << std::endl;
  std::cout << " NOT: " << c.getNotCount() << " AND: " << c.getAndCount()
            << " OR: " << c.getOrCount();
  return hash;
}
<|endoftext|>


<commit_before>/*
 * Memory.cpp -- dynamic memory allocation
 *
 * Copyright (c) 2007-2012, Frank Mertens
 *
 * This file is part of the a free software library. You can redistribute
 * it and/or modify it under the terms of FTL's 2-clause BSD license.
 *
 * See the LICENSE.txt file for details at the top-level of FTL's sources.
 */

#include <sys/mman.h>
#include <unistd.h>
#include <assert.h>
#include <new>
#include "debug.hpp"
#include "types.hpp"
#include "Mutex.hpp"
#include "Memory.hpp"

#ifndef MAP_ANONYMOUS
#define MAP_ANONYMOUS MAP_ANON
#endif

namespace ftl
{

#ifndef FTL_MEM_GRANULARITY
#define FTL_MEM_GRANULARITY 16
	// some CPUs require objects in memory to be aligned to 16 byte boundaries,
	// e.g. the XMMS instruction movdqa may segfault on unaligned arguments
#endif

#define FTL_MEM_ALIGN(x) (((x) / FTL_MEM_GRANULARITY + ((x) % FTL_MEM_GRANULARITY != 0)) * FTL_MEM_GRANULARITY)

void *Memory::operator new(size_t size)
{
	long pageSize = ::sysconf(_SC_PAGE_SIZE);
	check(pageSize > 0);
	check(size <= (unsigned long)pageSize);
	void *data = ::mmap(0, pageSize, PROT_READ|PROT_WRITE, MAP_ANONYMOUS|MAP_PRIVATE, -1, 0);
	check(data != MAP_FAILED);
	return data;
}

void Memory::operator delete(void *data, size_t size)
{
	check(::munmap(data, ::sysconf(_SC_PAGE_SIZE)) == 0);
}

class Memory::BucketHeader: public Mutex
{
public:
	uint32_t bytesDirty_;
	uint32_t objectCount_;
	bool open_;
};

Memory::Memory()
	: pageSize_(::sysconf(_SC_PAGE_SIZE)),
	  bucket_(0)
{}

void *Memory::allocate(size_t size)
{
	Ref<Memory> allocator = instance();
	BucketHeader *bucket = allocator->bucket_;
	size_t pageSize = allocator->pageSize_;

	size = FTL_MEM_ALIGN(size);

	if (size == pageSize) {
		void *pageStart = ::mmap(0, pageSize, PROT_READ|PROT_WRITE, MAP_ANONYMOUS|MAP_PRIVATE, -1, 0);
		check(pageStart != MAP_FAILED);
		return pageStart;
	}

	if (!bucket) {
		if (size > pageSize - FTL_MEM_ALIGN(sizeof(BucketHeader))) {
			size += sizeof(uint32_t);
			uint32_t pageCount = size / pageSize + ((size % pageSize) > 0);
			void *pageStart = ::mmap(0, pageCount * pageSize, PROT_READ|PROT_WRITE, MAP_ANONYMOUS|MAP_PRIVATE, -1, 0);
			check(pageStart != MAP_FAILED);
			*(uint32_t *)pageStart = pageCount;
			return (void *)((uint32_t *)pageStart + 1);
		}
		else {
			void *pageStart = ::mmap(0, pageSize, PROT_READ|PROT_WRITE, MAP_ANONYMOUS|MAP_PRIVATE, -1, 0);
			check(pageStart != MAP_FAILED);
			bucket = new(pageStart)BucketHeader;
			check((char*)bucket == (char*)pageStart);
			bucket->bytesDirty_ = FTL_MEM_ALIGN(sizeof(BucketHeader)) + size;
			bucket->objectCount_ = 1;
			bucket->open_ = true;
			allocator->bucket_ = bucket;
			return (void *)((char *)pageStart + FTL_MEM_ALIGN(sizeof(BucketHeader)));
		}
	}
	else {
		bucket->acquire();
		if (size <= pageSize - bucket->bytesDirty_) {
			void *data = (void *)(((char *)bucket) + bucket->bytesDirty_);
			bucket->bytesDirty_ += size;
			++bucket->objectCount_;
			bucket->release();
			return data;
		}
		else {
			bucket->open_ = false;
			bucket->release();
			allocator->bucket_ = 0;
			return allocate(size);
		}
	}
}

void Memory::free(void *data)
{
	Ref<Memory> allocator = instance();
	size_t pageSize = allocator ? allocator->pageSize_ : size_t(::sysconf(_SC_PAGE_SIZE));

	uint32_t offset = ((char *)data - (char *)0) % pageSize;

	if (offset == 0) {
		check(::munmap(data, pageSize) == 0);
	}
	else if (offset == sizeof(uint32_t)) {
		void *pageStart = (void *)((char *)data - sizeof(uint32_t));
		uint32_t pageCount = *(uint32_t *)pageStart;
		check(::munmap(pageStart, pageCount * pageSize) == 0);
	}
	else {
		BucketHeader *bucket = (BucketHeader *)((char *)data - offset);
		bucket->acquire();
		bool dispose = ((--bucket->objectCount_) == 0) && (!bucket->open_);
		bucket->release();
		if (dispose) {
			bucket->~BucketHeader();
			check(::munmap((void *)((char *)data - offset), pageSize) == 0);
		}
	}
}

size_t Memory::pageSize()
{
	return instance()->pageSize_;
}

} // namespace ftl
<commit_msg>Heap allocator: increase density of small allocations<commit_after>/*
 * Memory.cpp -- dynamic memory allocation
 *
 * Copyright (c) 2007-2012, Frank Mertens
 *
 * This file is part of the a free software library. You can redistribute
 * it and/or modify it under the terms of FTL's 2-clause BSD license.
 *
 * See the LICENSE.txt file for details at the top-level of FTL's sources.
 */

#include <sys/mman.h>
#include <unistd.h>
#include <assert.h>
#include <new>
#include "debug.hpp"
#include "types.hpp"
#include "Mutex.hpp"
#include "Memory.hpp"

#ifndef MAP_ANONYMOUS
#define MAP_ANONYMOUS MAP_ANON
#endif

namespace ftl
{

#define FTL_MEM_GRANULARITY_SHIFT(x) ((x >= 16) ?  4 : ((x >= 4) ? 2 : 0))
#define FTL_MEM_GRANULARITY_MASK(x)  ((x >= 16) ? 15 : ((x >= 4) ? 3 : 0))
#define FTL_MEM_ALIGN(x) ((((x) >> FTL_MEM_GRANULARITY_SHIFT(x)) + (((x) & FTL_MEM_GRANULARITY_MASK(x)) != 0)) << FTL_MEM_GRANULARITY_SHIFT(x))
	// some CPUs require objects in memory to be aligned to 16 byte boundaries,
	// e.g. the XMMS instruction movdqa may segfault on unaligned arguments

void *Memory::operator new(size_t size)
{
	long pageSize = ::sysconf(_SC_PAGE_SIZE);
	check(pageSize > 0);
	check(size <= (unsigned long)pageSize);
	void *data = ::mmap(0, pageSize, PROT_READ|PROT_WRITE, MAP_ANONYMOUS|MAP_PRIVATE, -1, 0);
	check(data != MAP_FAILED);
	return data;
}

void Memory::operator delete(void *data, size_t size)
{
	check(::munmap(data, ::sysconf(_SC_PAGE_SIZE)) == 0);
}

class Memory::BucketHeader: public Mutex
{
public:
	uint32_t bytesDirty_;
	uint32_t objectCount_;
	bool open_;
};

Memory::Memory()
	: pageSize_(::sysconf(_SC_PAGE_SIZE)),
	  bucket_(0)
{}

void *Memory::allocate(size_t size)
{
	Ref<Memory> allocator = instance();
	BucketHeader *bucket = allocator->bucket_;
	size_t pageSize = allocator->pageSize_;

	size = FTL_MEM_ALIGN(size);

	if (size == pageSize) {
		void *pageStart = ::mmap(0, pageSize, PROT_READ|PROT_WRITE, MAP_ANONYMOUS|MAP_PRIVATE, -1, 0);
		check(pageStart != MAP_FAILED);
		return pageStart;
	}

	if (!bucket) {
		if (size > pageSize - FTL_MEM_ALIGN(sizeof(BucketHeader))) {
			size += sizeof(uint32_t);
			uint32_t pageCount = size / pageSize + ((size % pageSize) > 0);
			void *pageStart = ::mmap(0, pageCount * pageSize, PROT_READ|PROT_WRITE, MAP_ANONYMOUS|MAP_PRIVATE, -1, 0);
			check(pageStart != MAP_FAILED);
			*(uint32_t *)pageStart = pageCount;
			return (void *)((uint32_t *)pageStart + 1);
		}
		else {
			void *pageStart = ::mmap(0, pageSize, PROT_READ|PROT_WRITE, MAP_ANONYMOUS|MAP_PRIVATE, -1, 0);
			check(pageStart != MAP_FAILED);
			bucket = new(pageStart)BucketHeader;
			check((char*)bucket == (char*)pageStart);
			bucket->bytesDirty_ = FTL_MEM_ALIGN(sizeof(BucketHeader)) + size;
			bucket->objectCount_ = 1;
			bucket->open_ = true;
			allocator->bucket_ = bucket;
			return (void *)((char *)pageStart + FTL_MEM_ALIGN(sizeof(BucketHeader)));
		}
	}
	else {
		bucket->acquire();
		if (size <= pageSize - bucket->bytesDirty_) {
			void *data = (void *)(((char *)bucket) + bucket->bytesDirty_);
			bucket->bytesDirty_ += size;
			++bucket->objectCount_;
			bucket->release();
			return data;
		}
		else {
			bucket->open_ = false;
			bucket->release();
			allocator->bucket_ = 0;
			return allocate(size);
		}
	}
}

void Memory::free(void *data)
{
	Ref<Memory> allocator = instance();
	size_t pageSize = allocator ? allocator->pageSize_ : size_t(::sysconf(_SC_PAGE_SIZE));

	uint32_t offset = ((char *)data - (char *)0) % pageSize;

	if (offset == 0) {
		check(::munmap(data, pageSize) == 0);
	}
	else if (offset == sizeof(uint32_t)) {
		void *pageStart = (void *)((char *)data - sizeof(uint32_t));
		uint32_t pageCount = *(uint32_t *)pageStart;
		check(::munmap(pageStart, pageCount * pageSize) == 0);
	}
	else {
		BucketHeader *bucket = (BucketHeader *)((char *)data - offset);
		bucket->acquire();
		bool dispose = ((--bucket->objectCount_) == 0) && !bucket->open_;
		bucket->release();
		if (dispose) {
			bucket->~BucketHeader();
			check(::munmap((void *)((char *)data - offset), pageSize) == 0);
		}
	}
}

size_t Memory::pageSize()
{
	return instance()->pageSize_;
}

} // namespace ftl
<|endoftext|>


<commit_before>#include <fstream>
#include <iostream>
#include <string>
#include <cstring>
#include <vector>

#include "mugen_item_content.h"
#include "mugen_section.h"
#include "mugen_reader.h"
#include "globals.h"

using namespace std;

// Check for Clsn
static bool checkClsn( const std::string &clsn ){
  return ( clsn.find("Clsn") != std::string::npos );
}

MugenReader::MugenReader( const char * file ){
    Global::debug(1) << "[mugen reader] Opening file '" << file << "'" << endl;
    ifile.open( file );
    if (!ifile){
        perror("cant open file");
    }
    myfile = string( file );
}

MugenReader::MugenReader( const string & file ){
    Global::debug(1) << "[mugen reader] Opening file '" << file << "'" << endl;
    ifile.open( file.c_str() );
    if (!ifile){
        perror("cant open file");
    }
    myfile = file;
}

MugenReader::~MugenReader(){
    ifile.close();

    for( std::vector< MugenSection * >::iterator i = collection.begin() ; i != collection.end() ; ++i ){
        if(*i)delete (*i);
    }

}

const std::vector< MugenSection * > & MugenReader::getCollection() throw(MugenException){

  if ( !ifile ){
      throw MugenException( std::string("Could not open file: ") + myfile );
  }

  std::string line;

  const char openbracket = '[';
  const char closebracket = ']';
  const char comment = ';';
  const char seperator = ',';
  const char colon = ':';
  const char equal = '=';
  const char quote = '"';
  const char * ignored = "\r\n";

  SearchState state = Section;
  // Our section and items
  MugenSection * sectionHolder = 0;
  // Marker for areas
  bool beginSection = false;

  while( !ifile.eof() ){
      getline( ifile, line );
      // Use to hold section or content in the options
      std::string contentHolder = "";
      // Place holder to put back all the grabbed content
      MugenItemContent *itemHolder = new MugenItemContent();
      // Needed to kill loop
      bool breakLoop = false;
      bool inQuote = false;
      bool getExpression = false;

      for( unsigned int i = 0; i < line.size(); ++i ){
	    // Go to work
	    switch( state ){
	      case Section:{
		// Done with this
		if( line[i] == comment ){
		  breakLoop = true;
		  break;
		}
		else if ( line[i] == ' ' && !beginSection )continue;
		//Start grabbing our section
		else if( line[i] == openbracket){
		  beginSection = true;
		}
		//End of our section store and go to ContentGet
		else if( line[i] == closebracket){
		  sectionHolder = new MugenSection();
		  sectionHolder->setHeader( contentHolder );
		  state = ContentGet;
		  beginSection = false;
		  breakLoop = true;
		  break;
		}
		else if( beginSection )contentHolder += line[i];
	      }
	      break;
	      case ContentGet:
	      default:{
		// Done with this
		if( line[i] == comment ){
		  if( itemHolder->hasItems() ){
		    if( !contentHolder.empty() ){
		      *itemHolder << contentHolder;
		    }
		    *sectionHolder << itemHolder;
		  }
		  breakLoop = true;
		  break;
		}
		// Check if we are near the end to kill it
		if( i+1 == line.size() && !contentHolder.empty() ){
		    if (line[i] != ' ' && !strchr(ignored, line[i])){
                        contentHolder += line[i];
                    }
		    *itemHolder << contentHolder;
		    *sectionHolder << itemHolder;
		    breakLoop = true;
		    break;
		}
		// Buh bye spaces
		if( line[i] == ' ' && !inQuote ){
		  continue;
		}
		// Start getting expression
		if( line[i] != ' ' && getExpression ){
		  inQuote = true;
		}
		// Check if this section is done, push it on the stack and reset everything
		if( line[i] == openbracket && !checkClsn( contentHolder ) && !itemHolder->hasItems() ){
		  addSection( sectionHolder );
		  beginSection = true;
		  state = Section;
		  contentHolder = "";
		  break;
		}
		// We got one push back the other and reset the holder to get the next
		else if( line[i] == colon || line[i] == seperator ){
		  if( !contentHolder.empty() ) *itemHolder << contentHolder;
		  contentHolder = "";
		}
		// Equal
		else if(line[i] == equal && !inQuote ){
		  if( !contentHolder.empty() ) *itemHolder << contentHolder;
		  getExpression = true;
		  contentHolder = "";
		}
		// We has a quote begin or end it
		else if( line[i] == quote ){
		  inQuote = !inQuote;
		}
		//Start grabbing our item
		else if (! strchr(ignored, line[i])){
                    contentHolder += line[i];
                }
	      }
	      break;
	    }
	    if( breakLoop )break;
      }
  }
  // Add in last section
  addSection( sectionHolder );

  return collection;
}

void MugenReader::addSection( MugenSection * section ){
  collection.push_back ( section );
}

<commit_msg>Updated reader to not skip lines in windows.<commit_after>#include <fstream>
#include <iostream>
#include <string>
#include <cstring>
#include <vector>

#include "mugen_item_content.h"
#include "mugen_section.h"
#include "mugen_reader.h"
#include "globals.h"

using namespace std;

// Check for Clsn
static bool checkClsn( const std::string &clsn ){
  return ( clsn.find("Clsn") != std::string::npos );
}

MugenReader::MugenReader( const char * file ){
    Global::debug(1) << "[mugen reader] Opening file '" << file << "'" << endl;
    ifile.open( file );
    if (!ifile){
        perror("cant open file");
    }
    myfile = string( file );
}

MugenReader::MugenReader( const string & file ){
    Global::debug(1) << "[mugen reader] Opening file '" << file << "'" << endl;
    ifile.open( file.c_str() );
    if (!ifile){
        perror("cant open file");
    }
    myfile = file;
}

MugenReader::~MugenReader(){
    ifile.close();

    for( std::vector< MugenSection * >::iterator i = collection.begin() ; i != collection.end() ; ++i ){
        if(*i)delete (*i);
    }

}

const std::vector< MugenSection * > & MugenReader::getCollection() throw(MugenException){

  if ( !ifile ){
      throw MugenException( std::string("Could not open file: ") + myfile );
  }

  std::string line;

  const char openbracket = '[';
  const char closebracket = ']';
  const char comment = ';';
  const char seperator = ',';
  const char colon = ':';
  const char equal = '=';
  const char quote = '"';
  const char * ignored = "\r\n";

  SearchState state = Section;
  // Our section and items
  MugenSection * sectionHolder = 0;
  // Marker for areas
  bool beginSection = false;

  while( !ifile.eof() ){
      getline( ifile, line );
      // Use to hold section or content in the options
      std::string contentHolder = "";
      // Place holder to put back all the grabbed content
      MugenItemContent *itemHolder = new MugenItemContent();
      // Needed to kill loop
      bool breakLoop = false;
      bool inQuote = false;
      bool getExpression = false;
      bool startComment = false;

      Global::debug(0) << line << endl;

      for( unsigned int i = 0; i < line.size(); ++i ){
	    // Go to work
	    switch( state ){
	      case Section:{
		// Done with this
		if( line[i] == comment ){
		  breakLoop = true;
		  break;
		}
		else if ( line[i] == ' ' && !beginSection )continue;
		//Start grabbing our section
		else if( line[i] == openbracket){
		  beginSection = true;
		}
		//End of our section store and go to ContentGet
		else if( line[i] == closebracket){
		  sectionHolder = new MugenSection();
		  sectionHolder->setHeader( contentHolder );
		  state = ContentGet;
		  beginSection = false;
		  breakLoop = true;
		  break;
		}
		else if( beginSection )contentHolder += line[i];
	      }
	      break;
	      case ContentGet:
	      default:{
		// Done with this
		if( line[i] == comment ){
		  startComment = true;
		}
		// Check if we are near the end to kill it
		if( i+1 == line.size() && !contentHolder.empty() ){
		    if (line[i] != ' ' && !strchr(ignored, line[i])){
                        contentHolder += line[i];
                    }
		    *itemHolder << contentHolder;
		    *sectionHolder << itemHolder;
		    breakLoop = true;
		    break;
		}
		// Buh bye spaces
		if( line[i] == ' ' && !inQuote ){
		  continue;
		}
		// Start getting expression
		if( line[i] != ' ' && getExpression ){
		  inQuote = true;
		}
		// Check if this section is done, push it on the stack and reset everything
		if( line[i] == openbracket && !checkClsn( contentHolder ) && !itemHolder->hasItems() ){
		  addSection( sectionHolder );
		  beginSection = true;
		  state = Section;
		  contentHolder = "";
		  break;
		}
		// We got one push back the other and reset the holder to get the next
		else if( line[i] == colon || line[i] == seperator ){
		  if( !contentHolder.empty() && !strchr(ignored, contentHolder[0]) ){
		      *itemHolder << contentHolder;
		  }
		  contentHolder = "";
		}
		// Equal
		else if(line[i] == equal && !inQuote ){
		  if( !contentHolder.empty() ) *itemHolder << contentHolder;
		  getExpression = true;
		  contentHolder = "";
		}
		// We has a quote begin or end it
		else if( line[i] == quote ){
		  inQuote = !inQuote;
		}
		//Start grabbing our item
		else if (!startComment && !strchr(ignored, line[i])){
                    contentHolder += line[i];
                }
	      }
	      break;
	    }
	    if( breakLoop )break;
      }
      if (state == ContentGet){
	    if( itemHolder->hasItems() ){
		if( !contentHolder.empty() && !strchr(ignored, contentHolder[0]) ){
		    *itemHolder << contentHolder;
		}
		*sectionHolder << itemHolder;
	    }
	}
  }
  // Add in last section
  addSection( sectionHolder );

  return collection;
}

void MugenReader::addSection( MugenSection * section ){
  collection.push_back ( section );
}

<|endoftext|>


<commit_before>/*
Copyright (c) 2007-2011, Trustees of The Leland Stanford Junior University
All rights reserved.

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

Redistributions of source code must retain the above copyright notice, this list
of conditions and the following disclaimer.
Redistributions in binary form must reproduce the above copyright notice, this
list of conditions and the following disclaimer in the documentation and/or
other materials provided with the distribution.
Neither the name of the Stanford University nor the names of its contributors
may be used to endorse or promote products derived from this software without
specific prior written permission.

THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER 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.
*/

#ifndef _DragonFly_HPP_
#define _DragonFly_HPP_

#include "network.hpp"
#include "routefunc.hpp"

class DragonFlyNew : public Network {

  int _m;
  int _n;
  int _r;
  int _k;
  int _p, _a, _g;
  int _radix;
  int _net_size;
  int _stageout;
  int _numinput;
  int _stages;
  int _num_of_switch;
  int _grp_num_routers;
  int _grp_num_nodes;

  void _ComputeSize( const Configuration &config );
  void _BuildNet( const Configuration &config );

public:
  DragonFlyNew( const Configuration &config, const string & name );

  int GetN( ) const;
  int GetK( ) const;

  double Capacity( ) const;
  static void RegisterRoutingFunctions();
  void InsertRandomFaults( const Configuration &config );

};
int dragonfly_port(int rID, int source, int dest);

void ugal_dragonflynew( const Router *r, const Flit *f, int in_channel,
		       OutputSet *outputs, bool inject );
void ugalprog_dragonflynew( const Router *r, const Flit *f, int in_channel,
		       OutputSet *outputs, bool inject );
void min_dragonflynew( const Router *r, const Flit *f, int in_channel,
		       OutputSet *outputs, bool inject );

void res_dragonflynew( const Router *r, const Flit *f, int in_channel,
		       OutputSet *outputs, bool inject );
void compressed_dragonflynew( const Router *r, const Flit *f, int in_channel,
		       OutputSet *outputs, bool inject );
#endif
<commit_msg>remove unused function declarations<commit_after>/*
Copyright (c) 2007-2011, Trustees of The Leland Stanford Junior University
All rights reserved.

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

Redistributions of source code must retain the above copyright notice, this list
of conditions and the following disclaimer.
Redistributions in binary form must reproduce the above copyright notice, this
list of conditions and the following disclaimer in the documentation and/or
other materials provided with the distribution.
Neither the name of the Stanford University nor the names of its contributors
may be used to endorse or promote products derived from this software without
specific prior written permission.

THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER 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.
*/

#ifndef _DragonFly_HPP_
#define _DragonFly_HPP_

#include "network.hpp"
#include "routefunc.hpp"

class DragonFlyNew : public Network {

  int _m;
  int _n;
  int _r;
  int _k;
  int _p, _a, _g;
  int _radix;
  int _net_size;
  int _stageout;
  int _numinput;
  int _stages;
  int _num_of_switch;
  int _grp_num_routers;
  int _grp_num_nodes;

  void _ComputeSize( const Configuration &config );
  void _BuildNet( const Configuration &config );

public:
  DragonFlyNew( const Configuration &config, const string & name );

  int GetN( ) const;
  int GetK( ) const;

  double Capacity( ) const;
  static void RegisterRoutingFunctions();
  void InsertRandomFaults( const Configuration &config );

};
int dragonfly_port(int rID, int source, int dest);

void ugal_dragonflynew( const Router *r, const Flit *f, int in_channel,
		       OutputSet *outputs, bool inject );
void min_dragonflynew( const Router *r, const Flit *f, int in_channel,
		       OutputSet *outputs, bool inject );

#endif
<|endoftext|>


<commit_before>/*******************************************************************************
* Copyright 2017-2018 Intel Corporation
*
* 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 "ngraph/ops/softmax.hpp"

#include <algorithm>

#include "ngraph/builder/autobroadcast.hpp"
#include "ngraph/ops/multiply.hpp"
#include "ngraph/ops/reshape.hpp"
#include "ngraph/ops/subtract.hpp"
#include "ngraph/ops/sum.hpp"

void ngraph::op::Softmax::generate_adjoints(autodiff::Adjoints& adjoints,
                                            const std::shared_ptr<Node>& delta)
{
    auto z = delta * shared_from_this();
    auto zsum = std::make_shared<op::Sum>(z, m_axes);

    Shape shape;
    for (size_t i = 0; i < get_shape().size(); ++i)
    {
        if (m_axes.find(i) == m_axes.end())
        {
            shape.push_back(get_shape()[i]);
        }
        else
        {
            shape.push_back(1);
        }
    }
    AxisVector order(zsum->get_shape().size());
    std::iota(order.begin(), order.end(), 0);
    auto zreshape = std::make_shared<op::Reshape>(zsum, order, shape);

    auto adjoint =
        z - builder::make_with_numpy_broadcast<op::Multiply>(shared_from_this(), zreshape);

    auto x = get_input_op(0);
    adjoints.add_delta(x, adjoint);
}
<commit_msg>Missing include (#584)<commit_after>/*******************************************************************************
* Copyright 2017-2018 Intel Corporation
*
* 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 "ngraph/ops/softmax.hpp"

#include <algorithm>
#include <numeric>

#include "ngraph/builder/autobroadcast.hpp"
#include "ngraph/ops/multiply.hpp"
#include "ngraph/ops/reshape.hpp"
#include "ngraph/ops/subtract.hpp"
#include "ngraph/ops/sum.hpp"

void ngraph::op::Softmax::generate_adjoints(autodiff::Adjoints& adjoints,
                                            const std::shared_ptr<Node>& delta)
{
    auto z = delta * shared_from_this();
    auto zsum = std::make_shared<op::Sum>(z, m_axes);

    Shape shape;
    for (size_t i = 0; i < get_shape().size(); ++i)
    {
        if (m_axes.find(i) == m_axes.end())
        {
            shape.push_back(get_shape()[i]);
        }
        else
        {
            shape.push_back(1);
        }
    }
    AxisVector order(zsum->get_shape().size());
    std::iota(order.begin(), order.end(), 0);
    auto zreshape = std::make_shared<op::Reshape>(zsum, order, shape);

    auto adjoint =
        z - builder::make_with_numpy_broadcast<op::Multiply>(shared_from_this(), zreshape);

    auto x = get_input_op(0);
    adjoints.add_delta(x, adjoint);
}
<|endoftext|>


<commit_before>
#define __CL_ENABLE_EXCEPTIONS

#include "density_clustering_opencl.hpp"

#include <iostream>

namespace Clustering {
namespace Density {
namespace OpenCL {

  std::map<float, std::vector<std::size_t>>
  calculate_populations(const float* coords,
                        const std::size_t n_rows,
                        const std::size_t n_cols,
                        std::vector<float> radii) {

    unsigned int uint_n_rows = (unsigned int) n_rows;
    unsigned int uint_n_cols = (unsigned int) n_cols;

    try {

      std::vector<cl::Platform> platforms;
      cl::Platform::get(&platforms);
      cl_context_properties cps[3] = {
        CL_CONTEXT_PLATFORM,
        (cl_context_properties) (platforms[0])(),
        0
      };
      cl::Context context(CL_DEVICE_TYPE_GPU, cps);
      std::vector<cl::Device> devices = context.getInfo<CL_CONTEXT_DEVICES>();
      std::vector<cl::CommandQueue> queues;
      for (cl::Device dev: devices) {
        queues.push_back(cl::CommandQueue(context, dev));
      }

      // compute needed/avail mem sizes
      std::size_t n_bytes_per_row;
      std::size_t n_bytes_global_mem;
      {
        cl::Device d = devices[0];
        n_bytes_per_row = n_cols * sizeof(float);
        n_bytes_global_mem = d.getInfo<CL_DEVICE_GLOBAL_MEM_SIZE>();
      }
      // has device enough memory for full data set?
      if (n_bytes_per_row * n_rows + (sizeof(unsigned int)*n_rows) < n_bytes_global_mem) {
        std::string kernel_src =
            "__kernel void\n"
            "pops(const unsigned int n_rows,\n"
            "     const unsigned int n_cols,\n"
            "     __global const float* coords,\n"
            "     const float rad2,\n"
            "     __global unsigned int* pops) {\n"
            "  float row_i[20];\n"
            "  int k,j;\n"
            "  unsigned int pop_i = 0;\n"
            "  float dist2, tmp_d;\n"
            "  int i = get_global_id(0);\n"
            "  for (k=0; k < n_cols; ++k) {\n"
            "    row_i[k] = coords[i*n_cols+k];\n"
            "  }\n"
            "  for (j=0; j < n_rows; ++j) {\n"
            "    dist2 = 0.0f;\n"
            "    for (k=0; k < n_cols; ++k) {\n"
            "      tmp_d = row_i[k] - coords[j*n_cols+k];\n"
            "      dist2 += tmp_d * tmp_d;\n"
            "    }\n"
            "    pop_i += (unsigned int) (dist2 <= rad2);\n"
            "  }\n"
            "  pops[i] = pop_i;\n"
            "}\n"
        ;
        cl::Program::Sources src(1, {kernel_src.c_str(), kernel_src.length()+1});
        cl::Program prog = cl::Program(context, src);
        int err = prog.build(devices);
        if (err != CL_SUCCESS) {
          std::cerr << "error during kernel compilation" << std::endl;
          std::cerr << prog.getBuildInfo<CL_PROGRAM_BUILD_LOG>(devices[0]) << std::endl;
          exit(EXIT_FAILURE);
        }
        cl::Kernel kernel(prog, "pops");
        // copy data
        cl::Buffer buf_coords = cl::Buffer(context, CL_MEM_READ_ONLY, n_rows*n_cols*sizeof(float));
        cl::Buffer buf_pops = cl::Buffer(context, CL_MEM_WRITE_ONLY, n_rows*sizeof(unsigned int));
        queues[0].enqueueWriteBuffer(buf_coords, CL_TRUE, 0, n_rows*n_cols*sizeof(float), coords);
        // set kernel args
        float rad2 = radii[0]*radii[0];
        err = kernel.setArg(0, sizeof(unsigned int), &uint_n_rows);
        err |= kernel.setArg(1, sizeof(unsigned int), &uint_n_cols);
        err |= kernel.setArg(2, buf_coords);
        err |= kernel.setArg(3, sizeof(float), &rad2);
        err |= kernel.setArg(4, buf_pops);
        if (err != CL_SUCCESS) {
          std::cerr << "error while setting kernel arguments" << std::endl;
          exit(EXIT_FAILURE);
        }
        // run kernel
        // TODO play with workgroup sizes
        cl::NDRange global(n_rows);
        cl::NDRange local(1);
        queues[0].enqueueNDRangeKernel(kernel, cl::NullRange, global, local);
        // retrieve results
        std::vector<unsigned int> result(n_rows);
        queues[0].enqueueReadBuffer(buf_pops, CL_TRUE, 0, n_rows*sizeof(int), result.data());
        std::vector<std::size_t> pops;
        for (auto i: result) {
          pops.push_back(i);
        }
        return {{radii[0], pops}};
      } else {
        std::cerr << "error: not enough memory on GPU available." << std::endl;
        exit(EXIT_FAILURE);
      }
    } catch(cl::Error error) {
       std::cerr << error.what() << "(" << error.err() << ")" << std::endl;
       exit(EXIT_FAILURE);
    }
  }

} // end namespace OpenCL
} // end namespace Density
} // end namespace Clustering

<commit_msg>some comments on improvements<commit_after>
#define __CL_ENABLE_EXCEPTIONS

#include "density_clustering_opencl.hpp"

#include <iostream>

namespace Clustering {
namespace Density {
namespace OpenCL {

  std::map<float, std::vector<std::size_t>>
  calculate_populations(const float* coords,
                        const std::size_t n_rows,
                        const std::size_t n_cols,
                        std::vector<float> radii) {

    // TODO split up work into smaller chunks and run
    //      these separately with individual kernels.

    unsigned int uint_n_rows = (unsigned int) n_rows;
    unsigned int uint_n_cols = (unsigned int) n_cols;

    try {

      std::vector<cl::Platform> platforms;
      cl::Platform::get(&platforms);
      cl_context_properties cps[3] = {
        CL_CONTEXT_PLATFORM,
        (cl_context_properties) (platforms[0])(),
        0
      };
      cl::Context context(CL_DEVICE_TYPE_GPU, cps);
      std::vector<cl::Device> devices = context.getInfo<CL_CONTEXT_DEVICES>();
      std::vector<cl::CommandQueue> queues;
      for (cl::Device dev: devices) {
        queues.push_back(cl::CommandQueue(context, dev));
      }

      // compute needed/avail mem sizes
      std::size_t n_bytes_per_row;
      std::size_t n_bytes_global_mem;
      {
        cl::Device d = devices[0];
        n_bytes_per_row = n_cols * sizeof(float);
        n_bytes_global_mem = d.getInfo<CL_DEVICE_GLOBAL_MEM_SIZE>();
      }
      // has device enough memory for full data set?
      if (n_bytes_per_row * n_rows + (sizeof(unsigned int)*n_rows) < n_bytes_global_mem) {
        // TODO how about constant memory for coords?
        std::string kernel_src =
            "__kernel void\n"
            "pops(const unsigned int n_rows,\n"
            "     const unsigned int n_cols,\n"
            "     __global const float* coords,\n"
            "     const float rad2,\n"
            "     __global unsigned int* pops) {\n"
            "  float row_i[20];\n"
            "  int k,j;\n"
            "  unsigned int pop_i = 0;\n"
            "  float dist2, tmp_d;\n"
            "  int i = get_global_id(0);\n"
            "  for (k=0; k < n_cols; ++k) {\n"
            "    row_i[k] = coords[i*n_cols+k];\n"
            "  }\n"
            "  for (j=0; j < n_rows; ++j) {\n"
            "    dist2 = 0.0f;\n"
            "    for (k=0; k < n_cols; ++k) {\n"
            "      tmp_d = row_i[k] - coords[j*n_cols+k];\n"
            "      dist2 += tmp_d * tmp_d;\n"
            "    }\n"
            "    pop_i += (unsigned int) (dist2 <= rad2);\n"
            "  }\n"
            "  pops[i] = pop_i;\n"
            "}\n"
        ;
        cl::Program::Sources src(1, {kernel_src.c_str(), kernel_src.length()+1});
        cl::Program prog = cl::Program(context, src);
        int err = prog.build(devices);
        if (err != CL_SUCCESS) {
          std::cerr << "error during kernel compilation" << std::endl;
          std::cerr << prog.getBuildInfo<CL_PROGRAM_BUILD_LOG>(devices[0]) << std::endl;
          exit(EXIT_FAILURE);
        }
        cl::Kernel kernel(prog, "pops");
        // copy data
        cl::Buffer buf_coords = cl::Buffer(context, CL_MEM_READ_ONLY, n_rows*n_cols*sizeof(float));
        cl::Buffer buf_pops = cl::Buffer(context, CL_MEM_WRITE_ONLY, n_rows*sizeof(unsigned int));
        queues[0].enqueueWriteBuffer(buf_coords, CL_TRUE, 0, n_rows*n_cols*sizeof(float), coords);
        // set kernel args
        float rad2 = radii[0]*radii[0];
        err = kernel.setArg(0, sizeof(unsigned int), &uint_n_rows);
        err |= kernel.setArg(1, sizeof(unsigned int), &uint_n_cols);
        err |= kernel.setArg(2, buf_coords);
        err |= kernel.setArg(3, sizeof(float), &rad2);
        err |= kernel.setArg(4, buf_pops);
        if (err != CL_SUCCESS) {
          std::cerr << "error while setting kernel arguments" << std::endl;
          exit(EXIT_FAILURE);
        }
        // run kernel
        // TODO play with workgroup sizes
        cl::NDRange global(n_rows);
        cl::NDRange local(1);
        queues[0].enqueueNDRangeKernel(kernel, cl::NullRange, global, local);
        // retrieve results
        std::vector<unsigned int> result(n_rows);
        queues[0].enqueueReadBuffer(buf_pops, CL_TRUE, 0, n_rows*sizeof(int), result.data());
        std::vector<std::size_t> pops;
        for (auto i: result) {
          pops.push_back(i);
        }
        return {{radii[0], pops}};
      } else {
        std::cerr << "error: not enough memory on GPU available." << std::endl;
        exit(EXIT_FAILURE);
      }
    } catch(cl::Error error) {
       std::cerr << error.what() << "(" << error.err() << ")" << std::endl;
       exit(EXIT_FAILURE);
    }
  }

} // end namespace OpenCL
} // end namespace Density
} // end namespace Clustering

<|endoftext|>


<commit_before>#ifndef BEEEON_AUTH_SERVICE_TEST_H
#define BEEEON_AUTH_SERVICE_TEST_H

#include <Poco/Exception.h>

#include <cppunit/extensions/HelperMacros.h>

#include "provider/MockRandomProvider.h"
#include "provider/RandomProvider.h"
#include "service/NotificationService.h"
#include "service/AuthService.h"
#include "provider/PermitAuthProvider.h"
#include "dao/UserDao.h"
#include "dao/IdentityDao.h"
#include "dao/VerifiedIdentityDao.h"
#include "util/Base64.h"

using namespace std;
using namespace Poco;

namespace BeeeOn {

class TestableAuthService;
class MockNotificationService;

class AuthServiceTest : public CppUnit::TestFixture {
	CPPUNIT_TEST_SUITE(AuthServiceTest);
	CPPUNIT_TEST(testPermitAuth);
	CPPUNIT_TEST(testCreateUser);
	CPPUNIT_TEST(testLoginAsNew);
	CPPUNIT_TEST(testFirstLoginBySecondProvider);
	CPPUNIT_TEST_SUITE_END();

public:
	void setUp();
	void tearDown();
	void testPermitAuth();
	void testCreateUser();
	void testLoginAsNew();
	void testFirstLoginBySecondProvider();

private:
	MockUserDao m_userDao;
	MockIdentityDao m_identityDao;
	MockVerifiedIdentityDao m_verifiedIdentityDao;
	SessionManager m_manager;
	MockRandomProvider m_mockRandomProvider;
	InsecureRandomProvider m_insecureRandomProvider;
	MockNotificationService *m_notificationService;
	TestableAuthService *m_service;
};

CPPUNIT_TEST_SUITE_REGISTRATION(AuthServiceTest);

class TestableAuthService : public AuthService {
public:
	using AuthService::createUser;
	using AuthService::loginAsNew;
	using AuthService::verifyIdentityAndLogin;
};

class MockNotificationService : public NotificationService {
public:
	void notifyFirstLogin(const VerifiedIdentity &identity) override
	{
		m_identity = identity;
	}

	const VerifiedIdentity &lastIdentity()
	{
		return m_identity;
	}

private:
	VerifiedIdentity m_identity;
};

#define SESSION_ID64 string( \
	"abcdef0123456789"   \
	"abcdef0123456789"   \
	"abcdef0123456789"   \
	"abcdef0123456789")

void AuthServiceTest::setUp()
{
	m_userDao.storage().clear();
	m_identityDao.storage().clear();
	m_verifiedIdentityDao.storage().clear();

	m_mockRandomProvider.setNextRandom(SESSION_ID64);
	m_insecureRandomProvider.setProviderImpl(&m_mockRandomProvider);
	m_manager.setSecureRandomProvider(&m_insecureRandomProvider);
	m_manager.setMaxUserSessions(10);
	m_manager.setSessionExpireTime(1);

	m_notificationService = new MockNotificationService();

	m_service = new TestableAuthService();
	m_service->setUserDao(&m_userDao);
	m_service->setIdentityDao(&m_identityDao);
	m_service->setVerifiedIdentityDao(&m_verifiedIdentityDao);
	m_service->setSessionManager(&m_manager);
	m_service->setNotificationService(m_notificationService);
}

void AuthServiceTest::tearDown()
{
	delete m_service;
	delete m_notificationService;
}

void AuthServiceTest::testPermitAuth()
{
	UserID newID(UUIDGenerator::defaultGenerator().createRandom());
	User::Ptr user(new User(newID));
	m_userDao.storage().insert(make_pair(user->id(), user));

	Identity identity;
	identity.setEmail("permit@example.org");
	identity.setUser(*user);
	m_identityDao.create(identity);

	VerifiedIdentity verifiedIdentity;
	verifiedIdentity.setIdentity(identity);
	verifiedIdentity.setProvider("3rd-party");
	m_verifiedIdentityDao.create(verifiedIdentity);

	PermitAuthProvider provider;
	provider.setResultProvider("3rd-party");

	m_service->registerProvider(&provider);

	AuthCodeCredentials cred("permit", "permit@example.org");

	try {
		const ExpirableSession::Ptr session = m_service->login(cred);
		const SessionID id = session->sessionID();
		CPPUNIT_ASSERT(Base64::decode(id).compare(SESSION_ID64) == 0);
		m_service->logout(id);
	} catch(Exception &e) {
		CPPUNIT_FAIL("unexpected exception: " + e.displayText());
	}
}

void AuthServiceTest::testCreateUser()
{
	AuthResult result;
	result.setFirstName("Freddie");
	result.setLastName("Mercury");

	const User &user = m_service->createUser(result);
	CPPUNIT_ASSERT(user.firstName() == "Freddie");
	CPPUNIT_ASSERT(user.lastName() == "Mercury");

	User hasUser(user.id());
	CPPUNIT_ASSERT(m_userDao.fetch(hasUser));
	CPPUNIT_ASSERT(hasUser.firstName() == "Freddie");
	CPPUNIT_ASSERT(hasUser.lastName() == "Mercury");
}

void AuthServiceTest::testLoginAsNew()
{
	AuthResult result;
	result.setEmail("freddie@example.org");
	result.setFirstName("Freddie");
	result.setLastName("Mercury");

	ExpirableSession::Ptr session = m_service->loginAsNew(result);
	CPPUNIT_ASSERT(!session.isNull());

	Identity identity;
	CPPUNIT_ASSERT(m_identityDao.fetchBy(identity,
				"freddie@example.org"));
	CPPUNIT_ASSERT(!identity.id().isNull());
	CPPUNIT_ASSERT(identity.email() == "freddie@example.org");
	/*
	CPPUNIT_ASSERT(!identity.user().id().isNull());
	CPPUNIT_ASSERT(identity.user().firstName() == "Freddie");
	CPPUNIT_ASSERT(identity.user().lastName() == "Mercury");
	*/

	const VerifiedIdentity &verifiedIdentity =
		m_notificationService->lastIdentity();

	CPPUNIT_ASSERT(!verifiedIdentity.id().isNull());
	CPPUNIT_ASSERT(verifiedIdentity.id() == session->identityID());
	CPPUNIT_ASSERT(verifiedIdentity.identity().id() == identity.id());
	/*CPPUNIT_ASSERT(verifiedIdentity.user().id() == identity.user().id());*/
	CPPUNIT_ASSERT(verifiedIdentity.user().firstName() == "Freddie");
	CPPUNIT_ASSERT(verifiedIdentity.user().lastName() == "Mercury");
	CPPUNIT_ASSERT(verifiedIdentity.email() == "freddie@example.org");
}

void AuthServiceTest::testFirstLoginBySecondProvider()
{
	User user;
	user.setFirstName("Freddie");
	user.setLastName("Mercury");
	m_userDao.create(user);

	Identity identity;
	identity.setEmail("freddie@example.org");
	identity.setUser(user);
	m_identityDao.create(identity);

	VerifiedIdentity firstProvider;
	firstProvider.setIdentity(identity);
	firstProvider.setProvider("first-provider");
	m_verifiedIdentityDao.create(firstProvider);

	AuthResult result;
	result.setEmail("freddie@example.org");
	result.setProvider("second-provider");
	result.setFirstName("Freddie 2");
	result.setLastName("Mercury 2");

	ExpirableSession::Ptr session =
		m_service->verifyIdentityAndLogin(result);
	CPPUNIT_ASSERT(!session.isNull());

	const VerifiedIdentity &verifiedIdentity =
		m_notificationService->lastIdentity();

	CPPUNIT_ASSERT(!verifiedIdentity.id().isNull());
	CPPUNIT_ASSERT(verifiedIdentity.id() == session->identityID());
	CPPUNIT_ASSERT(verifiedIdentity.identity().id() == identity.id());
	CPPUNIT_ASSERT(verifiedIdentity.user().id() == user.id());
	CPPUNIT_ASSERT(verifiedIdentity.user().firstName() == "Freddie");
	CPPUNIT_ASSERT(verifiedIdentity.user().lastName() == "Mercury");
	CPPUNIT_ASSERT(verifiedIdentity.email() == "freddie@example.org");
}

}

#endif
<commit_msg>AuthServiceTest: avoid touching User via Identity<commit_after>#ifndef BEEEON_AUTH_SERVICE_TEST_H
#define BEEEON_AUTH_SERVICE_TEST_H

#include <Poco/Exception.h>

#include <cppunit/extensions/HelperMacros.h>

#include "provider/MockRandomProvider.h"
#include "provider/RandomProvider.h"
#include "service/NotificationService.h"
#include "service/AuthService.h"
#include "provider/PermitAuthProvider.h"
#include "dao/UserDao.h"
#include "dao/IdentityDao.h"
#include "dao/VerifiedIdentityDao.h"
#include "util/Base64.h"

using namespace std;
using namespace Poco;

namespace BeeeOn {

class TestableAuthService;
class MockNotificationService;

class AuthServiceTest : public CppUnit::TestFixture {
	CPPUNIT_TEST_SUITE(AuthServiceTest);
	CPPUNIT_TEST(testPermitAuth);
	CPPUNIT_TEST(testCreateUser);
	CPPUNIT_TEST(testLoginAsNew);
	CPPUNIT_TEST(testFirstLoginBySecondProvider);
	CPPUNIT_TEST_SUITE_END();

public:
	void setUp();
	void tearDown();
	void testPermitAuth();
	void testCreateUser();
	void testLoginAsNew();
	void testFirstLoginBySecondProvider();

private:
	MockUserDao m_userDao;
	MockIdentityDao m_identityDao;
	MockVerifiedIdentityDao m_verifiedIdentityDao;
	SessionManager m_manager;
	MockRandomProvider m_mockRandomProvider;
	InsecureRandomProvider m_insecureRandomProvider;
	MockNotificationService *m_notificationService;
	TestableAuthService *m_service;
};

CPPUNIT_TEST_SUITE_REGISTRATION(AuthServiceTest);

class TestableAuthService : public AuthService {
public:
	using AuthService::createUser;
	using AuthService::loginAsNew;
	using AuthService::verifyIdentityAndLogin;
};

class MockNotificationService : public NotificationService {
public:
	void notifyFirstLogin(const VerifiedIdentity &identity) override
	{
		m_identity = identity;
	}

	const VerifiedIdentity &lastIdentity()
	{
		return m_identity;
	}

private:
	VerifiedIdentity m_identity;
};

#define SESSION_ID64 string( \
	"abcdef0123456789"   \
	"abcdef0123456789"   \
	"abcdef0123456789"   \
	"abcdef0123456789")

void AuthServiceTest::setUp()
{
	m_userDao.storage().clear();
	m_identityDao.storage().clear();
	m_verifiedIdentityDao.storage().clear();

	m_mockRandomProvider.setNextRandom(SESSION_ID64);
	m_insecureRandomProvider.setProviderImpl(&m_mockRandomProvider);
	m_manager.setSecureRandomProvider(&m_insecureRandomProvider);
	m_manager.setMaxUserSessions(10);
	m_manager.setSessionExpireTime(1);

	m_notificationService = new MockNotificationService();

	m_service = new TestableAuthService();
	m_service->setUserDao(&m_userDao);
	m_service->setIdentityDao(&m_identityDao);
	m_service->setVerifiedIdentityDao(&m_verifiedIdentityDao);
	m_service->setSessionManager(&m_manager);
	m_service->setNotificationService(m_notificationService);
}

void AuthServiceTest::tearDown()
{
	delete m_service;
	delete m_notificationService;
}

void AuthServiceTest::testPermitAuth()
{
	UserID newID(UUIDGenerator::defaultGenerator().createRandom());
	User::Ptr user(new User(newID));
	m_userDao.storage().insert(make_pair(user->id(), user));

	Identity identity;
	identity.setEmail("permit@example.org");
	m_identityDao.create(identity);

	VerifiedIdentity verifiedIdentity;
	verifiedIdentity.setIdentity(identity);
	verifiedIdentity.setUser(*user);
	verifiedIdentity.setProvider("3rd-party");
	m_verifiedIdentityDao.create(verifiedIdentity);

	PermitAuthProvider provider;
	provider.setResultProvider("3rd-party");

	m_service->registerProvider(&provider);

	AuthCodeCredentials cred("permit", "permit@example.org");

	try {
		const ExpirableSession::Ptr session = m_service->login(cred);
		const SessionID id = session->sessionID();
		CPPUNIT_ASSERT(Base64::decode(id).compare(SESSION_ID64) == 0);
		m_service->logout(id);
	} catch(Exception &e) {
		CPPUNIT_FAIL("unexpected exception: " + e.displayText());
	}
}

void AuthServiceTest::testCreateUser()
{
	AuthResult result;
	result.setFirstName("Freddie");
	result.setLastName("Mercury");

	const User &user = m_service->createUser(result);
	CPPUNIT_ASSERT(user.firstName() == "Freddie");
	CPPUNIT_ASSERT(user.lastName() == "Mercury");

	User hasUser(user.id());
	CPPUNIT_ASSERT(m_userDao.fetch(hasUser));
	CPPUNIT_ASSERT(hasUser.firstName() == "Freddie");
	CPPUNIT_ASSERT(hasUser.lastName() == "Mercury");
}

void AuthServiceTest::testLoginAsNew()
{
	AuthResult result;
	result.setEmail("freddie@example.org");
	result.setFirstName("Freddie");
	result.setLastName("Mercury");

	ExpirableSession::Ptr session = m_service->loginAsNew(result);
	CPPUNIT_ASSERT(!session.isNull());

	Identity identity;
	CPPUNIT_ASSERT(m_identityDao.fetchBy(identity,
				"freddie@example.org"));
	CPPUNIT_ASSERT(!identity.id().isNull());
	CPPUNIT_ASSERT(identity.email() == "freddie@example.org");

	const VerifiedIdentity &verifiedIdentity =
		m_notificationService->lastIdentity();

	CPPUNIT_ASSERT(!verifiedIdentity.id().isNull());
	CPPUNIT_ASSERT(verifiedIdentity.id() == session->identityID());
	CPPUNIT_ASSERT(verifiedIdentity.identity().id() == identity.id());
	CPPUNIT_ASSERT(!verifiedIdentity.user().id().isNull());
	CPPUNIT_ASSERT(verifiedIdentity.user().firstName() == "Freddie");
	CPPUNIT_ASSERT(verifiedIdentity.user().lastName() == "Mercury");
	CPPUNIT_ASSERT(verifiedIdentity.email() == "freddie@example.org");
}

void AuthServiceTest::testFirstLoginBySecondProvider()
{
	User user;
	user.setFirstName("Freddie");
	user.setLastName("Mercury");
	m_userDao.create(user);

	Identity identity;
	identity.setEmail("freddie@example.org");
	identity.setUser(user);
	m_identityDao.create(identity);

	VerifiedIdentity firstProvider;
	firstProvider.setIdentity(identity);
	firstProvider.setProvider("first-provider");
	m_verifiedIdentityDao.create(firstProvider);

	AuthResult result;
	result.setEmail("freddie@example.org");
	result.setProvider("second-provider");
	result.setFirstName("Freddie 2");
	result.setLastName("Mercury 2");

	ExpirableSession::Ptr session =
		m_service->verifyIdentityAndLogin(result);
	CPPUNIT_ASSERT(!session.isNull());

	const VerifiedIdentity &verifiedIdentity =
		m_notificationService->lastIdentity();

	CPPUNIT_ASSERT(!verifiedIdentity.id().isNull());
	CPPUNIT_ASSERT(verifiedIdentity.id() == session->identityID());
	CPPUNIT_ASSERT(verifiedIdentity.identity().id() == identity.id());
	CPPUNIT_ASSERT(verifiedIdentity.user().id() == user.id());
	CPPUNIT_ASSERT(verifiedIdentity.user().firstName() == "Freddie");
	CPPUNIT_ASSERT(verifiedIdentity.user().lastName() == "Mercury");
	CPPUNIT_ASSERT(verifiedIdentity.email() == "freddie@example.org");
}

}

#endif
<|endoftext|>


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

#include "InnerProdRequest.h"
#include "InnerProdIndication.h"

const int NUMBER_OF_TESTS = 1;

class InnerProd : public InnerProdIndicationWrapper
{
    int cnt;
public:
  void incr_cnt(){
    if (++cnt == NUMBER_OF_TESTS)
      exit(0);
  }
  void innerProd(uint64_t v) {
    fprintf(stderr, "innerProd v=%llx\n", (long long)v);
  }
    InnerProd(unsigned int id) : InnerProdIndicationWrapper(id), cnt(0) {}
};

int main(int argc, const char **argv)
{
    InnerProd ind(IfcNames_InnerProdIndicationH2S);
    InnerProdRequestProxy device(IfcNames_InnerProdRequestS2H);
    device.pint.busyType = BUSY_SPIN;

    fprintf(stderr, "[%s:%d] waiting for response\n", __FILE__, __LINE__);
    int alumode = 0;
    int inmode = 0;
    device.innerProd(0x0080, 0x0080, 1, 1, alumode, inmode, 0x35);
    device.innerProd(0x0000, 0x0000, 1, 1, alumode, inmode, 0x20);
    device.innerProd(0x0100, 0x0080, 1, 1, alumode, inmode, 0x25);
    device.innerProd(0x0080, 0x0080, 1, 1, alumode, inmode, 0x25);
    device.innerProd(0x0100, 0x1000, 1, 1, alumode, inmode, 0x25);
    device.innerProd(0x0200, 0x1000, 1, 1, alumode, inmode, 0x25);
    device.start();
    for (int times = 0; times < 30; times++)
	sleep(1);
    device.finish();
}

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

#include "InnerProdRequest.h"
#include "InnerProdIndication.h"

const int NUMBER_OF_TESTS = 1;

class InnerProd : public InnerProdIndicationWrapper
{
    int cnt;
public:
  void incr_cnt(){
    if (++cnt == NUMBER_OF_TESTS)
      exit(0);
  }
  void innerProd(uint64_t v) {
    fprintf(stderr, "innerProd v=%llx\n", (long long)v);
  }
    InnerProd(unsigned int id) : InnerProdIndicationWrapper(id), cnt(0) {}
};

int main(int argc, const char **argv)
{
    InnerProd ind(IfcNames_InnerProdIndicationH2S);
    InnerProdRequestProxy device(IfcNames_InnerProdRequestS2H);
    device.pint.busyType = BUSY_SPIN;

    fprintf(stderr, "[%s:%d] waiting for response\n", __FILE__, __LINE__);
    int alumode = 0;
    int inmode = 0;
    device.innerProd(0x0080, 0x0080, 1, 0, alumode, inmode, 0x35);
    device.innerProd(0x0000, 0x0000, 0, 0, alumode, inmode, 0x20);
    device.innerProd(0x0100, 0x0080, 0, 0, alumode, inmode, 0x25);
    device.innerProd(0x0080, 0x0080, 0, 0, alumode, inmode, 0x25);
    device.innerProd(0x0100, 0x1000, 0, 0, alumode, inmode, 0x25);
    device.innerProd(0x0200, 0x1000, 0, 1, alumode, inmode, 0x25);
    device.start();
    for (int times = 0; times < 5; times++)
	sleep(1);
    device.finish();
}

<|endoftext|>