Slide 1

Slide 1 text

scala-ildl.org 11th of September 2015 Virtual Machines Meetup Zürich, Switzerland Data-centric Metaprogramming

Slide 2

Slide 2 text

scala-ildl.org STOP Please ask if things are not clear!

Slide 3

Slide 3 text

scala-ildl.org Vlad URECHE PhD student in the Scala Team @ EPFL Working on program transformations focusing on data representation. Miniboxing guy. Scala compiler geek. @ @VladUreche @VladUreche [email protected]

Slide 4

Slide 4 text

scala-ildl.org Data-centric Metaprogramming

Slide 5

Slide 5 text

scala-ildl.org Data-centric Metaprogramming Joint work with ● Martin Odersky ● Aggelos Biboudis ● Yannis Smaragdakis

Slide 6

Slide 6 text

scala-ildl.org infoscience.epfl.ch/record/207050

Slide 7

Slide 7 text

scala-ildl.org Motivation Transformation Applications Challenges Conclusion Related Work

Slide 8

Slide 8 text

scala-ildl.org Data-centric Metaprogramming

Slide 9

Slide 9 text

scala-ildl.org Data-centric Metaprogramming ... in Object-Oriented Languages

Slide 10

Slide 10 text

scala-ildl.org Object Composition Object Composition class Vector[T] { … }

Slide 11

Slide 11 text

scala-ildl.org Object Composition Object Composition class Vector[T] { … } The Vector collection in the Scala library

Slide 12

Slide 12 text

scala-ildl.org Object Composition Object Composition class Employee(...) ID NAME SALARY class Vector[T] { … } The Vector collection in the Scala library

Slide 13

Slide 13 text

scala-ildl.org Object Composition Object Composition class Employee(...) ID NAME SALARY Auto-generated, corresponds to a table row class Vector[T] { … } The Vector collection in the Scala library

Slide 14

Slide 14 text

scala-ildl.org Object Composition Object Composition class Vector[T] { … } class Employee(...) ID NAME SALARY

Slide 15

Slide 15 text

scala-ildl.org Object Composition Object Composition class Vector[T] { … } class Employee(...) ID NAME SALARY

Slide 16

Slide 16 text

scala-ildl.org Object Composition Object Composition class Employee(...) ID NAME SALARY Vector[Employee] ID NAME SALARY ID NAME SALARY class Vector[T] { … }

Slide 17

Slide 17 text

scala-ildl.org Object Composition Object Composition class Employee(...) ID NAME SALARY Vector[Employee] ID NAME SALARY ID NAME SALARY class Vector[T] { … } Traversal requires dereferencing a pointer for each employee.

Slide 18

Slide 18 text

scala-ildl.org A Better Representation A Better Representation Vector[Employee] ID NAME SALARY ID NAME SALARY

Slide 19

Slide 19 text

scala-ildl.org A Better Representation A Better Representation NAME ... NAME EmployeeVector ID ID ... ... SALARY SALARY Vector[Employee] ID NAME SALARY ID NAME SALARY

Slide 20

Slide 20 text

scala-ildl.org A Better Representation A Better Representation NAME ... NAME EmployeeVector ID ID ... ... SALARY SALARY Vector[Employee] ID NAME SALARY ID NAME SALARY iteration is 5x faster

Slide 21

Slide 21 text

scala-ildl.org A Better Representation A Better Representation NAME ... NAME EmployeeVector ID ID ... ... SALARY SALARY Vector[Employee] ID NAME SALARY ID NAME SALARY iteration is 5x faster C++ would produce a better representation here, but there are still cases where the C++ representation could be improved over.

Slide 22

Slide 22 text

scala-ildl.org A Better Representation A Better Representation ● In isolation Vector[T] and Employee are optimal

Slide 23

Slide 23 text

scala-ildl.org A Better Representation A Better Representation ● In isolation Vector[T] and Employee are optimal ● Together, Vector[Employee] can be optimized

Slide 24

Slide 24 text

scala-ildl.org A Better Representation A Better Representation ● In isolation Vector[T] and Employee are optimal ● Together, Vector[Employee] can be optimized Challenge: No means of communicating this to the compiler

Slide 25

Slide 25 text

