<commit_before>#ifndef MUNCHAR
#define MUNCHAR

#include <cstddef>

namespace Munchar {

  // Unconditional success

  struct Success {
    const char* operator()(const char* b, const char* e) const {
      return b;
    }
    const char* operator()(const char* b) const {
      return b;
    }
  };

  // Unconditional failure

  struct Failure {
    const char* operator()(const char* b, const char* e) const {
      return nullptr;
    }
    const char* operator()(const char* b) const {
      return nullptr;
    }
  };

  // Arbitrary character

  struct Any_Char {
    const char* operator()(const char* b, const char* e) const {
      return b < e ? b+1 : nullptr;
    }
    const char* operator()(const char* b) const {
      return *b ? b+1 : nullptr;
    }
  };

  // Character constant

  class Char {
    const char c_;
  public:
    constexpr Char(const char c) : c_(c) { }
    const char* operator()(const char* b, const char* e) const {
      return b < e && *b == c_ ? b+1 : nullptr;
    }
    const char* operator()(const char* b) const {
      return *b && *b == c_ ? b+1 : nullptr;
    }
  };

  constexpr Char operator"" _lit(const char c) {
    return Char { c };
  }

  constexpr Char CHR(const char c) {
    return Char { c };
  }

  // String constant

  template<typename Ptr = const char*, bool with_len = true>
  class Str {
    Ptr s_;
    size_t len_;
  public:
    constexpr Str(const Ptr& s, size_t len) : s_(s), len_(len) { }
    const char* operator()(const char* b, const char* e) const {
      Ptr s = s_;
      for (size_t i = 0; i < len_; ++i, ++b, ++s) {
        if (!(b < e) || (*s != *b)) return nullptr;
      }
      return b;
    }
    const char* operator()(const char* b) const {
      Ptr s = s_;
      for (size_t i = 0; i < len_; ++i, ++b, ++s) {
        if (!*b || (*s != *b)) return nullptr;
      }
      return b;
    }
  };

  template<typename Ptr>
  class Str<Ptr, false> {
    Ptr s_;
  public:
    constexpr Str(const Ptr& s) : s_(s) { }
    const char* operator()(const char* b, const char* e) const {
      Ptr s = s_;
      for (Ptr s = s_; *s; ++s) if (!(b < e) || (*s != *b)) return nullptr;
      return b;
    }
    const char* operator()(const char* b) const {
      Ptr s = s_;
      for (Ptr s = s_; *s; ++s) if (!*b || (*s != *b)) return nullptr;
      return b;
    }
  };

  constexpr Str<> operator"" _lit(const char* c, size_t len) {
    return Str<> { c, len };
  }

  template<typename Ptr>
  constexpr Str<Ptr, true> STR(const Ptr& s, size_t len) {
    return Str<Ptr, true> { s, len };
  }

  template<typename Ptr>
  constexpr Str<Ptr, false> STR(const Ptr& s) {
    return Str<Ptr, false> { s };
  }

  // Character class

  template<typename Ptr = const char*, bool with_len = true>
  class Char_Class {
    Ptr s_;
    size_t len_;
  public:
    constexpr Char_Class(const Ptr& s, size_t len) : s_(s), len_(len) { }
    const char* operator()(const char* b, const char* e) const {
      if (!(b < e)) return nullptr;
      Ptr s = s_;
      for (size_t i = 0; i < len_; ++i, ++s) if (*s == *b) return b+1;
      return nullptr;
    }
    const char* operator()(const char* b) const {
      if (!*b) return nullptr;
      Ptr s = s_;
      for (size_t i = 0; i < len_; ++i, ++s) if (*s == *b) return b+1;
      return nullptr;
    }
  };

  template<typename Ptr>
  class Char_Class<Ptr, false> {
    Ptr s_;
  public:
    constexpr Char_Class(const Ptr& s) : s_(s) { }
    const char* operator()(const char* b, const char* e) const {
      if (!(b < e)) return nullptr;
      for (Ptr s = s_; *s; ++s) if (*s == *b) return b+1;
      return nullptr;
    }
    const char* operator()(const char* b) const {
      if (!*b) return nullptr;
      for (Ptr s = s_; *s; ++s) if (*s == *b) return b+1;
      return nullptr;
    }
  };

  constexpr Char_Class<> operator"" _cls(const char* c, size_t len) {
    return Char_Class<> { c, len };
  }

  template<typename Ptr>
  constexpr Char_Class<Ptr, true> CLS(const Ptr& s, size_t len) {
    return Char_Class<Ptr, true> { s, len };
  }

  template<typename Ptr>
  constexpr Char_Class<Ptr, false> CLS(const Ptr& s) {
    return Char_Class<Ptr, false> { s };
  }

  // Predicate

  template<typename I, typename O, bool is_static = false>
  class Predicate {
    O (*const p_)(I);
  public:
    constexpr Predicate(O(p)(I)) : p_(p) { }
    const char* operator()(const char* b, const char* e) const {
      return (b < e) && p_(*b) ? b+1 : nullptr;
    }
    const char* operator()(const char* b) const {
      return *b && p_(*b) ? b+1 : nullptr;
    }
  };

  template<typename I, typename O>
  class Predicate<I, O, true> {
    template<O(p_)(I)>
    struct Static {
      const char* operator()(const char* b, const char* e) const {
        return (b < e) && p_(*b) ? b+1 : nullptr;
      }
      const char* operator()(const char* b) const {
        return *b && p_(*b) ? b+1 : nullptr;
      }
    };
  public:
    template<O(p)(I)>
    constexpr Static<p> instantiate() const {
      return Static<p> { };
    }
  };

  template<typename I, typename O>
  constexpr Predicate<I, O> P(O (p)(I)) {
    return Predicate<I, O> { p };
  }

  template<typename I, typename O>
  constexpr auto infer_predicate_signature(O (p)(I))
  -> decltype(Predicate<I, O, true> { }) {
    return Predicate<I, O, true> { };
  }

  #define MUNCHAR_STATIC_PREDICATE(p)\
  (infer_predicate_signature(p).instantiate<p>())

  // // Wrapper for functions that implement the Munchar interface

  // template<typename F>
  // class Function {
  //   F f_;
  // public:
  //   constexpr Function(const F& f) : f_(f) { }
  //   const char* operator()(const char* b, const char* e) const {
  //     return f_(b, e);
  //   }
  //   const char* operator()(const char* b) const {
  //     return f_(b);
  //   }
  // };

  // template<typename Fn>
  // constexpr Function<Fn> F(Fn f) {
  //   return Function<Fn> { f };
  // }

  // Base class for unary combinators

  template<typename M>
  class Unary {
  protected:
    const M m_;
  public:
    constexpr Unary(const M& m) : m_(m) { }
  };

  // Base class for binary combinators

  template<typename L, typename R>
  class Binary {
  protected:
    const L l_;
    const R r_;
  public:
    constexpr Binary(const L& l, const R& r) : l_(l), r_(r) { }
  };

  // Sequencing

  template<typename L, typename R>
  class Sequence : public Binary<L, R> {
  public:
    using Binary<L, R>::Binary;
    const char* operator()(const char* b, const char* e) const {
      return (b = this->l_(b, e)) ? this->r_(b, e) : nullptr;
    }
    const char* operator()(const char* b) const {
      return (b = this->l_(b)) ? this->r_(b) : nullptr;
    }
  };

  template<typename L, typename R>
  constexpr Sequence<L, R> operator^(const L& l, const R& r) {
    return Sequence<L, R> { l, r };
  }

  // Alternation

  template<typename L, typename R>
  class Alternation : public Binary<L, R> {
  public:
    using Binary<L, R>::Binary;
    const char* operator()(const char* b, const char* e) const {
      const char* p = this->l_(b);
      return p ? p : this->r_(b, e);
    }
    const char* operator()(const char* b) const {
      const char* p = this->l_(b);
      return p ? p : this->r_(b);
    }
  };

  template<typename L, typename R>
  constexpr Alternation<L, R> operator|(const L& l, const R& r) {
    return Alternation<L, R> { l, r };
  }

  // Option

  template<typename M>
  constexpr auto operator~(const M& m)
  -> decltype(m | Success { }) {
    return m | Success { };
  }

  // Repetition

  template<typename M>
  class Zero_Or_More : public Unary<M> {
  public:
    using Unary<M>::Unary;
    const char* operator()(const char* b, const char* e) const {
      for (const char* p = b; (p = this->m_(b, e)); b = p) ;
      return b;
    }
    const char* operator()(const char* b) const {
      for (const char* p = b; (p = this->m_(b)); b = p) ;
      return b;
    }
  };

  template<typename M>
  constexpr Zero_Or_More<M> operator*(const M& m) {
    return Zero_Or_More<M> { m };
  }

  template<typename M>
  constexpr auto operator+(const M& m)
  -> decltype(m ^ *m) {
    return m ^ *m;
  }

  // Bounded repetition

  template<typename M>
  class Exactly_N_Times : public Unary<M> {
    size_t n_;
  public:
    constexpr Exactly_N_Times(const M& m, size_t n) : Unary<M> { m }, n_(n) { }
    const char* operator()(const char* b, const char* e) const {
      size_t i;
      for (i = 0; i < n_ && (b = this->m_(b, e)); ++i) ;
      return i == n_ ? b : nullptr;
    }
    const char* operator()(const char* b) const {
      size_t i;
      for (i = 0; i < n_ && (b = this->m_(b)); ++i) ;
      return i == n_ ? b : nullptr;
    }
  };

  template<typename M>
  constexpr Exactly_N_Times<M> operator==(const M& m,  size_t n) {
    return Exactly_N_Times<M> { m, n };
  }

  template<typename M>
  constexpr auto operator>(const M& m,  size_t n)
  -> decltype((m == n) ^ +m) {
    return (m == n) ^ +m;
  }

  template<typename M>
  constexpr auto operator>=(const M& m,  size_t n)
  -> decltype((m == n) ^ *m) {
    return (m == n) ^ *m;
  }

  template<typename M>
  constexpr auto operator<(const M& m,  size_t n)
  -> decltype((m == n-1) | *m) {
    return (m == n-1) | *m;
  }

  template<typename M>
  constexpr auto operator<=(const M& m,  size_t n)
  -> decltype((m == n) | *m) {
    return (m == n) | *m;
  }

  template<typename M>
  constexpr auto between(size_t a, size_t b, const M& m)
  -> decltype((m == b) | (m >= a)) {
    return (a < b) ? (m == b) | (m >= a) : (m == a) | (m >= b);
  }

  // Negation

  template<typename M>
  class Negation : Unary<M> {
  public:
    using Unary<M>::Unary;
    const char* operator()(const char* b, const char* e) const {
      return this->m_(b, e) ? nullptr : b;
    }
    const char* operator()(const char* b) const {
      return this->m_(b) ? nullptr : b;
    }
  };

  template<typename M>
  constexpr Negation<M> operator!(const M& m) {
    return Negation<M> { m };
  }

  // Lookahead

  template<typename M>
  class Lookahead : Unary<M> {
  public:
    using Unary<M>::Unary;
    const char* operator()(const char* b, const char* e) const {
      return this->m_(b, e) ? b : nullptr;
    }
    const char* operator()(const char* b) const {
      return this->m_(b) ? b : nullptr;
    }
  };

  template<typename M>
  constexpr Lookahead<M> operator&(const M& m) {
    return Lookahead<M> { m };
  }

}

#endif<commit_msg>removing this decltype because clang doesn't like it<commit_after>#ifndef MUNCHAR
#define MUNCHAR

#include <cstddef>

namespace Munchar {

  // Unconditional success

  struct Success {
    const char* operator()(const char* b, const char* e) const {
      return b;
    }
    const char* operator()(const char* b) const {
      return b;
    }
  };

  // Unconditional failure

  struct Failure {
    const char* operator()(const char* b, const char* e) const {
      return nullptr;
    }
    const char* operator()(const char* b) const {
      return nullptr;
    }
  };

  // Arbitrary character

  struct Any_Char {
    const char* operator()(const char* b, const char* e) const {
      return b < e ? b+1 : nullptr;
    }
    const char* operator()(const char* b) const {
      return *b ? b+1 : nullptr;
    }
  };

  // Character constant

  class Char {
    const char c_;
  public:
    constexpr Char(const char c) : c_(c) { }
    const char* operator()(const char* b, const char* e) const {
      return b < e && *b == c_ ? b+1 : nullptr;
    }
    const char* operator()(const char* b) const {
      return *b && *b == c_ ? b+1 : nullptr;
    }
  };

  constexpr Char operator"" _lit(const char c) {
    return Char { c };
  }

  constexpr Char CHR(const char c) {
    return Char { c };
  }

  // String constant

