Boost.Proto


Boost.     #4 2011/02/26
         /@fjnli id:fjnl


1
Twitter       (   ) ...




          2
http://atnd.org/events/11551




           3
http://atnd.org/events/11551


Proto




           3
http://atnd.org/events/11551


    Proto




Lambda, Spirit, uBLAS
    Proto



               3
Boost.Proto




4
Boost.    #4
         Proto       (   )




            Proto




                 5
Agenda

•

• Boost.Proto

•

•        +


                  6
Agenda

•

• Boost.Proto

•

•        +


                  6
Agenda

•
                         15
• Boost.Proto
                         5
•

•        +


                  6
Agenda


• Boost.Proto
  • Boost.Proto
  • Expression Template (ET)
  • Boost.Proto

                               7
Agenda

•
    •             Boost.Proto

    • Boost.uBLAS
    • General Purpose computing on GPU (GPGPU)

    • ET →
                           8
•                  (         )

• @fjnli, id:fjnl

•                    →           (   )

• Ariel Networks

•            : GPU




                         9
•                  (           )

• @fjnli, id:fjnl

•                    →
                      Hatena ID    i
                                       (   )

• Ariel Networks

•            : GPU




                             9
•                  (           )

• @fjnli, id:fjnl

•                    →
                      Hatena ID
                        ※
                                   i
                                       (   )

• Ariel Networks

•            : GPU




                             9
•                  (          )

• @fjnli, id:fjnl

•                    →            (   )

• Ariel Networks

•            : GPU




                         10
.begin();


 11
Proto


• Expression Template (ET)

  • a + b * c → plus<A, multiply<B, C>>
• Boost 1.37
• Headers only

                             12
Proto

• Boost.Proto

• Boost Boost.Proto               :

  • Boost.Spirit (Qi, Karma, Lex)
  • Boost.Phoenix v3 (in the future)
  • Boost.MSM.eUML (experimental, 1.44)
  • Boost.Xpressive
                          13
ET



•
    •
        •                     ´   ω


    • Qi    Proto



                         14
using

namespace proto = boost::proto;
using namespace boost::proto;
using boost::proto::argsns_::list2,
using boost::proto::exprns_::expr;
using boost::proto::exprns_::term;



                 15
a[b] + (c * d)

 (Syntax Tree)   :




        16
a[b] + (c * d)

       (Syntax Tree)                 :


               (+)

    ([])                   (*)

a          b           c         d



               16
a[b] + (c * d)
expr<tag::plus,
  list2<
    expr<tag::subscript,
       list2<,
         expr<tag::terminal,   term<int>, 0>&,
         expr<tag::terminal,   term<int>, 0>&
       >, 2
    > const&,
    expr<tag::multiplies,
       list2<
         expr<tag::terminal,   term<int> 0>&,
         expr<tag::terminal,   term<int> 0>&
       >, 2
    > const&
  >, 2
> const
                               17
a[b] + (c * d)
expr<tag::plus,
  list2<
    expr<tag::subscript, expr
                 exprns_::
       list2<,
         expr<tag::terminal, term<int>, 0>&,
         expr<tag::terminal, term<int>, 0>&
       >, 2
    > const&,
    expr<tag::multiplies,
       list2<
         expr<tag::terminal, term<int> 0>&,
         expr<tag::terminal, term<int> 0>&
       >, 2
    > const&
  >, 2
> const
                              18
a[b] + (c * d)
expr<tag::plus,
  list2<                                   plus → +
    expr<tag::subscript,
                                        multiplies → *
       list2<,
         expr<tag::terminal,            subscript → []
                               term<int>, 0>&,
         expr<tag::terminal,   term<int>, 0>&    …
       >, 2
    > const&,
    expr<tag::multiplies,
       list2<
         expr<tag::terminal,   term<int> 0>&,
         expr<tag::terminal,   term<int> 0>&
       >, 2
    > const&
  >, 2
> const
                               19
a[b] + (c * d)
expr<tag::plus,
  list2<
    expr<tag::subscript,
       list2<,          argsns_::listN
         expr<tag::terminal, term<int>, 0>&,
         expr<tag::terminal, term<int>, 0>&
       >, 2
    > const&,
    expr<tag::multiplies,
       list2<
         expr<tag::terminal, term<int> 0>&,
         expr<tag::terminal, term<int> 0>&
       >, 2
    > const&
  >, 2