scala-ildl.org A Better Representation A Better Representation ● In isolation Vector[T] and Employee are optimal ● Together, Vector[Employee] can be optimized Challenge: No means of communicating this to the compiler You may disagree. We'll have a related work section later.

Slide 26

Slide 26 text

scala-ildl.org

Slide 27

Slide 27 text

scala-ildl.org ● Transforming the code by hand – Makes maintenance difficult – Changes are not contained

Slide 28

Slide 28 text

scala-ildl.org ● Transforming the code by hand – Makes maintenance difficult – Changes are not contained Can we automate this?

Slide 29

Slide 29 text

scala-ildl.org Motivation Transformation Applications Challenges Conclusion Related Work

Slide 30

Slide 30 text

scala-ildl.org Transformation Transformation Definition Application

Slide 31

Slide 31 text

scala-ildl.org Transformation Transformation Definition Application ● can't be automated ● based on experience ● based on speculation ● one-time effort

Slide 32

Slide 32 text

scala-ildl.org Transformation Transformation Definition Application ● can't be automated ● based on experience ● based on speculation ● one-time effort programmer

Slide 33

Slide 33 text

scala-ildl.org Transformation Transformation Definition Application ● can't be automated ● based on experience ● based on speculation ● one-time effort ● repetitive and simple ● affects code readability ● is verbose ● is error-prone programmer

Slide 34

Slide 34 text

scala-ildl.org Transformation Transformation programmer Definition Application ● can't be automated ● based on experience ● based on speculation ● one-time effort ● repetitive and simple ● affects code readability ● is verbose ● is error-prone compiler (automated)

Slide 35

Slide 35 text

scala-ildl.org Transformation Transformation programmer Definition Application ● can't be automated ● based on experience ● based on speculation ● one-time effort ● repetitive and simple ● affects code readability ● is verbose ● is error-prone compiler (automated)

Slide 36

Slide 36 text

scala-ildl.org Data-centric Metaprogramming Data-centric Metaprogramming object VectorOfEmployeeOpt extends Transformation { ... }

Slide 37

Slide 37 text

scala-ildl.org Data-centric Metaprogramming Data-centric Metaprogramming object VectorOfEmployeeOpt extends Transformation { ... } An object that describes a Transformation.

Slide 38

Slide 38 text

scala-ildl.org Data-centric Metaprogramming Data-centric Metaprogramming object VectorOfEmployeeOpt extends Transformation { ... } An object that describes a Transformation. A marker trait for transformations.

Slide 39

Slide 39 text

scala-ildl.org Data-centric Metaprogramming Data-centric Metaprogramming object VectorOfEmployeeOpt extends Transformation { ... }

Slide 40

Slide 40 text

scala-ildl.org Data-centric Metaprogramming Data-centric Metaprogramming object VectorOfEmployeeOpt extends Transformation { ... } What does the compiler need to know?

Slide 41

Slide 41 text

scala-ildl.org Data-centric Metaprogramming Data-centric Metaprogramming object VectorOfEmployeeOpt extends Transformation { ... } What does the compiler need to know? The target of the transformation and its representation.

Slide 42

Slide 42 text

scala-ildl.org Data-centric Metaprogramming Data-centric Metaprogramming object VectorOfEmployeeOpt extends Transformation { type Target = Vector[Employee] type Result = EmployeeVector ... }

Slide 43

Slide 43 text

scala-ildl.org Data-centric Metaprogramming Data-centric Metaprogramming object VectorOfEmployeeOpt extends Transformation { type Target = Vector[Employee] type Result = EmployeeVector ... } The transformation is type-driven we indicate → the type of the target and of the representation.

Slide 44

Slide 44 text

scala-ildl.org Data-centric Metaprogramming Data-centric Metaprogramming object VectorOfEmployeeOpt extends Transformation { type Target = Vector[Employee] type Result = EmployeeVector ... } The transformation is type-driven we indicate → the type of the target and of the representation. The improved representation is defined in the host language.

Slide 45

Slide 45 text

scala-ildl.org Data-centric Metaprogramming Data-centric Metaprogramming object VectorOfEmployeeOpt extends Transformation { type Target = Vector[Employee] type Result = EmployeeVector ... }