  template<typename Ptr = const char*, bool with_len = true>
  class Str {
    Ptr s_;
    size_t len_;
  public:
    constexpr Str(const Ptr& s, size_t len) : s_(s), len_(len) { }
    const char* operator()(const char* b, const char* e) const {
      Ptr s = s_;
      for (size_t i = 0; i < len_; ++i, ++b, ++s) {
        if (!(b < e) || (*s != *b)) return nullptr;
      }
      return b;
    }
    const char* operator()(const char* b) const {
      Ptr s = s_;
      for (size_t i = 0; i < len_; ++i, ++b, ++s) {
        if (!*b || (*s != *b)) return nullptr;
      }
      return b;
    }
  };

  template<typename Ptr>
  class Str<Ptr, false> {
    Ptr s_;
  public:
    constexpr Str(const Ptr& s) : s_(s) { }
    const char* operator()(const char* b, const char* e) const {
      Ptr s = s_;
      for (Ptr s = s_; *s; ++s) if (!(b < e) || (*s != *b)) return nullptr;
      return b;
    }
    const char* operator()(const char* b) const {
      Ptr s = s_;
      for (Ptr s = s_; *s; ++s) if (!*b || (*s != *b)) return nullptr;
      return b;
    }
  };

  constexpr Str<> operator"" _lit(const char* c, size_t len) {
    return Str<> { c, len };
  }

  template<typename Ptr>
  constexpr Str<Ptr, true> STR(const Ptr& s, size_t len) {
    return Str<Ptr, true> { s, len };
  }

  template<typename Ptr>
  constexpr Str<Ptr, false> STR(const Ptr& s) {
    return Str<Ptr, false> { s };
  }

  // Character class

  template<typename Ptr = const char*, bool with_len = true>
  class Char_Class {
    Ptr s_;
    size_t len_;
  public:
    constexpr Char_Class(const Ptr& s, size_t len) : s_(s), len_(len) { }
    const char* operator()(const char* b, const char* e) const {
      if (!(b < e)) return nullptr;
      Ptr s = s_;
      for (size_t i = 0; i < len_; ++i, ++s) if (*s == *b) return b+1;
      return nullptr;
    }
    const char* operator()(const char* b) const {
      if (!*b) return nullptr;
      Ptr s = s_;
      for (size_t i = 0; i < len_; ++i, ++s) if (*s == *b) return b+1;
      return nullptr;
    }
  };

  template<typename Ptr>
  class Char_Class<Ptr, false> {
    Ptr s_;
  public:
    constexpr Char_Class(const Ptr& s) : s_(s) { }
    const char* operator()(const char* b, const char* e) const {
      if (!(b < e)) return nullptr;
      for (Ptr s = s_; *s; ++s) if (*s == *b) return b+1;
      return nullptr;
    }
    const char* operator()(const char* b) const {
      if (!*b) return nullptr;
      for (Ptr s = s_; *s; ++s) if (*s == *b) return b+1;
      return nullptr;
    }
  };

  constexpr Char_Class<> operator"" _cls(const char* c, size_t len) {
    return Char_Class<> { c, len };
  }

  template<typename Ptr>
  constexpr Char_Class<Ptr, true> CLS(const Ptr& s, size_t len) {
    return Char_Class<Ptr, true> { s, len };
  }

  template<typename Ptr>
  constexpr Char_Class<Ptr, false> CLS(const Ptr& s) {
    return Char_Class<Ptr, false> { s };
  }

  // Predicate

  template<typename I, typename O, bool is_static = false>
  class Predicate {
    O (*const p_)(I);
  public:
    constexpr Predicate(O(p)(I)) : p_(p) { }
    const char* operator()(const char* b, const char* e) const {
      return (b < e) && p_(*b) ? b+1 : nullptr;
    }
    const char* operator()(const char* b) const {
      return *b && p_(*b) ? b+1 : nullptr;
    }
  };

  template<typename I, typename O>
  class Predicate<I, O, true> {
    template<O(p_)(I)>
    struct Static {
      const char* operator()(const char* b, const char* e) const {
        return (b < e) && p_(*b) ? b+1 : nullptr;
      }
      const char* operator()(const char* b) const {
        return *b && p_(*b) ? b+1 : nullptr;
      }
    };
  public:
    template<O(p)(I)>
    constexpr Static<p> instantiate() const {
      return Static<p> { };
    }
  };

  template<typename I, typename O>
  constexpr Predicate<I, O> P(O (p)(I)) {
    return Predicate<I, O> { p };
  }

  template<typename I, typename O>
  constexpr auto infer_predicate_signature(O (p)(I))
  -> decltype(Predicate<I, O, true> { }) {
    return Predicate<I, O, true> { };
  }

  #define MUNCHAR_STATIC_PREDICATE(p)\
  (infer_predicate_signature(p).instantiate<p>())

  // // Wrapper for functions that implement the Munchar interface

  // template<typename F>
  // class Function {
  //   F f_;
  // public:
  //   constexpr Function(const F& f) : f_(f) { }
  //   const char* operator()(const char* b, const char* e) const {
  //     return f_(b, e);
  //   }
  //   const char* operator()(const char* b) const {
  //     return f_(b);
  //   }
  // };

  // template<typename Fn>
  // constexpr Function<Fn> F(Fn f) {
  //   return Function<Fn> { f };
  // }

  // Base class for unary combinators

  template<typename M>
  class Unary {
  protected:
    const M m_;
  public:
    constexpr Unary(const M& m) : m_(m) { }
  };

  // Base class for binary combinators

  template<typename L, typename R>
  class Binary {
  protected:
    const L l_;
    const R r_;
  public:
    constexpr Binary(const L& l, const R& r) : l_(l), r_(r) { }
  };

  // Sequencing

  template<typename L, typename R>
  class Sequence : public Binary<L, R> {
  public:
    using Binary<L, R>::Binary;
    const char* operator()(const char* b, const char* e) const {
      return (b = this->l_(b, e)) ? this->r_(b, e) : nullptr;
    }
    const char* operator()(const char* b) const {
      return (b = this->l_(b)) ? this->r_(b) : nullptr;
    }
  };

  template<typename L, typename R>
  constexpr Sequence<L, R> operator^(const L& l, const R& r) {
    return Sequence<L, R> { l, r };
  }

  // Alternation

  template<typename L, typename R>
  class Alternation : public Binary<L, R> {
  public:
    using Binary<L, R>::Binary;
    const char* operator()(const char* b, const char* e) const {
      const char* p = this->l_(b);
      return p ? p : this->r_(b, e);
    }
    const char* operator()(const char* b) const {
      const char* p = this->l_(b);
      return p ? p : this->r_(b);
    }
  };

  template<typename L, typename R>
  constexpr Alternation<L, R> operator|(const L& l, const R& r) {
    return Alternation<L, R> { l, r };
  }

  // Option

  template<typename M>
  constexpr Alternation<M, Success> operator~(const M& m) {
    return m | Success { };
  }

  // Repetition

  template<typename M>
  class Zero_Or_More : public Unary<M> {
  public:
    using Unary<M>::Unary;
    const char* operator()(const char* b, const char* e) const {
      for (const char* p = b; (p = this->m_(b, e)); b = p) ;
      return b;
    }
    const char* operator()(const char* b) const {
      for (const char* p = b; (p = this->m_(b)); b = p) ;
      return b;
    }
  };

  template<typename M>
  constexpr Zero_Or_More<M> operator*(const M& m) {
    return Zero_Or_More<M> { m };
  }

  template<typename M>
  constexpr auto operator+(const M& m)
  -> decltype(m ^ *m) {
    return m ^ *m;
  }

  // Bounded repetition

  template<typename M>
  class Exactly_N_Times : public Unary<M> {
    size_t n_;
  public:
    constexpr Exactly_N_Times(const M& m, size_t n) : Unary<M> { m }, n_(n) { }
    const char* operator()(const char* b, const char* e) const {
      size_t i;
      for (i = 0; i < n_ && (b = this->m_(b, e)); ++i) ;
      return i == n_ ? b : nullptr;
    }
    const char* operator()(const char* b) const {
      size_t i;
      for (i = 0; i < n_ && (b = this->m_(b)); ++i) ;
      return i == n_ ? b : nullptr;
    }
  };

  template<typename M>
  constexpr Exactly_N_Times<M> operator==(const M& m,  size_t n) {
    return Exactly_N_Times<M> { m, n };
  }

  template<typename M>
  constexpr auto operator>(const M& m,  size_t n)
  -> decltype((m == n) ^ +m) {
    return (m == n) ^ +m;
  }

  template<typename M>
  constexpr auto operator>=(const M& m,  size_t n)
  -> decltype((m == n) ^ *m) {
    return (m == n) ^ *m;
  }

  template<typename M>
  constexpr auto operator<(const M& m,  size_t n)
  -> decltype((m == n-1) | *m) {
    return (m == n-1) | *m;
  }

  template<typename M>
  constexpr auto operator<=(const M& m,  size_t n)
  -> decltype((m == n) | *m) {
    return (m == n) | *m;
  }

  template<typename M>
  constexpr auto between(size_t a, size_t b, const M& m)
  -> decltype((m == b) | (m >= a)) {
    return (a < b) ? (m == b) | (m >= a) : (m == a) | (m >= b);
  }

  // Negation

  template<typename M>
  class Negation : Unary<M> {
  public:
    using Unary<M>::Unary;
    const char* operator()(const char* b, const char* e) const {
      return this->m_(b, e) ? nullptr : b;
    }
    const char* operator()(const char* b) const {
      return this->m_(b) ? nullptr : b;
    }
  };

  template<typename M>
  constexpr Negation<M> operator!(const M& m) {
    return Negation<M> { m };
  }

  // Lookahead

  template<typename M>
  class Lookahead : Unary<M> {
  public:
    using Unary<M>::Unary;
    const char* operator()(const char* b, const char* e) const {
      return this->m_(b, e) ? b : nullptr;
    }
    const char* operator()(const char* b) const {
      return this->m_(b) ? b : nullptr;
    }
  };

  template<typename M>
  constexpr Lookahead<M> operator&(const M& m) {
    return Lookahead<M> { m };
  }

}

#endif<|endoftext|>


<commit_before>//===-- PTXSelectionDAGInfo.cpp - PTX SelectionDAG Info -------------------===//
//
//                     The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
//
// This file implements the PTXSelectionDAGInfo class.
//
//===----------------------------------------------------------------------===//

#define DEBUG_TYPE "ptx-selectiondag-info"
#include "PTXTargetMachine.h"
#include "llvm/DerivedTypes.h"
#include "llvm/CodeGen/SelectionDAG.h"
using namespace llvm;

PTXSelectionDAGInfo::PTXSelectionDAGInfo(const TargetMachine &TM)
  : TargetSelectionDAGInfo(TM),
    Subtarget(&TM.getSubtarget<PTXSubtarget>()) {
}

PTXSelectionDAGInfo::~PTXSelectionDAGInfo() {
}

