Todos/fixes/concerns/task-list

Critical steps:

  • Finish semantics (partially done)
  • Detect and untie cycles in let exprs (done)
  • Add complete syntax for particles/emitters (done)
  • Make operations over vectors and scalars handle better
  • Try to reimplement examples from other systems, such as Fran, etc.)
  • Write some larger examples
  • Finalise and document the language
  • Implement CSE
  • Implement GPU-compilation (decide on Vertigo or Cg)
  • Test the compiler with tricky expressions
  • Finalise and document the optimizer/compiler
  • Implement rapid geometry transfer (using gl-extensions)
  • Implement complete app output (glut-framework)
  • Finalise and document C++ backend
  • Make nice color slides, present thesis
  • Graduate ;-)

Non-critical issues: (no ordering)

  • Smart Constructors
    Effectively eliminating LocalOpt.hs. This will ensure that we always have optimal expressions (locally), instead of the current situation were we run localopt on the expression only once and modify it afterwards, resulting in possibly unoptimal expressions.

  • Internal error checking
    Write a DExp validity checker, that checks types and the arity of each op. A lot of code just assumes things are correct and it would be nice to certify that it is so before doing anything.

  • Exp -> Code
    Make it easy to substitute particle commands for other commands, so that the compiler can be used for other purposes. A well designed set of type classes should do nicely.

  • Vector type
    Skip Vector3, Vector4, make Vector Int instead. Make Matrix Int Int too?

  • Scalar/Vector ops
    Am having problem with numeric literals. It works for my types, but not for simple literals.

  • Comparision of vectors?
    Comparision only works with scalar expressions. Should comparision of vector exps give a vector of 0,1 floats? (i.e. (1,2,3,4) < (4,3,2,1) => (1,1,0,0)) This could perhaps be useful in vertex programs (GF3/GF4-class), as they have this form of conditionals.

  • QuickCheck
    Use QuickCheck to verify the system? Will probably take quite some time to implement, but definitely seems to be a suitable framework. 


This serves as an aid to the diary.

Done:

  • Removed lots of issues that are void with the new design.

  • Rewrote Vec [DExp] as O Vec [DExp].. i.e. only one recursive case for the DExp datatype, which simplifies many operations.

  • Sorts out literals in multiple arity ops and folds these.

  • Removed constructor checks in DExp. Need not clutter that file with typechecks. Will write a checker Real Soon Now (tm).

  • Added LetRand & NewVar to DExp, to fix randomization optmimization problem. Also made:

    class Random a where 
      rand :: (a -> Exp b) -> Exp b

    with instantiations for FloatE, Float3E, Float4E and (2,3,4-element) tuples. Makes it really easy to write expressions with random variables.

  • Made Min/Max,&&* and ||* multiple-arity ops like * and +, and also added list-versions of these.

  • Unified Local, Particle and Environment variables into one.

    DExp = ... | Var Type Id Scope | ...
    data Scope = Temp | Local | Global

    Temp is used by the CSE/Randomization system. Local variables represent particle properties (read/write and variant) and global variables correspond to the environment (read-only and unform).

Solved:

  • Vector 'op' scalar
    How to use a single operator/function to multiply scalars and vectors in all permutations? Fran/Pan does not attempt to solve this, but it would be nice to mimic mathematical notation. (This is something that users simply expect to work. As do I. :)

    Solution: Multi-parameter typeclasses.
    It is not standard Haskell 98, but both GHC and Hugs support it through extensions.

    data Vector = Vector Float Float deriving Show 
    class Vec a b where add :: a -> b -> Vector 
    instance Vec Vector Float where 
    add (Vector a b) c = Vector (a+c) (a+c)
    instance Vec Float Vector where 
    add a (Vector b c) = Vector (a+b) (a+c)
    instance Vec Vector Vector where
    add (Vector a b) (Vector c d) = Vector (a+c) (b+d)

    This means that I can use add (or any similar operator) to make any componentwise operation possible without explicit scalar->vector expansion. Neat!
    (Might need to use functional dependecies.)

  • Optimisation of random values?
    Subexpressions with randomization in them are not equal, although the derived Eq instance surely says so. Massage all exps tagging each rand with a number? I do not want to expose my own let to the user (one which is used by the CSE-system), so how to distingush between the following two rows?

    r1 = let r = rand 
         in vec3 (r,r,r) 
    r2 = vec3 (rand, rand, rand)

    Solution, introduce special let for randomization:
    Extend DExp, define rand with var and use rand giving a function:

    LetRand String (Exp -> Exp) | NewVar (Var -> Exp) 
    
    rand :: (Exp -> Exp) -> Exp 
    rand f = NewVar $ \v -> LetRand v (f v) 
    
    rand3 :: (Exp ->Exp -> Exp -> Exp) -> Exp 
    rand3 f = rand $ \r1 -> rand $ \r2 -> rand $ \r3 -> f r1 r2 r3

    The two rows above would then be implemented as:

    r1 = rand $  \r -> vec3 (r,r,r) 
    r2 = rand3 $ \r1 r2 r3 -> vec3 (r1,r2,r3)

    Of course, we do not want to handle DExp:s with functions during optimization, so we process all expressions and create new local variables at each NewVar expression found. We should also check after CSE to see if the rand-vars are used only once, and inline the call to rand().