Slide 46

Slide 46 text

scala-ildl.org Data-centric Metaprogramming Data-centric Metaprogramming object VectorOfEmployeeOpt extends Transformation { type Target = Vector[Employee] type Result = EmployeeVector ... } How to transform Vector[Employee] into an EmployeeVector?

Slide 47

Slide 47 text

scala-ildl.org Data-centric Metaprogramming Data-centric Metaprogramming object VectorOfEmployeeOpt extends Transformation { type Target = Vector[Employee] type Result = EmployeeVector def toResult(t: Target): Result = ... def toTarget(t: Result): Target = ... ... }

Slide 48

Slide 48 text

scala-ildl.org Data-centric Metaprogramming Data-centric Metaprogramming object VectorOfEmployeeOpt extends Transformation { type Target = Vector[Employee] type Result = EmployeeVector def toResult(t: Target): Result = ... def toTarget(t: Result): Target = ... ... } Conversions to/from Vector[Employee] that consume/produce a EmployeeVector?

Slide 49

Slide 49 text

scala-ildl.org Data-centric Metaprogramming Data-centric Metaprogramming object VectorOfEmployeeOpt extends Transformation { type Target = Vector[Employee] type Result = EmployeeVector def toResult(t: Target): Result = ... def toTarget(t: Result): Target = ... ... }

Slide 50

Slide 50 text

scala-ildl.org Data-centric Metaprogramming Data-centric Metaprogramming object VectorOfEmployeeOpt extends Transformation { type Target = Vector[Employee] type Result = EmployeeVector def toResult(t: Target): Result = ... def toTarget(t: Result): Target = ... ... } So far so good, but how to execute Vector[Employee] operations on EmployeeVector?

Slide 51

Slide 51 text

scala-ildl.org Data-centric Metaprogramming Data-centric Metaprogramming object VectorOfEmployeeOpt extends Transformation { type Target = Vector[Employee] type Result = EmployeeVector def toResult(t: Target): Result = ... def toTarget(t: Result): Target = ... def bypass_length: Int = ... def bypass_apply(i: Int): Employee = ... def bypass_update(i: Int, v: Employee) = ... def bypass_toString: String = ... ... }

Slide 52

Slide 52 text

scala-ildl.org Data-centric Metaprogramming Data-centric Metaprogramming programmer Definition Application ● can't be automated ● based on experience ● based on speculation ● one-time effort ● repetitive and simple ● affects code readability ● is verbose ● is error-prone compiler (automated)

Slide 53

Slide 53 text

scala-ildl.org Transformation Transformation programmer Definition Application ● can't be automated ● based on experience ● based on speculation ● one-time effort ● repetitive and simple ● affects code readability ● is verbose ● is error-prone compiler (automated)

Slide 54

Slide 54 text

scala-ildl.org Transformation Transformation programmer Definition Application ● can't be automated ● based on experience ● based on speculation ● one-time effort ● repetitive and simple ● affects code readability ● is verbose ● is error-prone compiler (automated) In the paper

Slide 55

Slide 55 text

scala-ildl.org Motivation Transformation Applications Challenges Conclusion Related Work

Slide 56

Slide 56 text

scala-ildl.org Motivation Transformation Applications Challenges Conclusion Related Work Open-world Best Represenation? Composition

Slide 57

Slide 57 text

scala-ildl.org Motivation Transformation Applications Challenges Conclusion Related Work Open-world Best Represenation? Composition

Slide 58

Slide 58 text

scala-ildl.org Open World Assumption Open World Assumption class Vector[T] { … } class Employee(...) ID NAME SALARY

Slide 59

Slide 59 text

scala-ildl.org Open World Assumption Open World Assumption class Vector[T] { … } class Employee(...) ID NAME SALARY

Slide 60

Slide 60 text

scala-ildl.org Open World Assumption Open World Assumption class Employee(...) ID NAME SALARY Vector[Employee] ID NAME SALARY ID NAME SALARY class Vector[T] { … }

Slide 61

Slide 61 text

scala-ildl.org Open World Assumption Open World Assumption class Employee(...) ID NAME SALARY Vector[Employee] ID NAME SALARY ID NAME SALARY class Vector[T] { … } NAME ... NAME EmployeeVector ID ID ... ... SALARY SALARY