SDValue
PTXSelectionDAGInfo::EmitTargetCodeForMemcpy(SelectionDAG &DAG, DebugLoc dl,
                                             SDValue Chain,
                                             SDValue Dst, SDValue Src,
                                             SDValue Size, unsigned Align,
                                             bool isVolatile, bool AlwaysInline,
                                             MachinePointerInfo DstPtrInfo,
                                          MachinePointerInfo SrcPtrInfo) const {
  // Do repeated 4-byte loads and stores. To be improved.
  // This requires 4-byte alignment.
  if ((Align & 3) != 0)
    return SDValue();
  // This requires the copy size to be a constant, preferably
  // within a subtarget-specific limit.
  ConstantSDNode *ConstantSize = dyn_cast<ConstantSDNode>(Size);
  if (!ConstantSize)
    return SDValue();
  uint64_t SizeVal = ConstantSize->getZExtValue();
  // Always inline memcpys. In PTX, we do not have a C library that provides
  // a memcpy function.
  //if (!AlwaysInline)
  //  return SDValue();

  unsigned BytesLeft = SizeVal & 3;
  unsigned NumMemOps = SizeVal >> 2;
  unsigned EmittedNumMemOps = 0;
  EVT VT = MVT::i32;
  unsigned VTSize = 4;
  unsigned i = 0;
  const unsigned MAX_LOADS_IN_LDM = 6;
  SDValue TFOps[MAX_LOADS_IN_LDM];
  SDValue Loads[MAX_LOADS_IN_LDM];
  uint64_t SrcOff = 0, DstOff = 0;

  // Emit up to MAX_LOADS_IN_LDM loads, then a TokenFactor barrier, then the
  // same number of stores.  The loads and stores will get combined into
  // ldm/stm later on.
  while (EmittedNumMemOps < NumMemOps) {
    for (i = 0;
         i < MAX_LOADS_IN_LDM && EmittedNumMemOps + i < NumMemOps; ++i) {
      Loads[i] = DAG.getLoad(VT, dl, Chain,
                             DAG.getNode(ISD::ADD, dl, MVT::i32, Src,
                                         DAG.getConstant(SrcOff, MVT::i32)),
                             SrcPtrInfo.getWithOffset(SrcOff), isVolatile,
                             false, 0);
      TFOps[i] = Loads[i].getValue(1);
      SrcOff += VTSize;
    }
    Chain = DAG.getNode(ISD::TokenFactor, dl, MVT::Other, &TFOps[0], i);

    for (i = 0;
         i < MAX_LOADS_IN_LDM && EmittedNumMemOps + i < NumMemOps; ++i) {
      TFOps[i] = DAG.getStore(Chain, dl, Loads[i],
                              DAG.getNode(ISD::ADD, dl, MVT::i32, Dst,
                                          DAG.getConstant(DstOff, MVT::i32)),
                              DstPtrInfo.getWithOffset(DstOff),
                              isVolatile, false, 0);
      DstOff += VTSize;
    }
    Chain = DAG.getNode(ISD::TokenFactor, dl, MVT::Other, &TFOps[0], i);

    EmittedNumMemOps += i;
  }

  if (BytesLeft == 0)
    return Chain;

  // Issue loads / stores for the trailing (1 - 3) bytes.
  unsigned BytesLeftSave = BytesLeft;
  i = 0;
  while (BytesLeft) {
    if (BytesLeft >= 2) {
      VT = MVT::i16;
      VTSize = 2;
    } else {
      VT = MVT::i8;
      VTSize = 1;
    }

    Loads[i] = DAG.getLoad(VT, dl, Chain,
                           DAG.getNode(ISD::ADD, dl, MVT::i32, Src,
                                       DAG.getConstant(SrcOff, MVT::i32)),
                           SrcPtrInfo.getWithOffset(SrcOff), false, false, 0);
    TFOps[i] = Loads[i].getValue(1);
    ++i;
    SrcOff += VTSize;
    BytesLeft -= VTSize;
  }
  Chain = DAG.getNode(ISD::TokenFactor, dl, MVT::Other, &TFOps[0], i);

  i = 0;
  BytesLeft = BytesLeftSave;
  while (BytesLeft) {
    if (BytesLeft >= 2) {
      VT = MVT::i16;
      VTSize = 2;
    } else {
      VT = MVT::i8;
      VTSize = 1;
    }

    TFOps[i] = DAG.getStore(Chain, dl, Loads[i],
                            DAG.getNode(ISD::ADD, dl, MVT::i32, Dst,
                                        DAG.getConstant(DstOff, MVT::i32)),
                            DstPtrInfo.getWithOffset(DstOff), false, false, 0);
    ++i;
    DstOff += VTSize;
    BytesLeft -= VTSize;
  }
  return DAG.getNode(ISD::TokenFactor, dl, MVT::Other, &TFOps[0], i);
}

SDValue PTXSelectionDAGInfo::
EmitTargetCodeForMemset(SelectionDAG &DAG, DebugLoc dl,
                        SDValue Chain, SDValue Dst,
                        SDValue Src, SDValue Size,
                        unsigned Align, bool isVolatile,
                        MachinePointerInfo DstPtrInfo) const {
  llvm_unreachable("memset lowering not implemented for PTX yet");
}

<commit_msg>PTX: Fix memcpy intrinsic to handle 64-bit pointers<commit_after>//===-- PTXSelectionDAGInfo.cpp - PTX SelectionDAG Info -------------------===//
//
//                     The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
//
// This file implements the PTXSelectionDAGInfo class.
//
//===----------------------------------------------------------------------===//

#define DEBUG_TYPE "ptx-selectiondag-info"
#include "PTXTargetMachine.h"
#include "llvm/DerivedTypes.h"
#include "llvm/CodeGen/SelectionDAG.h"
using namespace llvm;

PTXSelectionDAGInfo::PTXSelectionDAGInfo(const TargetMachine &TM)
  : TargetSelectionDAGInfo(TM),
    Subtarget(&TM.getSubtarget<PTXSubtarget>()) {
}

PTXSelectionDAGInfo::~PTXSelectionDAGInfo() {
}

SDValue
PTXSelectionDAGInfo::EmitTargetCodeForMemcpy(SelectionDAG &DAG, DebugLoc dl,
                                             SDValue Chain,
                                             SDValue Dst, SDValue Src,
                                             SDValue Size, unsigned Align,
                                             bool isVolatile, bool AlwaysInline,
                                             MachinePointerInfo DstPtrInfo,
                                          MachinePointerInfo SrcPtrInfo) const {
  // Do repeated 4-byte loads and stores. To be improved.
  // This requires 4-byte alignment.
  if ((Align & 3) != 0)
    return SDValue();
  // This requires the copy size to be a constant, preferably
  // within a subtarget-specific limit.
  ConstantSDNode *ConstantSize = dyn_cast<ConstantSDNode>(Size);
  if (!ConstantSize)
    return SDValue();
  uint64_t SizeVal = ConstantSize->getZExtValue();
  // Always inline memcpys. In PTX, we do not have a C library that provides
  // a memcpy function.
  //if (!AlwaysInline)
  //  return SDValue();

  unsigned BytesLeft = SizeVal & 3;
  unsigned NumMemOps = SizeVal >> 2;
  unsigned EmittedNumMemOps = 0;
  EVT VT = MVT::i32;
  unsigned VTSize = 4;
  unsigned i = 0;
  const unsigned MAX_LOADS_IN_LDM = 6;
  SDValue TFOps[MAX_LOADS_IN_LDM];
  SDValue Loads[MAX_LOADS_IN_LDM];
  uint64_t SrcOff = 0, DstOff = 0;
  EVT PointerType = Subtarget->is64Bit() ? MVT::i64 : MVT::i32;

  // Emit up to MAX_LOADS_IN_LDM loads, then a TokenFactor barrier, then the
  // same number of stores.  The loads and stores will get combined into
  // ldm/stm later on.
  while (EmittedNumMemOps < NumMemOps) {
    for (i = 0;
         i < MAX_LOADS_IN_LDM && EmittedNumMemOps + i < NumMemOps; ++i) {
      Loads[i] = DAG.getLoad(VT, dl, Chain,
                             DAG.getNode(ISD::ADD, dl, PointerType, Src,
                                         DAG.getConstant(SrcOff, PointerType)),
                             SrcPtrInfo.getWithOffset(SrcOff), isVolatile,
                             false, 0);
      TFOps[i] = Loads[i].getValue(1);
      SrcOff += VTSize;
    }
    Chain = DAG.getNode(ISD::TokenFactor, dl, MVT::Other, &TFOps[0], i);

    for (i = 0;
         i < MAX_LOADS_IN_LDM && EmittedNumMemOps + i < NumMemOps; ++i) {
      TFOps[i] = DAG.getStore(Chain, dl, Loads[i],
                              DAG.getNode(ISD::ADD, dl, PointerType, Dst,
                                          DAG.getConstant(DstOff, PointerType)),
                              DstPtrInfo.getWithOffset(DstOff),
                              isVolatile, false, 0);
      DstOff += VTSize;
    }
    Chain = DAG.getNode(ISD::TokenFactor, dl, MVT::Other, &TFOps[0], i);

    EmittedNumMemOps += i;
  }

  if (BytesLeft == 0)
    return Chain;

  // Issue loads / stores for the trailing (1 - 3) bytes.
  unsigned BytesLeftSave = BytesLeft;
  i = 0;
  while (BytesLeft) {
    if (BytesLeft >= 2) {
      VT = MVT::i16;
      VTSize = 2;
    } else {
      VT = MVT::i8;
      VTSize = 1;
    }

    Loads[i] = DAG.getLoad(VT, dl, Chain,
                           DAG.getNode(ISD::ADD, dl, PointerType, Src,
                                       DAG.getConstant(SrcOff, PointerType)),
                           SrcPtrInfo.getWithOffset(SrcOff), false, false, 0);
    TFOps[i] = Loads[i].getValue(1);
    ++i;
    SrcOff += VTSize;
    BytesLeft -= VTSize;
  }
  Chain = DAG.getNode(ISD::TokenFactor, dl, MVT::Other, &TFOps[0], i);

  i = 0;
  BytesLeft = BytesLeftSave;
  while (BytesLeft) {
    if (BytesLeft >= 2) {
      VT = MVT::i16;
      VTSize = 2;
    } else {
      VT = MVT::i8;
      VTSize = 1;
    }

    TFOps[i] = DAG.getStore(Chain, dl, Loads[i],
                            DAG.getNode(ISD::ADD, dl, PointerType, Dst,
                                        DAG.getConstant(DstOff, PointerType)),
                            DstPtrInfo.getWithOffset(DstOff), false, false, 0);
    ++i;
    DstOff += VTSize;
    BytesLeft -= VTSize;
  }
  return DAG.getNode(ISD::TokenFactor, dl, MVT::Other, &TFOps[0], i);
}

SDValue PTXSelectionDAGInfo::
EmitTargetCodeForMemset(SelectionDAG &DAG, DebugLoc dl,
                        SDValue Chain, SDValue Dst,
                        SDValue Src, SDValue Size,
                        unsigned Align, bool isVolatile,
                        MachinePointerInfo DstPtrInfo) const {
  llvm_unreachable("memset lowering not implemented for PTX yet");
}

<|endoftext|>


<commit_before>// @(#)root/test:$Name:  $:$Id: MainEvent.cxx,v 1.25 2002/11/13 17:35:50 rdm Exp $
// Author: Rene Brun   19/01/97

////////////////////////////////////////////////////////////////////////
//
//             A simple example with a ROOT tree
//             =================================
//
//  This program creates :
//    - a ROOT file
//    - a tree
//  Additional arguments can be passed to the program to control the flow
//  of execution. (see comments describing the arguments in the code).
//      Event  nevent comp split fill
//  All arguments are optional. Default is:
//      Event  400      1    1     1
//
//  In this example, the tree consists of one single "super branch"
//  The statement ***tree->Branch("event", event, 64000,split);*** below
//  will parse the structure described in Event.h and will make
//  a new branch for each data member of the class if split is set to 1.
//    - 9 branches corresponding to the basic types fType, fNtrack,fNseg,
//           fNvertex,fFlag,fTemperature,fMeasures,fMatrix,fClosesDistance.
//    - 3 branches corresponding to the members of the subobject EventHeader.
//    - one branch for each data member of the class Track of TClonesArray.
//    - one branch for the TRefArray of high Pt tracks
//    - one branch for the TRefArray of muon tracks
//    - one branch for the reference pointer to the last track
//    - one branch for the object fH (histogram of class TH1F).
//
//  if split = 0 only one single branch is created and the complete event
//  is serialized in one single buffer.
//  if split = -2 the event is split using the old TBranchObject mechanism
//  if split = -1 the event is streamed using the old TBranchObject mechanism
//  if split > 0  the event is split using the new TBranchElement mechanism.
//
//  if comp = 0 no compression at all.
//  if comp = 1 event is compressed.
//  if comp = 2 same as 1. In addition branches with floats in the TClonesArray
//                         are also compressed.
//  The 4th argument fill can be set to 0 if one wants to time
//     the percentage of time spent in creating the event structure and
//     not write the event in the file.
//  In this example, one loops over nevent events.
//  The branch "event" is created at the first event.
//  The branch address is set for all other events.
//  For each event, the event header is filled and ntrack tracks
//  are generated and added to the TClonesArray list.
//  For each event the event histogram is saved as well as the list
//  of all tracks.
//
//  The two TRefArray contain only references to the original tracks owned by
//  the TClonesArray fTracks.
//
//  The number of events can be given as the first argument to the program.
//  By default 400 events are generated.
//  The compression option can be activated/deactivated via the second argument.
//
//   ---Running/Linking instructions----
//  This program consists of the following files and procedures.
//    - Event.h event class description
//    - Event.C event class implementation
//    - MainEvent.C the main program to demo this class might be used (this file)
//    - EventCint.C  the CINT dictionary for the event and Track classes
//        this file is automatically generated by rootcint (see Makefile),
//        when the class definition in Event.h is modified.
//
//   ---Analyzing the Event.root file with the interactive root
//        example of a simple session
//   Root > TFile f("Event.root")
//   Root > T.Draw("fNtrack")   //histogram the number of tracks per event
//   Root > T.Draw("fPx")       //histogram fPx for all tracks in all events
//   Root > T.Draw("fXfirst:fYfirst","fNtrack>600")
//                              //scatter-plot for x versus y of first point of each track
//   Root > T.Draw("fH.GetRMS()")  //histogram of the RMS of the event histogram
//
//   Look also in the same directory at the following macros:
//     - eventa.C  an example how to read the tree
//     - eventb.C  how to read events conditionally
//
////////////////////////////////////////////////////////////////////////

