Expression templates

Expression templates are a C++ template metaprogramming technique that builds structures representing a computation at compile time, where expressions are evaluated only as needed to produce efficient code for the entire computation.[1] Expression templates thus allow programmers to bypass the normal order of evaluation of the C++ language and achieve optimizations such as loop fusion.

Expression templates were invented independently by Todd Veldhuizen and David Vandevoorde;[2][3] it was Veldhuizen who gave them their name.[3] They are a popular technique for the implementation of linear algebra software.[1]

Motivation and example

Consider a library representing vectors and operations on them. One common mathematical operation is to add two vectors u and v, element-wise, to produce a new vector. The obvious C++ implementation of this operation would be an overloaded operator+ that returns a new vector object:

/// @brief class representing a mathematical 3D vector
class Vec : public std::array<double, 3> {
  public:
    using std::array<double, 3>::array; 
    // inherit constructor (C++11)
    // see https://en.cppreference.com/w/cpp/language/using_declaration
};


/// @brief sum 'u' and 'v' into a new instance of Vec
Vec operator+(Vec const &u, Vec const &v) {
    Vec sum;
    for (size_t i = 0; i < u.size(); i++) {
        sum[i] = u[i] + v[i];
    }
    return sum;
}

Users of this class can now write Vec x = a + b; where a and b are both instances of Vec.

A problem with this approach is that more complicated expressions such as Vec x = a + b + c are implemented inefficiently. The implementation first produces a temporary Vec to hold a + b, then produces another Vec with the elements of c added in. Even with return value optimization this will allocate memory at least twice and require two loops.

Delayed evaluation solves this problem, and can be implemented in C++ by letting operator+ return an object of an auxiliary type, say VecSum, that represents the unevaluated sum of two Vecs, or a vector with a VecSum, etc. Larger expressions then effectively build expression trees that are evaluated only when assigned to an actual Vec variable. But this requires traversing such trees to do the evaluation, which is in itself costly.[4]

Expression templates implement delayed evaluation using expression trees that only exist at compile time. Each assignment to a Vec, such as Vec x = a + b + c, generates a new Vec constructor if needed by template instantiation. This constructor operates on three Vec; it allocates the necessary memory and then performs the computation. Thus only one memory allocation is performed.

Example implementation of expression templates :

An example implementation of expression templates looks like the following. A base class VecExpression represents any vector-valued expression. It is templated on the actual expression type E to be implemented, per the curiously recurring template pattern. The existence of a base class like VecExpression is not strictly necessary for expression templates to work. It will merely serve as a function argument type to distinguish the expressions from other types (note the definition of a Vec constructor and operator+ below).

template <typename E>
class VecExpression {
  public:
    static constexpr bool is_leaf = false;

    double operator[](size_t i) const {
        // Delegation to the actual expression type. This avoids dynamic polymorphism (a.k.a. virtual functions in C++)
        return static_cast<E const&>(*this)[i];
    }
    size_t size() const { return static_cast<E const&>(*this).size(); }
};

The Boolean is_leaf is there to tag VecExpressions that are "leafs", i.e. that actually contain data. The Vec class is a leaf that stores the coordinates of a fully evaluated vector expression, and becomes a subclass of VecExpression.

class Vec : public VecExpression<Vec> {
    std::array<double, 3> elems;

  public:
    static constexpr bool is_leaf = true;

    decltype(auto) operator[](size_t i) const { return elems[i]; }
    decltype(auto) &operator[](size_t i)      { return elems[i]; }
    size_t size()               const { return elems.size(); }

    // construct Vec using initializer list 
    Vec(std::initializer_list<double> init) {
        std::copy(init.begin(), init.end(), elems.begin());
    }

    // A Vec can be constructed from any VecExpression, forcing its evaluation.
    template <typename E>
    Vec(VecExpression<E> const& expr) {
        for (size_t i = 0; i != expr.size(); ++i) {
            elems[i] = expr[i];
        }
    }
};

The sum of two Vecs is represented by a new type, VecSum, that is templated on the types of the left- and right-hand sides of the sum so that it can be applied to arbitrary pairs of Vec expressions. An overloaded operator+ serves as syntactic sugar for the VecSum constructor. A subtlety intervenes in this case: in order to reference the original data when summing two VecExpressions, VecSum needs to store a const reference to each VecExpression if it is a leaf, otherwise it is a temporary object that needs to be copied to be properly saved.

template <typename E1, typename E2>
class VecSum : public VecExpression<VecSum<E1, E2> > {
  // cref if leaf, copy otherwise
  typename std::conditional<E1::is_leaf, const E1&, const E1>::type _u;
  typename std::conditional<E2::is_leaf, const E2&, const E2>::type _v;

  public:
    static constexpr bool is_leaf = false;