Slide 62

Slide 62 text

scala-ildl.org Open World Assumption Open World Assumption class Employee(...) ID NAME SALARY Vector[Employee] ID NAME SALARY ID NAME SALARY class Vector[T] { … } NAME ... NAME EmployeeVector ID ID ... ... SALARY SALARY class NewEmployee(...) extends Employee(...) ID NAME SALARY DEPT

Slide 63

Slide 63 text

scala-ildl.org Open World Assumption Open World Assumption class Employee(...) ID NAME SALARY Vector[Employee] ID NAME SALARY ID NAME SALARY class Vector[T] { … } NAME ... NAME EmployeeVector ID ID ... ... SALARY SALARY class NewEmployee(...) extends Employee(...) ID NAME SALARY DEPT Oooops...

Slide 64

Slide 64 text

scala-ildl.org Open World Assumption Open World Assumption ● Globally anything can happen

Slide 65

Slide 65 text

scala-ildl.org Open World Assumption Open World Assumption ● Globally anything can happen ● Locally the programmer has full control: – Knows the values that will be used – Can reject non-conforming values

Slide 66

Slide 66 text

scala-ildl.org Open World Assumption Open World Assumption ● Globally anything can happen ● Locally the programmer has full control: – Knows the values that will be used – Can reject non-conforming values How to use this information?

Slide 67

Slide 67 text

scala-ildl.org Open World Assumption Open World Assumption ● Globally anything can happen ● Locally the programmer has full control: – Knows the values that will be used – Can reject non-conforming values How to use this information? Scopes

Slide 68

Slide 68 text

scala-ildl.org Scopes Scopes def indexSalary(employees: Vector[Employee], by: Float): Vector[Employee] = for (employee ← employees) yield employee.copy( salary = (1 + by) * employee.salary )

Slide 69

Slide 69 text

scala-ildl.org Scopes Scopes def indexSalary(employees: Vector[Employee], by: Float): Vector[Employee] = for (employee ← employees) yield employee.copy( salary = (1 + by) * employee.salary ) Method operating on Scala collections (familiar to programmers)

Slide 70

Slide 70 text

scala-ildl.org Scopes Scopes def indexSalary(employees: Vector[Employee], by: Float): Vector[Employee] = for (employee ← employees) yield employee.copy( salary = (1 + by) * employee.salary )

Slide 71

Slide 71 text

scala-ildl.org Scopes Scopes transform(VectorOfEmployeeOpt) { def indexSalary(employees: Vector[Employee], by: Float): Vector[Employee] = for (employee ← employees) yield employee.copy( salary = (1 + by) * employee.salary ) }

Slide 72

Slide 72 text

scala-ildl.org Scopes Scopes transform(VectorOfEmployeeOpt) { def indexSalary(employees: Vector[Employee], by: Float): Vector[Employee] = for (employee ← employees) yield employee.copy( salary = (1 + by) * employee.salary ) } Now the method operates on the EmployeeVector representation.

Slide 73

Slide 73 text

scala-ildl.org Scopes Scopes transform(VectorOfEmployeeOpt) { def indexSalary(employees: Vector[Employee], by: Float): Vector[Employee] = for (employee ← employees) yield employee.copy( salary = (1 + by) * employee.salary ) } Now the method operates on the EmployeeVector representation. Programmers can freely choose which parts of their code to transform.

Slide 74

Slide 74 text

scala-ildl.org Scopes Scopes ● Can wrap statements, methods even entire classes – Inlined immediately after the parser – Definitions are visible outside the "scope"

Slide 75

Slide 75 text

scala-ildl.org Scopes Scopes ● Can wrap statements, methods even entire classes – Inlined immediately after the parser – Definitions are visible outside the "scope" ● Locally closed world – Incoming/outgoing values go through conversions – Programmer can reject unexpected values

Slide 76

Slide 76 text

scala-ildl.org Motivation Transformation Applications Challenges Conclusion Related Work Open-world Best Represenation? Composition

Slide 77

Slide 77 text

scala-ildl.org Best Representation Best Representation Vector[Employee] ID NAME SALARY ID NAME SALARY