#include <stdlib.h>

#include "Riostream.h"
#include "TROOT.h"
#include "TFile.h"
#include "TNetFile.h"
#include "TRandom.h"
#include "TTree.h"
#include "TBranch.h"
#include "TClonesArray.h"
#include "TStopwatch.h"

#include "Event.h"

//______________________________________________________________________________
int main(int argc, char **argv)
{
   Int_t nevent = 400;     // by default create 400 events
   Int_t comp   = 1;       // by default file is compressed
   Int_t split  = 1;       // by default, split Event in sub branches
   Int_t write  = 1;       // by default the tree is filled
   Int_t hfill  = 0;       // by default histograms are not filled
   Int_t read   = 0;
   Int_t arg4   = 1;
   Int_t arg5   = 600;     //default number of tracks per event
   Int_t netf   = 0;

   if (argc > 1)  nevent = atoi(argv[1]);
   if (argc > 2)  comp   = atoi(argv[2]);
   if (argc > 3)  split  = atoi(argv[3]);
   if (argc > 4)  arg4   = atoi(argv[4]);
   if (argc > 5)  arg5   = atoi(argv[5]);
   if (arg4 ==  0) { write = 0; hfill = 0; read = 1;}
   if (arg4 ==  1) { write = 1; hfill = 0;}
   if (arg4 ==  2) { write = 0; hfill = 0;}
   if (arg4 == 10) { write = 0; hfill = 1;}
   if (arg4 == 11) { write = 1; hfill = 1;}
   if (arg4 == 20) { write = 0; read  = 1;}  //read sequential
   if (arg4 == 25) { write = 0; read  = 2;}  //read random
   if (arg4 >= 30) { netf  = 1; }            //use TNetFile
   if (arg4 == 30) { write = 0; read  = 1;}  //netfile + read sequential
   if (arg4 == 35) { write = 0; read  = 2;}  //netfile + read random
   if (arg4 == 36) { write = 1; }            //netfile + write sequential
   Int_t branchStyle = 1; //new style by default
   if (split < 0) {branchStyle = 0; split = -1-split;}

   TFile *hfile;
   TTree *tree;
   Event *event = 0;

   // Fill event, header and tracks with some random numbers
   //   Create a timer object to benchmark this loop
   TStopwatch timer;
   timer.Start();
   Int_t nb = 0;
   Int_t ev;
   Int_t bufsize;
   Double_t told = 0;
   Double_t tnew = 0;
   Int_t printev = 100;
   if (arg5 < 100) printev = 1000;
   if (arg5 < 10)  printev = 10000;

   //Authorize Trees up to 2 Terabytes (if the system can do it)
   TTree::SetMaxTreeSize(1000*Long64_t(2000000000));

//         Read case
   if (read) {
      if (netf) {
         hfile = new TNetFile("root://localhost/root/test/EventNet.root");
         hfile->UseCache(10);
      } else
         hfile = new TFile("Event.root");
      tree = (TTree*)hfile->Get("T");
      TBranch *branch = tree->GetBranch("event");
      branch->SetAddress(&event);
      Int_t nentries = (Int_t)tree->GetEntries();
      nevent = TMath::Max(nevent,nentries);
      if (read == 1) {  //read sequential
         for (ev = 0; ev < nevent; ev++) {
            if (ev%printev == 0) {
               tnew = timer.RealTime();
               printf("event:%d, rtime=%f s\n",ev,tnew-told);
               told=tnew;
               timer.Continue();
            }
            nb += tree->GetEntry(ev);        //read complete event in memory
         }
      } else {    //read random
         Int_t evrandom;
         for (ev = 0; ev < nevent; ev++) {
            if (ev%printev == 0) cout<<"event="<<ev<<endl;
            evrandom = Int_t(nevent*gRandom->Rndm(1));
            nb += tree->GetEntry(evrandom);  //read complete event in memory
         }
      }
   } else {
//         Write case
      // Create a new ROOT binary machine independent file.
      // Note that this file may contain any kind of ROOT objects, histograms,
      // pictures, graphics objects, detector geometries, tracks, events, etc..
      // This file is now becoming the current directory.
      if (netf) {
         hfile = new TNetFile("root://localhost/root/test/EventNet.root","RECREATE","TTree benchmark ROOT file");
         hfile->UseCache(10);
      } else
         hfile = new TFile("Event.root","RECREATE","TTree benchmark ROOT file");
      hfile->SetCompressionLevel(comp);

     // Create histogram to show write_time in function of time
     Float_t curtime = -0.5;
     Int_t ntime = nevent/printev;
     TH1F *htime = new TH1F("htime","Real-Time to write versus time",ntime,0,ntime);
     HistogramManager *hm = 0;
     if (hfill) {
        TDirectory *hdir = new TDirectory("histograms", "all histograms");
        hm = new HistogramManager(hdir);
     }

     // Create a ROOT Tree and one superbranch
      TTree *tree = new TTree("T","An example of a ROOT tree");
      tree->SetAutoSave(1000000000);  // autosave when 1 Gbyte written
      bufsize = 64000;
      if (split)  bufsize /= 4;
      event = new Event();
      TTree::SetBranchStyle(branchStyle);
      TBranch *branch = tree->Branch("event", "Event", &event, bufsize,split);
      branch->SetAutoDelete(kFALSE);
      Float_t ptmin = 1;

      for (ev = 0; ev < nevent; ev++) {
         if (ev%printev == 0) {
            tnew = timer.RealTime();
            printf("event:%d, rtime=%f s\n",ev,tnew-told);
            htime->Fill(curtime,tnew-told);
            curtime += 1;
            told=tnew;
            timer.Continue();
         }

         event->Build(ev, arg5, ptmin);

         if (write) nb += tree->Fill();  //fill the tree

         if (hm) hm->Hfill(event);      //fill histograms
      }
      if (write) {
         hfile = tree->GetCurrentFile(); //just in case we switched to a new file
         hfile->Write();
         tree->Print();
      }
   }

   //  Stop timer and print results
   timer.Stop();
   Float_t mbytes = 0.000001*nb;
   Double_t rtime = timer.RealTime();
   Double_t ctime = timer.CpuTime();

   printf("\n%d events and %d bytes processed.\n",nevent,nb);
   printf("RealTime=%f seconds, CpuTime=%f seconds\n",rtime,ctime);
   if (read) {
      printf("You read %f Mbytes/Realtime seconds\n",mbytes/rtime);
      printf("You read %f Mbytes/Cputime seconds\n",mbytes/ctime);
   } else {
      printf("compression level=%d, split=%d, arg4=%d\n",comp,split,arg4);
      printf("You write %f Mbytes/Realtime seconds\n",mbytes/rtime);
      printf("You write %f Mbytes/Cputime seconds\n",mbytes/ctime);
      //printf("file compression factor = %f\n",hfile.GetCompressionFactor());
   }
   hfile->Close();
   return 0;
}
<commit_msg>Change variable counting the number of bytes processed from Int_t to Long64_t<commit_after>// @(#)root/test:$Name:  $:$Id: MainEvent.cxx,v 1.26 2003/12/30 18:16:43 brun Exp $
// Author: Rene Brun   19/01/97

////////////////////////////////////////////////////////////////////////
//
//             A simple example with a ROOT tree
//             =================================
//
//  This program creates :
//    - a ROOT file
//    - a tree
//  Additional arguments can be passed to the program to control the flow
//  of execution. (see comments describing the arguments in the code).
//      Event  nevent comp split fill
//  All arguments are optional. Default is:
//      Event  400      1    1     1
//
//  In this example, the tree consists of one single "super branch"
//  The statement ***tree->Branch("event", event, 64000,split);*** below
//  will parse the structure described in Event.h and will make
//  a new branch for each data member of the class if split is set to 1.
//    - 9 branches corresponding to the basic types fType, fNtrack,fNseg,
//           fNvertex,fFlag,fTemperature,fMeasures,fMatrix,fClosesDistance.
//    - 3 branches corresponding to the members of the subobject EventHeader.
//    - one branch for each data member of the class Track of TClonesArray.
//    - one branch for the TRefArray of high Pt tracks
//    - one branch for the TRefArray of muon tracks
//    - one branch for the reference pointer to the last track
//    - one branch for the object fH (histogram of class TH1F).
//
//  if split = 0 only one single branch is created and the complete event
//  is serialized in one single buffer.
//  if split = -2 the event is split using the old TBranchObject mechanism
//  if split = -1 the event is streamed using the old TBranchObject mechanism
//  if split > 0  the event is split using the new TBranchElement mechanism.
//
//  if comp = 0 no compression at all.
//  if comp = 1 event is compressed.
//  if comp = 2 same as 1. In addition branches with floats in the TClonesArray
//                         are also compressed.
//  The 4th argument fill can be set to 0 if one wants to time
//     the percentage of time spent in creating the event structure and
//     not write the event in the file.
//  In this example, one loops over nevent events.
//  The branch "event" is created at the first event.
//  The branch address is set for all other events.
//  For each event, the event header is filled and ntrack tracks
//  are generated and added to the TClonesArray list.
//  For each event the event histogram is saved as well as the list
//  of all tracks.
//
//  The two TRefArray contain only references to the original tracks owned by
//  the TClonesArray fTracks.
//
//  The number of events can be given as the first argument to the program.
//  By default 400 events are generated.
//  The compression option can be activated/deactivated via the second argument.
//
//   ---Running/Linking instructions----
//  This program consists of the following files and procedures.
//    - Event.h event class description
//    - Event.C event class implementation
//    - MainEvent.C the main program to demo this class might be used (this file)
//    - EventCint.C  the CINT dictionary for the event and Track classes
//        this file is automatically generated by rootcint (see Makefile),
//        when the class definition in Event.h is modified.
//
//   ---Analyzing the Event.root file with the interactive root
//        example of a simple session
//   Root > TFile f("Event.root")
//   Root > T.Draw("fNtrack")   //histogram the number of tracks per event
//   Root > T.Draw("fPx")       //histogram fPx for all tracks in all events
//   Root > T.Draw("fXfirst:fYfirst","fNtrack>600")
//                              //scatter-plot for x versus y of first point of each track
//   Root > T.Draw("fH.GetRMS()")  //histogram of the RMS of the event histogram
//
//   Look also in the same directory at the following macros:
//     - eventa.C  an example how to read the tree
//     - eventb.C  how to read events conditionally
//
////////////////////////////////////////////////////////////////////////

#include <stdlib.h>

#include "Riostream.h"
#include "TROOT.h"
#include "TFile.h"
#include "TNetFile.h"
#include "TRandom.h"
#include "TTree.h"
#include "TBranch.h"
#include "TClonesArray.h"
#include "TStopwatch.h"

#include "Event.h"

