| | 381 | |
| | 382 | |
| | 383 | == なぜ僕はProtoをぺろぺろするのか == |
| | 384 | |
| | 385 | === Boost.Proto 概要 === |
| | 386 | |
| | 387 | * Expression Template の構築を補助するライブラリ |
| | 388 | * a + b * c -> plus<A, multiply<B, C> > |
| | 389 | * Boost 1.37 |
| | 390 | * Headers only |
| | 391 | |
| | 392 | === Boost.Proto は縁の下の力持ち === |
| | 393 | |
| | 394 | * 単体で使って嬉しいライブラリではない |
| | 395 | * Boost 内で利用しているライブラリ: |
| | 396 | * Boost.Spirit |
| | 397 | * Boost.Phoenix v3 |
| | 398 | * Boost.MSM.eUML |
| | 399 | * Boost.Xpressive |
| | 400 | |
| | 401 | === Expressoin Template (ET) の型 === |
| | 402 | |
| | 403 | * 割と重要 |
| | 404 | * エラーメッセ維持で頻出 |
| | 405 | * 恐ろしく長い |
| | 406 | * Qi で Proto 関係の部分でエラーを出すと遭遇 |
| | 407 | |
| | 408 | === とりあえず使ってみる === |
| | 409 | |
| | 410 | {{{ |
| | 411 | default_context const ctx; |
| | 412 | std::const << eval(lit(1) + 2 + 3, ctx) |
| | 413 | << std::endl; |
| | 414 | }}} |
| | 415 | |
| | 416 | 実行結果 |
| | 417 | {{{ |
| | 418 | 6 |
| | 419 | }}} |
| | 420 | |
| | 421 | * + を - とするコンテキスト |
| | 422 | {{{ |
| | 423 | struct my_context { |
| | 424 | template < |
| | 425 | class Expr, |
| | 426 | class Enable = void |
| | 427 | > struct eval; |
| | 428 | }; |
| | 429 | }}} |
| | 430 | |
| | 431 | === SFINAE === |
| | 432 | |
| | 433 | * Substitution Failure Is not An Error |
| | 434 | * 置き換え失敗はエラーにあらず |
| | 435 | * boost::enable_if など |
| | 436 | {{{ |
| | 437 | template <class T> |
| | 438 | typename enable_if<is_const<T> >::type foo(); |
| | 439 | }}} |
| | 440 | * SFINAE を用いて eval を分岐する。 |
| | 441 | |
| | 442 | * + を - とするコンテキスト |
| | 443 | {{{ |
| | 444 | template <class Expr> |
| | 445 | struct eval< |
| | 446 | Expr, |
| | 447 | typename boost::enable_if< |
| | 448 | matches<Expr, terminal<int> > |
| | 449 | >::type |
| | 450 | > { |
| | 451 | typedef int result_type; |
| | 452 | |
| | 453 | result_type |
| | 454 | operator ()(Expr& e, my_context const&) |
| | 455 | const { |
| | 456 | return value(e); |
| | 457 | } |
| | 458 | } |
| | 459 | }}} |
| | 460 | |
| | 461 | === Boost.Proto の拡張方法 === |
| | 462 | |
| | 463 | * Context |
| | 464 | * 評価に関する情報の提供 |
| | 465 | * Domain |
| | 466 | * 式の生成手段の提供 |
| | 467 | * Extends |
| | 468 | * 式を表す型を自分で提供 |
| | 469 | * Grammer |
| | 470 | * 文法を定義。演算子オーバーロード制御。 |
| | 471 | |
| | 472 | === 数値計算に Boost.Proto === |
| | 473 | |
| | 474 | * ET と数値計算は相性が良い |
| | 475 | * 「アルゴリズム」と「計算実装」を分離できる |
| | 476 | * 組み合わせの爆発を抑制 |
| | 477 | * 見た目が良い (+ が加算を表す) |
| | 478 | * 単純な計算の組み合わせで表現できる。 |
| | 479 | * Basic Linear Algebra Subprograms (BLAS) |
| | 480 | |
| | 481 | === Boost.uBLAS では満足できない理由 === |
| | 482 | |
| | 483 | * Boost.uBLAS は可読性を重視している |
| | 484 | * よって遅い |
| | 485 | * 拡張できない |
| | 486 | |
| | 487 | === General Purpose computing on GPU (GPGPU) について === |
| | 488 | |
| | 489 | * アルゴリズムは CPU, GPU 共通 |
| | 490 | * コードを共有したい→ bug が減る |
| | 491 | * 計算実装は CPU と GPU で異なり、内部実装が多種多様 |
| | 492 | |
| | 493 | |