Slide 78

Slide 78 text

scala-ildl.org Best ...? Best ...? NAME ... NAME EmployeeVector ID ID ... ... SALARY SALARY Vector[Employee] ID NAME SALARY ID NAME SALARY

Slide 79

Slide 79 text

scala-ildl.org Best ...? Best ...? NAME ... NAME EmployeeVector ID ID ... ... SALARY SALARY Vector[Employee] ID NAME SALARY ID NAME SALARY CompactVector

Slide 80

Slide 80 text

scala-ildl.org Best ...? Best ...? NAME ... NAME EmployeeVector ID ID ... ... SALARY SALARY Vector[Employee] ID NAME SALARY ID NAME SALARY EmployeeJSON { id: 123, name: “John Doe” salary: 100 } CompactVector

Slide 81

Slide 81 text

scala-ildl.org Best ...? Best ...? NAME ... NAME EmployeeVector ID ID ... ... SALARY SALARY Vector[Employee] ID NAME SALARY ID NAME SALARY EmployeeJSON { id: 123, name: “John Doe” salary: 100 } CompactVector Scopes!

Slide 82

Slide 82 text

scala-ildl.org Scopes Scopes transform(VectorOfEmployeeOpt) { def indexSalary(employees: Vector[Employee], by: Float): Vector[Employee] = for (employee ← employees) yield employee.copy( salary = (1 + by) * employee.salary ) }

Slide 83

Slide 83 text

scala-ildl.org Scopes Scopes transform(VectorOfEmployeeOpt) { def indexSalary(employees: Vector[Employee], by: Float): Vector[Employee] = for (employee ← employees) yield employee.copy( salary = (1 + by) * employee.salary ) } Method operating on column-based storage

Slide 84

Slide 84 text

scala-ildl.org Scopes Scopes transform(VectorOfEmployeeBinary) { def indexSalary(employees: Vector[Employee], by: Float): Vector[Employee] = for (employee ← employees) yield employee.copy( salary = (1 + by) * employee.salary ) } Method operating on binary data

Slide 85

Slide 85 text

scala-ildl.org Scopes Scopes transform(VectorOfEmployeeJSON) { def indexSalary(employees: Vector[Employee], by: Float): Vector[Employee] = for (employee ← employees) yield employee.copy( salary = (1 + by) * employee.salary ) } Method operating on JSON data

Slide 86

Slide 86 text

scala-ildl.org Motivation Transformation Applications Challenges Conclusion Related Work Open-world Best Represenation? Composition

Slide 87

Slide 87 text

scala-ildl.org Scope Composition Scope Composition ● Code can be – Left untransformed (using the original repr.) – Transformed using different representations

Slide 88

Slide 88 text

scala-ildl.org Scope Composition Scope Composition calling ● Original code ● Transformed code ● Original code ● Transformed code ● Same transformation ● Different transformation ● Code can be – Left untransformed (using the original repr.) – Transformed using different representations

Slide 89

Slide 89 text

scala-ildl.org Scope Composition Scope Composition calling ● Original code ● Transformed code ● Original code ● Transformed code ● Same transformation ● Different transformation ● Code can be – Left untransformed (using the original repr.) – Transformed using different representations

Slide 90

Slide 90 text

scala-ildl.org Scope Composition Scope Composition calling ● Original code ● Transformed code ● Original code ● Transformed code ● Same transformation ● Different transformation ● Code can be – Left untransformed (using the original repr.) – Transformed using different representations Coercions

Slide 91

Slide 91 text

scala-ildl.org Scope Composition Scope Composition calling ● Original code ● Transformed code ● Original code ● Transformed code ● Same transformation ● Different transformation ● Code can be – Left untransformed (using the original repr.) – Transformed using different representations Coercions

Slide 92

Slide 92 text

scala-ildl.org Scope Composition Scope Composition calling ● Original code ● Transformed code ● Original code ● Transformed code ● Same transformation ● Different transformation ● Code can be – Left untransformed (using the original repr.) – Transformed using different representations

Slide 93

Slide 93 text

scala-ildl.org Scope Composition Scope Composition calling ● Original code ● Transformed code ● Original code ● Transformed code ● Same transformation ● Different transformation ● Code can be – Left untransformed (using the original repr.) – Transformed using different representations

