Thursday, May 17, 2012

Introduction to Computational Fluid Dynamics in Paraiso

Now the first paper on Paraiso is accepted. This is good, but like other just-born languages, there's a lot of refinements to be done, and nobody can use it without detailed documentation (even myself!).

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.
Now, you should be able to install the latest Paraiso, as follows.
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