<commit_before>// This Source Code Form is subject to the terms of the Mozilla Public
// License, v. 2.0. If a copy of the MPL was not distributed with this
// file, You can obtain one at http://mozilla.org/MPL/2.0/.
//
// Copyright 2016 [bk]door.maus

#ifndef LIBGLURG_TRACE_VALUES_HPP
#define LIBGLURG_TRACE_VALUES_HPP

#include <cstdint>
#include <memory>
#include <string>
#include <vector>

namespace glurg
{
	class Array;
	class BitmaskSignature;
	class EnumerationSignature;
	class FileStream;
	class TraceFile;
	class Value;

	struct Enumeration
	{
		const EnumerationSignature* signature;
		Value* value;
	};

	struct Bitmask
	{
		const BitmaskSignature* signature;
		std::uint32_t value;
	};

	struct Blob
	{
		const std::uint8_t* data;
		std::size_t length;
	};

	class Value
	{
	public:
		typedef std::uint8_t Type;
		typedef Value* (* ReadFunction)(Type, TraceFile&, FileStream&);

		virtual Type get_type() const = 0;

		virtual bool to_boolean() const;

		virtual std::int32_t to_signed_integer() const;
		virtual std::uint32_t to_unsigned_integer() const;

		virtual float to_single() const;
		virtual double to_double() const;

		virtual std::string to_string() const;

		virtual Blob to_blob() const;
		virtual std::uint32_t to_handle() const;

		virtual Enumeration to_enumeration() const;
		virtual Bitmask to_bitmask() const;
		virtual const Array* to_array() const;

		virtual Value* clone() const = 0;
	};

	class Array
	{
	public:
		std::size_t get_size() const;
		void set_size(std::size_t value);

		const Value* get_value_at(std::size_t index) const;
		void set_value_at(std::size_t index, const Value* value);

	private:
		typedef std::unique_ptr<Value> ValuePointer;
		std::vector<ValuePointer> values;
	};

	class BoolValue : public Value
	{
	public:
		static const Type FALSE_BOOLEAN = 0x01;
		static const Type TRUE_BOOLEAN = 0x02;

		BoolValue() = default;
		explicit BoolValue(bool value);

		Type get_type() const override;
		Value* clone() const override;

		bool to_boolean() const override;

		static Value* read_false_boolean(
			Type type, TraceFile& trace, FileStream& stream);
		static Value* read_true_boolean(
			Type type, TraceFile& trace, FileStream& stream);

	private:
		bool value;
	};

	class IntegerValue : public Value
	{
	public:
		static const Type NEGATIVE_NUMBER = 0x03;
		static const Type POSITIVE_NUMBER = 0x04;

		IntegerValue() = default;
		explicit IntegerValue(std::int64_t value);

		Type get_type() const override;
		Value* clone() const override;

		std::int32_t to_signed_integer() const override;
		std::uint32_t to_unsigned_integer() const override;

		static Value* read_positive_integer(
			Type type, TraceFile& trace, FileStream& stream);
		static Value* read_negative_integer(
			Type type, TraceFile& trace, FileStream& stream);

	private:
		std::int64_t value;
	};

	class FloatingPointValue : public Value
	{
	public:
		static const Type FLOAT = 0x05;
		static const Type DOUBLE = 0x06;

		FloatingPointValue() = default;
		FloatingPointValue(Type type, double value);

		Type get_type() const override;
		Value* clone() const override;

		float to_single() const override;
		double to_double() const override;

		static Value* read_single(
			Type type, TraceFile& trace, FileStream& stream);
		static Value* read_double(
			Type type, TraceFile& trace, FileStream& stream);

	private:
		Type type;
		double value;
	};

	class StringValue : public Value
	{
	public:
		static const Type STRING = 0x07;

		StringValue() = default;
		StringValue(const std::string& value);

		Type get_type() const override;
		Value* clone() const override;

		std::string to_string() const override;
		Blob to_blob() const override;

		static Value* read_string(
			Type type, TraceFile& trace, FileStream& stream);

	private:
		std::string value;
	};

	class BlobValue : public Value
	{
	public:
		static const Type NULL_POINTER = 0x00;
		static const Type BLOB = 0x08;

		BlobValue() = default;
		explicit BlobValue(std::size_t length);
		BlobValue(std::size_t length, const std::uint8_t* data);
		~BlobValue();

		Type get_type() const override;
		Value* clone() const override;

		Blob to_blob() const override;

		static Value* read_blob(
			Type type, TraceFile& trace, FileStream& stream);
		static Value* read_null_pointer(
			Type type, TraceFile& trace, FileStream& stream);
	private:
		std::uint8_t* data;
		std::size_t length;
	};

	class EnumerationValue : public Value
	{
	public:
		static const Type ENUMERATION = 0x09;

		EnumerationValue() = default;
		EnumerationValue(const EnumerationSignature* signature, Value* value);
		~EnumerationValue();

		Type get_type() const override;
		Value* clone() const override;

		Enumeration to_enumeration() const override;

		static Value* read_enumeration(
			Type type, TraceFile& trace, FileStream& stream);

	private:
		Enumeration value;
	};

	class BitmaskValue : public Value
	{
	public:
		static const Type BITMASK = 0x0a;

		BitmaskValue() = default;
		BitmaskValue(const BitmaskSignature* signature, std::uint32_t value);

		Type get_type() const override;
		Value* clone() const override;

		Bitmask to_bitmask() const override;

		static Value* read_bitmask(
			Type type, TraceFile& trace, FileStream& stream);

	private:
		Bitmask value;
	};

	class ArrayValue : public Value
	{
	public:
		static const Type ARRAY = 0x0b;

		ArrayValue() = default;
		ArrayValue(const Array* array);

		Type get_type() const override;
		Value* clone() const override;

		const Array* to_array() const override;

		static Value* read_array(
			Type type, TraceFile& trace, FileStream& stream);
	private:
		Array value;
	};

	class HandleValue : public Value
	{
	public:
		static const Type HANDLE = 0x0d;

		HandleValue() = default;
		explicit HandleValue(std::uint32_t value);

		Type get_type() const override;
		Value* clone() const override;

		std::uint32_t to_handle() const override;

		static Value* read_handle(
			Type type, TraceFile& trace, FileStream& stream);

	private:
		std::uint32_t value;
	};
}

#endif
<commit_msg>Added virtual destructor to glurg::Value<commit_after>// This Source Code Form is subject to the terms of the Mozilla Public
// License, v. 2.0. If a copy of the MPL was not distributed with this
// file, You can obtain one at http://mozilla.org/MPL/2.0/.
//
// Copyright 2016 [bk]door.maus

#ifndef LIBGLURG_TRACE_VALUES_HPP
#define LIBGLURG_TRACE_VALUES_HPP

#include <cstdint>
#include <memory>
#include <string>
#include <vector>

namespace glurg
{
	class Array;
	class BitmaskSignature;
	class EnumerationSignature;
	class FileStream;
	class TraceFile;
	class Value;

	struct Enumeration
	{
		const EnumerationSignature* signature;
		Value* value;
	};

	struct Bitmask
	{
		const BitmaskSignature* signature;
		std::uint32_t value;
	};

	struct Blob
	{
		const std::uint8_t* data;
		std::size_t length;
	};

	class Value
	{
	public:
		typedef std::uint8_t Type;
		typedef Value* (* ReadFunction)(Type, TraceFile&, FileStream&);

		virtual ~Value() = default;

		virtual Type get_type() const = 0;

		virtual bool to_boolean() const;

		virtual std::int32_t to_signed_integer() const;
		virtual std::uint32_t to_unsigned_integer() const;

		virtual float to_single() const;
		virtual double to_double() const;

		virtual std::string to_string() const;

		virtual Blob to_blob() const;
		virtual std::uint32_t to_handle() const;

		virtual Enumeration to_enumeration() const;
		virtual Bitmask to_bitmask() const;
		virtual const Array* to_array() const;

		virtual Value* clone() const = 0;
	};

	class Array
	{
	public:
		std::size_t get_size() const;
		void set_size(std::size_t value);

		const Value* get_value_at(std::size_t index) const;
		void set_value_at(std::size_t index, const Value* value);

	private:
		typedef std::unique_ptr<Value> ValuePointer;
		std::vector<ValuePointer> values;
	};

	class BoolValue : public Value
	{
	public:
		static const Type FALSE_BOOLEAN = 0x01;
		static const Type TRUE_BOOLEAN = 0x02;

		BoolValue() = default;
		explicit BoolValue(bool value);

		Type get_type() const override;
		Value* clone() const override;

		bool to_boolean() const override;

		static Value* read_false_boolean(
			Type type, TraceFile& trace, FileStream& stream);
		static Value* read_true_boolean(
			Type type, TraceFile& trace, FileStream& stream);

	private:
		bool value;
	};

	class IntegerValue : public Value
	{
	public:
		static const Type NEGATIVE_NUMBER = 0x03;
		static const Type POSITIVE_NUMBER = 0x04;

		IntegerValue() = default;
		explicit IntegerValue(std::int64_t value);

		Type get_type() const override;
		Value* clone() const override;

		std::int32_t to_signed_integer() const override;
		std::uint32_t to_unsigned_integer() const override;

		static Value* read_positive_integer(
			Type type, TraceFile& trace, FileStream& stream);
		static Value* read_negative_integer(
			Type type, TraceFile& trace, FileStream& stream);

	private:
		std::int64_t value;
	};

	class FloatingPointValue : public Value
	{
	public:
		static const Type FLOAT = 0x05;
		static const Type DOUBLE = 0x06;

		FloatingPointValue() = default;
		FloatingPointValue(Type type, double value);

		Type get_type() const override;
		Value* clone() const override;

		float to_single() const override;
		double to_double() const override;

		static Value* read_single(
			Type type, TraceFile& trace, FileStream& stream);
		static Value* read_double(
			Type type, TraceFile& trace, FileStream& stream);

	private:
		Type type;
		double value;
	};

	class StringValue : public Value
	{
	public:
		static const Type STRING = 0x07;

		StringValue() = default;
		StringValue(const std::string& value);

		Type get_type() const override;
		Value* clone() const override;

		std::string to_string() const override;
		Blob to_blob() const override;

		static Value* read_string(
			Type type, TraceFile& trace, FileStream& stream);

	private:
		std::string value;
	};

	class BlobValue : public Value
	{
	public:
		static const Type NULL_POINTER = 0x00;
		static const Type BLOB = 0x08;

		BlobValue() = default;
		explicit BlobValue(std::size_t length);
		BlobValue(std::size_t length, const std::uint8_t* data);
		~BlobValue();

		Type get_type() const override;
		Value* clone() const override;

		Blob to_blob() const override;

		static Value* read_blob(
			Type type, TraceFile& trace, FileStream& stream);
		static Value* read_null_pointer(
			Type type, TraceFile& trace, FileStream& stream);
	private:
		std::uint8_t* data;
		std::size_t length;
	};

	class EnumerationValue : public Value
	{
	public:
		static const Type ENUMERATION = 0x09;

		EnumerationValue() = default;
		EnumerationValue(const EnumerationSignature* signature, Value* value);
		~EnumerationValue();

		Type get_type() const override;
		Value* clone() const override;

		Enumeration to_enumeration() const override;

		static Value* read_enumeration(
			Type type, TraceFile& trace, FileStream& stream);

	private:
		Enumeration value;
	};

	class BitmaskValue : public Value
	{
	public:
		static const Type BITMASK = 0x0a;

		BitmaskValue() = default;
		BitmaskValue(const BitmaskSignature* signature, std::uint32_t value);

		Type get_type() const override;
		Value* clone() const override;

		Bitmask to_bitmask() const override;

		static Value* read_bitmask(
			Type type, TraceFile& trace, FileStream& stream);

	private:
		Bitmask value;
	};

	class ArrayValue : public Value
	{
	public:
		static const Type ARRAY = 0x0b;

		ArrayValue() = default;
		ArrayValue(const Array* array);

		Type get_type() const override;
		Value* clone() const override;