> const
                              20
a[b] + (c * d)
expr<tag::plus,
  list2<
    expr<tag::subscript,                 exprns_::term
       list2<,
         expr<tag::terminal,   term<int>, 0>&,
         expr<tag::terminal,   term<int>, 0>&
       >, 2
    > const&,
    expr<tag::multiplies,
       list2<
         expr<tag::terminal,   term<int> 0>&,
         expr<tag::terminal,   term<int> 0>&
       >, 2
    > const&
  >, 2
> const
                               21
a[b] + (c * d)
expr<tag::plus,
  list2<
    expr<tag::subscript,
       list2<,
         expr<tag::terminal,   term<int>, 0>&,
         expr<tag::terminal,   term<int>, 0>&
       >, 2
    > const&,
    expr<tag::multiplies,
       list2<
         expr<tag::terminal,   term<int> 0>&,
         expr<tag::terminal,   term<int> 0>&
       >, 2
    > const&
  >, 2
> const
                               22
:

default_context const ctx;
std::cout << eval(lit(1) + 2 + 3, ctx)
          << std::endl;

        :

6


                   23
:

default_context const ctx;
std::cout << eval(lit(1) + 2 + 3, ctx)
          << std::endl;




                   24
default_context → C++
null_context →




                    25
+    -


•x + y        x-y



 •                       int   +



     •→

                    26
+   -
struct my_context {
   template <
     class Expr,
     class Enable = void
    > struct eval;
};

eval
my_context::eval<Expr>()(expr, ctx)



                     27
+   -
struct my_context {
   template <
     class Expr,
     class Enable = void
    > struct eval;
                           SFINAE
};

eval
my_context::eval<Expr>()(expr, ctx)



                     27
SFINAE

• SFINAE (            ?)

  • Substitution Failure Is Not An Error
  •
• boost::enable_if
  •template <class T>
   typename enable_if<is_const<T>>::type foo();

• SFINAE          eval

                          28
+       -
template <class Expr>
struct eval<
  Expr,
  typename boost::enable_if<
    matches<Expr, terminal<int>>
  >::type
> {
  typedef int result_type;

    result_type
    operator ()(Expr& e, my_context const&)
    const {
      return value(e);
    }
}
                           29
+       -
template <class Expr>
struct eval<
  Expr,
  typename boost::enable_if<
    matches<Expr, terminal<int>>
  >::type
> {                         proto                  :
  typedef int result_type;
                     Expr   terminal<int>

    result_type                             true
    operator ()(Expr& e, my_context const&)
    const {
      return value(e);
    }
}
                            30
+       -
template <class Expr>
struct eval<
  Expr,
  typename boost::enable_if<
    matches<Expr, terminal<int>>
  >::type
> {
  typedef int result_type;

    result_type
    operator ()(Expr& e, C++0x
                         my_context const&)
                                 decltype
    const {
      return value(e);
    }
}
                           31
+       -
template <class Expr>
struct eval<
  Expr,
  typename boost::enable_if<
    matches<Expr, terminal<int>>
  >::type
> {
  typedef int result_type;

    result_type
    operator ()(Expr& e, my_context const&)
    const {
      return value(e);
    }
}
                           32
+       -
template <class Expr>
struct eval<
  Expr,
  typename boost::enable_if<
    matches<Expr, terminal<int>>
  >::type
> {
  typedef int result_type;

    result_type
    operator ()(Expr& e, my_context const&)
    const {
      return value(e);
    }
}
                           33
+       -
template <class Expr>
struct eval<
  Expr,
  typename boost::enable_if<
    matches<Expr, plus<_, _>>
  >::type
> {
  typedef int result_type;

    result_type
    operator ()(Expr& e, my_context const& ctx)
    const {
      return proto::eval(left(e), ctx) -
             proto::eval(right(e), ctx);
    }
}
                           34
+       -
template <class Expr>
struct eval<
  Expr,
  typename boost::enable_if<
    matches<Expr, plus<_, _>>
  >::type