//______________________________________________________________________________
int main(int argc, char **argv)
{
   Int_t nevent = 400;     // by default create 400 events
   Int_t comp   = 1;       // by default file is compressed
   Int_t split  = 1;       // by default, split Event in sub branches
   Int_t write  = 1;       // by default the tree is filled
   Int_t hfill  = 0;       // by default histograms are not filled
   Int_t read   = 0;
   Int_t arg4   = 1;
   Int_t arg5   = 600;     //default number of tracks per event
   Int_t netf   = 0;

   if (argc > 1)  nevent = atoi(argv[1]);
   if (argc > 2)  comp   = atoi(argv[2]);
   if (argc > 3)  split  = atoi(argv[3]);
   if (argc > 4)  arg4   = atoi(argv[4]);
   if (argc > 5)  arg5   = atoi(argv[5]);
   if (arg4 ==  0) { write = 0; hfill = 0; read = 1;}
   if (arg4 ==  1) { write = 1; hfill = 0;}
   if (arg4 ==  2) { write = 0; hfill = 0;}
   if (arg4 == 10) { write = 0; hfill = 1;}
   if (arg4 == 11) { write = 1; hfill = 1;}
   if (arg4 == 20) { write = 0; read  = 1;}  //read sequential
   if (arg4 == 25) { write = 0; read  = 2;}  //read random
   if (arg4 >= 30) { netf  = 1; }            //use TNetFile
   if (arg4 == 30) { write = 0; read  = 1;}  //netfile + read sequential
   if (arg4 == 35) { write = 0; read  = 2;}  //netfile + read random
   if (arg4 == 36) { write = 1; }            //netfile + write sequential
   Int_t branchStyle = 1; //new style by default
   if (split < 0) {branchStyle = 0; split = -1-split;}

   TFile *hfile;
   TTree *tree;
   Event *event = 0;

   // Fill event, header and tracks with some random numbers
   //   Create a timer object to benchmark this loop
   TStopwatch timer;
   timer.Start();
   Long64_t nb = 0;
   Int_t ev;
   Int_t bufsize;
   Double_t told = 0;
   Double_t tnew = 0;
   Int_t printev = 100;
   if (arg5 < 100) printev = 1000;
   if (arg5 < 10)  printev = 10000;

   //Authorize Trees up to 2 Terabytes (if the system can do it)
   TTree::SetMaxTreeSize(1000*Long64_t(2000000000));

//         Read case
   if (read) {
      if (netf) {
         hfile = new TNetFile("root://localhost/root/test/EventNet.root");
         hfile->UseCache(10);
      } else
         hfile = new TFile("Event.root");
      tree = (TTree*)hfile->Get("T");
      TBranch *branch = tree->GetBranch("event");
      branch->SetAddress(&event);
      Int_t nentries = (Int_t)tree->GetEntries();
      nevent = TMath::Max(nevent,nentries);
      if (read == 1) {  //read sequential
         for (ev = 0; ev < nevent; ev++) {
            if (ev%printev == 0) {
               tnew = timer.RealTime();
               printf("event:%d, rtime=%f s\n",ev,tnew-told);
               told=tnew;
               timer.Continue();
            }
            nb += tree->GetEntry(ev);        //read complete event in memory
         }
      } else {    //read random
         Int_t evrandom;
         for (ev = 0; ev < nevent; ev++) {
            if (ev%printev == 0) cout<<"event="<<ev<<endl;
            evrandom = Int_t(nevent*gRandom->Rndm(1));
            nb += tree->GetEntry(evrandom);  //read complete event in memory
         }
      }
   } else {
//         Write case
      // Create a new ROOT binary machine independent file.
      // Note that this file may contain any kind of ROOT objects, histograms,
      // pictures, graphics objects, detector geometries, tracks, events, etc..
      // This file is now becoming the current directory.
      if (netf) {
         hfile = new TNetFile("root://localhost/root/test/EventNet.root","RECREATE","TTree benchmark ROOT file");
         hfile->UseCache(10);
      } else
         hfile = new TFile("Event.root","RECREATE","TTree benchmark ROOT file");
      hfile->SetCompressionLevel(comp);

     // Create histogram to show write_time in function of time
     Float_t curtime = -0.5;
     Int_t ntime = nevent/printev;
     TH1F *htime = new TH1F("htime","Real-Time to write versus time",ntime,0,ntime);
     HistogramManager *hm = 0;
     if (hfill) {
        TDirectory *hdir = new TDirectory("histograms", "all histograms");
        hm = new HistogramManager(hdir);
     }

     // Create a ROOT Tree and one superbranch
      TTree *tree = new TTree("T","An example of a ROOT tree");
      tree->SetAutoSave(1000000000);  // autosave when 1 Gbyte written
      bufsize = 64000;
      if (split)  bufsize /= 4;
      event = new Event();
      TTree::SetBranchStyle(branchStyle);
      TBranch *branch = tree->Branch("event", "Event", &event, bufsize,split);
      branch->SetAutoDelete(kFALSE);
      Float_t ptmin = 1;

      for (ev = 0; ev < nevent; ev++) {
         if (ev%printev == 0) {
            tnew = timer.RealTime();
            printf("event:%d, rtime=%f s\n",ev,tnew-told);
            htime->Fill(curtime,tnew-told);
            curtime += 1;
            told=tnew;
            timer.Continue();
         }

         event->Build(ev, arg5, ptmin);

         if (write) nb += tree->Fill();  //fill the tree

         if (hm) hm->Hfill(event);      //fill histograms
      }
      if (write) {
         hfile = tree->GetCurrentFile(); //just in case we switched to a new file
         hfile->Write();
         tree->Print();
      }
   }

   //  Stop timer and print results
   timer.Stop();
   Float_t mbytes = 0.000001*nb;
   Double_t rtime = timer.RealTime();
   Double_t ctime = timer.CpuTime();

   printf("\n%d events and %lld bytes processed.\n",nevent,nb);
   printf("RealTime=%f seconds, CpuTime=%f seconds\n",rtime,ctime);
   if (read) {
      printf("You read %f Mbytes/Realtime seconds\n",mbytes/rtime);
      printf("You read %f Mbytes/Cputime seconds\n",mbytes/ctime);
   } else {
      printf("compression level=%d, split=%d, arg4=%d\n",comp,split,arg4);
      printf("You write %f Mbytes/Realtime seconds\n",mbytes/rtime);
      printf("You write %f Mbytes/Cputime seconds\n",mbytes/ctime);
      //printf("file compression factor = %f\n",hfile.GetCompressionFactor());
   }
   hfile->Close();
   return 0;
}
<|endoftext|>


<commit_before>/**
 * @file		typedef.hpp
 * @brief		COSSB Type definitions
 * @author		Byunghun Hwang<bhhwang@nsynapse.com>
 * @date 		2015. 6. 21
 * @details
 */

#ifndef _COSSB_TYPEDEF_HPP_
#define _COSSB_TYPEDEF_HPP_

#include <boost/thread.hpp>
#include <boost/shared_ptr.hpp>

using namespace boost;

namespace coosb {

namespace process {
	typedef boost::shared_ptr<boost::thread> task;

	#define task_register(fnptr)	boost::thread(boost::bind(fnptr, this))
	#define create_task(fnptr)	boost::shared_ptr<boost::thread>(new task_register(&fnptr))
	#define destroy_task(instance)	if(instance){ instance->interrupt(); instance->join(); }
}

namespace types {

	#define COMPONENT_EXT	".comp"
	#define PROFILE_EXT		".xml"

	enum class comp_type : unsigned int { ASSIST=101, SERVICE, APP, GUI };
	enum class comp_status : unsigned int { READY = 0, RUNNING, STOPPED };
	enum class return_type : int { EXIST=-1, FAIL=0, SUCCESS=1 };

} /* namespace types */
} /* namespace cossb */

#endif /* _COSSB_TYPEDEF_HPP_ */
<commit_msg>add type definitions<commit_after>/**
 * @file		typedef.hpp
 * @brief		COSSB Type definitions
 * @author		Byunghun Hwang<bhhwang@nsynapse.com>
 * @date 		2015. 6. 21
 * @details
 */

#ifndef _COSSB_TYPEDEF_HPP_
#define _COSSB_TYPEDEF_HPP_

#include <boost/thread.hpp>
#include <boost/shared_ptr.hpp>

using namespace boost;

namespace cossb {

namespace process {
	typedef boost::shared_ptr<boost::thread> task;

	#define task_register(fnptr)	boost::thread(boost::bind(fnptr, this))
	#define create_task(fnptr)	boost::shared_ptr<boost::thread>(new task_register(&fnptr))
	#define destroy_task(instance)	if(instance){ instance->interrupt(); instance->join(); }
}

namespace types {

	#define COMPONENT_EXT	".comp"
	#define PROFILE_EXT		".xml"

	enum class comp_type : unsigned int { ASSIST=101, SERVICE, APP, GUI };
	enum class comp_status : unsigned int { READY = 0, RUNNING, STOPPED };
	enum class return_type : int { EXIST=-1, FAIL=0, SUCCESS=1 };

} /* namespace types */
} /* namespace cossb */

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


<commit_before>// UjoImro, 2013
// Experimental Research Code for the CARP Project

#ifndef __CARP__UTILITY__HPP__
#define __CARP__UTILITY__HPP__

#include <chrono>
#include <string>
#include <iomanip>
#include <iostream>
#include <fstream>

#include <opencv2/core/core.hpp>
#include <opencv2/highgui/highgui.hpp>
#include <stdexcept>

namespace carp {

class Timing
{
    std::vector<double> cpu_timings;
    std::vector<double> gpu_p_copy_timings;
public:
    Timing(const std::string & name) {
        std::cout << "Measuring performance of " << name << std::endl;
    }

    void print( const std::chrono::duration<double,std::milli> &cpu, const std::chrono::duration<double,std::milli> &gpu_p_copy ) {
        std::cout << std::fixed << std::setprecision(6);
        std::cout << std::endl << "OpenCV time measurements for an individual experiment:" << std::endl;
        std::cout << "CPU Time    - GPU+copy" << std::endl;
        std::cout << std::setw(8) << cpu       .count() << " ms - ";
        std::cout << std::setw(8) << gpu_p_copy.count() << " ms" << std::endl;

        cpu_timings       .push_back(cpu       .count());
        gpu_p_copy_timings.push_back(gpu_p_copy.count());
    }

    ~Timing() {
        std::cout << std::endl << "OpenCV accumulated time measurements for all the experiments (in ms):" << std::endl;
        std::cout<<"[RealEyes] Accumulate CPU time           : "<< std::accumulate(cpu_timings       .begin(),cpu_timings       .end(),0.0) << "\n";
        std::cout<<"[RealEyes] Accumulate GPU time (inc copy): "<< std::accumulate(gpu_p_copy_timings.begin(),gpu_p_copy_timings.end(),0.0) << "\n";
    }
};

class record_t {
private:
    char *m_path;

public:
    cv::Mat cpuimg() const {
        return cv::imread(m_path);
    }

    record_t( char *path )
    {
	m_path = path;
    }

};

bool file_exists (char *name) {

    std::ifstream f(name);

    if (f.good()) {
        f.close();
        return true;
    } else {
        f.close();
        return false;
    }
}

std::vector<record_t>
get_pool( int argc, char *argv[] )
{
    int i;
    std::vector<record_t> pool;

    if (argc <= 1)
    {
	throw std::runtime_error("Please provide an image as an argument to the program: ./program <image>");
    }
    else
    {
	    for ( i = 1; i < argc; i++ )
	    {
		if (file_exists(argv[i]))
		        pool.push_back(record_t(argv[i]));
		else
			std::cerr << "File " << argv[i]
				  << " does not exist." << std::endl;
	    }
    }

    return pool;
}
}

#endif
<commit_msg>Exit with an error message but without throwing a runtime error if the user does not provide an image as input as throwing a runtime error confuses users<commit_after>// UjoImro, 2013
// Experimental Research Code for the CARP Project

#ifndef __CARP__UTILITY__HPP__
#define __CARP__UTILITY__HPP__

#include <chrono>
#include <string>
#include <iomanip>
#include <iostream>
#include <fstream>

#include <opencv2/core/core.hpp>
#include <opencv2/highgui/highgui.hpp>
#include <stdexcept>

namespace carp {

class Timing
{
    std::vector<double> cpu_timings;
    std::vector<double> gpu_p_copy_timings;
public:
    Timing(const std::string & name) {
        std::cout << "Measuring performance of " << name << std::endl;
    }

    void print( const std::chrono::duration<double,std::milli> &cpu, const std::chrono::duration<double,std::milli> &gpu_p_copy ) {
        std::cout << std::fixed << std::setprecision(6);
        std::cout << std::endl << "OpenCV time measurements for an individual experiment:" << std::endl;
        std::cout << "CPU Time    - GPU+copy" << std::endl;
        std::cout << std::setw(8) << cpu       .count() << " ms - ";
        std::cout << std::setw(8) << gpu_p_copy.count() << " ms" << std::endl;

        cpu_timings       .push_back(cpu       .count());
        gpu_p_copy_timings.push_back(gpu_p_copy.count());
    }

    ~Timing() {
        std::cout << std::endl << "OpenCV accumulated time measurements for all the experiments (in ms):" << std::endl;
        std::cout<<"[RealEyes] Accumulate CPU time           : "<< std::accumulate(cpu_timings       .begin(),cpu_timings       .end(),0.0) << "\n";
        std::cout<<"[RealEyes] Accumulate GPU time (inc copy): "<< std::accumulate(gpu_p_copy_timings.begin(),gpu_p_copy_timings.end(),0.0) << "\n";
    }
};

class record_t {
private:
    char *m_path;

public:
    cv::Mat cpuimg() const {
        return cv::imread(m_path);
    }

    record_t( char *path )
    {
	m_path = path;
    }

};

bool file_exists (char *name) {

    std::ifstream f(name);

    if (f.good()) {
        f.close();
        return true;
    } else {
        f.close();
        return false;
    }
}

std::vector<record_t>
get_pool( int argc, char *argv[] )
{
    int i;
    std::vector<record_t> pool;

    if (argc <= 1)
    {
       std::cerr << "Please provide an image as an argument to the program: ./program <image>" << std::endl;
       exit(1);
    }
    else
    {
	    for ( i = 1; i < argc; i++ )
	    {
		if (file_exists(argv[i]))
		        pool.push_back(record_t(argv[i]));
		else
			std::cerr << "File " << argv[i]
				  << " does not exist." << std::endl;
	    }
    }

    return pool;
}
}

#endif
<|endoftext|>


<commit_before><commit_msg>use the newly introduced LO_LIB_DIRS variable<commit_after><|endoftext|>


<commit_before>#include <iostream>
#include <complex>
#include <vector>

