Presentation is loading. Please wait.

Presentation is loading. Please wait.

School of Computing Faculty of Engineering Meshing with Grids: Toward Functional Abstractions for Grid-based Visualization Rita Borgo & David Duke Visualization.

Similar presentations


Presentation on theme: "School of Computing Faculty of Engineering Meshing with Grids: Toward Functional Abstractions for Grid-based Visualization Rita Borgo & David Duke Visualization."— Presentation transcript:

1 School of Computing Faculty of Engineering Meshing with Grids: Toward Functional Abstractions for Grid-based Visualization Rita Borgo & David Duke Visualization & Virtual Reality Group School of Computing University of Leeds, UK Colin Runciman & Malcolm Wallace Department of Computer Science University of York, UK

2 Overview Why functional programming (still) matters Project: a lazy polytypic grid Marching cubes Streaming Making it generic Performance Looking back, looking forwards

3 Why Functional Programming Still Matters Academic arguments J. Hughes, Why Functional Programming Matters Problem decomposition program composition Absence of side-effects Higher-order functions Laziness Practical arguments: Natural progression: OO service-orientation Tower of Babel Novel solutions come from working against the OO grain!

4 Introduction to FP and Haskell Functional building blocks square :: Int -> Int square x = x*x map :: (a -> b) -> [a] -> [b] map _ [] = [] map f (a:as) = (f a):(map f as) (.) :: (b -> c) -> (a -> b) -> (a -> c) (f. g) x = f(g(x)) sqList ls = map square ls sqsqList ls = map sqList (map sqList ls) = (map sqList. map sqList) ls = map (sqList. sqList) ls fibs = [0,1] ++ [ a+b | (a,b) <- zip fibs (tail fibs) ] Further information: see www.haskell.org Note: loop fusion law encoded as a rule in GHC compiler

5 Why FP matters (to grid-enabled vis) pipeline architecture widespread in visualization supports distribution and streaming However Streaming is ad-hoc and coarse grained Algorithms depend on mesh type Data traversed multiple times readerozone levelsisosurfacenormals isosurfacereadertemperature displaygeo-reference ? Note: analogy of pipeline composition and function composition: f. g

6 A Lazy Polytypic Grid Grid enabling: distribution of the run-time system and on-demand streaming of arbitrary data. Through fusion laws, multiple traversals on a single resource are folded into one pass. 2 readerozone levelsisosurfacenormals isosurfac e reade r temperatu re geo-referencedisplay Algorithms: written once, based on generic pattern of data types, then instantiated for any type. 1 3 Specialization: adapt programs to utilize resources available – data or computational.

7 Isosurfaces Widely-used technique for both 2D and 3D scalar data Two general approaches: Contour tracking: follow a feature through the dataset Marching: traverse dataset, processing each cell as encountered in-core versus out-of-core variations 2D examples: skull cross-section; isoline for t=5

8 Marching Squares Input: a dataset, and a threshold value to be contoured Output: line segments representing contour's path within dataset Algorithm: For each cell, compare field value at point with threshold Sixteen possible cases: index into case-table to find edges Interpolate along edges to find intersection points Note ambiguity in cases 5 and 10!

9 Marching Cubes... and beyond 3D surface generalizes 2D case: Isolines become surfaces composed of triangles 16-case lookup table becomes 256-case table (15 cases if we use symmetry) Tetrahedral cells also common Other cell types possible common pattern of processing need appropriate case-table

10 Implementation 1: Functional Arrays Basic types type XYZ = (Int,Int,Int) type Num a => Dataset a = Array XYZ a type Cell a = (a,a,a,a,a,a,a,a) Top-level traversal isoA :: (Ord a, Intgeral a) => a -> Dataset a -> [Triangle] isoA th sampleArr = concat. zipWith1 (mcubeA th lookup) addrs where addrs = [ (i,j,k) | k <- [1..ksz-1], j <- [1..jsz-1], i <- [1..isz-1]] lookup arr (x,y,z) = (arr!(x,y,z), arr!(x+1,y,z),.., arr!(x+1,y+1,z+1)) Worker function mcubeA :: (Ord a, Intgeral a) => a -> (XYZ -> Cell a) -> XYZ -> [Triangle] mcubeA th lookup xyz = group3. map (interp th cell xyz). mctable!. toByte. map8 (>th) $ cell where cell = lookup xyz

11 Problems Entire dataset must be resident in memory Vertex shared by n cells threshold comparison repeated n times > 1 triangle in a cell => edge interpolation repeated within cell Edge shared by m cells interpolation repeated m times

12 Thinking differently - streaming mkStream :: XYZ -> [a] -> [Cell a] mkStream (isz,jsz,ksz) origin = zip8 origin (drop 1 origin) (drop (line+1) origin) (drop line origin) (drop plane origin) (drop (plane+1) origin) (drop (planeline+1) origin) (drop planeline origin) where line = isz plane = isz * jsz planeline = plane + line line plane 8-tuple...