    VecSum(E1 const& u, E2 const& v) : _u(u), _v(v) {
        assert(u.size() == v.size());
    }
    decltype(auto) operator[](size_t i) const { return _u[i] + _v[i]; }
    size_t size()               const { return _v.size(); }
};
  
template <typename E1, typename E2>
VecSum<E1, E2>
operator+(VecExpression<E1> const& u, VecExpression<E2> const& v) {
   return VecSum<E1, E2>(*static_cast<const E1*>(&u), *static_cast<const E2*>(&v));
}

With the above definitions, the expression a + b + c is of type

VecSum<VecSum<Vec, Vec>, Vec>

so Vec x = a + b + c invokes the templated Vec constructor Vec(VecExpression<E> const& expr) with its template argument E being this type (meaning VecSum<VecSum<Vec, Vec>, Vec>). Inside this constructor, the loop body

elems[i] = expr[i];

is effectively expanded (following the recursive definitions of operator+ and operator[]on this type) to

elems[i] = a.elems[i] + b.elems[i] + c.elems[i];

with no temporary Vec objects needed and only one pass through each memory block.

Basic Usage :

int main() {
    Vec v0 = {23.4,  12.5,  144.56};
    Vec v1 = {67.12, 34.8,  90.34};
    Vec v2 = {34.90, 111.9, 45.12};
    
    // Following assignment will call the ctor of Vec which accept type of 
    // `VecExpression<E> const&`. Then expand the loop body to 
    // a.elems[i] + b.elems[i] + c.elems[i]
    Vec sum_of_vec_type = v0 + v1 + v2; 

    for (size_t i = 0; i < sum_of_vec_type.size(); ++i)
        std::cout << sum_of_vec_type[i] << std::endl;

    // To avoid creating any extra storage, other than v0, v1, v2
    // one can do the following (Tested with C++11 on GCC 5.3.0)
    auto sum = v0 + v1 + v2;
    for (size_t i = 0; i < sum.size(); ++i)
        std::cout << sum[i] << std::endl;
    // Observe that in this case typeid(sum) will be VecSum<VecSum<Vec, Vec>, Vec>
    // and this chaining of operations can go on.
}

Applications

Expression templates have been found especially useful by the authors of libraries for linear algebra, that is, for dealing with vectors and matrices of numbers. Among libraries employing expression template are Dlib, Armadillo, Blaze,[5] Blitz++,[6] Boost uBLAS,[7] Eigen,[8] POOMA,[9] Stan Math Library,[10] and xtensor.[11] Expression templates can also accelerate C++ automatic differentiation implementations,[12] as demonstrated in the Adept library.

Outside of vector math, the Spirit parser framework uses expression templates to represent formal grammars and compile these into parsers.

See also

References

  1. ^ a b Matsuzaki, Kiminori; Emoto, Kento (2009). Implementing fusion-equipped parallel skeletons by expression templates. Proc. Int'l Symp. on Implementation and Application of Functional Languages. pp. 72–89.
  2. ^ Vandevoorde, David; Josuttis, Nicolai (2002). C++ Templates: The Complete Guide. Addison Wesley. ISBN 0-201-73484-2.
  3. ^ a b Veldhuizen, Todd (1995). "Expression Templates". C++ Report. 7 (5): 26–31. Archived from the original on 10 February 2005.
  4. ^ Abrahams, David; Gurtovoy, Aleksey (2004). C++ Template Metaprogramming: Concepts, Tools, and Techniques from Boost and Beyond. Pearson Education. ISBN 9780321623911.
  5. ^ Bitbucket
  6. ^ "Blitz++ User's Guide" (PDF). Retrieved December 12, 2015.
  7. ^ "Boost Basic Linear Algebra Library". Retrieved October 25, 2015.
  8. ^ Guennebaud, Gaël (2013). Eigen: A C++ linear algebra library (PDF). Eurographics/CGLibs.
  9. ^ Veldhuizen, Todd (2000). Just when you thought your little language was safe: "Expression Templates" in Java. Int'l Symp. Generative and Component-Based Software Engineering. CiteSeerX 10.1.1.22.6984.
  10. ^ "Stan documentation". Retrieved April 27, 2016.
  11. ^ "Multi-dimensional arrays with broadcasting and lazy computing". Retrieved September 18, 2017.
  12. ^ Hogan, Robin J. (2014). "Fast reverse-mode automatic differentiation using expression templates in C++" (PDF). ACM Trans. Math. Softw. 40 (4): 26:1–26:16. doi:10.1145/2560359. S2CID 9047237.

Read other articles:

Future frigate of the Royal Navy The winning design submitted by Babcock which is based on the Iver Huitfeldt-class frigates Class overview NameType 31 Frigate Builders Babcock International[5] PAL Indonesia[6] PGZ Stocznia Wojenna[7] Operators  Royal Navy  Indonesian Navy  Polish Navy Preceded byType 23 frigate Cost£268 million (2019)[1] per unit (est.) In service2027[2][3] Planned 10 (total)[4] 5 (UK) 2 (Indonesia)...

 