Slide 94

Slide 94 text

scala-ildl.org Scope Composition Scope Composition calling ● Original code ● Transformed code ● Original code ● Transformed code ● Same transformation ● Different transformation ● Code can be – Left untransformed (using the original repr.) – Transformed using different representations No coercions

Slide 95

Slide 95 text

scala-ildl.org Scope Composition Scope Composition calling ● Original code ● Transformed code ● Original code ● Transformed code ● Same transformation ● Different transformation ● Code can be – Left untransformed (using the original repr.) – Transformed using different representations No coercions Even across separate compilation

Slide 96

Slide 96 text

scala-ildl.org Scope Composition Scope Composition calling ● Original code ● Transformed code ● Original code ● Transformed code ● Same transformation ● Different transformation ● Code can be – Left untransformed (using the original repr.) – Transformed using different representations

Slide 97

Slide 97 text

scala-ildl.org Scope Composition Scope Composition calling ● Original code ● Transformed code ● Original code ● Transformed code ● Same transformation ● Different transformation ● Code can be – Left untransformed (using the original repr.) – Transformed using different representations

Slide 98

Slide 98 text

scala-ildl.org Scope Composition Scope Composition calling ● Original code ● Transformed code ● Original code ● Transformed code ● Same transformation ● Different transformation ● Code can be – Left untransformed (using the original repr.) – Transformed using different representations Two coercions Repr1 Target Repr2 → →

Slide 99

Slide 99 text

scala-ildl.org Scope Composition Scope Composition calling ● Original code ● Transformed code ● Original code ● Transformed code ● Same transformation ● Different transformation ● Code can be – Left untransformed (using the original repr.) – Transformed using different representations

Slide 100

Slide 100 text

scala-ildl.org Scope Composition Scope Composition calling overriding ● Original code ● Transformed code ● Original code ● Transformed code ● Same transformation ● Different transformation ● Code can be – Left untransformed (using the original repr.) – Transformed using different representations

Slide 101

Slide 101 text

scala-ildl.org Scope Composition Scope Composition calling overriding ● Original code ● Transformed code ● Original code ● Transformed code ● Same transformation ● Different transformation ● Code can be – Left untransformed (using the original repr.) – Transformed using different representations The transformation has to preserve the object model.

Slide 102

Slide 102 text

scala-ildl.org Scope Composition Scope Composition calling overriding ● Original code ● Transformed code ● Original code ● Transformed code ● Same transformation ● Different transformation ● Code can be – Left untransformed (using the original repr.) – Transformed using different representations The transformation has to preserve the object model. Handled automatically by the ildl transformation!

Slide 103

Slide 103 text

scala-ildl.org Motivation Transformation Applications Challenges Conclusion Related Work Open-world Best Represenation? Composition

Slide 104

Slide 104 text

scala-ildl.org Array of Stuct Array of Stuct (Column-oriented) (Column-oriented) NAME ... NAME EmployeeVector ID ID ... ... SALARY SALARY Vector[Employee] ID NAME SALARY ID NAME SALARY

Slide 105

Slide 105 text

scala-ildl.org Array of Stuct Array of Stuct (Column-oriented) (Column-oriented) NAME ... NAME EmployeeVector ID ID ... ... SALARY SALARY Vector[Employee] ID NAME SALARY ID NAME SALARY 5x faster

Slide 106

Slide 106 text

scala-ildl.org Specialization Specialization and stack allocation and stack allocation 3 5 (3,5) Tuples in Scala are generic so they need to use pointers and objects

Slide 107

Slide 107 text

scala-ildl.org Specialization Specialization and stack allocation and stack allocation 3 5 3 5 (3,5) (3,5) Tuples in Scala are generic so they need to use pointers and objects + stack allocation

Slide 108

Slide 108 text

scala-ildl.org + stack allocation Specialization Specialization and stack allocation and stack allocation 14x faster reduced memory footprint 3 5 3 5 (3,5) (3,5) Tuples in Scala are generic so they need to use pointers and objects

Slide 109

Slide 109 text

scala-ildl.org Deforestation Deforestation List(1,2,3).map(_ + 1).map(_ * 2).sum