#include <htool/cluster.hpp>
#include <htool/lrmat.hpp>
#include <htool/fullACA.hpp>

using namespace std;
using namespace htool;

class MyMatrix: public IMatrix<double>{
	const vector<R3>& p1;
	const vector<R3>& p2;

public:
	MyMatrix(const vector<R3>& p10,const vector<R3>& p20 ):IMatrix<double>(p10.size(),p20.size()),p1(p10),p2(p20) {}
	 double get_coef(const int& i, const int& j)const {return 1./(4*M_PI*norm(p1[i]-p2[j]));}
	 std::vector<double> operator*(std::vector<double> a){
		std::vector<double> result(p1.size(),0);
		for (int i=0;i<p1.size();i++){
			for (int k=0;k<p2.size();k++){
				result[i]+=this->get_coef(i,k)*a[k];
			}
		}
		return result;
	 }
};

int main(){
	const int ndistance = 4;
	double distance[ndistance];
	distance[0] = 10; distance[1] = 20; distance[2] = 30; distance[3] = 40;
	SetNdofPerElt(1);
	bool test = 0;

	for(int idist=0; idist<ndistance; idist++)
	{
		cout << "Distance between the clusters: " << distance[idist] << endl;
		SetEpsilon(0.0001);
		srand (1);
		// we set a constant seed for rand because we want always the same result if we run the check many times
		// (two different initializations with the same seed will generate the same succession of results in the subsequent calls to rand)

		int nr = 500;
		int nc = 100;
		vector<int> Ir(nr); // row indices for the lrmatrix
		vector<int> Ic(nc); // column indices for the lrmatrix

		double z1 = 1;
		vector<R3>     p1(nr);
		vector<double> r1(nr);
		vector<int>  tab1(nr);
		for(int j=0; j<nr; j++){
			Ir[j] = j;
			double rho = ((double) rand() / (double)(RAND_MAX)); // (double) otherwise integer division!
			double theta = ((double) rand() / (double)(RAND_MAX));
			p1[j][0] = sqrt(rho)*cos(2*M_PI*theta); p1[j][1] = sqrt(rho)*sin(2*M_PI*theta); p1[j][2] = z1;
			// sqrt(rho) otherwise the points would be concentrated in the center of the disk
			r1[j]=0.;
			tab1[j]=j;
		}
		// p2: points in a unit disk of the plane z=z2
		double z2 = 1+distance[idist];
		vector<R3> p2(nc);
		vector<double> r2(nc);
		vector<int> tab2(nc);
		for(int j=0; j<nc; j++){
            Ic[j] = j;
			double rho = ((double) rand() / (RAND_MAX)); // (double) otherwise integer division!
			double theta = ((double) rand() / (RAND_MAX));
			p2[j][0] = sqrt(rho)*cos(2*M_PI*theta); p2[j][1] = sqrt(rho)*sin(2*M_PI*theta); p2[j][2] = z2;
			r2[j]=0.;
			tab2[j]=j;
		}

		MyMatrix A(p1,p2);

		// ACA
		int reqrank_max = 10;
		fullACA<double> A_fullACA(Ir,Ic,reqrank_max);
		A_fullACA.build(A);

		std::vector<double> fullACA_errors;
		for (int k = 0 ; k < A_fullACA.rank_of()+1 ; k++){
			fullACA_errors.push_back(Frobenius_absolute_error(A_fullACA,A,k));
		}

		// Test errors
		for (int i =1 ;i<fullACA_errors.size();i++){
			test = test || !(fullACA_errors[i-1]>fullACA_errors[i]);
		}
		cout << "Errors with Frobenius norm: "<<fullACA_errors<<endl;

		// Test compression
		test = test || !(0.87<A_fullACA.compression() && A_fullACA.compression()<0.89);
		cout << "Compression rate : "<<A_fullACA.compression()<<endl;

		// Test error on mat vec prod
		std::vector<double> f(nc,1);
		double error=norm2(A*f-A_fullACA*f);
		test = test ||!(error<1e-7);
		cout << "Errors on a mat vec prod : "<< error<<endl;

	}

	return test ;
}
<commit_msg>fullACA_tests => lrmat_fullACA_tests<commit_after><|endoftext|>


<commit_before>#include "gtest/gtest.h"
#include "asset.h"
#include "player.h"
#include "obstacle.h"

TEST(obstacle_test, collides_with_player) {
    int16_t x_position_player = 20;
    int16_t x_position_obstacle = 20;
    int16_t asset_width = 10;
    int16_t asset_height = 10;
    Asset asset(asset_width, asset_height, nullptr);
    Player player(x_position_player, asset);
    Obstacle obstacle(asset, x_position_obstacle);

    ASSERT_TRUE(obstacle.CollidesWith(player));
}

TEST(obstacle_test, doesnt_collide_with_player) {
    int16_t x_position_player = 20;
    int16_t x_position_obstacle = 40;
    int16_t asset_width = 10;
    int16_t asset_height = 10;
    Asset asset(asset_width, asset_height, nullptr);
    Player player(x_position_player, asset);
    Obstacle obstacle(asset, x_position_obstacle);

    ASSERT_FALSE(obstacle.CollidesWith(player));
}
<commit_msg>Test edge cases for collision on x-axis, start on y-axis test<commit_after>#include "gtest/gtest.h"
#include "asset.h"
#include "player.h"
#include "obstacle.h"

TEST(obstacle_test, collides_with_player) {
    int16_t x_position_player = 20;
    int16_t x_position_obstacle = 30;
    int16_t asset_width = 10;
    int16_t asset_height = 10;
    Asset asset(asset_width, asset_height, nullptr);
    Player player(x_position_player, asset);
    Obstacle obstacle(asset, x_position_obstacle);

    ASSERT_TRUE(obstacle.CollidesWith(player));
}

TEST(obstacle_test, doesnt_collide_with_player) {
    int16_t x_position_player = 20;
    int16_t x_position_obstacle = 31;
    int16_t asset_width = 10;
    int16_t asset_height = 10;
    Asset asset(asset_width, asset_height, nullptr);
    Player player(x_position_player, asset);
    Obstacle obstacle(asset, x_position_obstacle);

    ASSERT_FALSE(obstacle.CollidesWith(player));
}

TEST(obstacle_test, player_jumps_over_object) {
    int16_t x_position_player = 20;
    // distance is so that the player doesn't collide here
    int16_t x_position_obstacle = 31;
    int16_t asset_width = 10;
    int16_t asset_height = 5;
    Asset asset(asset_width, asset_height, nullptr);
    Player player(x_position_player, asset);
    Obstacle obstacle(asset, x_position_obstacle);

    // if player collided already, it's game over
    ASSERT_FALSE(obstacle.CollidesWith(player));

    player.Jump();
    player.UpdateYPosition();

    // assumption: the player velocity is 9, which is defined in the player.h file
    ASSERT_NE(0, player.GetYPosition());
    obstacle.UpdateXPosition();

    ASSERT_FALSE(obstacle.CollidesWith(player));
}<|endoftext|>


<commit_before>
#include <stdlib.h>
#include <stdio.h>
#include <stdint.h>
#include <string.h>

#include <sstream>
#include <iostream>
#include <iomanip>
#include <atomic>
#include <thread>
#include <chrono>

#include "jimi/http_all.h"
#include "stop_watch.h"

using namespace jimi;
using namespace jimi::http;

#ifdef NDEBUG
static const std::size_t kIterations = 3000000;
#else
static const std::size_t kIterations = 10000;
#endif

#if 1
    static const char * http_header =
        "GET /cookies HTTP/1.1\r\n"
        "Host: 127.0.0.1:8090\r\n"
        "Connection: keep-alive\r\n"
        "Cache-Control: max-age=0\r\n"
        "Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8\r\n"
        "User-Agent: Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.17 (KHTML, like Gecko) Chrome/24.0.1312.56 Safari/537.17\r\n"
        "Accept-Encoding: gzip,deflate,sdch\r\n"
        "Accept-Language: en-US,en;q=0.8\r\n"
        "Accept-Charset: ISO-8859-1,utf-8;q=0.7,*;q=0.3\r\n"
        "Cookie: name=wookie\r\n"
        "\r\n";
#else
    // Reference from /h2o/picohttpparser/benchmark.c
    static const char * http_header =
        "GET /wp-content/uploads/2010/03/hello-kitty-darth-vader-pink.jpg HTTP/1.1\r\n"
        "Host: www.kittyhell.com\r\n"
        "User-Agent: Mozilla/5.0 (Macintosh; U; Intel Mac OS X 10.6; ja-JP-mac; rv:1.9.2.3) Gecko/20100401 Firefox/3.6.3 Pathtraq/0.9\r\n"
        "Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8\r\n"
        "Accept-Language: ja,en-us;q=0.7,en;q=0.3\r\n"
        "Accept-Encoding: gzip,deflate\r\n"
        "Accept-Charset: Shift_JIS,utf-8;q=0.7,*;q=0.7\r\n"
        "Keep-Alive: 115\r\n"
        "Connection: keep-alive\r\n"
        "Cookie: wp_ozh_wsa_visits=2; wp_ozh_wsa_visit_lasttime=xxxxxxxxxx; "
        "__utma=xxxxxxxxx.xxxxxxxxxx.xxxxxxxxxx.xxxxxxxxxx.xxxxxxxxxx.x; "
        "__utmz=xxxxxxxxx.xxxxxxxxxx.x.x.utmccn=(referral)|utmcsr=reader.livedoor.com|utmcct=/reader/|utmcmd=referral\r\n"
        "\r\n";
#endif

void stop_watch_test()
{
    StopWatch sw;
    getTickCountStopWatch swTickCount;
    static const std::size_t kSleepIterations = 20;

    StopWatch::time_stamp_t start_time, end_time;
    StopWatch::time_point_t start_point, end_point;
    start_time = StopWatch::timestamp();
    start_point = StopWatch::now();
    sw.start();
    swTickCount.start();
    for (std::size_t i = 0; i < kSleepIterations; ++i) {
        std::this_thread::sleep_for(std::chrono::milliseconds(100));
    }
    swTickCount.stop();
    sw.stop();
    end_time = StopWatch::timestamp();
    end_point = StopWatch::now();

    std::cout << "Iterations:        " << kSleepIterations << std::endl;
    if (sw.getMillisec() != 0.0) {
        std::cout << "Time spent:        " << sw.getMillisec() << " ms" << std::endl;
        std::cout << "Time spent(*):     " << StopWatch::duration(end_time, start_time).millisecs() << " ms" << std::endl;
        std::cout << "Time spent(**):    " << StopWatch::duration(end_point, start_point).millisecs() << " ms" << std::endl;
        std::cout << "Time spent(Tick):  " << swTickCount.getMillisec() << " ms" << std::endl;
    }
    else {
        std::cout << "Time spent:        0.0 ms" << std::endl;
    }
    std::cout << std::endl;
}

void http_parser_test()
{
    StopWatch sw;
    int sum = 0;
    std::size_t request_len = ::strlen(http_header);

    std::cout << "-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=" << std::endl;
    std::cout << "  http_parser_test()" << std::endl;
    std::cout << "-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=" << std::endl;

    sw.start();
    for (std::size_t i = 0; i < kIterations; ++i) {
        http::Parser<1024> http_parser;
        sum += http_parser.parseRequest(http_header, request_len);
    }
    sw.stop();

    std::cout << std::endl;
    std::cout << "Sum:               " << sum << std::endl;
    std::cout << "Length:            " << ::strlen(http_header) << std::endl;
    std::cout << "Iterations:        " << kIterations << std::endl;
    if (sw.getMillisec() != 0.0) {
        std::cout << "Time spent:        " << sw.getMillisec() << " ms" << std::endl;
        std::cout << "Parse speed:       " << (uint64_t)((double)kIterations / sw.getSecond()) << " Parse/Sec" << std::endl;
        std::cout << "Parse throughput:  " << (double)(kIterations * request_len) / sw.getSecond() / (1024.0 * 1024.0) << " MB/Sec" << std::endl;
    }
    else {
        std::cout << "Time spent:        0.0 ms" << std::endl;
        std::cout << "Parse speed:       0   Parse/Sec" << std::endl;
        std::cout << "Parse throughput:  0.0 MB/Sec" << std::endl;
    }
    std::cout << std::endl;
}