		const Array* to_array() const override;

		static Value* read_array(
			Type type, TraceFile& trace, FileStream& stream);
	private:
		Array value;
	};

	class HandleValue : public Value
	{
	public:
		static const Type HANDLE = 0x0d;

		HandleValue() = default;
		explicit HandleValue(std::uint32_t value);

		Type get_type() const override;
		Value* clone() const override;

		std::uint32_t to_handle() const override;

		static Value* read_handle(
			Type type, TraceFile& trace, FileStream& stream);

	private:
		std::uint32_t value;
	};
}

#endif
<|endoftext|>


<commit_before>#define CATCH_CONFIG_MAIN  // This tells Catch to provide a main() - only do this in one cpp file
#include "catch.hpp"
#include "Vec.h"

TEST_CASE( "vector", "[vec]" ) {

  Vec a = Vec();
  Vec b = Vec(4);
  a.SetDim(4);

  for( int i = 0; i < 4; i++ ){
    a._vec[i] = i;
    b._vec[i] = i + 10;
  }

  Vec c = a+b;

  REQUIRE( c._vec[0] == 10 );
  REQUIRE( c._vec[1] == 12 );
  REQUIRE( c._vec[2] == 14 );
  REQUIRE( c._vec[3] == 16 );
}
<commit_msg>added vector math tests<commit_after>#define CATCH_CONFIG_MAIN  // This tells Catch to provide a main() - only do this in one cpp file
#include "catch.hpp"
#include "Vec.h"

TEST_CASE( "vector", "[vec]" ) {

  Vec a = Vec(5);
  Vec b = Vec(4);

  for( int i = 0; i < 4; i++ ){
    a._vec[i] = i; //0 to 3
    b._vec[i] = i + 10; //10 to 13
  }
  a._vec[4] = 4;

  //resize dim
  a.SetDim(4);

  SECTION( "resizing dimension" ) {
    REQUIRE( a._dim == 4 );
    for( int i = 0; i < 4; i++ ){
      REQUIRE( a._vec[i] == i );
    }
  }

  SECTION( "addition" ) {
    Vec c = a+b;

    REQUIRE( c._vec[0] == 10 );
    REQUIRE( c._vec[1] == 12 );
    REQUIRE( c._vec[2] == 14 );
    REQUIRE( c._vec[3] == 16 );
  }

  SECTION( "subtraction" ) {
    Vec c = b-a;

    REQUIRE( c._vec[0] == 10 );
    REQUIRE( c._vec[1] == 10 );
    REQUIRE( c._vec[2] == 10 );
    REQUIRE( c._vec[3] == 10 );
  }

  SECTION( "dot product" ) {
    float c = b.Dot(a);

    REQUIRE( c == 74 );
  }

  SECTION( "cross product" ) {
    a.SetDim(3);
    b.SetDim(3);
    Vec c = b.Cross(a);

    REQUIRE( c._vec[0] == 10 );
    REQUIRE( c._vec[1] == -20 );
    REQUIRE( c._vec[2] == 10 );
  }

}
<|endoftext|>


<commit_before>//
// This source file is part of the Swift.org open source project
//
// Copyright (c) 2014 - 2021 Apple Inc. and the Swift project authors
// Licensed under Apache License v2.0 with Runtime Library Exception
//
// See https://swift.org/LICENSE.txt for license information
// See https://swift.org/CONTRIBUTORS.txt for the list of Swift project authors
//

#include "swift/AST/Builtins.h"
#include "swift/SIL/MemAccessUtils.h"
#include "swift/SIL/OwnershipUtils.h"
#include "swift/SIL/SILBasicBlock.h"
#include "swift/SILOptimizer/Utils/CanonicalizeBorrowScope.h"
#include "swift/SILOptimizer/Utils/InstOptUtils.h"
#include "swift/SILOptimizer/Utils/InstructionDeleter.h"

#define DEBUG_TYPE "copy-propagation"

using namespace swift;

//===----------------------------------------------------------------------===//
//                           MARK: Local utilities
//===----------------------------------------------------------------------===//

// TODO: Move to be member function on SILInstruction.
static SILInstruction *getPreviousInstruction(SILInstruction *inst) {
  auto pos = inst->getIterator();
  return pos == inst->getParent()->begin() ? nullptr
                                           : &*std::prev(inst->getIterator());
}

// TODO: Move to be member function on SILInstruction.
static SILInstruction *getNextInstruction(SILInstruction *inst) {
  auto nextPos = std::next(inst->getIterator());
  return nextPos == inst->getParent()->end() ? nullptr : &*nextPos;
}

//===----------------------------------------------------------------------===//
//                       MARK: ShrinkBorrowScope
//===----------------------------------------------------------------------===//

class ShrinkBorrowScope {
  // The instruction that begins this borrow scope.
  BeginBorrowInst *introducer;

  InstructionDeleter &deleter;

  SmallVectorImpl<CopyValueInst *> &modifiedCopyValueInsts;

  SmallPtrSet<SILInstruction *, 16> users;

  /// Deinit barriers that obstruct hoisting end_borrow instructions.
  llvm::SmallVector<std::pair<SILBasicBlock *, SILInstruction *>>
      barrierInstructions;

  SmallPtrSet<SILBasicBlock *, 8> blocksToEndAtTop;

  llvm::SmallDenseMap<ApplySite, size_t> transitiveUsesPerApplySite;

  // The list of blocks to look for new points at which to insert end_borrows
  // in.  A block must not be processed if all of its successors have not yet
  // been.  For that reason, it is necessary to allow the same block to be
  // visited multiple times, at most once for each successor.
  SmallVector<SILBasicBlock *, 8> worklist;
  // The instructions from which the shrinking starts, the scope ending
  // instructions, keyed off the block in which they appear.
  llvm::SmallDenseMap<SILBasicBlock *, SILInstruction *> startingInstructions;

public:
  ShrinkBorrowScope(BeginBorrowInst *bbi, InstructionDeleter &deleter,
                    SmallVectorImpl<CopyValueInst *> &modifiedCopyValueInsts)
      : introducer(bbi), deleter(deleter),
        modifiedCopyValueInsts(modifiedCopyValueInsts) {}

  bool run();

  bool populateUsers();
  bool initializeWorklist();
  void findBarriers();
  void rewrite();
  void createEndBorrow(SILInstruction *insertionPoint);

  bool isBarrierApply(SILInstruction *instruction) {
    // For now, treat every apply (that doesn't use the borrowed value) as a
    // barrier.
    return isa<ApplySite>(instruction);
  }

  bool mayAccessPointer(SILInstruction *instruction) {
    if (!instruction->mayReadOrWriteMemory())
      return false;
    bool fail = false;
    visitAccessedAddress(instruction, [&fail](Operand *operand) {
      auto accessStorage = AccessStorage::compute(operand->get());
      if (accessStorage.getKind() != AccessRepresentation::Kind::Unidentified)
        fail = true;
    });
    return fail;
  }

  bool mayLoadWeakOrUnowned(SILInstruction *instruction) {
    // TODO: It is possible to do better here by looking at the address that is
    //       being loaded.
    return isa<LoadWeakInst>(instruction) || isa<LoadUnownedInst>(instruction);
  }

  bool isDeinitBarrier(SILInstruction *instruction) {
    return isBarrierApply(instruction) || instruction->maySynchronize() ||
           mayAccessPointer(instruction) || mayLoadWeakOrUnowned(instruction);
  }

  bool canReplaceValueWithBorrowedValue(SILValue value) {
    while (true) {
      auto *instruction = value.getDefiningInstruction();
      if (!instruction)
        return false;
      if (auto *cvi = dyn_cast<CopyValueInst>(instruction)) {
        value = cvi->getOperand();
        continue;
      } else if (auto *bbi = dyn_cast<BeginBorrowInst>(instruction)) {
        if (bbi == introducer) {
          return true;
        }
      }
      return false;
    }
  }

  size_t usesInApply(ApplySite apply) {
    if (auto count = transitiveUsesPerApplySite.lookup(apply))
      return count;
    return 0;
  }

  bool tryHoistOverInstruction(SILInstruction *instruction) {
    if (users.contains(instruction)) {
      if (auto apply = ApplySite::isa(instruction)) {
        SmallVector<int, 2> rewritableArgumentIndices;
        auto count = apply.getNumArguments();
        for (unsigned index = 0; index < count; ++index) {
          auto argument = apply.getArgument(index);
          if (canReplaceValueWithBorrowedValue(argument)) {
            rewritableArgumentIndices.push_back(index);
          }
        }
        if (rewritableArgumentIndices.size() != usesInApply(apply)) {
          return false;
        }
        // We can rewrite all the arguments which are transitive uses of the
        // borrow.
        for (auto index : rewritableArgumentIndices) {
          auto argument = apply.getArgument(index);
          auto borrowee = introducer->getOperand();
          if (auto *cvi = dyn_cast<CopyValueInst>(argument)) {
            cvi->setOperand(borrowee);
            modifiedCopyValueInsts.push_back(cvi);
          } else {
            apply.setArgument(index, borrowee);
          }
        }
        return true;
      } else if (auto *bbi = dyn_cast<BeginBorrowInst>(instruction)) {
        if (bbi->isLexical() &&
            canReplaceValueWithBorrowedValue(bbi->getOperand())) {
          auto borrowee = introducer->getOperand();
          bbi->setOperand(borrowee);
          return true;
        }
      } else if (auto *cvi = dyn_cast<CopyValueInst>(instruction)) {
        if (canReplaceValueWithBorrowedValue(cvi->getOperand())) {
          auto borrowee = introducer->getOperand();
          cvi->setOperand(borrowee);
          modifiedCopyValueInsts.push_back(cvi);
          return true;
        }
      }
      return false;
    }
    return !isDeinitBarrier(instruction);
  }
};

//===----------------------------------------------------------------------===//
//                        MARK: Rewrite borrow scopes
//===----------------------------------------------------------------------===//

bool ShrinkBorrowScope::run() {
  if (!BorrowedValue(introducer).isLocalScope())
    return false;
  if (!populateUsers())
    return false;
  if (!initializeWorklist())
    return false;

  findBarriers();

  rewrite();

  return true;
}

bool ShrinkBorrowScope::populateUsers() {
  SmallVector<Operand *, 16> uses;
  if (!findExtendedUsesOfSimpleBorrowedValue(BorrowedValue(introducer),
                                             &uses)) {
    // If the value produced by begin_borrow escapes, don't shrink the borrow
    // scope.
    return false;
  }
  for (auto *use : uses) {
    auto *user = use->getUser();
    users.insert(user);
    if (auto apply = ApplySite::isa(user)) {
      ++transitiveUsesPerApplySite[apply];
    }
  }
  return true;
}

bool ShrinkBorrowScope::initializeWorklist() {
  llvm::SmallVector<SILInstruction *, 16> scopeEndingInsts;
  BorrowedValue(introducer).getLocalScopeEndingInstructions(scopeEndingInsts);

  // Form a map of the scopeEndingInsts, keyed off the block they occur in.  If
  // a scope ending instruction is not an end_borrow, bail out.
  for (auto *instruction : scopeEndingInsts) {
    if (!isa<EndBorrowInst>(instruction))
      return false;
    auto *block = instruction->getParent();
    worklist.push_back(block);
    startingInstructions[block] = instruction;
  }

  return true;
}