Slide 110

Slide 110 text

scala-ildl.org Deforestation Deforestation List(1,2,3).map(_ + 1).map(_ * 2).sum List(2,3,4)

Slide 111

Slide 111 text

scala-ildl.org Deforestation Deforestation List(1,2,3).map(_ + 1).map(_ * 2).sum List(2,3,4) List(4,6,8)

Slide 112

Slide 112 text

scala-ildl.org Deforestation Deforestation List(1,2,3).map(_ + 1).map(_ * 2).sum List(2,3,4) List(4,6,8) 18

Slide 113

Slide 113 text

scala-ildl.org Deforestation Deforestation List(1,2,3).map(_ + 1).map(_ * 2).sum List(2,3,4) List(4,6,8) 18

Slide 114

Slide 114 text

scala-ildl.org Deforestation Deforestation List(1,2,3).map(_ + 1).map(_ * 2).sum List(2,3,4) List(4,6,8) 18 transform(ListDeforestation) { List(1,2,3).map(_ + 1).map(_ * 2).sum }

Slide 115

Slide 115 text

scala-ildl.org Deforestation Deforestation List(1,2,3).map(_ + 1).map(_ * 2).sum List(2,3,4) List(4,6,8) 18 transform(ListDeforestation) { List(1,2,3).map(_ + 1).map(_ * 2).sum } accumulate function

Slide 116

Slide 116 text

scala-ildl.org Deforestation Deforestation List(1,2,3).map(_ + 1).map(_ * 2).sum List(2,3,4) List(4,6,8) 18 transform(ListDeforestation) { List(1,2,3).map(_ + 1).map(_ * 2).sum } accumulate function accumulate function

Slide 117

Slide 117 text

scala-ildl.org Deforestation Deforestation List(1,2,3).map(_ + 1).map(_ * 2).sum List(2,3,4) List(4,6,8) 18 transform(ListDeforestation) { List(1,2,3).map(_ + 1).map(_ * 2).sum } accumulate function accumulate function compute: 18

Slide 118

Slide 118 text

scala-ildl.org Deforestation Deforestation List(1,2,3).map(_ + 1).map(_ * 2).sum List(2,3,4) List(4,6,8) 18 transform(ListDeforestation) { List(1,2,3).map(_ + 1).map(_ * 2).sum } accumulate function accumulate function compute: 18 6x faster

Slide 119

Slide 119 text

scala-ildl.org Motivation Transformation Applications Challenges Conclusion Related Work Open-world Best Represenation? Composition

Slide 120

Slide 120 text

scala-ildl.org Multi-Stage Programming Multi-Stage Programming ● Multi-Stage Programming – “Abstraction without regret” - Tiark Rompf – DSLs small enough to be staged → ● 10000x speed improvements

Slide 121

Slide 121 text

scala-ildl.org Multi-Stage Programming Multi-Stage Programming ● Multi-Stage Programming – “Abstraction without regret” - Tiark Rompf – DSLs small enough to be staged → ● 10000x speed improvements – Scala many features not supported by LMS: → ● Separate compilation/modularization ● Dynamic dispatch ● Aliasing ● Reflection

Slide 122

Slide 122 text