13 Discontinuities Two solutions: Rewrite mkStream, considering dataset boundaries; or Strip phantom cells from output of mkStream disContinuities :: XYZ -> [b] -> [b] disContinuities (isz,jsz,ksz) = step (0,0,0) where step (i,j,k) (x:xs) | i==(isz-1) = step (0,j+1,k) xs | j==(jsz-1) = step (0,0,k+1) (drop (isz-1) xs) | k==(ksz-1) = [] | otherwise = x : step (i+1,j,k) xs cellStream = disContinuities size. stream

14 Implementations 2 & 3: Streams Version 2: replace array lookup with stream access isoS th samples = concat. zipWith2 (mcubeS th) addrs cells where cells = stream size samples mcubeS :: a -> XYZ -> Cell a -> [Triangle] mcubeS th xyz cell = group3. map (interp th cell xyz). mctable!. toByte. map8 (>th) $ cell Version 3: share vertex comparison by creating a stream of case-indices isoT th samples = concat. zipWith3 (mcubeS th) addrs cells indices where indices = map toByte. stream. map (>th) mcubeT :: a -> XYZ -> Cell a -> Byte -> [Triangle] mcubeT th xyz cell index = group3. map (interp th cell xyz). mctable! $ index Further improvements explored in IEEE Visualization paper

15 From generic cells... Functions already polymorphic.. generic over one or more type variables constraints may limit instantiation isoA :: (Ord a, Intgeral a, Fractional b) => a -> Dataset a -> [Triangle b]... and abstracting from Cell type is (nearly) straightforward mcubeRec :: (Num a, Floating b) => a -> XYZ -> CellR a -> [Triangle b] mcubeRec th xyz cell = group3. map (interp th cell xyz ). mcTable!. toByte8. map8 (>th) $ cell mcubeTet :: (Num a, Floating b) => a -> CellT a -> CellT b -> [Triangle b] mcubeTet th g cell verts = group3. map (interp th cell verts). mtTable!. toByte4. map4 (>th) $ cell Can capture general pattern within a type-class class Cell T where patch :: (Num a, Floating b) => a -> T a -> T b -> [Triangle b]

16 ... to generic meshes Dealing with different mesh-type organizations is harder... Regular meshes: implicit geometry and topology Irregular meshes: implicit geometry Unstructured meshes: geometry and topology explicit Polytypic functions are independent of data organization Haskell data constructions isomorphic to sum-of-products type Foundation on categorical model of data type structure Examples data List a = Nil | Cons a (List a) --> List = 1 + (a x List) data Tree a = Leaf a | Node (Tree a) a (Tree a) --> Tree = a + (Tree x a x Tree)

17 Polytypism in practice From Generic Haskell: Practice & Theory, Hinze & Jeuring, 2001 define generic function by induction over type structure generic version can then be instantiated for any SoP type mapG {|t::kind|} :: Map {|kind|} t t mapG {|Char|} c = c mapG {|Int|} i = i mapG {|Unit|} Unit = Unit mapG {|:+:|} mapa mapb (InL a) = InL (mapa a) mapG {|:+:|} mapa mapb (InR b) = InR (mapb b) mapG {|:*:|} mapa mapb a :*: b = mapa a :*: mapb b data Tree a = Leaf a | Node (Tree a) a (Tree a) mapList = mapG {| List |} -- standard Haskell map mapTree = mapG {| Tree |} -- apply function to each node in the tree Research question: can we actually apply this idea to mesh traversal? surface t = concat. mapG {| Mesh |} (\c -> patch t c)

18 Sample Results

19 Performance Performance difference decreases with surface size D.J. Duke, M. Wallace, R. Borgo, and C. Runciman, Fine-grained visualization pipelines and lazy functional languages, to appear in Proc. IEEE Vis06

20 Conclusions and Future Work What we've achieved: re-constructed fundamental visualization algorithms Implemented fine-grained streaming demonstrated that FP can be (surprisingly) efficient What we're doing now: generalizing from specific types of mesh exploring capabilities of generic programming Where we are going next: grid-enabled Haskell pipelines some prior work: GRID-GUM, Michaelson, Trinder, Al Zain build into York Haskell Compiler (bytecode) RTS want simple, lightweight grid tools!

21 Finally... Thanks to EPSRC Fundamental Computing for e-Science Programme Further information: hackage.haskell.org/trac/PolyFunViz/ Any Questions?


Download ppt "School of Computing Faculty of Engineering Meshing with Grids: Toward Functional Abstractions for Grid-based Visualization Rita Borgo & David Duke Visualization."

Similar presentations


Ads by Google