American actor Josh HollowayHolloway at the 2013 San Diego Comic-ConBornJosh Lee Holloway[1] (1969-07-20) July 20, 1969 (age 54)San Jose, California, U.S.OccupationActorYears active1993–presentSpouse Yessica Kumala ​(m. 2004)​Children2 Josh Lee Holloway (born July 20, 1969) is an American actor best known for his roles as James Sawyer Ford on the television show Lost and as Will Bowman on the science fiction drama Colony. He also had a recurrin...

 

Cet article est une ébauche concernant une chronologie ou une date et Paris. Vous pouvez partager vos connaissances en l’améliorant (comment ?) selon les recommandations des projets correspondants. Chronologies Données clés 2005 2006 2007  2008  2009 2010 2011Décennies :1970 1980 1990  2000  2010 2020 2030Siècles :XIXe XXe  XXIe  XXIIe XXIIIeMillénaires :Ier IIe  IIIe  Chronologies géographiques Afrique Afrique du Sud, Alg...

Portada de Historia, crítica y apologética de la Virgen nuestra señora del Pilar de Zaragoza. Madrid, hros. de Alejandro Gómez Fuentenebro. Historia, crítica y apologética de la Virgen nuestra Señora del Pilar de Zaragoza es una obra de Mariano Nougués Secall, con marcado carácter de investigación historiográfica, aunque en ocasiones su punto de vista es sesgado y tendencioso hacia los cánones de la Iglesia católica. Fue publicado en Madrid en 1862, bajo el patrocinio de Isabel I...

 

Colombian crime bosses Cali Cartel Drug barons of Colombia refer to some of the most notable drug lords which operate in illegal drug trafficking in Colombia. Several of them, notably Pablo Escobar, were long considered among the world's most dangerous and most wanted men by U.S. intelligence. Ruthless and immensely powerful, several political leaders, such as President Virgilio Barco Vargas, became convinced that the drug lords were becoming so powerful that they could oust the formal govern...

 

This article does not cite any sources. Please help improve this article by adding citations to reliable sources. Unsourced material may be challenged and removed.Find sources: Civil War: The Initiative – news · newspapers · books · scholar · JSTOR (December 2017) (Learn how and when to remove this template message) Civil War: The InitiativeMarc Silvestri cover toCivil War: The Initiative #1 (April 2007)PublisherMarvel ComicsPublication dateMarch ...