> {                        _
  typedef int result_type;        (wildcard)

    result_type
    operator ()(Expr& e, my_context const& ctx)
    const {
      return proto::eval(left(e), ctx) -
             proto::eval(right(e), ctx);
    }
}
                           35
+       -
template <class Expr>
struct eval<
  Expr,
  typename boost::enable_if<
    matches<Expr, plus<_, _>>
  >::type
> {
  typedef int result_type;
                                left: 1
    result_type
                              right: 2
    operator ()(Expr& e, my_context const& ctx)
    const {
      return proto::eval(left(e), ctx) -
             proto::eval(right(e), ctx);
    }
}
                           36
+       -
template <class Expr>
struct eval<
  Expr,
  typename boost::enable_if<
    matches<Expr, plus<_, _>>
  >::type
> {
  typedef int result_type;

    result_type
    operator ()(Expr& e, my_context const& ctx)
    const {
      return proto::eval(left(e), ctx) -
             proto::eval(right(e), ctx);
    }
}
                           37
+       -
template <class Expr>
struct eval<
  Expr,
  typename boost::enable_if<
    matches<Expr, plus<_, _>>
  >::type
> {
  typedef int result_type;

    result_type
    operator ()(Expr& e, my_context const& ctx)
    const {
      return proto::eval(left(e), ctx) -
             proto::eval(right(e), ctx);
    }
}
                           38
2

     :

my_context const ctx;
std::cout << eval(lit(1) + 2 + 3, ctx)
          << std::endl;

         :

-4


                   39
/


•                :

    • proto::left, proto::right
•                                 :

    • proto::result_of::left, proto::result_of::right
    • C++0x

                                  40
• Context
  •
• Domain
  •
• Extends
  •
• Grammer
  •
            41
:


1.User’s Guide
     http://www.boost.org/doc/libs/1_46_0/doc/html/proto/
     users_guide.html
2.              (C++ Advent Calender JP 2010; 16     )

     http://d.hatena.ne.jp/fjnl/20101222/


                                42
.end();
.begin();


 43
Proto
• ET
  •
    •
  •              (+               )

•(                         )



 • Basic Linear Algebra Subprograms (BLAS)
                          44
Boost.uBLAS



• Boost.uBLAS
• Boost.uBLAS
• Boost.uBLAS


                45
Boost.uBLAS

•                  CPU, GPU

    •                   →

•                CPU   GPU

    •    :

        •
        • CPU:         , ATLAS, GotoBLAS, OpenCL

        • GPU:         , CUBLAS, OpenCL
                              46
ET →
        Backend::scalar a;
        Backend::vector b, x, y;
        y = a * x + b;




Backend::eval<
  multiply, scalar, vector>()(y, a, x);
Backend::eval<
  plus, vector, vector>()(y, y, b);

                   47
(Cell, GPU    )
               [a * x + y]
plus<multiply<scalar, vector>, vector>



axpy<scalar, vector, vector>

                   48
49

