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