Artikel ini sebatang kara, artinya tidak ada artikel lain yang memiliki pranala balik ke halaman ini.Bantulah menambah pranala ke artikel ini dari artikel yang berhubungan atau coba peralatan pencari pranala.Tag ini diberikan pada Oktober 2022. Divisi Grenadier ke-1919. Grenadier-DivisionAktifAgustus 1944 – Oktober 1944Negara Jerman NaziCabangAngkatan Darat Jerman (Wehrmacht)Tipe unitInfanteriJumlah personelDivisiPertempuranPerang Dunia IIDivisi Grenadier ke-19 (Jerman: 19. Grenadi...

 

Ten artykuł od 2021-07 wymaga zweryfikowania podanych informacji.Należy podać wiarygodne źródła, najlepiej w formie przypisów bibliograficznych.Część lub nawet wszystkie informacje w artykule mogą być nieprawdziwe. Jako pozbawione źródeł mogą zostać zakwestionowane i usunięte.Sprawdź w źródłach: Encyklopedia PWN • Google Books • Google Scholar • Federacja Bibliotek Cyfrowych • BazHum • RCIN • Int...

 

3103 EgerPenemuanDitemukan olehM. LovasSitus penemuan561Tanggal penemuan1982/01/20Ciri-ciri orbitAphelion1.902Perihelion0.907Sumbu semimayor1.404Eksentrisitas0.354Anomali rata-rata94.9Inklinasi20.9Bujur node menaik129.8Argumen perihelion254.0Ciri-ciri fisikMagnitudo mutlak (H)15.38 3103 Eger (1982 BB) adalah sebuah asteroid. Asteroid ini merupakan bagian dari asteroid Apollo, yang terletak dekat dengan bumi. Eksentrisitas orbit asteroid ini tercatat sebesar 0.354, sem...

Dutch chess player & mathematician Max EuweEuwe in 1963Full nameMachgielis EuweCountryNetherlandsBorn(1901-05-20)May 20, 1901Amsterdam, NetherlandsDiedNovember 26, 1981(1981-11-26) (aged 80)Amsterdam, NetherlandsTitleGrandmaster (1950)World Champion1935–37Peak rating2530 (May 1974) Machgielis Max Euwe (Dutch: [ˈøːʋə];[1] May 20, 1901 – November 26, 1981) was a Dutch chess player, mathematician, author, and chess administrator. He was the fifth ...

 

メソ対流系(メソたいりゅうけい、英: mesoscale convective system、MCS)とは、メソスケールでの気象のシステムのひとつ。ひとつひとつの降水セルが多数発生して、いくつかの種類のセル集団、いわばセルの複合体に発達して、より激しい天候(荒天)をもたらすもの。集中豪雨などの解明方法のひとつとして用いられる考え方。 メソ対流系のシステムと種類 「降水セル...

 

「山」のその他の用法については「山 (曖昧さ回避)」をご覧ください。 富士山 プロジェクト 山 山(やま)とは、周囲よりも高く盛り上がった地形や場所のことをいう。地形学では丘陵や「台地」よりも周囲との相対的高度差(比高)や起伏が大きいものを指す。平地と比べ、傾斜した地形から成る[注 1]。 概要 蓼科山 周囲とどの程度の高度差があれば山と...

Селище Світле Країна  Україна Область Дніпропетровська область Район Кам'янська міська громада Рада Південна районна у місті Кам'янському рада Код КАТОТТГ: Облікова картка Облікова картка  Основні дані Засноване — Площа 0 км² Населення 397 Густота 0 осіб/км² Пош...

 

Manitoba party election for party leader and premier 2021 Progressive Conservative Party of Manitoba leadership election ← 2012 October 30, 2021 Next →   Candidate Heather Stefanson Shelly Glover Popular vote 8,405 8,042 Percentage 51.1% 48.9% Leader before election Kelvin Goertzen (interim) Elected Leader Heather Stefanson 2021 Progressive Conservative Party of Manitoba leadership electionDateOctober 30, 2021Resigning leaderBrian PallisterBallots1Candidates2En...

 

This article relies excessively on references to primary sources. Please improve this article by adding secondary or tertiary sources. Find sources: Paula's Best Dishes – news · newspapers · books · scholar · JSTOR (May 2009) (Learn how and when to remove this template message) American TV series or program Paula's Best DishesLogoStarringPaula DeenCountry of originUnited StatesNo. of seasons3No. of episodes40 (list of episodes)ProductionRunning ti...

Practice of calligraphy in India Part of a series onCalligraphy By region Arabic (Islamic) Chinese Cyrillic Georgian Indian Japanese Korean Mongolian Persian Serbian Tibetan Turkish Vietnamese Western A Calligraphic design in Odia script Indian calligraphy is the Indian tradition of calligraphy. The art form has served multiple purposes since its inception in the second century BCE, including the duplication of religious texts and as a form of basic communication. History Early calligraphy (2...

 

Augustus Willson Augustus Everett Willson (* 13. Oktober 1846 in Maysville, Kentucky; † 24. August 1931 in Louisville, Kentucky) war ein US-amerikanischer Politiker und der 36. Gouverneur des Bundesstaates Kentucky. Frühe Jugend und politischer Aufstieg Augustus Willson erhielt seine schulische Ausbildung im Staat New York. Er besuchte die Alfred Academy und die Harvard University. Anschließend studierte er an der Harvard Law School Jura und wurde 1870 als Rechtsanwalt zugelassen. Danach ...

 

South Korean singer (born 2004) In this Korean name, the family name is Jang. Jang Won-youngJang at Incheon International Airportin October 2023Born (2004-08-31) August 31, 2004 (age 19)Ichon-dong, Yongsan-gu, Seoul, South Korea[1]Alma materSchool of Performing Arts SeoulOccupationSingerMusical careerGenresK-popJ-popInstrument(s)VocalsYears active2018–presentLabelsStarshipOff the Record[a]EMI[a]Columbia[b]Member ofIveFormerly ofIz*One Musical artist...

Canadian politician Christine HogarthMPPParliamentary Assistant to the Solicitor General (Community Safety)IncumbentAssumed office June 26, 2019MinisterSylvia JonesMember of the Ontario Provincial Parliamentfor Etobicoke—LakeshoreIncumbentAssumed office June 7, 2018Preceded byPeter Milczyn Personal detailsPolitical partyProgressive ConservativeOther politicalaffiliationsConservative (federal)Residence(s)Etobicoke, Toronto, OntarioAlma materLake Superior State University (BSc)Occupat...

 

أنس لهوير العلمي معلومات شخصية الميلاد مارس 1968 (55 سنة)  الرباط  مواطنة المغرب  الحياة العملية المدرسة الأم المدرسة المحمدية للمهندسين  المهنة مهندس،  ومصرفي  اللغة الأم الأمازيغية  اللغات العربية،  والأمازيغية  تعديل مصدري - تعديل   أنس لهوير العلم...

 

Strategi Solo vs Squad di Free Fire: Cara Menang Mudah!