void http_parser_ref_test()
{
    StopWatch sw;
    int sum = 0;
    std::size_t request_len = ::strlen(http_header);

    StringRefHelper helper;
    static int mark = 0;

    std::cout << "-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=" << std::endl;
    std::cout << "  http_parser_ref_test()" << std::endl;
    std::cout << "-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=" << std::endl;
    std::cout << std::endl;

    sw.start();
    for (std::size_t i = 0; i < kIterations; ++i) {
        http::ParserRef<1024> http_parser;
        sum += http_parser.parseRequest(http_header, request_len);
        if (mark < 3) {
            if (helper.attach(http_parser.getMethodStr())) {
                helper.truncate();
                std::cout << "method = " << http_parser.getMethodStr().c_str() << std::endl;
                helper.recover();
            }
            mark++;
        }
    }
    sw.stop();

    std::cout << std::endl;
    std::cout << "Sum:               " << sum << std::endl;
    std::cout << "Length:            " << ::strlen(http_header) << std::endl;
    std::cout << "Iterations:        " << kIterations << std::endl;
    if (sw.getMillisec() != 0.0) {
        std::cout << "Time spent:        " << sw.getMillisec() << " ms" << std::endl;
        std::cout << "Parse speed:       " << (uint64_t)((double)kIterations / sw.getSecond()) << " Parse/Sec" << std::endl;
        std::cout << "Parse throughput:  " << (double)(kIterations * request_len) / sw.getSecond() / (1024.0 * 1024.0) << " MB/Sec" << std::endl;
    }
    else {
        std::cout << "Time spent:        0.0 ms" << std::endl;
        std::cout << "Parse speed:       0   Parse/Sec" << std::endl;
        std::cout << "Parse throughput:  0.0 MB/Sec" << std::endl;
    }
    std::cout << std::endl;
}

void http_parser_benchmark()
{
    std::cout << "-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=" << std::endl;
    std::cout << "  http_parser_benchmark()" << std::endl;
    std::cout << "-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=" << std::endl;
    std::cout << std::endl;

    static const int kMaxLoop = 11;
    static std::atomic<int> loop_cnt(0);
	auto request_len = ::strlen(http_header);
	volatile int64_t count = 0;
    volatile int64_t dummy = 0;
	std::thread counter([&] {
		auto last_count = count;
		auto count_ = count;
        auto dummy_ = dummy;
		do {
            std::atomic_thread_fence(std::memory_order_acquire);
			count_ = count;
            dummy_ = dummy;
            std::atomic_thread_fence(std::memory_order_release);
#if 1
            std::cout << std::right << std::setw(10) << std::setfill(' ') << std::dec;
            std::cout << (count_ - last_count);
            std::cout << ", ";
			std::cout << std::right << std::setw(9) << std::setfill(' ') << std::fixed << std::setprecision(3);
            std::cout << (double)((count_ - last_count) * request_len) / 1024.0 / 1024.0 << " MB/Sec";
            std::cout << ",  ";
            std::cout << std::left << std::dec << ::strlen(http_header);
            std::cout << " bytes,  dummy = ";
            std::cout << std::left << std::dec << dummy_;
            std::cout << std::endl;
#else
            printf("%lld,  %0.3f MB/Sec,  %llu bytes,  %lld\n", (count_ - last_count), (double)((count_ - last_count) * request_len) / 1024.0 / 1024.0,
                ::strlen(http_header), dummy);
#endif
			last_count = count_;
			std::this_thread::sleep_for(std::chrono::milliseconds(1000));
            loop_cnt++;
            if (loop_cnt > kMaxLoop) {
                break;
            }
		} while (1);
	});

    http::Parser<1024> http_parser;
	do {
        int dummy_tmp = http_parser.parseRequest(http_header, request_len);
        //dummy_tmp += parser.getEntrySize();
        http_parser.reset();
        std::atomic_thread_fence(std::memory_order_acquire);
        dummy += dummy_tmp;
		count++;
        if (loop_cnt > kMaxLoop) {
            std::atomic_thread_fence(std::memory_order_release);
            if (counter.joinable()) {
                counter.join();
            }
            break;
        }
        std::atomic_thread_fence(std::memory_order_release);
	} while (1);

    std::cout << std::endl;
}

void http_parser_ref_benchmark()
{
    std::cout << "-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=" << std::endl;
    std::cout << "  http_parser_ref_benchmark()" << std::endl;
    std::cout << "-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=" << std::endl;
    std::cout << std::endl;

    static const int kMaxLoop = 11;
    static std::atomic<int> loop_cnt(0);
	auto request_len = ::strlen(http_header);
	volatile int64_t count = 0;
    volatile int64_t dummy = 0;
	std::thread counter([&] {
		auto last_count = count;
		auto count_ = count;
        auto dummy_ = dummy;
		do {
            std::atomic_thread_fence(std::memory_order_acquire);
			count_ = count;
            dummy_ = dummy;
            std::atomic_thread_fence(std::memory_order_release);
#if 1
            std::cout << std::right << std::setw(10) << std::setfill(' ') << std::dec;
            std::cout << (count_ - last_count);
            std::cout << ", ";
			std::cout << std::right << std::setw(9) << std::setfill(' ') << std::fixed << std::setprecision(3);
            std::cout << (double)((count_ - last_count) * request_len) / 1024.0 / 1024.0 << " MB/Sec";
            std::cout << ",  ";
            std::cout << std::left << std::dec << ::strlen(http_header);
            std::cout << " bytes,  dummy = ";
            std::cout << std::left << std::dec << dummy_;
            std::cout << std::endl;
#else
            printf("%lld,  %0.3f MB/Sec,  %llu bytes,  %lld\n", (count_ - last_count), (double)((count_ - last_count) * request_len) / 1024.0 / 1024.0,
                ::strlen(http_header), dummy);
#endif
			last_count = count_;
			std::this_thread::sleep_for(std::chrono::milliseconds(1000));
            loop_cnt++;
            if (loop_cnt > kMaxLoop) {
                break;
            }
		} while (1);
	});

    http::ParserRef<1024> http_parser;
	do {
        int dummy_tmp = http_parser.parseRequest(http_header, request_len);
        //dummy_tmp += parser.getEntrySize();
        http_parser.reset();
        std::atomic_thread_fence(std::memory_order_acquire);
        dummy += dummy_tmp;
		count++;
        if (loop_cnt > kMaxLoop) {
            std::atomic_thread_fence(std::memory_order_release);
            if (counter.joinable()) {
                counter.join();
            }
            break;
        }
        std::atomic_thread_fence(std::memory_order_release);
	} while (1);

    std::cout << std::endl;
}

int main(int argn, char * argv[])
{
    std::cout << std::endl;
    std::cout << "-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=" << std::endl;
    std::cout << "  Program: http_parser_test" << std::endl;
    std::cout << "-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=" << std::endl;
    std::cout << std::endl;

    http::Parser<1024> http_parser;
    http_parser.parseRequest(http_header, ::strlen(http_header));
    printf("http_parser.getVersion() = %u\n", http_parser.getVersion());
    printf("http_parser.getMethod() = %u\n", http_parser.getMethod());
    printf("\n");
    http_parser.displayFields();
    printf("\n");

#if 1
    //stop_watch_test();
    http_parser_test();
    http_parser_ref_test();
#endif

    http_parser_benchmark();
    http_parser_ref_benchmark();

#ifdef _WIN32
    ::system("pause");
#endif
    return 0;
}
<commit_msg>增加Dummy值的累加;<commit_after>
#include <stdlib.h>
#include <stdio.h>
#include <stdint.h>
#include <string.h>

#include <sstream>
#include <iostream>
#include <iomanip>
#include <atomic>
#include <thread>
#include <chrono>

#include "jimi/http_all.h"
#include "stop_watch.h"

using namespace jimi;
using namespace jimi::http;

#ifdef NDEBUG
static const std::size_t kIterations = 3000000;
#else
static const std::size_t kIterations = 10000;
#endif

#if 1
    static const char * http_header =
        "GET /cookies HTTP/1.1\r\n"
        "Host: 127.0.0.1:8090\r\n"
        "Connection: keep-alive\r\n"
        "Cache-Control: max-age=0\r\n"
        "Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8\r\n"
        "User-Agent: Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.17 (KHTML, like Gecko) Chrome/24.0.1312.56 Safari/537.17\r\n"
        "Accept-Encoding: gzip,deflate,sdch\r\n"
        "Accept-Language: en-US,en;q=0.8\r\n"
        "Accept-Charset: ISO-8859-1,utf-8;q=0.7,*;q=0.3\r\n"
        "Cookie: name=wookie\r\n"
        "\r\n";
#else
    // Reference from /h2o/picohttpparser/benchmark.c
    static const char * http_header =
        "GET /wp-content/uploads/2010/03/hello-kitty-darth-vader-pink.jpg HTTP/1.1\r\n"
        "Host: www.kittyhell.com\r\n"
        "User-Agent: Mozilla/5.0 (Macintosh; U; Intel Mac OS X 10.6; ja-JP-mac; rv:1.9.2.3) Gecko/20100401 Firefox/3.6.3 Pathtraq/0.9\r\n"
        "Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8\r\n"
        "Accept-Language: ja,en-us;q=0.7,en;q=0.3\r\n"
        "Accept-Encoding: gzip,deflate\r\n"
        "Accept-Charset: Shift_JIS,utf-8;q=0.7,*;q=0.7\r\n"
        "Keep-Alive: 115\r\n"
        "Connection: keep-alive\r\n"
        "Cookie: wp_ozh_wsa_visits=2; wp_ozh_wsa_visit_lasttime=xxxxxxxxxx; "
        "__utma=xxxxxxxxx.xxxxxxxxxx.xxxxxxxxxx.xxxxxxxxxx.xxxxxxxxxx.x; "
        "__utmz=xxxxxxxxx.xxxxxxxxxx.x.x.utmccn=(referral)|utmcsr=reader.livedoor.com|utmcct=/reader/|utmcmd=referral\r\n"
        "\r\n";
#endif

void stop_watch_test()
{
    StopWatch sw;
    getTickCountStopWatch swTickCount;
    static const std::size_t kSleepIterations = 20;

    StopWatch::time_stamp_t start_time, end_time;
    StopWatch::time_point_t start_point, end_point;
    start_time = StopWatch::timestamp();
    start_point = StopWatch::now();
    sw.start();
    swTickCount.start();
    for (std::size_t i = 0; i < kSleepIterations; ++i) {
        std::this_thread::sleep_for(std::chrono::milliseconds(100));
    }
    swTickCount.stop();
    sw.stop();
    end_time = StopWatch::timestamp();
    end_point = StopWatch::now();

    std::cout << "Iterations:        " << kSleepIterations << std::endl;
    if (sw.getMillisec() != 0.0) {
        std::cout << "Time spent:        " << sw.getMillisec() << " ms" << std::endl;
        std::cout << "Time spent(*):     " << StopWatch::duration(end_time, start_time).millisecs() << " ms" << std::endl;
        std::cout << "Time spent(**):    " << StopWatch::duration(end_point, start_point).millisecs() << " ms" << std::endl;
        std::cout << "Time spent(Tick):  " << swTickCount.getMillisec() << " ms" << std::endl;
    }
    else {
        std::cout << "Time spent:        0.0 ms" << std::endl;
    }
    std::cout << std::endl;
}

void http_parser_test()
{
    StopWatch sw;
    int sum = 0;
    std::size_t request_len = ::strlen(http_header);

    std::cout << "-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=" << std::endl;
    std::cout << "  http_parser_test()" << std::endl;
    std::cout << "-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=" << std::endl;

    sw.start();
    for (std::size_t i = 0; i < kIterations; ++i) {
        http::Parser<1024> http_parser;
        sum += http_parser.parseRequest(http_header, request_len);
    }
    sw.stop();

    std::cout << std::endl;
    std::cout << "Sum:               " << sum << std::endl;
    std::cout << "Length:            " << ::strlen(http_header) << std::endl;
    std::cout << "Iterations:        " << kIterations << std::endl;
    if (sw.getMillisec() != 0.0) {
        std::cout << "Time spent:        " << sw.getMillisec() << " ms" << std::endl;
        std::cout << "Parse speed:       " << (uint64_t)((double)kIterations / sw.getSecond()) << " Parse/Sec" << std::endl;
        std::cout << "Parse throughput:  " << (double)(kIterations * request_len) / sw.getSecond() / (1024.0 * 1024.0) << " MB/Sec" << std::endl;
    }
    else {
        std::cout << "Time spent:        0.0 ms" << std::endl;
        std::cout << "Parse speed:       0   Parse/Sec" << std::endl;
        std::cout << "Parse throughput:  0.0 MB/Sec" << std::endl;
    }
    std::cout << std::endl;
}