void ShrinkBorrowScope::findBarriers() {
  // Walk the cfg backwards from the blocks containing scope ending
  // instructions, visiting only the initial blocks (which contained those
  // instructions) and those blocks all of whose successors have already been
  // visited.
  //
  // TODO: Handle loops.
  SmallPtrSet<SILBasicBlock *, 8> blocksWithReachedTops;
  auto reachedTopOfAllSuccessors =
      [&blocksWithReachedTops](SILBasicBlock *block) -> bool {
    return llvm::all_of(block->getSuccessorBlocks(), [=](auto *successor) {
      return blocksWithReachedTops.contains(successor);
    });
  };

  while (!worklist.empty()) {
    auto *block = worklist.pop_back_val();
    auto *startingInstruction = startingInstructions.lookup(block);
    if (!startingInstruction && !reachedTopOfAllSuccessors(block)) {
      continue;
    }
    if (!startingInstruction &&
        !tryHoistOverInstruction(block->getTerminator())) {
      // This block was walked to--it was not one containing one of the initial
      // end_borrow instructions.  Check whether it forwards the ownership of
      // the borrowed value (either directly or indirectly).  If it does, we
      // must not hoist the end_borrow above it.
      continue;
    }
    for (auto *successor : block->getSuccessorBlocks()) {
      blocksToEndAtTop.erase(successor);
    }

    // We either have processed all successors of block or else it is a block
    // which contained one of the original scope-ending instructions.  Scan the
    // block backwards, looking for the first deinit barrier.  If we've visited
    // all successors, start scanning from the terminator.  If the block
    // contained an original scope-ending instruction, start scanning from it.
    SILInstruction *instruction =
        startingInstruction ? startingInstruction : block->getTerminator();
    SILInstruction *barrier = nullptr;
    while ((instruction = getPreviousInstruction(instruction))) {
      if (instruction == introducer) {
        barrier = instruction;
        break;
      }
      if (!tryHoistOverInstruction(instruction)) {
        barrier = instruction;
        break;
      }
    }

    if (barrier) {
      barrierInstructions.push_back({block, barrier});
    } else {
      blocksWithReachedTops.insert(block);
      blocksToEndAtTop.insert(block);
      for (auto *predecessor : block->getPredecessorBlocks()) {
        worklist.push_back(predecessor);
      }
    }
  }
}

void ShrinkBorrowScope::rewrite() {
  // Remove all the original end_borrow instructions.
  for (auto pair : startingInstructions) {
    deleter.forceDelete(pair.getSecond());
  }

  // Insert the new end_borrow instructions that occur after deinit barriers.
  for (auto pair : barrierInstructions) {
    auto *insertionPoint = getNextInstruction(pair.second);
    createEndBorrow(insertionPoint);
  }

  // Insert the new end_borrow instructions that occur at the beginning of
  // blocks which we couldn't hoist out of.
  for (auto *block : blocksToEndAtTop) {
    auto *insertionPoint = &*block->begin();
    createEndBorrow(insertionPoint);
  }
}

void ShrinkBorrowScope::createEndBorrow(SILInstruction *insertionPoint) {
  auto builder = SILBuilderWithScope(insertionPoint);
  builder.createEndBorrow(
      RegularLocation::getAutoGeneratedLocation(insertionPoint->getLoc()),
      introducer);
}

bool swift::shrinkBorrowScope(
    BeginBorrowInst *bbi, InstructionDeleter &deleter,
    SmallVectorImpl<CopyValueInst *> &modifiedCopyValueInsts) {
  ShrinkBorrowScope borrowShrinker(bbi, deleter, modifiedCopyValueInsts);
  return borrowShrinker.run();
}
<commit_msg>[Gardening] Improved variable name.<commit_after>//
// This source file is part of the Swift.org open source project
//
// Copyright (c) 2014 - 2021 Apple Inc. and the Swift project authors
// Licensed under Apache License v2.0 with Runtime Library Exception
//
// See https://swift.org/LICENSE.txt for license information
// See https://swift.org/CONTRIBUTORS.txt for the list of Swift project authors
//

#include "swift/AST/Builtins.h"
#include "swift/SIL/MemAccessUtils.h"
#include "swift/SIL/OwnershipUtils.h"
#include "swift/SIL/SILBasicBlock.h"
#include "swift/SILOptimizer/Utils/CanonicalizeBorrowScope.h"
#include "swift/SILOptimizer/Utils/InstOptUtils.h"
#include "swift/SILOptimizer/Utils/InstructionDeleter.h"

#define DEBUG_TYPE "copy-propagation"

using namespace swift;

//===----------------------------------------------------------------------===//
//                           MARK: Local utilities
//===----------------------------------------------------------------------===//

// TODO: Move to be member function on SILInstruction.
static SILInstruction *getPreviousInstruction(SILInstruction *inst) {
  auto pos = inst->getIterator();
  return pos == inst->getParent()->begin() ? nullptr
                                           : &*std::prev(inst->getIterator());
}

// TODO: Move to be member function on SILInstruction.
static SILInstruction *getNextInstruction(SILInstruction *inst) {
  auto nextPos = std::next(inst->getIterator());
  return nextPos == inst->getParent()->end() ? nullptr : &*nextPos;
}

//===----------------------------------------------------------------------===//
//                       MARK: ShrinkBorrowScope
//===----------------------------------------------------------------------===//

class ShrinkBorrowScope {
  // The instruction that begins this borrow scope.
  BeginBorrowInst *introducer;

  InstructionDeleter &deleter;

  SmallVectorImpl<CopyValueInst *> &modifiedCopyValueInsts;

  SmallPtrSet<SILInstruction *, 16> users;

  /// Deinit barriers that obstruct hoisting end_borrow instructions.
  llvm::SmallVector<std::pair<SILBasicBlock *, SILInstruction *>>
      barrierInstructions;

  SmallPtrSet<SILBasicBlock *, 8> blocksToEndAtTop;

  llvm::SmallDenseMap<ApplySite, size_t> transitiveUsesPerApplySite;

  // The list of blocks to look for new points at which to insert end_borrows
  // in.  A block must not be processed if all of its successors have not yet
  // been.  For that reason, it is necessary to allow the same block to be
  // visited multiple times, at most once for each successor.
  SmallVector<SILBasicBlock *, 8> worklist;
  // The instructions from which the shrinking starts, the scope ending
  // instructions, keyed off the block in which they appear.
  llvm::SmallDenseMap<SILBasicBlock *, SILInstruction *> startingInstructions;

public:
  ShrinkBorrowScope(BeginBorrowInst *bbi, InstructionDeleter &deleter,
                    SmallVectorImpl<CopyValueInst *> &modifiedCopyValueInsts)
      : introducer(bbi), deleter(deleter),
        modifiedCopyValueInsts(modifiedCopyValueInsts) {}

  bool run();

  bool populateUsers();
  bool initializeWorklist();
  void findBarriers();
  void rewrite();
  void createEndBorrow(SILInstruction *insertionPoint);

  bool isBarrierApply(SILInstruction *instruction) {
    // For now, treat every apply (that doesn't use the borrowed value) as a
    // barrier.
    return isa<ApplySite>(instruction);
  }

  bool mayAccessPointer(SILInstruction *instruction) {
    if (!instruction->mayReadOrWriteMemory())
      return false;
    bool fail = false;
    visitAccessedAddress(instruction, [&fail](Operand *operand) {
      auto accessStorage = AccessStorage::compute(operand->get());
      if (accessStorage.getKind() != AccessRepresentation::Kind::Unidentified)
        fail = true;
    });
    return fail;
  }

  bool mayLoadWeakOrUnowned(SILInstruction *instruction) {
    // TODO: It is possible to do better here by looking at the address that is
    //       being loaded.
    return isa<LoadWeakInst>(instruction) || isa<LoadUnownedInst>(instruction);
  }

  bool isDeinitBarrier(SILInstruction *instruction) {
    return isBarrierApply(instruction) || instruction->maySynchronize() ||
           mayAccessPointer(instruction) || mayLoadWeakOrUnowned(instruction);
  }

  bool canReplaceValueWithBorrowedValue(SILValue value) {
    while (true) {
      auto *instruction = value.getDefiningInstruction();
      if (!instruction)
        return false;
      if (auto *cvi = dyn_cast<CopyValueInst>(instruction)) {
        value = cvi->getOperand();
        continue;
      } else if (auto *bbi = dyn_cast<BeginBorrowInst>(instruction)) {
        if (bbi == introducer) {
          return true;
        }
      }
      return false;
    }
  }

  size_t usesInApply(ApplySite apply) {
    if (auto count = transitiveUsesPerApplySite.lookup(apply))
      return count;
    return 0;
  }

  bool tryHoistOverInstruction(SILInstruction *instruction) {
    if (users.contains(instruction)) {
      if (auto apply = ApplySite::isa(instruction)) {
        SmallVector<int, 2> rewritableArgumentIndices;
        auto count = apply.getNumArguments();
        for (unsigned index = 0; index < count; ++index) {
          auto argument = apply.getArgument(index);
          if (canReplaceValueWithBorrowedValue(argument)) {
            rewritableArgumentIndices.push_back(index);
          }
        }
        if (rewritableArgumentIndices.size() != usesInApply(apply)) {
          return false;
        }
        // We can rewrite all the arguments which are transitive uses of the
        // borrow.
        for (auto index : rewritableArgumentIndices) {
          auto argument = apply.getArgument(index);
          auto borrowee = introducer->getOperand();
          if (auto *cvi = dyn_cast<CopyValueInst>(argument)) {
            cvi->setOperand(borrowee);
            modifiedCopyValueInsts.push_back(cvi);
          } else {
            apply.setArgument(index, borrowee);
          }
        }
        return true;
      } else if (auto *bbi = dyn_cast<BeginBorrowInst>(instruction)) {
        if (bbi->isLexical() &&
            canReplaceValueWithBorrowedValue(bbi->getOperand())) {
          auto borrowee = introducer->getOperand();
          bbi->setOperand(borrowee);
          return true;
        }
      } else if (auto *cvi = dyn_cast<CopyValueInst>(instruction)) {
        if (canReplaceValueWithBorrowedValue(cvi->getOperand())) {
          auto borrowee = introducer->getOperand();
          cvi->setOperand(borrowee);
          modifiedCopyValueInsts.push_back(cvi);
          return true;
        }
      }
      return false;
    }
    return !isDeinitBarrier(instruction);
  }
};

//===----------------------------------------------------------------------===//
//                        MARK: Rewrite borrow scopes
//===----------------------------------------------------------------------===//

bool ShrinkBorrowScope::run() {
  if (!BorrowedValue(introducer).isLocalScope())
    return false;
  if (!populateUsers())
    return false;
  if (!initializeWorklist())
    return false;

  findBarriers();

  rewrite();

  return true;
}

bool ShrinkBorrowScope::populateUsers() {
  SmallVector<Operand *, 16> uses;
  if (!findExtendedUsesOfSimpleBorrowedValue(BorrowedValue(introducer),
                                             &uses)) {
    // If the value produced by begin_borrow escapes, don't shrink the borrow
    // scope.
    return false;
  }
  for (auto *use : uses) {
    auto *user = use->getUser();
    users.insert(user);
    if (auto apply = ApplySite::isa(user)) {
      ++transitiveUsesPerApplySite[apply];
    }
  }
  return true;
}

bool ShrinkBorrowScope::initializeWorklist() {
  llvm::SmallVector<SILInstruction *, 16> scopeEndingInsts;
  BorrowedValue(introducer).getLocalScopeEndingInstructions(scopeEndingInsts);

  // Form a map of the scopeEndingInsts, keyed off the block they occur in.  If
  // a scope ending instruction is not an end_borrow, bail out.
  for (auto *instruction : scopeEndingInsts) {
    if (!isa<EndBorrowInst>(instruction))
      return false;
    auto *block = instruction->getParent();
    worklist.push_back(block);
    startingInstructions[block] = instruction;
  }

  return true;
}