scala-ildl.org Multi-Stage Programming Multi-Stage Programming ● Multi-Stage Programming – “Abstraction without regret” - Tiark Rompf – DSLs small enough to be staged → ● 10000x speed improvements – Scala many features not supported by LMS: → ● Separate compilation/modularization ● Dynamic dispatch ● Aliasing ● Reflection If we add support, we lose the ability to optimize code :(

Slide 123

Slide 123 text

scala-ildl.org Low-level Optimizers Low-level Optimizers ● JIT optimizers with virtual machine support – Access to the low-level code – Can assume a (local) closed world – Can speculate based on profiles – On the critical path – limited analysis

Slide 124

Slide 124 text

scala-ildl.org Low-level Optimizers Low-level Optimizers ● JIT optimizers with virtual machine support – Access to the low-level code – Can assume a (local) closed world – Can speculate based on profiles – On the critical path – limited analysis – Biggest opportunities are high-level - O(n2) O(n) → ● Incoming code is low-level ● Rarely possible to recover opportunities

Slide 125

Slide 125 text

scala-ildl.org Low-level Optimizers Low-level Optimizers ● JIT optimizers with virtual machine support – Access to the low-level code – Can assume a (local) closed world – Can speculate based on profiles – On the critical path – limited analysis – Biggest opportunities are high-level - O(n2) O(n) → ● Incoming code is low-level ● Rarely possible to recover opportunities Typical solution: Metaprogramming

Slide 126

Slide 126 text

scala-ildl.org Metaprogramming Metaprogramming ● Not your grandpa's C preprocessor def optimize(tree: AST): AST = { ... }

Slide 127

Slide 127 text

scala-ildl.org Metaprogramming Metaprogramming ● Not your grandpa's C preprocessor ● Full-fledged program transformers – :) Lots of power def optimize(tree: AST): AST = { ... }

Slide 128

Slide 128 text

scala-ildl.org Metaprogramming Metaprogramming ● Not your grandpa's C preprocessor ● Full-fledged program transformers – :) Lots of power – :( Lots of responsibility def optimize(tree: AST): AST = { ... }

Slide 129

Slide 129 text

scala-ildl.org Metaprogramming Metaprogramming ● Not your grandpa's C preprocessor ● Full-fledged program transformers – :) Lots of power – :( Lots of responsibility ● Compiler invariants ● Object-oriented model ● Modularity def optimize(tree: AST): AST = { ... }

Slide 130

Slide 130 text

scala-ildl.org Metaprogramming Metaprogramming ● Not your grandpa's C preprocessor ● Full-fledged program transformers – :) Lots of power – :( Lots of responsibility ● Compiler invariants ● Object-oriented model ● Modularity def optimize(tree: AST): AST = { ... } Can we make metaprogramming “high-level”?

Slide 131

Slide 131 text

scala-ildl.org Motivation Transformation Applications Challenges Conclusion Related Work Open-world Best Represenation? Composition

Slide 132

Slide 132 text

scala-ildl.org Conclusion Conclusion ● Object-oriented composition inefcient representation → ● Solution: data-centric metaprogramming – Splitting the responsibility: ● Defining the Transformation programmer → ● Applying the Transformation compiler → – Scopes ● Adapt the data representation to the operation ● Allow speculating properties of the scope ● We've just begun to scratch the surface – Many interesting research questions lie ahead

Slide 133

Slide 133 text

scala-ildl.org Conclusion Conclusion ● Object-oriented composition inefcient representation → ● Solution: data-centric metaprogramming – Splitting the responsibility: ● Defining the Transformation programmer → ● Applying the Transformation compiler → – Scopes ● Adapt the data representation to the operation ● Allow speculating properties of the scope ● We've just begun to scratch the surface – Many interesting research questions lie ahead

Slide 134

Slide 134 text

scala-ildl.org Conclusion Conclusion ● Object-oriented composition inefcient representation → ● Solution: data-centric metaprogramming – Splitting the responsibility: ● Defining the Transformation programmer → ● Applying the Transformation compiler → – Scopes ● Adapt the data representation to the operation ● Allow speculating properties of the scope ● We've just begun to scratch the surface – Many interesting research questions lie ahead

Slide 135

Slide 135 text

scala-ildl.org Conclusion Conclusion ● Object-oriented composition inefcient representation → ● Solution: data-centric metaprogramming – Splitting the responsibility: ● Defining the Transformation programmer → ● Applying the Transformation compiler → – Scopes ● Adapt the data representation to the operation ● Allow speculating properties of the scope ● We've just begun to scratch the surface – Many interesting research questions lie ahead

Slide 136

Slide 136 text

scala-ildl.org infoscience.epfl.ch/record/207050

Slide 137

Slide 137 text

scala-ildl.org github.com/miniboxing/ildl-plugin

Slide 138

Slide 138 text

scala-ildl.org github.com/miniboxing/ildl-plugin

Slide 139

Slide 139 text

scala-ildl.org github.com/miniboxing/ildl-plugin Examples of data-centric metaprogramming applications

Slide 140

Slide 140 text

scala-ildl.org

Slide 141

Slide 141 text

scala-ildl.org Thank you!