Boost.勉強会#4 Boost.Proto

  • 1.
    Boost.Proto Boost. #4 2011/02/26 /@fjnli id:fjnl 1
  • 2.
    Twitter ( ) ... 2
  • 3.
  • 4.
  • 5.
    http://atnd.org/events/11551 Proto Lambda, Spirit, uBLAS Proto 3
  • 6.
  • 7.
    Boost. #4 Proto ( ) Proto 5
  • 8.
  • 9.
  • 10.
    Agenda • 15 • Boost.Proto 5 • • + 6
  • 11.
    Agenda • Boost.Proto • Boost.Proto • Expression Template (ET) • Boost.Proto 7
  • 12.
    Agenda • • Boost.Proto • Boost.uBLAS • General Purpose computing on GPU (GPGPU) • ET → 8
  • 13.
    ( ) • @fjnli, id:fjnl • → ( ) • Ariel Networks • : GPU 9
  • 14.
    ( ) • @fjnli, id:fjnl • → Hatena ID i ( ) • Ariel Networks • : GPU 9
  • 15.
    ( ) • @fjnli, id:fjnl • → Hatena ID ※ i ( ) • Ariel Networks • : GPU 9
  • 16.
    ( ) • @fjnli, id:fjnl • → ( ) • Ariel Networks • : GPU 10
  • 17.
  • 18.
    Proto • Expression Template(ET) • a + b * c → plus<A, multiply<B, C>> • Boost 1.37 • Headers only 12
  • 19.
    Proto • Boost.Proto • BoostBoost.Proto : • Boost.Spirit (Qi, Karma, Lex) • Boost.Phoenix v3 (in the future) • Boost.MSM.eUML (experimental, 1.44) • Boost.Xpressive 13
  • 20.
    ET • • • ´ ω • Qi Proto 14
  • 21.
    using namespace proto =boost::proto; using namespace boost::proto; using boost::proto::argsns_::list2, using boost::proto::exprns_::expr; using boost::proto::exprns_::term; 15
  • 22.
    a[b] + (c* d) (Syntax Tree) : 16
  • 23.
    a[b] + (c* d) (Syntax Tree) : (+) ([]) (*) a b c d 16
  • 24.
    a[b] + (c* d) expr<tag::plus, list2< expr<tag::subscript, list2<, expr<tag::terminal, term<int>, 0>&, expr<tag::terminal, term<int>, 0>& >, 2 > const&, expr<tag::multiplies, list2< expr<tag::terminal, term<int> 0>&, expr<tag::terminal, term<int> 0>& >, 2 > const& >, 2 > const 17
  • 25.
    a[b] + (c* d) expr<tag::plus, list2< expr<tag::subscript, expr exprns_:: list2<, expr<tag::terminal, term<int>, 0>&, expr<tag::terminal, term<int>, 0>& >, 2 > const&, expr<tag::multiplies, list2< expr<tag::terminal, term<int> 0>&, expr<tag::terminal, term<int> 0>& >, 2 > const& >, 2 > const 18
  • 26.
    a[b] + (c* d) expr<tag::plus, list2< plus → + expr<tag::subscript, multiplies → * list2<, expr<tag::terminal, subscript → [] term<int>, 0>&, expr<tag::terminal, term<int>, 0>& … >, 2 > const&, expr<tag::multiplies, list2< expr<tag::terminal, term<int> 0>&, expr<tag::terminal, term<int> 0>& >, 2 > const& >, 2 > const 19
  • 27.
    a[b] + (c* d) expr<tag::plus, list2< expr<tag::subscript, list2<, argsns_::listN expr<tag::terminal, term<int>, 0>&, expr<tag::terminal, term<int>, 0>& >, 2 > const&, expr<tag::multiplies, list2< expr<tag::terminal, term<int> 0>&, expr<tag::terminal, term<int> 0>& >, 2 > const& >, 2 > const 20
  • 28.
    a[b] + (c* d) expr<tag::plus, list2< expr<tag::subscript, exprns_::term list2<, expr<tag::terminal, term<int>, 0>&, expr<tag::terminal, term<int>, 0>& >, 2 > const&, expr<tag::multiplies, list2< expr<tag::terminal, term<int> 0>&, expr<tag::terminal, term<int> 0>& >, 2 > const& >, 2 > const 21
  • 29.
    a[b] + (c* d) expr<tag::plus, list2< expr<tag::subscript, list2<, expr<tag::terminal, term<int>, 0>&, expr<tag::terminal, term<int>, 0>& >, 2 > const&, expr<tag::multiplies, list2< expr<tag::terminal, term<int> 0>&, expr<tag::terminal, term<int> 0>& >, 2 > const& >, 2 > const 22
  • 30.
    : default_context const ctx; std::cout<< eval(lit(1) + 2 + 3, ctx) << std::endl; : 6 23
  • 31.
    : default_context const ctx; std::cout<< eval(lit(1) + 2 + 3, ctx) << std::endl; 24
  • 32.
  • 33.
    + - •x + y x-y • int + •→ 26
  • 34.
    + - struct my_context { template < class Expr, class Enable = void > struct eval; }; eval my_context::eval<Expr>()(expr, ctx) 27
  • 35.
    + - struct my_context { template < class Expr, class Enable = void > struct eval; SFINAE }; eval my_context::eval<Expr>()(expr, ctx) 27
  • 36.
    SFINAE • SFINAE ( ?) • Substitution Failure Is Not An Error • • boost::enable_if •template <class T> typename enable_if<is_const<T>>::type foo(); • SFINAE eval 28
  • 37.
    + - template <class Expr> struct eval< Expr, typename boost::enable_if< matches<Expr, terminal<int>> >::type > { typedef int result_type; result_type operator ()(Expr& e, my_context const&) const { return value(e); } } 29
  • 38.
    + - template <class Expr> struct eval< Expr, typename boost::enable_if< matches<Expr, terminal<int>> >::type > { proto : typedef int result_type; Expr terminal<int> result_type true operator ()(Expr& e, my_context const&) const { return value(e); } } 30
  • 39.
    + - template <class Expr> struct eval< Expr, typename boost::enable_if< matches<Expr, terminal<int>> >::type > { typedef int result_type; result_type operator ()(Expr& e, C++0x my_context const&) decltype const { return value(e); } } 31
  • 40.
    + - template <class Expr> struct eval< Expr, typename boost::enable_if< matches<Expr, terminal<int>> >::type > { typedef int result_type; result_type operator ()(Expr& e, my_context const&) const { return value(e); } } 32
  • 41.
    + - template <class Expr> struct eval< Expr, typename boost::enable_if< matches<Expr, terminal<int>> >::type > { typedef int result_type; result_type operator ()(Expr& e, my_context const&) const { return value(e); } } 33
  • 42.
    + - template <class Expr> struct eval< Expr, typename boost::enable_if< matches<Expr, plus<_, _>> >::type > { typedef int result_type; result_type operator ()(Expr& e, my_context const& ctx) const { return proto::eval(left(e), ctx) - proto::eval(right(e), ctx); } } 34
  • 43.
    + - template <class Expr> struct eval< Expr, typename boost::enable_if< matches<Expr, plus<_, _>> >::type > { _ typedef int result_type; (wildcard) result_type operator ()(Expr& e, my_context const& ctx) const { return proto::eval(left(e), ctx) - proto::eval(right(e), ctx); } } 35
  • 44.
    + - template <class Expr> struct eval< Expr, typename boost::enable_if< matches<Expr, plus<_, _>> >::type > { typedef int result_type; left: 1 result_type right: 2 operator ()(Expr& e, my_context const& ctx) const { return proto::eval(left(e), ctx) - proto::eval(right(e), ctx); } } 36
  • 45.
    + - template <class Expr> struct eval< Expr, typename boost::enable_if< matches<Expr, plus<_, _>> >::type > { typedef int result_type; result_type operator ()(Expr& e, my_context const& ctx) const { return proto::eval(left(e), ctx) - proto::eval(right(e), ctx); } } 37
  • 46.
    + - template <class Expr> struct eval< Expr, typename boost::enable_if< matches<Expr, plus<_, _>> >::type > { typedef int result_type; result_type operator ()(Expr& e, my_context const& ctx) const { return proto::eval(left(e), ctx) - proto::eval(right(e), ctx); } } 38
  • 47.
    2 : my_context const ctx; std::cout << eval(lit(1) + 2 + 3, ctx) << std::endl; : -4 39
  • 48.
    / • : • proto::left, proto::right • : • proto::result_of::left, proto::result_of::right • C++0x 40
  • 49.
    • Context • • Domain • • Extends • • Grammer • 41
  • 50.
    : 1.User’s Guide http://www.boost.org/doc/libs/1_46_0/doc/html/proto/ users_guide.html 2. (C++ Advent Calender JP 2010; 16 ) http://d.hatena.ne.jp/fjnl/20101222/ 42
  • 51.
  • 52.
    Proto • ET • • • (+ ) •( ) • Basic Linear Algebra Subprograms (BLAS) 44
  • 53.
  • 54.
    Boost.uBLAS • CPU, GPU • → • CPU GPU • : • • CPU: , ATLAS, GotoBLAS, OpenCL • GPU: , CUBLAS, OpenCL 46
  • 55.
    ET → Backend::scalar a; Backend::vector b, x, y; y = a * x + b; Backend::eval< multiply, scalar, vector>()(y, a, x); Backend::eval< plus, vector, vector>()(y, y, b); 47
  • 56.
    (Cell, GPU ) [a * x + y] plus<multiply<scalar, vector>, vector> axpy<scalar, vector, vector> 48
  • 57.