void ShrinkBorrowScope::findBarriers() {
  // Walk the cfg backwards from the blocks containing scope ending
  // instructions, visiting only the initial blocks (which contained those
  // instructions) and those blocks all of whose successors have already been
  // visited.
  //
  // TODO: Handle loops.

  // Blocks to the top of which the borrow scope has been shrunk.
  SmallPtrSet<SILBasicBlock *, 8> deadBlocks;
  auto hasOnlyDeadSuccessors =
      [&deadBlocks](SILBasicBlock *block) -> bool {
    return llvm::all_of(block->getSuccessorBlocks(), [=](auto *successor) {
      return deadBlocks.contains(successor);
    });
  };

  while (!worklist.empty()) {
    auto *block = worklist.pop_back_val();
    auto *startingInstruction = startingInstructions.lookup(block);
    if (!startingInstruction && !hasOnlyDeadSuccessors(block)) {
      continue;
    }
    if (!startingInstruction &&
        !tryHoistOverInstruction(block->getTerminator())) {
      // This block was walked to--it was not one containing one of the initial
      // end_borrow instructions.  Check whether it forwards the ownership of
      // the borrowed value (either directly or indirectly).  If it does, we
      // must not hoist the end_borrow above it.
      continue;
    }
    for (auto *successor : block->getSuccessorBlocks()) {
      blocksToEndAtTop.erase(successor);
    }

    // We either have processed all successors of block or else it is a block
    // which contained one of the original scope-ending instructions.  Scan the
    // block backwards, looking for the first deinit barrier.  If we've visited
    // all successors, start scanning from the terminator.  If the block
    // contained an original scope-ending instruction, start scanning from it.
    SILInstruction *instruction =
        startingInstruction ? startingInstruction : block->getTerminator();
    SILInstruction *barrier = nullptr;
    while ((instruction = getPreviousInstruction(instruction))) {
      if (instruction == introducer) {
        barrier = instruction;
        break;
      }
      if (!tryHoistOverInstruction(instruction)) {
        barrier = instruction;
        break;
      }
    }

    if (barrier) {
      barrierInstructions.push_back({block, barrier});
    } else {
      deadBlocks.insert(block);
      blocksToEndAtTop.insert(block);
      for (auto *predecessor : block->getPredecessorBlocks()) {
        worklist.push_back(predecessor);
      }
    }
  }
}

void ShrinkBorrowScope::rewrite() {
  // Remove all the original end_borrow instructions.
  for (auto pair : startingInstructions) {
    deleter.forceDelete(pair.getSecond());
  }

  // Insert the new end_borrow instructions that occur after deinit barriers.
  for (auto pair : barrierInstructions) {
    auto *insertionPoint = getNextInstruction(pair.second);
    createEndBorrow(insertionPoint);
  }

  // Insert the new end_borrow instructions that occur at the beginning of
  // blocks which we couldn't hoist out of.
  for (auto *block : blocksToEndAtTop) {
    auto *insertionPoint = &*block->begin();
    createEndBorrow(insertionPoint);
  }
}

void ShrinkBorrowScope::createEndBorrow(SILInstruction *insertionPoint) {
  auto builder = SILBuilderWithScope(insertionPoint);
  builder.createEndBorrow(
      RegularLocation::getAutoGeneratedLocation(insertionPoint->getLoc()),
      introducer);
}

bool swift::shrinkBorrowScope(
    BeginBorrowInst *bbi, InstructionDeleter &deleter,
    SmallVectorImpl<CopyValueInst *> &modifiedCopyValueInsts) {
  ShrinkBorrowScope borrowShrinker(bbi, deleter, modifiedCopyValueInsts);
  return borrowShrinker.run();
}
<|endoftext|>


<commit_before>#include "../include/NEAT.h"

#define WEIGHTMUTATE 0
#define PERTURBMUTATE 1
#define ENABLEMUTATE 2
#define STEPSIZE 3
#define LINKMUTATE 4
#define NODEMUTATE 5
#define CROSSOVER 6

NEAT::NEAT(int inputs, int outputs) {
    std::srand(time(NULL));
    population = 150;
    f.open("log.txt");
    m[WEIGHTMUTATE] = .8;
    m[PERTURBMUTATE] = .9;
    m[ENABLEMUTATE] = .02;
    m[STEPSIZE] = .4;
    m[LINKMUTATE] = .05;
    m[NODEMUTATE] = .03;
    m[CROSSOVER] = .75;
    c1 = 1;
    c2 = 1;
    c3 = .4;
    staleThreshold = 15;
    distanceThreshold = 3;
    //maxSpecies = 20;
    maxFitness = 0;
    generation = 0;
    for (int i = 0; i < population; ++i) {
        pool.push_back(Genome(inputs, outputs, m));
        labelInnovations(pool.back());
    }
    for (int i = 0; i < inputs; ++i) {
        for (int j = 0; j < outputs; ++j) {
            newInnovation(i, inputs + j);
        }
    }
    classify();
}

//doesn't check if combination exists, must check innovationExists() before
int NEAT::newInnovation(int a, int b) {
    std::array<int, 2> temp = {a, b};
    innovation.push_back(temp);
    return innovation.size() - 1;
}

int NEAT::findInnovation(int a, int b) {
    for (int i = 0; i < innovation.size(); ++i) {
        if (innovation[i][0] == a && innovation[i][1] == b) {
            return i;
        }
    }
    return newInnovation(a, b);
}

void NEAT::labelInnovations(Genome &g) {
    for (int i = 0; i < g.structure.size(); ++i) {
        g.structure[i].id = findInnovation(g.structure[i].input, g.structure[i].output);
    }
}

Genome NEAT::mate(Genome *a, Genome *b) {
    if (b->fitness > a->fitness) {
        Genome *temp = a;
        a = b;
        b = temp;
    }
    Genome child = Genome(*a);
    if (double(rand()) / RAND_MAX < child.mutationRates[CROSSOVER]) {
        for (int i = 0; i < child.structure.size(); ++i) {
            for (int j = 0; j < b->structure.size(); ++j) {
                if (b->structure[j].id == child.structure[i].id) {
                    child.structure[i].weight = (child.structure[i].weight + b->structure[j].weight) / 2;
                    if (child.structure[i].enabled != b->structure[i].enabled) {
                        child.structure[i].enabled = rand() / RAND_MAX < .25;
                    }
                    break;
                }
            }
        }
    }
    mutate(child);
    return child;
}

void NEAT::mutate(Genome &g) {
    //ENABLE
    if (double(rand()) / RAND_MAX < g.mutationRates[ENABLEMUTATE]) {
        int temp = rand() % g.structure.size();
        g.structure[temp].enabled = !g.structure[temp].enabled;
    }
    //WEIGHTS
    if (double(rand()) / RAND_MAX < g.mutationRates[WEIGHTMUTATE]) {
        for (int i = 0; i < g.structure.size(); ++i) {
            if (double(rand()) / RAND_MAX < g.mutationRates[PERTURBMUTATE]) {
                g.structure[i].weight += ((rand() % 2) * 2 - 1) * (rand() / RAND_MAX) * g.mutationRates[STEPSIZE];
            } else {
                g.structure[i].weight = double(rand()) * 4. / RAND_MAX - 2;
            }
        }
    }
    //ADD CONNECTION
    if (double(rand()) / RAND_MAX < g.mutationRates[LINKMUTATE]) {
        int a = rand() % g.nodes;
        int b = rand() % (g.nodes - g.inputs) + g.inputs;
        bool temp = true;
        for (int i = 0; i < g.structure.size(); ++i) {
            if (g.structure[i].input == a && g.structure[i].output == b) {
                temp = false;
            }
        }
        if (temp) {
            g.structure.push_back(Link(a, b, double(rand()) * 4. / RAND_MAX - 2));
            g.structure.back().id = findInnovation(a, b);
        }
    }
    //ADD NODE
    if (double(rand()) / RAND_MAX < g.mutationRates[NODEMUTATE]) {
        int temp = rand() % g.structure.size();
        if (g.structure[temp].enabled) {
            g.structure[temp].enabled = false;
            g.structure.push_back(Link(g.structure[temp].input, g.nodes, 1));
            g.structure.back().id = findInnovation(g.structure[temp].input, g.nodes);
            g.structure.push_back(Link(g.nodes, g.structure[temp].output, g.structure[temp].weight));
            g.structure.back().id = findInnovation(g.nodes, g.structure[temp].output);
            g.nodes++;
        }
    }
    //slightly alter all mutation rates (.05 is the volatility)
    for (int i = 0; i < 7; ++i) {
        g.mutationRates[i] += ((rand() % 2) * 2 - 1) * .05 * g.mutationRates[i];
    }
}

double NEAT::distance(Genome a, Genome b) {
    int aMaxID = 0;
    for (int i = 0; i < a.structure.size(); ++i) {
        aMaxID = std::max(aMaxID, a.structure[i].id);
    }
    int bMaxID = 0;
    for (int i = 0; i < b.structure.size(); ++i) {
        bMaxID = std::max(bMaxID, b.structure[i].id);
    }
    int disjoint = 0;
    double weights = 0;
    int similarConnections = 0;
    int ai=0, bi=0;
    for (int i = 0; i < innovation.size(); ++i) {
        int tempa = -1;
        int tempb = -1;
        while(ai<a.structure.size()&&a.structure[ai].id<i){
            ai++;
        }
        if(a.structure[ai].id==i);{
            tempa = ai;
        }
        while(bi<b.structure.size()&&b.structure[bi].id<i){
            bi++;
        }
        if(b.structure[bi].id==i);{
            tempb = bi;
        }
        if (tempa != -1 && tempb != -1) {
            similarConnections++;
            weights += std::abs(a.structure[tempa].weight - b.structure[tempb].weight);
        } else if (tempa != -1 || tempb != -1) {
            disjoint++;
        }
    }
    int n = std::max(a.structure.size(), b.structure.size());
    return std::abs(c1 * std::abs(a.structure.size() - b.structure.size()) / n + c2 * disjoint / n + c3 * weights / similarConnections);
}

void NEAT::adjustFitness() {
    for (int i = 0; i < species.size(); ++i) {
        std::sort(std::begin(species[i].genomes), std::end(species[i].genomes), Genome::compare);
        for (int j = 0; j < species[i].genomes.size(); ++j) {
            species[i].genomes[j]->adjustedFitness = species[i].genomes[j]->fitness;
            species[i].genomes[j]->adjustedFitness /= species[i].genomes.size();
        }
        if (species[i].genomes[0]->fitness > species[i].maxFitness) {
            species[i].maxFitness = species[i].genomes[0]->fitness;
            species[i].staleness = 0;
            maxFitness = std::max(maxFitness, species[i].maxFitness);
        } else {
            species[i].staleness++;
        }
    }
    std::sort(std::begin(species), std::end(species), Species::compare);
}

void NEAT::cull() {
    for (int i = 0; i < species.size(); ++i) {
        if (species[i].staleness >= staleThreshold && species[i].maxFitness < maxFitness) {
            species.erase(species.begin() + i);
            i--;
        }
    }
}

//only adds champion if species has 5+ genomes
void NEAT::repopulate() {
    std::vector<Genome> newPool;
    newPool.reserve(population);
    std::vector<int> parents;
    for (int i = 0; i < species.size(); ++i) {
        newPool.push_back(Genome(*species[i].genomes[0]));
        //only top 20 percent of species is allowed to reproduce unless it is smaller than 6 genomes
        if (species[i].genomes.size() >= 5) {
            species[i].genomes.resize(species[i].genomes.size() / 5);
        }
        for (int j = 0; j < species[i].genomes.size(); ++j) {
            parents.push_back(i);
        }
    }
    while (newPool.size() < population) {
        /* Only needed if stuff is breaking
        if (parents.size() == 0) {
            newPool.push_back(Genome(pool[0].inputs, pool[0].outputs, m));;
            continue;
        }
        */
        int temp = parents[rand() % parents.size()];
        // 1 in 1000 chance of interspecies mating
        if (rand() % 1000 == 1) {
            int temp2 = parents[rand() % parents.size()];
            newPool.push_back(mate(species[temp].genomes[rand() % species[temp].genomes.size()],
                                   species[temp2].genomes[rand() % species[temp2].genomes.size()]));
        } else {
            newPool.push_back(mate(species[temp].genomes[rand() % species[temp].genomes.size()],
                                   species[temp].genomes[rand() % species[temp].genomes.size()]));
        }
    }
    //~Vector Magic~ prob not necessary but it will serve as a reminder of the monolithic memory leak I had earlier
    std::vector<Genome>().swap(pool);
    pool = newPool;
    for (int i = 0; i < species.size(); ++i) {
        species[i].genomes.clear();
        //I actually have no clue how vector memory allocation works... this is prob irrelevant
        species[i].genomes.shrink_to_fit();
        species[i].genomes.push_back(&pool[i]);
    }
    for(int i=0;i<pool.size();++i){
        std::sort(std::begin(pool[i].structure),std::end(pool[i].structure),Link::compare);
    }
}