void http_parser_ref_test()
{
    StopWatch sw;
    int sum = 0;
    std::size_t request_len = ::strlen(http_header);

    StringRefHelper helper;
    static int mark = 0;

    std::cout << "-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=" << std::endl;
    std::cout << "  http_parser_ref_test()" << std::endl;
    std::cout << "-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=" << std::endl;
    std::cout << std::endl;

    sw.start();
    for (std::size_t i = 0; i < kIterations; ++i) {
        http::ParserRef<1024> http_parser;
        sum += http_parser.parseRequest(http_header, request_len);
        if (mark < 3) {
            if (helper.attach(http_parser.getMethodStr())) {
                helper.truncate();
                std::cout << "method = " << http_parser.getMethodStr().c_str() << std::endl;
                helper.recover();
            }
            mark++;
        }
    }
    sw.stop();

    std::cout << std::endl;
    std::cout << "Sum:               " << sum << std::endl;
    std::cout << "Length:            " << ::strlen(http_header) << std::endl;
    std::cout << "Iterations:        " << kIterations << std::endl;
    if (sw.getMillisec() != 0.0) {
        std::cout << "Time spent:        " << sw.getMillisec() << " ms" << std::endl;
        std::cout << "Parse speed:       " << (uint64_t)((double)kIterations / sw.getSecond()) << " Parse/Sec" << std::endl;
        std::cout << "Parse throughput:  " << (double)(kIterations * request_len) / sw.getSecond() / (1024.0 * 1024.0) << " MB/Sec" << std::endl;
    }
    else {
        std::cout << "Time spent:        0.0 ms" << std::endl;
        std::cout << "Parse speed:       0   Parse/Sec" << std::endl;
        std::cout << "Parse throughput:  0.0 MB/Sec" << std::endl;
    }
    std::cout << std::endl;
}

void http_parser_benchmark()
{
    std::cout << "-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=" << std::endl;
    std::cout << "  http_parser_benchmark()" << std::endl;
    std::cout << "-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=" << std::endl;
    std::cout << std::endl;

    static const int kMaxLoop = 11;
    static std::atomic<int> loop_cnt(0);
	auto request_len = ::strlen(http_header);
	volatile int64_t count = 0;
    volatile int64_t dummy = 0;
	std::thread counter([&] {
		auto last_count = count;
		auto count_ = count;
        auto dummy_ = dummy;
		do {
            std::atomic_thread_fence(std::memory_order_acquire);
			count_ = count;
            dummy_ = dummy;
            std::atomic_thread_fence(std::memory_order_release);
#if 1
            std::cout << std::right << std::setw(10) << std::setfill(' ') << std::dec;
            std::cout << (count_ - last_count);
            std::cout << ", ";
			std::cout << std::right << std::setw(9) << std::setfill(' ') << std::fixed << std::setprecision(3);
            std::cout << (double)((count_ - last_count) * request_len) / 1024.0 / 1024.0 << " MB/Sec";
            std::cout << ",  ";
            std::cout << std::left << std::dec << ::strlen(http_header);
            std::cout << " bytes,  dummy = ";
            std::cout << std::left << std::dec << dummy_;
            std::cout << std::endl;
#else
            printf("%lld,  %0.3f MB/Sec,  %llu bytes,  %lld\n", (count_ - last_count), (double)((count_ - last_count) * request_len) / 1024.0 / 1024.0,
                ::strlen(http_header), dummy);
#endif
			last_count = count_;
			std::this_thread::sleep_for(std::chrono::milliseconds(1000));
            loop_cnt++;
            if (loop_cnt > kMaxLoop) {
                break;
            }
		} while (1);
	});

    http::Parser<1024> http_parser;
	do {
        int64_t dummy_tmp = http_parser.parseRequest(http_header, request_len);
        dummy_tmp += (int64_t)http_parser.getEntrySize();
        http_parser.reset();
        std::atomic_thread_fence(std::memory_order_acquire);
        dummy += dummy_tmp;
		count++;
        if (loop_cnt > kMaxLoop) {
            std::atomic_thread_fence(std::memory_order_release);
            if (counter.joinable()) {
                counter.join();
            }
            break;
        }
        std::atomic_thread_fence(std::memory_order_release);
	} while (1);

    std::cout << std::endl;
}

void http_parser_ref_benchmark()
{
    std::cout << "-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=" << std::endl;
    std::cout << "  http_parser_ref_benchmark()" << std::endl;
    std::cout << "-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=" << std::endl;
    std::cout << std::endl;

    static const int kMaxLoop = 11;
    static std::atomic<int> loop_cnt(0);
	auto request_len = ::strlen(http_header);
	volatile int64_t count = 0;
    volatile int64_t dummy = 0;
	std::thread counter([&] {
		auto last_count = count;
		auto count_ = count;
        auto dummy_ = dummy;
		do {
            std::atomic_thread_fence(std::memory_order_acquire);
			count_ = count;
            dummy_ = dummy;
            std::atomic_thread_fence(std::memory_order_release);
#if 1
            std::cout << std::right << std::setw(10) << std::setfill(' ') << std::dec;
            std::cout << (count_ - last_count);
            std::cout << ", ";
			std::cout << std::right << std::setw(9) << std::setfill(' ') << std::fixed << std::setprecision(3);
            std::cout << (double)((count_ - last_count) * request_len) / 1024.0 / 1024.0 << " MB/Sec";
            std::cout << ",  ";
            std::cout << std::left << std::dec << ::strlen(http_header);
            std::cout << " bytes,  dummy = ";
            std::cout << std::left << std::dec << dummy_;
            std::cout << std::endl;
#else
            printf("%lld,  %0.3f MB/Sec,  %llu bytes,  %lld\n", (count_ - last_count), (double)((count_ - last_count) * request_len) / 1024.0 / 1024.0,
                ::strlen(http_header), dummy);
#endif
			last_count = count_;
			std::this_thread::sleep_for(std::chrono::milliseconds(1000));
            loop_cnt++;
            if (loop_cnt > kMaxLoop) {
                break;
            }
		} while (1);
	});

    http::ParserRef<1024> http_parser;
	do {
        int64_t dummy_tmp = http_parser.parseRequest(http_header, request_len);
        dummy_tmp += (int64_t)http_parser.getEntrySize();
        http_parser.reset();
        std::atomic_thread_fence(std::memory_order_acquire);
        dummy += dummy_tmp;
		count++;
        if (loop_cnt > kMaxLoop) {
            std::atomic_thread_fence(std::memory_order_release);
            if (counter.joinable()) {
                counter.join();
            }
            break;
        }
        std::atomic_thread_fence(std::memory_order_release);
	} while (1);

    std::cout << std::endl;
}

int main(int argn, char * argv[])
{
    std::cout << std::endl;
    std::cout << "-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=" << std::endl;
    std::cout << "  Program: http_parser_test" << std::endl;
    std::cout << "-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=" << std::endl;
    std::cout << std::endl;

    http::Parser<1024> http_parser;
    http_parser.parseRequest(http_header, ::strlen(http_header));
    printf("http_parser.getVersion() = %u\n", http_parser.getVersion());
    printf("http_parser.getMethod() = %u\n", http_parser.getMethod());
    printf("\n");
    http_parser.displayFields();
    printf("\n");

#if 1
    //stop_watch_test();
    http_parser_test();
    http_parser_ref_test();
#endif

    http_parser_benchmark();
    http_parser_ref_benchmark();

#ifdef _WIN32
    ::system("pause");
#endif
    return 0;
}
<|endoftext|>


<commit_before>#include <stan/services/error_codes.hpp>
#include <cmdstan/command.hpp>
#include <gtest/gtest.h>
#include <string>
#include <test/utility.hpp>
#include <stdexcept>
#include <boost/math/policies/error_handling.hpp>
#include <stan/callbacks/stream_writer.hpp>

using cmdstan::test::convert_model_path;
using cmdstan::test::count_matches;
using cmdstan::test::multiple_command_separator;
using cmdstan::test::run_command;
using cmdstan::test::run_command_output;

TEST(StanUiCommand, metric_file_test) {
  std::vector<std::string> models = { "proper", "test_model" };
  std::vector<std::string> engines = { "static", "nuts" };
  std::vector<std::string> metrics = { "diag_e", "dense_e" };
  std::vector<std::string> adapts = { "0", "1" };

  std::map<std::string, std::map<std::string, std::string> > expected_output = {
    { "proper", {
        { "diag_e", "# Diagonal elements of inverse mass matrix:\n# 1.5" },
        { "dense_e", "# Elements of inverse mass matrix:\n# 1.5" }
      }
    },
    { "test_model", {
        { "diag_e", "# Diagonal elements of inverse mass matrix:\n# 1.5, 1.8" },
        { "dense_e", "# Elements of inverse mass matrix:\n# 1.5, 1\n# 1, 1.5" }
      }
    }
  };

  for (auto model : models) {
    for (auto engine : engines) {
      for (auto metric : metrics) {
        for (auto adapt : adapts) {
          std::vector<std::string> model_path;
          model_path.push_back("src");
          model_path.push_back("test");
          model_path.push_back("test-models");
          model_path.push_back(model);

          std::vector<std::string> metric_file_path;
          metric_file_path.push_back("src");
          metric_file_path.push_back("test");
          metric_file_path.push_back("test-models");
          metric_file_path.push_back(model + "." + metric + "_metric.dat.R");

          std::string command = convert_model_path(model_path) +
            " method=sample num_samples=1 num_warmup=1 adapt engaged=" + adapt +
            " algorithm=hmc engine=" + engine + " metric=" + metric +
            " metric_file=" + convert_model_path(metric_file_path) +
            " output file=test/output.csv";

          run_command_output out = run_command(command);
          EXPECT_EQ(int(stan::services::error_codes::OK), out.err_code);

          std::fstream output_csv_stream("test/output.csv");
          std::stringstream output_sstream;
          output_sstream << output_csv_stream.rdbuf();
          output_csv_stream.close();
          std::string output = output_sstream.str();

          EXPECT_EQ(1, count_matches(expected_output[model][metric], output));
        }
      }
    }
  }
}
<commit_msg>Added some more tests to the metric initialization to try to figure out Issue 602<commit_after>#include <stan/services/error_codes.hpp>
#include <cmdstan/command.hpp>
#include <gtest/gtest.h>
#include <string>
#include <test/utility.hpp>
#include <stdexcept>
#include <boost/math/policies/error_handling.hpp>
#include <stan/callbacks/stream_writer.hpp>

using cmdstan::test::convert_model_path;
using cmdstan::test::count_matches;
using cmdstan::test::multiple_command_separator;
using cmdstan::test::run_command;
using cmdstan::test::run_command_output;

TEST(StanUiCommand, metric_file_test) {
  std::vector<std::string> models = { "proper", "test_model" };
  std::vector<std::string> engines = { "static", "nuts" };
  std::vector<std::string> metrics = { "diag_e", "dense_e" };
  std::vector<std::string> adapts = { "0", "1" };
  std::vector<std::string> stepsizes = { "0.1", "0.5", "1.25" };
  std::vector<std::string> num_warmups = { "0", "1", "100" };

  std::map<std::string, std::map<std::string, std::string> > expected_output = {
    { "proper", {
        { "diag_e", "# Diagonal elements of inverse mass matrix:\n# 1.5" },
        { "dense_e", "# Elements of inverse mass matrix:\n# 1.5" }
      }
    },
    { "test_model", {
        { "diag_e", "# Diagonal elements of inverse mass matrix:\n# 1.5, 1.8" },
        { "dense_e", "# Elements of inverse mass matrix:\n# 1.5, 1\n# 1, 1.5" }
      }
    }
  };

  for (auto model : models) {
    for (auto engine : engines) {
      for (auto metric : metrics) {
        for (auto adapt : adapts) {
          for (auto stepsize : stepsizes) {
            for (auto num_warmup : num_warmups) {
              std::vector<std::string> model_path;
              model_path.push_back("src");
              model_path.push_back("test");
              model_path.push_back("test-models");
              model_path.push_back(model);

              std::vector<std::string> metric_file_path;
              metric_file_path.push_back("src");
              metric_file_path.push_back("test");
              metric_file_path.push_back("test-models");
              metric_file_path.push_back(model + "." + metric +
                                         "_metric.dat.R");

              std::string command = convert_model_path(model_path) +
                " method=sample num_samples=100 num_warmup=" + num_warmup +
                " adapt engaged=" + adapt + " algorithm=hmc engine=" + engine +
                " metric=" + metric +
                " metric_file=" + convert_model_path(metric_file_path) +
                " stepsize=" + stepsize + " output file=test/output.csv";

              run_command_output out = run_command(command);
              EXPECT_EQ(int(stan::services::error_codes::OK), out.err_code);

              std::fstream output_csv_stream("test/output.csv");
              std::stringstream output_sstream;
              output_sstream << output_csv_stream.rdbuf();
              output_csv_stream.close();
              std::string output = output_sstream.str();

              EXPECT_EQ(1, count_matches(expected_output[model][metric],
                                         output));
              if(adapt == "0")
                EXPECT_EQ(1, count_matches("# Step size = " + stepsize,
                                           output));
            }
          }
        }
      }
    }
  }
}
<|endoftext|>