To provide introduction to Paraiso syntax and its applications, I decided to post a series of articles that introduces computational fluid dynamics (CFD), in Paraiso.
For that end, we will be using the new donut branch and Paraiso 0.3.0.0 . Please refer to the Haddock and the Paraiso language website for further details.
The new branch
~$ git clone -b donut https://github.com/nushio3/Paraiso.git Cloning into 'Paraiso'... remote: Counting objects: 4743, done. remote: Compressing objects: 100% (1815/1815), done. remote: Total 4743 (delta 2885), reused 4637 (delta 2779) Receiving objects: 100% (4743/4743), 2.65 MiB | 411 KiB/s, done. Resolving deltas: 100% (2885/2885), done. ~$ cd Paraiso/ Paraiso$ git branch * donut Paraiso$
This branch already introduces a few changes from the published version, so be careful when reading the paper that
- Realms are more conventionally called Array and Scalar, rather than being Local and Global
- C++ class generated by Paraiso has different interface.
Paraiso$ cabal install (...a few minutes...) Registering Paraiso-0.3.0.0... Paraiso$
Hello World
Bad news is that, all the examples found in the first paper on Paraiso are now deprecated. However, you can find a new genetarion of examples here:
Paraiso$ cd examples/HelloWorld/ HelloWorld$ cat Generator.hs
Here is a Haskell code that uses Paraiso and generates a very simple library, in C++:
#!/usr/bin/env runhaskell {-# LANGUAGE NoImplicitPrelude, OverloadedStrings #-} {-# OPTIONS -Wall #-} import Data.Dynamic import Data.Tensor.TypeLevel import qualified Data.Text.IO as T import Language.Paraiso.Annotation (Annotation) import Language.Paraiso.Generator (generateIO) import qualified Language.Paraiso.Generator.Native as Native import Language.Paraiso.Name import Language.Paraiso.OM import Language.Paraiso.OM.Builder import Language.Paraiso.OM.DynValue as DVal import Language.Paraiso.OM.PrettyPrint (prettyPrintA1) import Language.Paraiso.OM.Realm import qualified Language.Paraiso.OM.Reduce as Reduce import Language.Paraiso.Optimization import NumericPrelude import System.Process (system) -- the names we use table, total, create, tableMaker :: Name table = mkName "table" total = mkName "total" create = mkName "create" tableMaker = mkName "TableMaker" main :: IO () main = do _ <- system "mkdir -p output" T.writeFile "output/OM.txt" $ prettyPrintA1 $ myOM _ <- generateIO mySetup myOM return () mySetup :: Native.Setup Vec2 Int mySetup = (Native.defaultSetup $ Vec :~ 10 :~ 20) { Native.directory = "./dist/" } myOM :: OM Vec2 Int Annotation myOM = optimize O3 $ makeOM tableMaker [] myVars myKernels myVars :: [Named DynValue] myVars = [Named table $ DynValue Array (typeOf (undefined::Int)), Named total $ DynValue Scalar (typeOf (undefined::Int))] myKernels :: [Named (Builder Vec2 Int Annotation ())] myKernels = [Named create createBuilder] createBuilder :: Builder Vec2 Int Annotation () createBuilder = do x <- bind $ loadIndex (undefined::Int) (Axis 0) y <- bind $ loadIndex (undefined::Int) (Axis 1) z <- bind $ x*y store table z store total $ reduce Reduce.Sum z
Now let it generate the code and use it!
HelloWorld$ make runhaskell Generator.hs g++ main.cpp dist/TableMaker.cpp -o main.out
main.out uses the generated library and prints out the nice multiplication table for us.
HelloWorld$ ./main.out 0 0 0 0 0 0 0 0 0 0 0 1 2 3 4 5 6 7 8 9 0 2 4 6 8 10 12 14 16 18 0 3 6 9 12 15 18 21 24 27 0 4 8 12 16 20 24 28 32 36 0 5 10 15 20 25 30 35 40 45 0 6 12 18 24 30 36 42 48 54 0 7 14 21 28 35 42 49 56 63 0 8 16 24 32 40 48 56 64 72 0 9 18 27 36 45 54 63 72 81 0 10 20 30 40 50 60 70 80 90 0 11 22 33 44 55 66 77 88 99 0 12 24 36 48 60 72 84 96 108 0 13 26 39 52 65 78 91 104 117 0 14 28 42 56 70 84 98 112 126 0 15 30 45 60 75 90 105 120 135 0 16 32 48 64 80 96 112 128 144 0 17 34 51 68 85 102 119 136 153 0 18 36 54 72 90 108 126 144 162 0 19 38 57 76 95 114 133 152 171 total: 8550 HelloWorld$
No comments:
Post a Comment