void NEAT::classify() {
    for (int i = species.size(); i < population; ++i) {
        bool newSpecies = true;
        for (int j = 0; j < species.size(); ++j) {
            if (distance(pool[i], *species[j].genomes[0]) < distanceThreshold) {
                newSpecies = false;
                species[j].genomes.push_back(&pool[i]);
                break;
            }
        }
        if (newSpecies) {
            species.push_back(Species());
            species.back().genomes.push_back(&pool[i]);
        }
    }
    /* Experimental feature: reactive threshold to stabilize species numbers
    if(species.size()>maxSpecies){
        distanceThreshold+=.1;
    }
     */
}

void NEAT::nextGen() {
    adjustFitness();
    log();
    status();
    cull();
    repopulate();
    classify();
    generation++;
}

void NEAT::log() {
    f << "Gen: " << generation << std::endl;
    f << "Max Fitness: " << pool[0].fitness << std::endl;
    f << "Champion: " << pool[0].encode().c_str() << std::endl;

}

void NEAT::status() {
    double averageSize = 0;
    double averageFitness = 0;
    double minSize = 999, maxSize = 0;
    for (int i = 0; i < population; ++i) {
        averageSize += pool[i].structure.size();
        averageFitness += pool[i].fitness;
        minSize = std::min(minSize, (double) pool[i].structure.size());
        maxSize = std::max(maxSize, (double) pool[i].structure.size());
    }
    averageSize /= population;
    averageFitness /= population;
    std::cout << "Gen: " << generation << " Fitness: " << species[0].genomes[0]->fitness << " " << averageFitness
              << " Species: " << species.size() << " Size: " << minSize << " " << averageSize << " " << maxSize
              << std::endl;
}

<commit_msg>Made wheels turn faster (breaks other stuff)<commit_after>#include "../include/NEAT.h"

#define WEIGHTMUTATE 0
#define PERTURBMUTATE 1
#define ENABLEMUTATE 2
#define STEPSIZE 3
#define LINKMUTATE 4
#define NODEMUTATE 5
#define CROSSOVER 6
//TEST
NEAT::NEAT(int inputs, int outputs) {
    std::srand(time(NULL));
    population = 150;
    f.open("log.txt");
    m[WEIGHTMUTATE] = .8;
    m[PERTURBMUTATE] = .9;
    m[ENABLEMUTATE] = .02;
    m[STEPSIZE] = .4;
    m[LINKMUTATE] = .05;
    m[NODEMUTATE] = .03;
    m[CROSSOVER] = .75;
    c1 = 1;
    c2 = 1;
    c3 = .4;
    staleThreshold = 15;
    distanceThreshold = 3;
    //maxSpecies = 20;
    maxFitness = 0;
    generation = 0;
    for (int i = 0; i < population; ++i) {
        pool.push_back(Genome(inputs, outputs, m));
        labelInnovations(pool.back());
    }
    for (int i = 0; i < inputs; ++i) {
        for (int j = 0; j < outputs; ++j) {
            newInnovation(i, inputs + j);
        }
    }
    classify();
}

//doesn't check if combination exists, must check innovationExists() before
int NEAT::newInnovation(int a, int b) {
    std::array<int, 2> temp = {a, b};
    innovation.push_back(temp);
    return innovation.size() - 1;
}

int NEAT::findInnovation(int a, int b) {
    for (int i = 0; i < innovation.size(); ++i) {
        if (innovation[i][0] == a && innovation[i][1] == b) {
            return i;
        }
    }
    return newInnovation(a, b);
}

void NEAT::labelInnovations(Genome &g) {
    for (int i = 0; i < g.structure.size(); ++i) {
        g.structure[i].id = findInnovation(g.structure[i].input, g.structure[i].output);
    }
}

Genome NEAT::mate(Genome *a, Genome *b) {
    if (b->fitness > a->fitness) {
        Genome *temp = a;
        a = b;
        b = temp;
    }
    Genome child = Genome(*a);
    if (double(rand()) / RAND_MAX < child.mutationRates[CROSSOVER]) {
        for (int i = 0; i < child.structure.size(); ++i) {
            for (int j = 0; j < b->structure.size(); ++j) {
                if (b->structure[j].id == child.structure[i].id) {
                    child.structure[i].weight = (child.structure[i].weight + b->structure[j].weight) / 2;
                    if (child.structure[i].enabled != b->structure[i].enabled) {
                        child.structure[i].enabled = rand() / RAND_MAX < .25;
                    }
                    break;
                }
            }
        }
    }
    mutate(child);
    return child;
}

void NEAT::mutate(Genome &g) {
    //ENABLE
    if (double(rand()) / RAND_MAX < g.mutationRates[ENABLEMUTATE]) {
        int temp = rand() % g.structure.size();
        g.structure[temp].enabled = !g.structure[temp].enabled;
    }
    //WEIGHTS
    if (double(rand()) / RAND_MAX < g.mutationRates[WEIGHTMUTATE]) {
        for (int i = 0; i < g.structure.size(); ++i) {
            if (double(rand()) / RAND_MAX < g.mutationRates[PERTURBMUTATE]) {
                g.structure[i].weight += ((rand() % 2) * 2 - 1) * (rand() / RAND_MAX) * g.mutationRates[STEPSIZE];
            } else {
                g.structure[i].weight = double(rand()) * 4. / RAND_MAX - 2;
            }
        }
    }
    //ADD CONNECTION
    if (double(rand()) / RAND_MAX < g.mutationRates[LINKMUTATE]) {
        int a = rand() % g.nodes;
        int b = rand() % (g.nodes - g.inputs) + g.inputs;
        bool temp = true;
        for (int i = 0; i < g.structure.size(); ++i) {
            if (g.structure[i].input == a && g.structure[i].output == b) {
                temp = false;
            }
        }
        if (temp) {
            g.structure.push_back(Link(a, b, double(rand()) * 4. / RAND_MAX - 2));
            g.structure.back().id = findInnovation(a, b);
        }
    }
    //ADD NODE
    if (double(rand()) / RAND_MAX < g.mutationRates[NODEMUTATE]) {
        int temp = rand() % g.structure.size();
        if (g.structure[temp].enabled) {
            g.structure[temp].enabled = false;
            g.structure.push_back(Link(g.structure[temp].input, g.nodes, 1));
            g.structure.back().id = findInnovation(g.structure[temp].input, g.nodes);
            g.structure.push_back(Link(g.nodes, g.structure[temp].output, g.structure[temp].weight));
            g.structure.back().id = findInnovation(g.nodes, g.structure[temp].output);
            g.nodes++;
        }
    }
    //slightly alter all mutation rates (.05 is the volatility)
    for (int i = 0; i < 7; ++i) {
        g.mutationRates[i] += ((rand() % 2) * 2 - 1) * .05 * g.mutationRates[i];
    }
}

double NEAT::distance(Genome a, Genome b) {
    int aMaxID = 0;
    for (int i = 0; i < a.structure.size(); ++i) {
        aMaxID = std::max(aMaxID, a.structure[i].id);
    }
    int bMaxID = 0;
    for (int i = 0; i < b.structure.size(); ++i) {
        bMaxID = std::max(bMaxID, b.structure[i].id);
    }
    int disjoint = 0;
    double weights = 0;
    int similarConnections = 0;
    int ai=0, bi=0;
    for (int i = 0; i < innovation.size(); ++i) {
        int tempa = -1;
        int tempb = -1;
        while(ai<a.structure.size()&&a.structure[ai].id<i){
            ai++;
        }
        if(a.structure[ai].id==i);{
            tempa = ai;
        }
        while(bi<b.structure.size()&&b.structure[bi].id<i){
            bi++;
        }
        if(b.structure[bi].id==i);{
            tempb = bi;
        }
        if (tempa != -1 && tempb != -1) {
            similarConnections++;
            weights += std::abs(a.structure[tempa].weight - b.structure[tempb].weight);
        } else if (tempa != -1 || tempb != -1) {
            disjoint++;
        }
    }
    int n = std::max(a.structure.size(), b.structure.size());
    return std::abs(c1 * std::abs(a.structure.size() - b.structure.size()) / n + c2 * disjoint / n + c3 * weights / similarConnections);
}

void NEAT::adjustFitness() {
    for (int i = 0; i < species.size(); ++i) {
        std::sort(std::begin(species[i].genomes), std::end(species[i].genomes), Genome::compare);
        for (int j = 0; j < species[i].genomes.size(); ++j) {
            species[i].genomes[j]->adjustedFitness = species[i].genomes[j]->fitness;
            species[i].genomes[j]->adjustedFitness /= species[i].genomes.size();
        }
        if (species[i].genomes[0]->fitness > species[i].maxFitness) {
            species[i].maxFitness = species[i].genomes[0]->fitness;
            species[i].staleness = 0;
            maxFitness = std::max(maxFitness, species[i].maxFitness);
        } else {
            species[i].staleness++;
        }
    }
    std::sort(std::begin(species), std::end(species), Species::compare);
}

void NEAT::cull() {
    for (int i = 0; i < species.size(); ++i) {
        if (species[i].staleness >= staleThreshold && species[i].maxFitness < maxFitness) {
            species.erase(species.begin() + i);
            i--;
        }
    }
}

//only adds champion if species has 5+ genomes
void NEAT::repopulate() {
    std::vector<Genome> newPool;
    newPool.reserve(population);
    std::vector<int> parents;
    for (int i = 0; i < species.size(); ++i) {
        newPool.push_back(Genome(*species[i].genomes[0]));
        //only top 20 percent of species is allowed to reproduce unless it is smaller than 6 genomes
        if (species[i].genomes.size() >= 5) {
            species[i].genomes.resize(species[i].genomes.size() / 5);
        }
        for (int j = 0; j < species[i].genomes.size(); ++j) {
            parents.push_back(i);
        }
    }
    while (newPool.size() < population) {
        /* Only needed if stuff is breaking
        if (parents.size() == 0) {
            newPool.push_back(Genome(pool[0].inputs, pool[0].outputs, m));;
            continue;
        }
        */
        int temp = parents[rand() % parents.size()];
        // 1 in 1000 chance of interspecies mating
        if (rand() % 1000 == 1) {
            int temp2 = parents[rand() % parents.size()];
            newPool.push_back(mate(species[temp].genomes[rand() % species[temp].genomes.size()],
                                   species[temp2].genomes[rand() % species[temp2].genomes.size()]));
        } else {
            newPool.push_back(mate(species[temp].genomes[rand() % species[temp].genomes.size()],
                                   species[temp].genomes[rand() % species[temp].genomes.size()]));
        }
    }
    //~Vector Magic~ prob not necessary but it will serve as a reminder of the monolithic memory leak I had earlier
    std::vector<Genome>().swap(pool);
    pool = newPool;
    for (int i = 0; i < species.size(); ++i) {
        species[i].genomes.clear();
        //I actually have no clue how vector memory allocation works... this is prob irrelevant
        species[i].genomes.shrink_to_fit();
        species[i].genomes.push_back(&pool[i]);
    }
    for(int i=0;i<pool.size();++i){
        std::sort(std::begin(pool[i].structure),std::end(pool[i].structure),Link::compare);
    }
}

void NEAT::classify() {
    for (int i = species.size(); i < population; ++i) {
        bool newSpecies = true;
        for (int j = 0; j < species.size(); ++j) {
            if (distance(pool[i], *species[j].genomes[0]) < distanceThreshold) {
                newSpecies = false;
                species[j].genomes.push_back(&pool[i]);
                break;
            }
        }
        if (newSpecies) {
            species.push_back(Species());
            species.back().genomes.push_back(&pool[i]);
        }
    }
    /* Experimental feature: reactive threshold to stabilize species numbers
    if(species.size()>maxSpecies){
        distanceThreshold+=.1;
    }
     */
}

void NEAT::nextGen() {
    adjustFitness();
    log();
    status();
    cull();
    repopulate();
    classify();
    generation++;
}

void NEAT::log() {
    f << "Gen: " << generation << std::endl;
    f << "Max Fitness: " << pool[0].fitness << std::endl;
    f << "Champion: " << pool[0].encode().c_str() << std::endl;

}

void NEAT::status() {
    double averageSize = 0;
    double averageFitness = 0;
    double minSize = 999, maxSize = 0;
    for (int i = 0; i < population; ++i) {
        averageSize += pool[i].structure.size();
        averageFitness += pool[i].fitness;
        minSize = std::min(minSize, (double) pool[i].structure.size());
        maxSize = std::max(maxSize, (double) pool[i].structure.size());
    }
    averageSize /= population;
    averageFitness /= population;
    std::cout << "Gen: " << generation << " Fitness: " << species[0].genomes[0]->fitness << " " << averageFitness
              << " Species: " << species.size() << " Size: " << minSize << " " << averageSize << " " << maxSize
              << std::endl;
}

<|endoftext|>


<commit_before>/*
 *  Software License Agreement (BSD License)
 *
 *  Copyright (c) 2016-2019, Natalnet Laboratory for Perceptual Robotics
 *  All rights reserved.
 *  Redistribution and use in source and binary forms, with or without modification, are permitted provided
 *  that the following conditions are met:
 *
 *  1. Redistributions of source code must retain the above copyright notice, this list of conditions and
 *     the following disclaimer.
 *
 *  2. 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.
 *
 *  3. Neither the name of the copyright holder nor the names of its contributors may be used to endorse or
 *     promote products derived from this software without specific prior written permission.
 *
 *  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, *  INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
 *  DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
 *  SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
 *  SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
 *  WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE
 *  USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 *
 */

#include <iostream>
#include <cstdarg>

#include <event_logger.h>

#include <pcl/console/print.h>

using namespace pcl::console;

/*
 * All functions below are copy/paste from the PCL counterparts
 * because variadic functions don't allow redirecting calls to another
 * variadic function.
 */

void EventLogger::print(const char *format, ...)
{
	reset_text_color(stdout);

	va_list stdout_args, file_args;

	//Write message to stdout and file
	va_start(stdout_args, format);
	va_copy(file_args, stdout_args);
	vfprintf(stdout, format, stdout_args);
	vfprintf(log_file_, format, file_args);
	va_end(stdout_args);
	va_end(file_args);
}

void EventLogger::printDebug(const char* module_class, const char* msg)
{
	if(!isVerbosityLevelEnabled(L_DEBUG))
		return;

	print("[%s] DEBUG: %s\n", module_class, msg);
}

void EventLogger::printInfo(const char* module_class, const char* msg)
{
	if(!isVerbosityLevelEnabled(L_INFO))
		return;

	print("[%s] INFO: %s\n", module_class, msg);
}

void EventLogger::printWarning(const char* module_class, const char* msg)
{
	if(!isVerbosityLevelEnabled(L_WARN))
		return;

	print("[%s] WARNING: %s\n", module_class, msg);
}

void EventLogger::printError(const char* module_class, const char* msg)
{
	if(!isVerbosityLevelEnabled(L_ERROR))
		return;

	print("[%s] ERROR: %s\n", module_class, msg);
}<commit_msg>Corrected changing colors for the different verbosity levels.<commit_after>/*
 *  Software License Agreement (BSD License)
 *
 *  Copyright (c) 2016-2019, Natalnet Laboratory for Perceptual Robotics
 *  All rights reserved.
 *  Redistribution and use in source and binary forms, with or without modification, are permitted provided
 *  that the following conditions are met:
 *
 *  1. Redistributions of source code must retain the above copyright notice, this list of conditions and
 *     the following disclaimer.
 *
 *  2. 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.
 *
 *  3. Neither the name of the copyright holder nor the names of its contributors may be used to endorse or
 *     promote products derived from this software without specific prior written permission.
 *
 *  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, *  INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
 *  DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
 *  SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
 *  SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
 *  WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE
 *  USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 *
 */

#include <iostream>
#include <cstdarg>

#include <event_logger.h>

#include <pcl/console/print.h>

using namespace pcl::console;

/*
 * All functions below are copy/paste from the PCL counterparts
 * because variadic functions don't allow redirecting calls to another
 * variadic function.
 */

void EventLogger::print(const char *format, ...)
{
	va_list stdout_args, file_args;

	//Write message to stdout and file
	va_start(stdout_args, format);
	va_copy(file_args, stdout_args);
	vfprintf(stdout, format, stdout_args);
	vfprintf(log_file_, format, file_args);
	va_end(stdout_args);
	va_end(file_args);
}

void EventLogger::printDebug(const char* module_class, const char* msg)
{
	if(!isVerbosityLevelEnabled(L_DEBUG))
		return;

	change_text_color (stdout, TT_RESET, TT_GREEN);

	print("[%s] DEBUG: %s\n", module_class, msg);
}

void EventLogger::printInfo(const char* module_class, const char* msg)
{
	if(!isVerbosityLevelEnabled(L_INFO))
		return;

	reset_text_color(stdout);

	print("[%s] INFO: %s\n", module_class, msg);
}

void EventLogger::printWarning(const char* module_class, const char* msg)
{
	if(!isVerbosityLevelEnabled(L_WARN))
		return;

	change_text_color(stderr, TT_BRIGHT, TT_YELLOW);

	print("[%s] WARNING: %s\n", module_class, msg);
}

void EventLogger::printError(const char* module_class, const char* msg)
{
	if(!isVerbosityLevelEnabled(L_ERROR))
		return;

	change_text_color(stderr, TT_BRIGHT, TT_RED);

	print("[%s] ERROR: %s\n", module_class, msg);
}<|endoftext|>


<commit_before>/**************************************************************************
 * Copyright(c) 1998-1999, ALICE Experiment at CERN, All rights reserved. *
 *                                                                        *
 * Author: The ALICE Off-line Project.                                    *
 * Contributors are mentioned in the code where appropriate.              *
 *                                                                        *
 * Permission to use, copy, modify and distribute this software and its   *
 * documentation strictly for non-commercial purposes is hereby granted   *
 * without fee, provided that the above copyright notice appears in all   *
 * copies and that both the copyright notice and this permission notice   *
 * appear in the supporting documentation. The authors make no claims     *
 * about the suitability of this software for any purpose. It is          *
 * provided "as is" without express or implied warranty.                  *
 **************************************************************************/

/*

*/
// T0 preprocessor:
// 2) takes data after  pass0 ,
// processes it, and stores either to OCDB .

#include "AliT0PreprocessorOffline.h"
#include "AliT0RecoParam.h"
#include "AliT0CalibTimeEq.h"
#include "AliCDBStorage.h"
#include "AliCDBMetaData.h"
#include "AliCDBManager.h"
#include "AliCTPTimeParams.h"
#include "AliLHCClockPhase.h"
#include "AliT0CalibSeasonTimeShift.h"
#include "AliT0CalibLatency.h"
#include "AliCDBEntry.h"
#include "AliLog.h"

#include <TTimeStamp.h>
#include <TFile.h>
#include <TObjString.h>
#include <TNamed.h>
#include "TClass.h"

ClassImp(AliT0PreprocessorOffline)

//____________________________________________________
AliT0PreprocessorOffline::AliT0PreprocessorOffline():
TNamed("AliT0PreprocessorOffline","AliT0PreprocessorOffline"),
  startRun(0),
  endRun(0),
  startTime(0),
  endTime(0),
  ocdbStorage("")
{
  //constructor
}
//____________________________________________________

AliT0PreprocessorOffline::~AliT0PreprocessorOffline()
{
  //destructor

}
//____________________________________________________
void AliT0PreprocessorOffline::Process(TString filePhysName, Int_t ustartRun, Int_t uendRun, TString pocdbStorage)
{
  CalibOffsetChannels(filePhysName, ustartRun, uendRun, pocdbStorage);
  CalibT0sPosition(filePhysName, ustartRun, uendRun, pocdbStorage);
}
//____________________________________________________

void AliT0PreprocessorOffline::CalibOffsetChannels(TString filePhysName, Int_t ustartRun, Int_t uendRun, TString pocdbStorage)
{

  Float_t zero_timecdb[24]={0};
  Float_t *timecdb = zero_timecdb;
  Float_t *cfdvalue = zero_timecdb;
  Int_t badpmt=0;
  //Processing data from DAQ Physics run
  AliInfo("Processing Time Offset between channels");
  if (pocdbStorage.Length()>0) ocdbStorage=pocdbStorage;
  else
    ocdbStorage="local://"+gSystem->GetFromPipe("pwd")+"/OCDB";
  AliCDBEntry *entry = AliCDBManager::Instance()->Get("GRP/CTP/CTPtiming");
  if (!entry) AliFatal("CTP timing parameters are not found in OCDB !");
  AliCTPTimeParams *ctpParams = (AliCTPTimeParams*)entry->GetObject();
  Float_t l1Delay = (Float_t)ctpParams->GetDelayL1L0()*25.0;

  AliCDBEntry *entry1 = AliCDBManager::Instance()->Get("GRP/CTP/TimeAlign");
  if (!entry1) AliFatal("CTP time-alignment is not found in OCDB !");
  AliCTPTimeParams *ctpTimeAlign = (AliCTPTimeParams*)entry1->GetObject();
  l1Delay += ((Float_t)ctpTimeAlign->GetDelayL1L0()*25.0);

  AliCDBEntry *entry4 = AliCDBManager::Instance()->Get("GRP/Calib/LHCClockPhase");
  if (!entry4) AliFatal("LHC clock-phase shift is not found in OCDB !");
  AliLHCClockPhase *phase = (AliLHCClockPhase*)entry4->GetObject();
  Float_t fGRPdelays = l1Delay - phase->GetMeanPhase();

  AliCDBEntry *entryL = AliCDBManager::Instance()->Get("T0/Calib/Latency");
  if (!entryL) AliFatal(" T0 Latency is not found in OCDB !");
  AliT0CalibLatency *lat = (AliT0CalibLatency*)entryL->GetObject();
  Float_t fLatencyHPTDC = lat->GetLatencyHPTDC();
  Float_t fLatencyL1 = lat->GetLatencyL1();

  AliCDBEntry *entryCalib = AliCDBManager::Instance()->Get("T0/Calib/TimeDelay");
  if(!entryCalib) {
    AliWarning(Form("Cannot find any AliCDBEntry for [Calib, TimeDelay]!"));
  }
  else
    {
      AliT0CalibTimeEq *clb = (AliT0CalibTimeEq*)entryCalib->GetObject();
       timecdb = clb->GetTimeEq();
       cfdvalue = clb->GetCFDvalue();
    }
  //AliCDBEntry *entryCalibreco = AliCDBManager::Instance()->Get("T0/Calib/RecoParam");
  //  if(entryCalibreco) {
  //  AliT0RecoParam *rpr = (AliT0RecoParam*) entryCalibreco->GetObject();
    //    badpmt = rpr->GetRefPoint();
  badpmt = -1;
  // }
  AliT0CalibTimeEq *offline = new AliT0CalibTimeEq();
  Bool_t writeok = offline->ComputeOfflineParams(filePhysName.Data(), timecdb, cfdvalue, badpmt);
  AliCDBMetaData metaData;
  metaData.SetBeamPeriod(1);
  metaData.SetResponsible("Alla Maevskaya");
  metaData.SetComment("Time equalizing result with slew");

  if (writeok)  {
    AliCDBId* id1=NULL;
    id1=new AliCDBId("T0/Calib/TimeDelay", ustartRun, uendRun );
    AliCDBStorage* gStorage = AliCDBManager::Instance()->GetStorage(ocdbStorage);
    gStorage->Put(offline, (*id1), &metaData);
  }
  else {

    AliWarning(Form("writeok = %d data is not OK to be in OCDB",writeok));
      }

  delete offline;

}
//-------------------------------------------------------------------------------------
void AliT0PreprocessorOffline::CalibT0sPosition(TString filePhysName, Int_t ustartRun, Int_t uendRun, TString pocdbStorage)
{
  Float_t zero_timecdb[4]={0};
  Float_t *timecdb = zero_timecdb;
  if (pocdbStorage.Length()>0) ocdbStorage=pocdbStorage;
  else
    ocdbStorage="local://"+gSystem->GetFromPipe("pwd")+"/OCDB";
  AliCDBEntry *entryCalib = AliCDBManager::Instance()->Get("T0/Calib/TimeAdjust");
  if(!entryCalib) {
    AliWarning(Form("Cannot find any AliCDBEntry for [Calib, TimeAdjust]!"));
  }
  else
    {
      AliT0CalibSeasonTimeShift *clb = (AliT0CalibSeasonTimeShift*)entryCalib->GetObject();
      timecdb = clb->GetT0Means();
    }

  AliT0CalibSeasonTimeShift *offline = new AliT0CalibSeasonTimeShift();
  Bool_t writeok = offline->SetT0Par(filePhysName.Data(), timecdb);
  AliCDBMetaData metaData;
  metaData.SetBeamPeriod(1);
  metaData.SetResponsible("Alla Maevskaya");
  metaData.SetComment("Time equalizing result with slew");

  if (writeok)  {
    AliCDBId* id1=NULL;
    id1=new AliCDBId("T0/Calib/TimeAdjust", ustartRun, uendRun);
    AliCDBStorage* gStorage = AliCDBManager::Instance()->GetStorage(ocdbStorage);
    gStorage->Put(offline, (*id1), &metaData);
  }

}
<commit_msg>coverity fixed<commit_after>/**************************************************************************
 * Copyright(c) 1998-1999, ALICE Experiment at CERN, All rights reserved. *
 *                                                                        *
 * Author: The ALICE Off-line Project.                                    *
 * Contributors are mentioned in the code where appropriate.              *
 *                                                                        *
 * Permission to use, copy, modify and distribute this software and its   *
 * documentation strictly for non-commercial purposes is hereby granted   *
 * without fee, provided that the above copyright notice appears in all   *
 * copies and that both the copyright notice and this permission notice   *
 * appear in the supporting documentation. The authors make no claims     *
 * about the suitability of this software for any purpose. It is          *
 * provided "as is" without express or implied warranty.                  *
 **************************************************************************/

/*

*/
// T0 preprocessor:
// 2) takes data after  pass0 ,
// processes it, and stores either to OCDB .

#include "AliT0PreprocessorOffline.h"
#include "AliT0RecoParam.h"
#include "AliT0CalibTimeEq.h"
#include "AliCDBStorage.h"
#include "AliCDBMetaData.h"
#include "AliCDBManager.h"
#include "AliCTPTimeParams.h"
#include "AliLHCClockPhase.h"
#include "AliT0CalibSeasonTimeShift.h"
#include "AliT0CalibLatency.h"
#include "AliCDBEntry.h"
#include "AliLog.h"

#include <TTimeStamp.h>
#include <TFile.h>
#include <TObjString.h>
#include <TNamed.h>
#include "TClass.h"

ClassImp(AliT0PreprocessorOffline)

//____________________________________________________
AliT0PreprocessorOffline::AliT0PreprocessorOffline():
TNamed("AliT0PreprocessorOffline","AliT0PreprocessorOffline"),
  startRun(0),
  endRun(0),
  startTime(0),
  endTime(0),
  ocdbStorage("")
{
  //constructor
}
//____________________________________________________

AliT0PreprocessorOffline::~AliT0PreprocessorOffline()
{
  //destructor

}
//____________________________________________________
void AliT0PreprocessorOffline::Process(TString filePhysName, Int_t ustartRun, Int_t uendRun, TString pocdbStorage)
{
  CalibOffsetChannels(filePhysName, ustartRun, uendRun, pocdbStorage);
  CalibT0sPosition(filePhysName, ustartRun, uendRun, pocdbStorage);
}
//____________________________________________________

void AliT0PreprocessorOffline::CalibOffsetChannels(TString filePhysName, Int_t ustartRun, Int_t uendRun, TString pocdbStorage)
{

  Float_t zero_timecdb[24]={0};
  Float_t *timecdb = zero_timecdb;
  Float_t *cfdvalue = zero_timecdb;
  Int_t badpmt=0;
  //Processing data from DAQ Physics run
  AliInfo("Processing Time Offset between channels");
  if (pocdbStorage.Length()>0) ocdbStorage=pocdbStorage;
  else
    ocdbStorage="local://"+gSystem->GetFromPipe("pwd")+"/OCDB";

  AliCDBEntry *entryCalib = AliCDBManager::Instance()->Get("T0/Calib/TimeDelay");
  if(!entryCalib) {
    AliWarning(Form("Cannot find any AliCDBEntry for [Calib, TimeDelay]!"));
  }
  else
    {
      AliT0CalibTimeEq *clb = (AliT0CalibTimeEq*)entryCalib->GetObject();
       timecdb = clb->GetTimeEq();
       cfdvalue = clb->GetCFDvalue();
    }
  //AliCDBEntry *entryCalibreco = AliCDBManager::Instance()->Get("T0/Calib/RecoParam");
  //  if(entryCalibreco) {
  //  AliT0RecoParam *rpr = (AliT0RecoParam*) entryCalibreco->GetObject();
    //    badpmt = rpr->GetRefPoint();
  badpmt = -1;
  // }
  AliT0CalibTimeEq *offline = new AliT0CalibTimeEq();
  Bool_t writeok = offline->ComputeOfflineParams(filePhysName.Data(), timecdb, cfdvalue, badpmt);
  AliCDBMetaData metaData;
  metaData.SetBeamPeriod(1);
  metaData.SetResponsible("Alla Maevskaya");
  metaData.SetComment("Time equalizing result with slew");

  if (writeok)  {
    AliCDBId* id1=NULL;
    id1=new AliCDBId("T0/Calib/TimeDelay", ustartRun, uendRun );
    AliCDBStorage* gStorage = AliCDBManager::Instance()->GetStorage(ocdbStorage);
    gStorage->Put(offline, (*id1), &metaData);
  }
  else {

    AliWarning(Form("writeok = %d data is not OK to be in OCDB",writeok));
      }

  delete offline;

}
//-------------------------------------------------------------------------------------
void AliT0PreprocessorOffline::CalibT0sPosition(TString filePhysName, Int_t ustartRun, Int_t uendRun, TString pocdbStorage)
{
  Float_t zero_timecdb[4]={0};
  Float_t *timecdb = zero_timecdb;
  if (pocdbStorage.Length()>0) ocdbStorage=pocdbStorage;
  else
    ocdbStorage="local://"+gSystem->GetFromPipe("pwd")+"/OCDB";
  AliCDBEntry *entryCalib = AliCDBManager::Instance()->Get("T0/Calib/TimeAdjust");
  if(!entryCalib) {
    AliWarning(Form("Cannot find any AliCDBEntry for [Calib, TimeAdjust]!"));
  }
  else
    {
      AliT0CalibSeasonTimeShift *clb = (AliT0CalibSeasonTimeShift*)entryCalib->GetObject();
      timecdb = clb->GetT0Means();
    }

  AliT0CalibSeasonTimeShift *offline = new AliT0CalibSeasonTimeShift();
  Bool_t writeok = offline->SetT0Par(filePhysName.Data(), timecdb);
  AliCDBMetaData metaData;
  metaData.SetBeamPeriod(1);
  metaData.SetResponsible("Alla Maevskaya");
  metaData.SetComment("Time equalizing result with slew");

  if (writeok)  {
    AliCDBId* id1=NULL;
    id1=new AliCDBId("T0/Calib/TimeAdjust", ustartRun, uendRun);
    AliCDBStorage* gStorage = AliCDBManager::Instance()->GetStorage(ocdbStorage);
    gStorage->Put(offline, (*id1), &metaData);
  }

}
<|endoftext|>


<commit_before>// Copyright (c) 2011 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include "chrome/browser/ui/gtk/html_dialog_gtk.h"

#include <gtk/gtk.h>

#include "base/utf_string_conversions.h"
#include "chrome/browser/ui/browser.h"
#include "chrome/browser/ui/browser_dialogs.h"
#include "chrome/browser/ui/browser_window.h"
#include "chrome/browser/ui/gtk/gtk_util.h"
#include "chrome/browser/ui/gtk/tab_contents_container_gtk.h"
#include "chrome/browser/ui/tab_contents/tab_contents_wrapper.h"
#include "chrome/browser/ui/webui/html_dialog_ui.h"
#include "content/browser/tab_contents/tab_contents.h"
#include "content/common/native_web_keyboard_event.h"

namespace browser {

gfx::NativeWindow ShowHtmlDialog(gfx::NativeWindow parent, Profile* profile,
                                 HtmlDialogUIDelegate* delegate) {
  HtmlDialogGtk* html_dialog =
      new HtmlDialogGtk(profile, delegate, parent);
  return html_dialog->InitDialog();
}

} // namespace browser

////////////////////////////////////////////////////////////////////////////////
// HtmlDialogGtk, public:

HtmlDialogGtk::HtmlDialogGtk(Profile* profile,
                             HtmlDialogUIDelegate* delegate,
                             gfx::NativeWindow parent_window)
    : HtmlDialogTabContentsDelegate(profile),
      delegate_(delegate),
      parent_window_(parent_window),
      dialog_(NULL) {
}

HtmlDialogGtk::~HtmlDialogGtk() {
}

////////////////////////////////////////////////////////////////////////////////
// HtmlDialogUIDelegate implementation:

bool HtmlDialogGtk::IsDialogModal() const {
  return delegate_ ? delegate_->IsDialogModal() : false;
}

std::wstring HtmlDialogGtk::GetDialogTitle() const {
  return delegate_ ? delegate_->GetDialogTitle() : L"";
}

GURL HtmlDialogGtk::GetDialogContentURL() const {
  if (delegate_)
    return delegate_->GetDialogContentURL();
  else
    return GURL();
}

void HtmlDialogGtk::GetWebUIMessageHandlers(
    std::vector<WebUIMessageHandler*>* handlers) const {
  if (delegate_)
    delegate_->GetWebUIMessageHandlers(handlers);
  else
    handlers->clear();
}

void HtmlDialogGtk::GetDialogSize(gfx::Size* size) const {
  if (delegate_)
    delegate_->GetDialogSize(size);
  else
    *size = gfx::Size();
}

std::string HtmlDialogGtk::GetDialogArgs() const {
  if (delegate_)
    return delegate_->GetDialogArgs();
  else
    return std::string();
}

void HtmlDialogGtk::OnDialogClosed(const std::string& json_retval) {
  DCHECK(dialog_);

  Detach();
  if (delegate_) {
    HtmlDialogUIDelegate* dialog_delegate = delegate_;
    delegate_ = NULL;  // We will not communicate further with the delegate.
    dialog_delegate->OnDialogClosed(json_retval);
  }
  gtk_widget_destroy(dialog_);
  delete this;
}

bool HtmlDialogGtk::ShouldShowDialogTitle() const {
  return true;
}

////////////////////////////////////////////////////////////////////////////////
// TabContentsDelegate implementation:

// A simplified version of BrowserWindowGtk::HandleKeyboardEvent().
// We don't handle global keyboard shortcuts here, but that's fine since
// they're all browser-specific. (This may change in the future.)
void HtmlDialogGtk::HandleKeyboardEvent(const NativeWebKeyboardEvent& event) {
  GdkEventKey* os_event = event.os_event;
  if (!os_event || event.type == WebKit::WebInputEvent::Char)
    return;

  // To make sure the default key bindings can still work, such as Escape to
  // close the dialog.
  gtk_bindings_activate_event(GTK_OBJECT(dialog_), os_event);
}

////////////////////////////////////////////////////////////////////////////////
// HtmlDialogGtk:

gfx::NativeWindow HtmlDialogGtk::InitDialog() {
  tab_.reset(new TabContentsWrapper(
      new TabContents(profile(), NULL, MSG_ROUTING_NONE, NULL, NULL)));
  tab_->tab_contents()->set_delegate(this);

  // This must be done before loading the page; see the comments in
  // HtmlDialogUI.
  HtmlDialogUI::GetPropertyAccessor().SetProperty(
      tab_->tab_contents()->property_bag(), this);

  tab_->controller().LoadURL(GetDialogContentURL(),
                             GURL(), PageTransition::START_PAGE);
  GtkDialogFlags flags = GTK_DIALOG_NO_SEPARATOR;
  if (delegate_->IsDialogModal())
    flags = static_cast<GtkDialogFlags>(flags | GTK_DIALOG_MODAL);

  dialog_ = gtk_dialog_new_with_buttons(
      WideToUTF8(delegate_->GetDialogTitle()).c_str(),
      parent_window_,
      flags,
      NULL);

  g_signal_connect(dialog_, "response", G_CALLBACK(OnResponseThunk), this);

  tab_contents_container_.reset(new TabContentsContainerGtk(NULL));
  gtk_box_pack_start(GTK_BOX(GTK_DIALOG(dialog_)->vbox),
                     tab_contents_container_->widget(), TRUE, TRUE, 0);

  tab_contents_container_->SetTab(tab_.get());

  gfx::Size dialog_size;
  delegate_->GetDialogSize(&dialog_size);

  gtk_widget_set_size_request(GTK_WIDGET(tab_contents_container_->widget()),
                              dialog_size.width(),
                              dialog_size.height());

  gtk_widget_show_all(dialog_);

  return GTK_WINDOW(dialog_);
}

void HtmlDialogGtk::OnResponse(GtkWidget* dialog, int response_id) {
  OnDialogClosed(std::string());
}
<commit_msg>Remove extra spacing around html content to maximize WebUI real estate.<commit_after>// Copyright (c) 2011 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include "chrome/browser/ui/gtk/html_dialog_gtk.h"

#include <gtk/gtk.h>

#include "base/utf_string_conversions.h"
#include "chrome/browser/ui/browser.h"
#include "chrome/browser/ui/browser_dialogs.h"
#include "chrome/browser/ui/browser_window.h"
#include "chrome/browser/ui/gtk/gtk_util.h"
#include "chrome/browser/ui/gtk/tab_contents_container_gtk.h"
#include "chrome/browser/ui/tab_contents/tab_contents_wrapper.h"
#include "chrome/browser/ui/webui/html_dialog_ui.h"
#include "content/browser/tab_contents/tab_contents.h"
#include "content/common/native_web_keyboard_event.h"

namespace browser {

gfx::NativeWindow ShowHtmlDialog(gfx::NativeWindow parent, Profile* profile,
                                 HtmlDialogUIDelegate* delegate) {
  HtmlDialogGtk* html_dialog =
      new HtmlDialogGtk(profile, delegate, parent);
  return html_dialog->InitDialog();
}

} // namespace browser

namespace {

void SetDialogStyle() {
  static bool style_was_set = false;

  if (style_was_set)
    return;
  style_was_set = true;

  gtk_rc_parse_string(
      "style \"chrome-html-dialog\" {\n"
      "  GtkDialog::action-area-border = 0\n"
      "  GtkDialog::content-area-border = 0\n"
      "  GtkDialog::content-area-spacing = 0\n"
      "}\n"
      "widget \"*chrome-html-dialog\" style \"chrome-html-dialog\"");
}

}  // namespace

////////////////////////////////////////////////////////////////////////////////
// HtmlDialogGtk, public:

HtmlDialogGtk::HtmlDialogGtk(Profile* profile,
                             HtmlDialogUIDelegate* delegate,
                             gfx::NativeWindow parent_window)
    : HtmlDialogTabContentsDelegate(profile),
      delegate_(delegate),
      parent_window_(parent_window),
      dialog_(NULL) {
}

HtmlDialogGtk::~HtmlDialogGtk() {
}

////////////////////////////////////////////////////////////////////////////////
// HtmlDialogUIDelegate implementation:

bool HtmlDialogGtk::IsDialogModal() const {
  return delegate_ ? delegate_->IsDialogModal() : false;
}

std::wstring HtmlDialogGtk::GetDialogTitle() const {
  return delegate_ ? delegate_->GetDialogTitle() : L"";
}

GURL HtmlDialogGtk::GetDialogContentURL() const {
  if (delegate_)
    return delegate_->GetDialogContentURL();
  else
    return GURL();
}

void HtmlDialogGtk::GetWebUIMessageHandlers(
    std::vector<WebUIMessageHandler*>* handlers) const {
  if (delegate_)
    delegate_->GetWebUIMessageHandlers(handlers);
  else
    handlers->clear();
}

void HtmlDialogGtk::GetDialogSize(gfx::Size* size) const {
  if (delegate_)
    delegate_->GetDialogSize(size);
  else
    *size = gfx::Size();
}

std::string HtmlDialogGtk::GetDialogArgs() const {
  if (delegate_)
    return delegate_->GetDialogArgs();
  else
    return std::string();
}

void HtmlDialogGtk::OnDialogClosed(const std::string& json_retval) {
  DCHECK(dialog_);

  Detach();
  if (delegate_) {
    HtmlDialogUIDelegate* dialog_delegate = delegate_;
    delegate_ = NULL;  // We will not communicate further with the delegate.
    dialog_delegate->OnDialogClosed(json_retval);
  }
  gtk_widget_destroy(dialog_);
  delete this;
}

bool HtmlDialogGtk::ShouldShowDialogTitle() const {
  return true;
}

////////////////////////////////////////////////////////////////////////////////
// TabContentsDelegate implementation:

// A simplified version of BrowserWindowGtk::HandleKeyboardEvent().
// We don't handle global keyboard shortcuts here, but that's fine since
// they're all browser-specific. (This may change in the future.)
void HtmlDialogGtk::HandleKeyboardEvent(const NativeWebKeyboardEvent& event) {
  GdkEventKey* os_event = event.os_event;
  if (!os_event || event.type == WebKit::WebInputEvent::Char)
    return;

  // To make sure the default key bindings can still work, such as Escape to
  // close the dialog.
  gtk_bindings_activate_event(GTK_OBJECT(dialog_), os_event);
}

////////////////////////////////////////////////////////////////////////////////
// HtmlDialogGtk:

gfx::NativeWindow HtmlDialogGtk::InitDialog() {
  tab_.reset(new TabContentsWrapper(
      new TabContents(profile(), NULL, MSG_ROUTING_NONE, NULL, NULL)));
  tab_->tab_contents()->set_delegate(this);

  // This must be done before loading the page; see the comments in
  // HtmlDialogUI.
  HtmlDialogUI::GetPropertyAccessor().SetProperty(
      tab_->tab_contents()->property_bag(), this);

  tab_->controller().LoadURL(GetDialogContentURL(),
                             GURL(), PageTransition::START_PAGE);
  GtkDialogFlags flags = GTK_DIALOG_NO_SEPARATOR;
  if (delegate_->IsDialogModal())
    flags = static_cast<GtkDialogFlags>(flags | GTK_DIALOG_MODAL);

  dialog_ = gtk_dialog_new_with_buttons(
      WideToUTF8(delegate_->GetDialogTitle()).c_str(),
      parent_window_,
      flags,
      NULL);

  SetDialogStyle();
  gtk_widget_set_name(dialog_, "chrome-html-dialog");
  g_signal_connect(dialog_, "response", G_CALLBACK(OnResponseThunk), this);

  tab_contents_container_.reset(new TabContentsContainerGtk(NULL));
  gtk_box_pack_start(GTK_BOX(GTK_DIALOG(dialog_)->vbox),
                     tab_contents_container_->widget(), TRUE, TRUE, 0);

  tab_contents_container_->SetTab(tab_.get());

  gfx::Size dialog_size;
  delegate_->GetDialogSize(&dialog_size);

  gtk_widget_set_size_request(GTK_WIDGET(tab_contents_container_->widget()),
                              dialog_size.width(),
                              dialog_size.height());

  gtk_widget_show_all(dialog_);

  return GTK_WINDOW(dialog_);
}

void HtmlDialogGtk::OnResponse(GtkWidget* dialog, int response_id) {
  OnDialogClosed(std::string());
}
<|endoftext|>


<commit_before>////////////////////////////////////////////////////////////////////////////////
/// @brief a basis class which defines the methods for determining
///        when an input is "complete"
///
/// @file
///
/// DISCLAIMER
///
/// Copyright 2014 ArangoDB GmbH, Cologne, Germany
/// Copyright 2004-2014 triAGENS GmbH, Cologne, Germany
///
/// 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.
///
/// Copyright holder is ArangoDB GmbH, Cologne, Germany
///
/// @author Esteban Lombeyda
/// @author Copyright 2014, ArangoDB GmbH, Cologne, Germany
/// @author Copyright 2011-2014, triAGENS GmbH, Cologne, Germany
////////////////////////////////////////////////////////////////////////////////

#ifdef _WIN32
#include "LinenoiseShell.h"
#elif TRI_HAVE_LINENOISE
#include "LinenoiseShell.h"
#elif TRI_HAVE_READLINE
#include "ReadlineShell.h"
#else
#include "DummyShell.h"
#endif

#include "ShellImplFactory.h"

using namespace triagens;
using namespace std;

ShellImplementation* ShellImplFactory::buildShell (string const & history,
                                                   Completer* completer) {

#ifdef _WIN32
  //under windows the readline is not compilable
  return new LinenoiseShell(history, completer);
#elif defined TRI_HAVE_LINENOISE
  return new LinenoiseShell(history, completer);
#elif defined TRI_HAVE_READLINE
  return new ReadlineShell(history, completer);
#else
  // last resort!
  return new DummyShell(history, completer);
#endif

}

// -----------------------------------------------------------------------------
// --SECTION--                                                       END-OF-FILE
// -----------------------------------------------------------------------------

// Local Variables:
// mode: outline-minor
// outline-regexp: "/// @brief\\|/// {@inheritDoc}\\|/// @page\\|// --SECTION--\\|/// @\\}"
// End:
<commit_msg>readline vs. linenoise vs. dummyshell: next try<commit_after>////////////////////////////////////////////////////////////////////////////////
/// @brief a basis class which defines the methods for determining
///        when an input is "complete"
///
/// @file
///
/// DISCLAIMER
///
/// Copyright 2014 ArangoDB GmbH, Cologne, Germany
/// Copyright 2004-2014 triAGENS GmbH, Cologne, Germany
///
/// 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.
///
/// Copyright holder is ArangoDB GmbH, Cologne, Germany
///
/// @author Esteban Lombeyda
/// @author Copyright 2014, ArangoDB GmbH, Cologne, Germany
/// @author Copyright 2011-2014, triAGENS GmbH, Cologne, Germany
////////////////////////////////////////////////////////////////////////////////

#ifdef _WIN32
#include "LinenoiseShell.h"
#elif defined TRI_HAVE_LINENOISE
#include "LinenoiseShell.h"
#elif defined TRI_HAVE_READLINE
#include "ReadlineShell.h"
#else
#include "DummyShell.h"
#endif

#include "ShellImplFactory.h"

using namespace triagens;
using namespace std;

ShellImplementation* ShellImplFactory::buildShell (string const & history,
                                                   Completer* completer) {

#ifdef _WIN32
  //under windows the readline is not compilable
  return new LinenoiseShell(history, completer);
#elif defined TRI_HAVE_LINENOISE
  return new LinenoiseShell(history, completer);
#elif defined TRI_HAVE_READLINE
  return new ReadlineShell(history, completer);
#else
  // last resort!
  return new DummyShell(history, completer);
#endif

}

// -----------------------------------------------------------------------------
// --SECTION--                                                       END-OF-FILE
// -----------------------------------------------------------------------------

// Local Variables:
// mode: outline-minor
// outline-regexp: "/// @brief\\|/// {@inheritDoc}\\|/// @page\\|// --SECTION--\\|/// @\\}"
// End:
<|endoftext|>